adlibtracker2-2.4.23/0000755000000000000000000000000013176573537013032 5ustar rootrootadlibtracker2-2.4.23/cleanup.bat0000644000000000000000000000302413176573532015143 0ustar rootroot@echo off echo. echo ************************************ echo ** ** echo ** Deleting file garbage ** echo ** ** echo ************************************ echo. if not exist *.exe goto :no_exe_file del *.exe >nul :no_exe_file if not exist *.ppu goto :no_ppu_file del *.ppu :no_ppu_file if not exist *.o goto :no_o_file del *.o :no_o_file if not exist !log goto :no_log_file del !log :no_log_file if not exist adt2help.* goto :no_help_file del adt2help.* >nul :no_help_file if not exist adt2play\*.exe goto :no_exe_file2 del adt2play\*.exe >nul :no_exe_file2 if not exist adt2play\*.fpd goto :no_fpd_file2 del adt2play\*.fpd >nul :no_fpd_file2 if not exist adt2play\*.map goto :no_map_file2 del adt2play\*.map :no_map_file2 if not exist adt2play\*.obj goto :no_obj_file2 del adt2play\*.obj :no_obj_file2 if not exist adt2play\*.sym goto :no_sym_file2 del adt2play\*.sym :no_sym_file2 if not exist adt2play\!log goto :no_log_file2 del adt2play\!log :no_log_file2 if not exist *.ppu goto :no_ppu_file del /F /Q *.ppu :no_ppu_file if not exist *.o goto :no_o_file del /F /Q *.o :no_o_file if not exist *.or goto :no_or_file del /F /Q *.or :no_or_file if not exist *.res goto :no_res_file del /F /Q *.res :no_res_file if not exist sdl\*.ppu goto :no_ppu_file2 del /F /Q sdl\*.ppu :no_ppu_file2 if not exist sdl\*.o goto :no_o_file2 del /F /Q sdl\*.o :no_o_file2 if not exist sdl\*.a goto :no_a_file del /F /Q sdl\*.a :no_a_file adlibtracker2-2.4.23/adt2sys.pas0000644000000000000000000006534113176573532015134 0ustar rootrootunit AdT2sys; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const virtual_screen__first_row: Longint = 0; virtual_cur_shape: Word = 0; virtual_cur_pos: Word = 0; slide_ticks: Longint = 0; reset_slide_ticks: Boolean = FALSE; {$IFDEF GO32V2} gfx_ticks: Longint = 0; reset_gfx_ticks: Boolean = FALSE; scroll_ticks: Real = 0; mouse_active: Boolean = FALSE; {$ENDIF} blink_ticks: Longint = 0; blink_flag: Boolean = FALSE; cursor_sync: Boolean = FALSE; {$IFDEF GO32V2} _draw_screen_without_vsync: Boolean = FALSE; _draw_screen_without_delay: Boolean = FALSE; {$ELSE} _draw_screen_without_delay: Boolean = FALSE; _update_sdl_screen: Boolean = FALSE; _name_scrl_shift_ctr: Shortint = 1; _name_scrl_shift: Byte = 0; _name_scrl_pending_frames: Longint = 0; {$ENDIF} _cursor_blink_factor: Longint = 13; _cursor_blink_pending_frames: Longint = 0; _generic_blink_event_flag: Boolean = FALSE; _realtime_gfx_no_update: Boolean = FALSE; {$IFDEF GO32V2} _screen_refresh_pending_frames: Longint = 0; _custom_svga_cfg: array[1..31] of Record flag: Boolean; value: Longint; end = ((flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1)); {$ENDIF} const _debug_: Boolean = FALSE; _last_debug_str_: String = ''; _debug_str_: String = ''; const _force_program_quit: Boolean = FALSE; _traceprc_last_order: Byte = 0; _traceprc_last_pattern: Byte = 0; _traceprc_last_line: Byte = 0; _pattedit_lastpos: Byte = 0; procedure sys_init; procedure sys_done; procedure draw_screen; {$IFNDEF GO32V2} const _FrameBuffer: Pointer = NIL; procedure vid_Init; procedure vid_Deinit; procedure vid_SetVideoMode(do_delay: Boolean); procedure vid_SetRGBPalette(var palette); procedure vid_FadeOut; {$ELSE} var _FrameBuffer_mirror: array[0..PRED(1024*768)] of Byte; {$ENDIF} function iCASE_filename(str: String): String; function Lower_filename(str: String): String; function Upper_filename(str: String): String; procedure ResetF_RW(var f: File); procedure ResetF(var f: File); procedure RewriteF(var f: File); procedure BlockReadF(var f: File; var data; size: Longint; var bytes_read: Longint); procedure BlockWriteF(var f: File; var data; size: Longint; var bytes_written: Longint); procedure SeekF(var f: File; fpos: Longint); procedure EraseF(var f: File); procedure CloseF(var f: File); implementation uses {$IFDEF GO32V2} DOS,GO32,AdT2vesa, {$ELSE} DOS,SDL,SDL_Video,SDL_Timer,SDL__rwops, AdT2opl3, {$ENDIF} AdT2unit,AdT2text,AdT2keyb,AdT2data, TxtScrIO,StringIO,ParserIO; {$IFNDEF GO32V2} var screen: PSDL_Surface; rgb_color_alt: array[0..15] of tRGB; {$ENDIF} procedure sys_init; begin {$IFNDEF GO32V2} vid_Init; // SDL video AdT2opl3.snd_init; // SDL sound + opl3 emulation {$ENDIF} end; procedure sys_done; begin {$IFNDEF GO32V2} vid_Deinit; {$ENDIF} end; {$IFDEF GO32V2} procedure draw_VESA_screen_800x600_1; const H_RES = 800; V_RES = 600; H_CHR = 90; V_CHR = 30; var bit_pos,bit_mask: Byte; cur_pos_lo,cur_pos_hi: Byte; cur_shape: Word; pos_x,pos_y: Byte; base_ofs,skip_ofs: Dword; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm push ebx push esi push edi mov ax,word ptr [virtual_cur_pos] mov cur_pos_lo,al mov cur_pos_hi,ah mov ax,word ptr [virtual_cur_shape] mov cur_shape,ax mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] lea edi,[_FrameBuffer_mirror] mov base_ofs,edi add edi,(H_RES-H_CHR*8)/2+(V_RES-V_CHR*16)/2*H_RES mov ebx,dword ptr [screen_ptr] mov eax,virtual_screen__first_row mov skip_ofs,eax movzx eax,MAX_ROWS mov loop_idx1,eax mov pos_y,1 @@2: mov bit_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,H_CHR mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,bit_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 cmp skip_ofs,0 jz @@6 dec skip_ofs jmp @@9 @@6: mov eax,edi sub eax,base_ofs cmp eax,H_RES*V_RES-(H_RES-H_CHR*8)/2-(V_RES-V_CHR*16)/2*H_RES jnbe @@12 cmp byte ptr [cursor_sync],1 jnz @@7 movzx eax,pos_x cmp al,cur_pos_lo jnz @@7 mov ax,cur_shape cmp bit_pos,ah jb @@7 cmp bit_pos,al ja @@7 movzx eax,pos_y cmp al,cur_pos_hi jnz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,H_CHR*2 cmp skip_ofs,0 jz @@10 sub skip_ofs,H_RES-H_CHR*8 jmp @@11 @@10: add edi,H_RES-H_CHR*8 @@11: inc bit_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,H_CHR*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 @@12: end; end; procedure draw_VESA_screen_800x600_2; const H_RES = 800; V_RES = 600; H_CHR = 90; V_CHR = 36; var bit_pos,bit_mask: Byte; cur_pos_lo,cur_pos_hi: Byte; cur_shape: Word; pos_x,pos_y: Byte; base_ofs,skip_ofs: Dword; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov ax,word ptr [virtual_cur_pos] mov cur_pos_lo,al mov cur_pos_hi,ah mov ax,word ptr [virtual_cur_shape] mov cur_shape,ax mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] lea edi,[_FrameBuffer_mirror] mov base_ofs,edi add edi,(H_RES-H_CHR*8)/2+(V_RES-V_CHR*16)/2*H_RES mov ebx,dword ptr [screen_ptr] mov eax,virtual_screen__first_row mov skip_ofs,eax movzx eax,MAX_ROWS mov loop_idx1,eax mov pos_y,1 @@2: mov bit_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,H_CHR mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,bit_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 cmp skip_ofs,0 jz @@6 dec skip_ofs jmp @@9 @@6: mov eax,edi sub eax,base_ofs cmp eax,H_RES*V_RES-(H_RES-H_CHR*8)/2-(V_RES-V_CHR*16)/2*H_RES jnbe @@12 cmp byte ptr [cursor_sync],1 jnz @@7 movzx eax,pos_x cmp al,cur_pos_lo jnz @@7 mov ax,cur_shape cmp bit_pos,ah jb @@7 cmp bit_pos,al ja @@7 movzx eax,pos_y cmp al,cur_pos_hi jnz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,H_CHR*2 cmp skip_ofs,0 jz @@10 sub skip_ofs,H_RES-H_CHR*8 jmp @@11 @@10: add edi,H_RES-H_CHR*8 @@11: inc bit_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,H_CHR*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 @@12: end; end; procedure draw_VESA_screen_1024x768; const H_RES = 1024; V_RES = 768; H_CHR = 120; V_CHR = 46; var bit_pos,bit_mask: Byte; cur_pos_lo,cur_pos_hi: Byte; cur_shape: Word; pos_x,pos_y: Byte; base_ofs: Dword; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov ax,word ptr [virtual_cur_pos] mov cur_pos_lo,al mov cur_pos_hi,ah mov ax,word ptr [virtual_cur_shape] mov cur_shape,ax mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] lea edi,[_FrameBuffer_mirror] mov base_ofs,edi add edi,(H_RES-H_CHR*8)/2+(V_RES-V_CHR*16)/2*H_RES mov ebx,dword ptr [screen_ptr] movzx eax,MAX_ROWS mov loop_idx1,eax mov pos_y,1 @@2: mov bit_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,H_CHR mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,bit_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 mov eax,edi sub eax,base_ofs cmp eax,H_RES*V_RES-(H_RES-H_CHR*8)/2-(V_RES-V_CHR*16)/2*H_RES jnbe @@9 cmp byte ptr [cursor_sync],1 jnz @@6 movzx eax,pos_x cmp al,cur_pos_lo jnz @@6 mov ax,cur_shape cmp bit_pos,ah jb @@6 cmp bit_pos,al ja @@6 movzx eax,pos_y cmp al,cur_pos_hi jnz @@6 mov al,[ebx+1] and al,01111b stosb jmp @@8 @@6: movzx eax,bit_mask test dl,al jz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@8 @@7: mov al,[ebx+1] shr al,4 stosb @@8: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,H_CHR*2 add edi,H_RES-H_CHR*8 inc bit_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,H_CHR*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 @@9: end; end; procedure dump_VESA_buffer(buffer_size: Longint); var dumped_data_size,bank_data_size: Longint; current_bank: Byte; begin If NOT _draw_screen_without_vsync then WaitRetrace; dumped_data_size := 0; current_bank := 0; While (dumped_data_size < buffer_size) do begin If (dumped_data_size+65536 <= buffer_size) then bank_data_size := 65536 else bank_data_size := buffer_size-dumped_data_size; VESA_SwitchBank(current_bank); dosmemput($0a000,0,_FrameBuffer_mirror[dumped_data_size],bank_data_size); Inc(dumped_data_size,bank_data_size); Inc(current_bank); end; end; procedure shift_text_screen; var xsize: Byte; xshift: Byte; begin xsize := SCREEN_RES_X DIV scr_font_width; xshift := (xsize-MAX_COLUMNS) DIV 2; FillChar(ptr_temp_screen2^,SCREEN_MEM_SIZE,0); asm mov esi,dword ptr [screen_ptr] mov edi,dword ptr [ptr_temp_screen2] cld movzx ecx,MAX_ROWS movzx ebx,xshift shl ebx,1 add edi,ebx @@1: xchg ecx,edx movzx ecx,xsize rep movsw xchg ecx,edx loop @@1 end; end; procedure draw_screen; begin If _draw_screen_without_delay then _draw_screen_without_delay := FALSE else If do_synchronize and NOT (_screen_refresh_pending_frames > fps_down_factor) then EXIT else _screen_refresh_pending_frames := 0; If Compare(screen_ptr,ptr_screen_mirror,(SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2) then EXIT else begin ScreenMemCopy(screen_ptr,ptr_screen_mirror); If NOT is_VESA_emulated_mode then begin If NOT _draw_screen_without_vsync then WaitRetrace; If NOT (program_screen_mode in [4,5]) then dosmemput(v_seg,v_ofs,screen_ptr^,MAX_COLUMNS*MAX_ROWS*2) else begin shift_text_screen; dosmemput(v_seg,v_ofs,ptr_temp_screen2^,(SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2); end; end; end; _draw_screen_without_vsync := FALSE; If is_VESA_emulated_mode then Case get_VESA_emulated_mode_idx of 0: begin draw_VESA_screen_800x600_1; dump_VESA_buffer(800*600); end; 1: begin draw_VESA_screen_800x600_2; dump_VESA_buffer(800*600); end; 2: begin draw_VESA_screen_1024x768; dump_VESA_buffer(1024*768); end; end; end; {$ELSE} procedure draw_SDL_screen_720x480; var bit_pos,bit_mask: Byte; pos_x,pos_y: Byte; skip: Dword; framebuffer_end: Dword; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] mov edi,dword ptr [_FrameBuffer] mov framebuffer_end,edi add framebuffer_end,720*480 mov ebx,dword ptr [screen_ptr] mov eax,virtual_screen__first_row mov skip,eax mov loop_idx1,40 mov pos_y,1 @@2: mov bit_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,90 mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,bit_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 cmp skip,0 jz @@6 dec skip jmp @@9 @@6: cmp cursor_sync,1 jnz @@7 movzx eax,byte ptr [pos_x] cmp al,byte ptr [virtual_cur_pos] jnz @@7 mov ax,word ptr [virtual_cur_shape] cmp bit_pos,ah jb @@7 cmp bit_pos,al ja @@7 movzx eax,pos_y cmp al,byte ptr [virtual_cur_pos+1] jnz @@7 mov al,[ebx+1] and al,01111b cmp edi,framebuffer_end ja @@9 stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b cmp edi,framebuffer_end ja @@9 stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 cmp edi,framebuffer_end ja @@9 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,90*2 inc bit_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,90*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 end; end; procedure draw_SDL_screen_960x800; var bit_pos,bit_mask: Byte; pos_x,pos_y: Byte; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] mov edi,dword ptr [_FrameBuffer] mov ebx,dword ptr [screen_ptr] mov loop_idx1,50 mov pos_y,1 @@2: mov bit_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,120 mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,bit_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 @@6: cmp cursor_sync,1 jnz @@7 movzx eax,byte ptr [pos_x] cmp al,byte ptr [virtual_cur_pos] jnz @@7 mov ax,word ptr [virtual_cur_shape] cmp bit_pos,ah jb @@7 cmp bit_pos,al ja @@7 movzx eax,pos_y cmp al,byte ptr [virtual_cur_pos+1] jnz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,120*2 inc bit_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,120*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 end; end; procedure draw_SDL_screen_1440x960; var bit_pos,bit_mask: Byte; pos_x,pos_y: Byte; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] mov edi,dword ptr [_FrameBuffer] mov ebx,dword ptr [screen_ptr] mov loop_idx1,60 mov pos_y,1 @@2: mov bit_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,180 mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,bit_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 @@6: cmp cursor_sync,1 jnz @@7 movzx eax,byte ptr [pos_x] cmp al,byte ptr [virtual_cur_pos] jnz @@7 mov ax,word ptr [virtual_cur_shape] cmp bit_pos,ah jb @@7 cmp bit_pos,al ja @@7 movzx eax,pos_y cmp al,byte ptr [virtual_cur_pos+1] jnz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,180*2 inc bit_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,180*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 end; end; procedure draw_screen_proc; begin _update_sdl_screen := FALSE; If Compare(screen_ptr,ptr_screen_mirror,(SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2) then EXIT else ScreenMemCopy(screen_ptr,ptr_screen_mirror); _cursor_blink_factor := ROUND(13/100*sdl_frame_rate); _update_sdl_screen := TRUE; Case program_screen_mode of 0: draw_SDL_screen_720x480; 1: draw_SDL_screen_960x800; 2: draw_SDL_screen_1440x960; end; end; procedure vid_Init; begin SDL_Init(SDL_INIT_VIDEO or SDL_INIT_TIMER or SDL_INIT_AUDIO); end; procedure vid_Deinit; begin SDL_FreeSurface(screen); SDL_Quit; end; procedure vid_SetRGBPalette(var palette); begin SDL_SetPalette(screen,SDL_PHYSPAL,SDL_ColorArray(palette),0,16); end; procedure draw_screen; const frame_start: Longint = 0; frame_end: Longint = 0; actual_frame_end: Longint = 0; begin realtime_gfx_poll_proc; draw_screen_proc; If _update_sdl_screen then SDL_Flip(screen); If _draw_screen_without_delay then _draw_screen_without_delay := FALSE else begin // keep framerate actual_frame_end := SDL_GetTicks; frame_end := frame_start+(1000 DIV sdl_frame_rate); // always sleep at least 2 msec If (actual_frame_end+2 > frame_end) then frame_end := actual_frame_end+2; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; end; end; procedure vid_SetVideoMode(do_delay: Boolean); var icon: pSDL_Surface; rwop: pSDL_RWops; win_title: String; begin If do_delay then SDL_Delay(1000); screen := SDL_SetVideoMode(SCREEN_RES_x,SCREEN_RES_y,8,SDL_SWSURFACE); If (screen = NIL) then begin WriteLn('SDL: Couldn''t initialize video mode'); HALT(1); end; vid_SetRGBPalette(Addr(rgb_color)^); Move(rgb_color,rgb_color_alt,SizeOf(rgb_color)); _FrameBuffer := screen^.pixels; rwop := SDL_RWFromMem(adt2_icon_bitmap,SizeOf(adt2_icon_bitmap)); icon := SDL_LoadBMP_RW(rwop,TRUE); SDL_WM_SetIcon(icon,NIL); win_title := '/|DLiB TR/|CK3R ][ SDL'+#0; SDL_WM_SetCaption(Addr(win_title[1]),NIL); end; procedure vid_FadeOut; var idx: Byte; function min0(val: Longint): Longint; begin If (val <= 0) then min0 := 0 else min0 := val; end; begin For idx := 1 to 15 do begin rgb_color_alt[idx].r := min0(rgb_color_alt[idx].r-1); rgb_color_alt[idx].g := min0(rgb_color_alt[idx].g-1); rgb_color_alt[idx].b := min0(rgb_color_alt[idx].b-1); end; SDL_SetPalette(screen,SDL_PHYSPAL,SDL_ColorArray(Addr(rgb_color_alt)^),0,16); end; {$ENDIF} function iCASE_filename(str: String): String; begin {$IFDEF UNIX} iCASE_filename := str; {$ELSE} iCASE_filename := iCASE(str); {$ENDIF} end; function Lower_filename(str: String): String; begin {$IFDEF UNIX} Lower_filename := str; {$ELSE} Lower_filename := Lower(str); {$ENDIF} end; function Upper_filename(str: String): String; begin {$IFDEF UNIX} Upper_filename := str; {$ELSE} Upper_filename := Upper(str); {$ENDIF} end; procedure ResetF_RW(var f: File); var fattr: Word; begin _debug_str_:= 'ADT2SYS.PAS:ResetF_RW'; GetFAttr(f,fattr); If (fattr AND ReadOnly = ReadOnly) then SetFAttr(f,fattr AND NOT ReadOnly); If (DosError <> 0) then ; FileMode := 2; {$i-} Reset(f,1); {$i+} end; procedure ResetF(var f: File); var fattr: Word; begin _debug_str_:= 'ADT2SYS.PAS:ResetF'; GetFAttr(f,fattr); If (fattr AND ReadOnly = ReadOnly) then FileMode := 0; {$i-} Reset(f,1); {$i+} end; procedure RewriteF(var f: File); var fattr: Word; begin _debug_str_:= 'ADT2SYS.PAS:RewriteF'; GetFAttr(f,fattr); If (fattr AND ReadOnly = ReadOnly) then SetFAttr(f,fattr AND NOT ReadOnly); {$i-} Rewrite(f,1); {$i+} end; procedure BlockReadF(var f: File; var data; size: Longint; var bytes_read: Longint); begin _debug_str_:= 'ADT2SYS.PAS:BlockReadF'; {$i-} BlockRead(f,data,size,bytes_read); {$i+} If (IOresult <> 0) then bytes_read := 0; end; procedure BlockWriteF(var f: File; var data; size: Longint; var bytes_written: Longint); begin _debug_str_:= 'ADT2SYS.PAS:BlockWriteF'; {$i-} BlockWrite(f,data,size,bytes_written); {$i+} If (IOresult <> 0) then bytes_written := 0; end; procedure SeekF(var f: File; fpos: Longint); begin _debug_str_:= 'ADT2SYS.PAS:SeekF'; {$i-} Seek(f,fpos); {$i+} end; procedure EraseF(var f: File); begin _debug_str_:= 'ADT2SYS.PAS:EraseF'; {$i-} Erase(f); {$i+} If (IOresult <> 0) then ; end; procedure CloseF(var f: File); begin _debug_str_:= 'ADT2SYS.PAS:CloseF'; {$i-} Close(f); {$i+} If (IOresult <> 0) then ; end; end. adlibtracker2-2.4.23/adt2extn.pas0000644000000000000000000107001213176573532015264 0ustar rootrootunit AdT2extn; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const remap_mtype: Byte = 1; remap_ins1: Byte = 1; remap_ins2: Byte = 1; remap_selection: Byte = 1; rearrange_selection: Byte = 1; replace_selection: Byte = 1; replace_prompt: Boolean = FALSE; replace_data: Record event_to_find: Record note: String[3]; inst: String[2]; fx_1: String[3]; fx_2: String[3]; end; new_event: Record note: String[3]; inst: String[2]; fx_1: String[3]; fx_2: String[3]; end; end = ( event_to_find: (note: '???'; inst: '??'; fx_1: '???'; fx_2: '???'); new_event: (note: '???'; inst: '??'; fx_1: '???'; fx_2: '???')); var fkey: Word; var progress_xstart,progress_ystart: Byte; progress_num_steps: Byte; progress_step: Byte; progress_value: Dword; progress_old_value,progress_new_value: Byte; var tracing_block_pattern, tracing_block_xend, tracing_block_yend: Byte; const copypos1: Byte = 1; copypos2: Byte = 1; copypos3: Byte = 1; copypos4: Byte = 1; clearpos: Byte = 1; pattern_list__page: Byte = 1; pattern2use: Byte = BYTE(NOT 0); type tTRANSPOSE_TYPE = (ttTransposeUp,ttTransposeDown, ttTransposeCurrentIns,ttTransposeAllIns); function _patts_marked: Byte; procedure nul_volume_bars; procedure transpose_custom_area(type1,type2: tTRANSPOSE_TYPE; patt0,patt1,track0,track1,line0,line1: Byte; factor: Byte); procedure TRANSPOSE; procedure REMAP; procedure REARRANGE; procedure REPLACE; procedure POSITIONS_reset; procedure DEBUG_INFO; procedure LINE_MARKING_SETUP; procedure OCTAVE_CONTROL; procedure SONG_VARIABLES; procedure FILE_save(ext: String); function FILE_open(masks: String; loadBankPossible: Boolean): Byte; procedure NUKE; procedure MESSAGE_BOARD; procedure QUIT_request; procedure show_progress(value: Longint); implementation uses {$IFNDEF UNIX} CRT, {$ENDIF} {$IFNDEF GO32V2} SDL_Timer, {$ENDIF} AdT2opl3, AdT2sys,AdT2keyb,AdT2unit,AdT2ext2,AdT2ext3,AdT2ext4,AdT2ext5,AdT2text,AdT2pack, StringIO,DialogIO,ParserIO,TxtScrIO,MenuLib1,MenuLib2; function _patts_marked: Byte; var temp, result: Byte; begin result := 0; For temp := 0 to $7f do If (songdata.pattern_names[temp][1] = #16) then Inc(result); _patts_marked := result; end; procedure nul_volume_bars; var chan: Byte; begin For chan := chan_pos to chan_pos+MAX_TRACKS-1 do If channel_flag[chan] then show_str(08+(chan-PRED(chan_pos)-1)*15,MAX_PATTERN_ROWS+11, ExpStrR('',14,#205), pattern_bckg+pattern_border); end; const transp_menu2: Boolean = FALSE; transp_pos1: Byte = 1; transp_pos2: Byte = 1; procedure transpose_custom_area(type1,type2: tTRANSPOSE_TYPE; patt0,patt1,track0,track1,line0,line1: Byte; factor: Byte); var skip_all,erase_all: Boolean; _1st_choice: Byte; _break,_continue: Boolean; chunk: tCHUNK; temp,temp1,temp2,temp3: Byte; status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:transpose_custom_area'; {$ENDIF} status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; PATTERN_position_preview(BYTE_NULL,BYTE_NULL,BYTE_NULL,0); _1st_choice := BYTE_NULL; _break := FALSE; _continue := TRUE; Case type1 of ttTransposeUp: For temp3 := patt0 to patt1 do begin For temp2 := track0 to track1 do begin For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If NOT (type2 = ttTransposeCurrentIns) then begin If NOT (chunk.note+factor <= 12*8+1) and NOT (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' TRANSPOSE ',1); _1st_choice := temp; If (dl_environment.keystroke <> kESC) and (_1st_choice <> 5) then begin _break := TRUE; BREAK; end else begin _break := TRUE; _continue := FALSE; BREAK; end; end; end else If NOT (chunk.note < 12*8+1) and NOT (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' TRANSPOSE ',1); _1st_choice := temp; If (dl_environment.keystroke <> kESC) and (_1st_choice <> 5) then begin _break := TRUE; BREAK; end else begin _break := TRUE; _continue := FALSE; BREAK; end; end; end; If _break then BREAK; end; If _break then BREAK; end; ttTransposeDown: For temp3 := patt0 to patt1 do begin For temp2 := track0 to track1 do begin For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If NOT (type2 = ttTransposeCurrentIns) then begin If NOT (chunk.note >= factor+1) and NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' TRANSPOSE ',1); _1st_choice := temp; If (dl_environment.keystroke <> kESC) and (_1st_choice <> 5) then begin _break := TRUE; BREAK; end else begin _break := TRUE; _continue := FALSE; BREAK; end; end; end else If NOT (chunk.note >= factor+1) and NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' TRANSPOSE ',1); _1st_choice := temp; If (dl_environment.keystroke <> kESC) and (_1st_choice <> 5) then begin _break := TRUE; BREAK; end else begin _break := TRUE; _continue := FALSE; BREAK; end; end; end; If _break then BREAK; end; If _break then BREAK; end; end; _break := FALSE; skip_all := FALSE; erase_all := FALSE; If _continue then Case type1 of ttTransposeUp: For temp3 := patt0 to patt1 do begin For temp2 := track0 to track1 do begin For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If NOT (type2 = ttTransposeCurrentIns) then begin If NOT (chunk.note+factor <= 12*8+1) and NOT (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin If (_1st_choice <> BYTE_NULL) then begin Case _1st_choice of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (_1st_choice = 2) then erase_all := TRUE; end; 3, 4: If (_1st_choice = 4) then skip_all := TRUE; end; put_chunk(temp3,temp1,temp2,chunk); _1st_choice := BYTE_NULL; CONTINUE; end; If skip_all then CONTINUE; If erase_all then begin chunk.note := 0; chunk.instr_def := 0; put_chunk(temp3,temp1,temp2,chunk); CONTINUE; end; PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' TRANSPOSE ',1); If (dl_environment.keystroke <> kESC) then begin Case temp of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (temp = 2) then erase_all := TRUE; end; 3, 4: If (temp = 4) then skip_all := TRUE; 5: begin _break := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin Inc(chunk.note,factor); put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note < 12*8+1) and NOT (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin If (_1st_choice <> BYTE_NULL) then begin Case _1st_choice of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (_1st_choice = 2) then erase_all := TRUE; end; 3, 4: If (_1st_choice = 4) then skip_all := TRUE; end; put_chunk(temp3,temp1,temp2,chunk); _1st_choice := BYTE_NULL; CONTINUE; end; If skip_all then CONTINUE; If erase_all then begin chunk.note := 0; chunk.instr_def := 0; put_chunk(temp3,temp1,temp2,chunk); CONTINUE; end; PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' TRANSPOSE ',1); If (dl_environment.keystroke <> kESC) then begin Case temp of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (temp = 2) then erase_all := TRUE; end; 3, 4: If (temp = 4) then skip_all := TRUE; 5: begin _break := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin Inc(chunk.note,factor); put_chunk(temp3,temp1,temp2,chunk); end; end; If _break then BREAK; end; If _break then BREAK; end; ttTransposeDown: For temp3 := patt0 to patt1 do begin For temp2 := track0 to track1 do begin For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If NOT (type2 = ttTransposeCurrentIns) then begin If NOT (chunk.note >= factor+1) and NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin If (_1st_choice <> BYTE_NULL) then begin Case _1st_choice of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (_1st_choice = 2) then erase_all := TRUE; end; 3, 4: If (_1st_choice = 4) then skip_all := TRUE; end; put_chunk(temp3,temp1,temp2,chunk); _1st_choice := BYTE_NULL; CONTINUE; end; If skip_all then CONTINUE; If erase_all then begin chunk.note := 0; chunk.instr_def := 0; put_chunk(temp3,temp1,temp2,chunk); CONTINUE; end; PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' TRANSPOSE ',1); If (dl_environment.keystroke <> kESC) then begin Case temp of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (temp = 2) then erase_all := TRUE; end; 3, 4: If (temp = 4) then skip_all := TRUE; 5: begin _break := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin Dec(chunk.note,factor); put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note >= factor+1) and NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin If (_1st_choice <> BYTE_NULL) then begin Case _1st_choice of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (_1st_choice = 2) then erase_all := TRUE; end; 3, 4: If (_1st_choice = 4) then skip_all := TRUE; end; put_chunk(temp3,temp1,temp2,chunk); _1st_choice := BYTE_NULL; CONTINUE; end; If skip_all then CONTINUE; If erase_all then begin chunk.note := 0; chunk.instr_def := 0; put_chunk(temp3,temp1,temp2,chunk); CONTINUE; end; PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' TRANSPOSE ',1); If (dl_environment.keystroke <> kESC) then begin Case temp of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (temp = 2) then erase_all := TRUE; end; 3, 4: If (temp = 4) then skip_all := TRUE; 5: begin _break := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin Dec(chunk.note,factor); put_chunk(temp3,temp1,temp2,chunk); end; end; If _break then BREAK; end; If _break then BREAK; end; end; PATTERN_position_preview(BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; procedure transpose__control_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:transpose__control_proc'; {$ENDIF} If (mn_environment.curr_pos in [1..8]) then begin If (mn_environment.curr_pos in [1..4]) then begin transp_menu_str1[2] := Copy(transp_menu_str1[2],1,18)+transp_mnu_str5[1]; transp_menu_str1[3] := Copy(transp_menu_str1[3],1,18)+transp_mnu_str5[2]; transp_menu_str1[5] := Copy(transp_menu_str1[5],1,37)+transp_mnu_str5[18]; transp_menu_str1[6] := Copy(transp_menu_str1[6],1,18)+transp_mnu_str5[3]; transp_menu_str1[7] := Copy(transp_menu_str1[7],1,18)+transp_mnu_str5[4]; end else begin transp_menu_str1[2] := Copy(transp_menu_str1[2],1,18)+transp_mnu_str5[5]; transp_menu_str1[3] := Copy(transp_menu_str1[3],1,18)+transp_mnu_str5[6]; transp_menu_str1[5] := Copy(transp_menu_str1[5],1,37)+transp_mnu_str5[18]; transp_menu_str1[6] := Copy(transp_menu_str1[6],1,18)+transp_mnu_str5[7]; transp_menu_str1[7] := Copy(transp_menu_str1[7],1,18)+transp_mnu_str5[8]; end; If NOT transp_menu2 then transp_menu_str1[4] := Copy(transp_menu_str1[4],1,37)+transp_mnu_str5[10] else transp_menu_str1[4] := Copy(transp_menu_str1[4],1,37)+transp_mnu_str5[11]; end else begin transp_menu_str1[2] := Copy(transp_menu_str1[2],1,18)+transp_mnu_str5[5]; transp_menu_str1[3] := Copy(transp_menu_str1[3],1,18)+transp_mnu_str5[9]; transp_menu_str1[5] := Copy(transp_menu_str1[5],1,37)+transp_mnu_str5[19]; transp_menu_str1[6] := Copy(transp_menu_str1[6],1,18)+transp_mnu_str5[3]; transp_menu_str1[7] := Copy(transp_menu_str1[7],1,18)+transp_mnu_str5[4]; If NOT transp_menu2 then transp_menu_str1[4] := Copy(transp_menu_str1[4],1,37)+transp_mnu_str5[12] else transp_menu_str1[4] := Copy(transp_menu_str1[4],1,37)+transp_mnu_str5[13]; end; If (mn_environment.curr_pos in [10..17]) then begin If (mn_environment.curr_pos in [10..13]) then begin transp_menu_str1[11] := Copy(transp_menu_str1[11],1,18)+transp_mnu_str5[1]; transp_menu_str1[12] := Copy(transp_menu_str1[12],1,18)+transp_mnu_str5[2]; transp_menu_str1[14] := Copy(transp_menu_str1[14],1,37)+transp_mnu_str5[18]; transp_menu_str1[15] := Copy(transp_menu_str1[15],1,18)+transp_mnu_str5[3]; transp_menu_str1[16] := Copy(transp_menu_str1[16],1,18)+transp_mnu_str5[4]; end else begin transp_menu_str1[11] := Copy(transp_menu_str1[11],1,18)+transp_mnu_str5[5]; transp_menu_str1[12] := Copy(transp_menu_str1[12],1,18)+transp_mnu_str5[6]; transp_menu_str1[14] := Copy(transp_menu_str1[14],1,37)+transp_mnu_str5[18]; transp_menu_str1[15] := Copy(transp_menu_str1[15],1,18)+transp_mnu_str5[7]; transp_menu_str1[16] := Copy(transp_menu_str1[16],1,18)+transp_mnu_str5[8]; end; If NOT transp_menu2 then transp_menu_str1[13] := Copy(transp_menu_str1[13],1,37)+transp_mnu_str5[14] else transp_menu_str1[13] := Copy(transp_menu_str1[13],1,37)+transp_mnu_str5[15]; end else If NOT (transp_menu2 and NOT marking) then begin transp_menu_str1[11] := Copy(transp_menu_str1[11],1,18)+transp_mnu_str5[5]; transp_menu_str1[12] := Copy(transp_menu_str1[12],1,18)+transp_mnu_str5[9]; transp_menu_str1[14] := Copy(transp_menu_str1[14],1,37)+transp_mnu_str5[19]; transp_menu_str1[15] := Copy(transp_menu_str1[15],1,18)+transp_mnu_str5[3]; transp_menu_str1[16] := Copy(transp_menu_str1[16],1,18)+transp_mnu_str5[4]; If NOT transp_menu2 then transp_menu_str1[13] := Copy(transp_menu_str1[13],1,37)+transp_mnu_str5[16] else transp_menu_str1[13] := Copy(transp_menu_str1[13],1,37)+transp_mnu_str5[17]; end; mn_environment.do_refresh := TRUE; mn_environment.refresh; end; procedure TRANSPOSE; var patt0,patt1,track0,track1,line0,line1: Byte; patterns: Byte; old_text_attr: Byte; const factor: array[1..17] of Byte = (1,12,1,12,1,12,1,12,BYTE_NULL, 1,12,1,12,1,12,1,12); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:TRANSPOSE'; {$ENDIF} old_text_attr := mn_setting.text_attr; mn_setting.text_attr := dialog_background+dialog_text; mn_setting.cycle_moves := TRUE; mn_setting.fixed_len := 14; mn_setting.terminate_keys[3] := kTAB; mn_environment.ext_proc := transpose__control_proc; count_patterns(patterns); Repeat If transp_menu2 then begin mn_environment.context := ' TAB '#196#16' PATTERN/SONG '; transp_menu_str1[4] := transp_menu_str4[3]; If marking then begin Move(transp_menu_str2,transp_menu_str1[10],SizeOf(transp_menu_str2)); transp_menu_str1[13] := transp_menu_str4[4]; end else Move(transp_menu_str3,transp_menu_str1[10],SizeOf(transp_menu_str3)); end else begin mn_environment.context := ' TAB '#196#16' TRACK/BLOCK '; Move(transp_menu_str2,transp_menu_str1[10],SizeOf(transp_menu_str2)); transp_menu_str1[4] := transp_menu_str4[1]; transp_menu_str1[13] := transp_menu_str4[2]; end; transpos := Menu(transp_menu_str1,01,01,transpos,50,17,17,' TRANSPOSE '); If transp_menu2 then transp_pos1 := transpos else transp_pos2 := transpos; If (mn_environment.keystroke = kTAB) then begin transp_menu2 := NOT transp_menu2; If transp_menu2 then transpos := transp_pos1 else transpos := transp_pos2; keyboard_reset_buffer; end; If (mn_environment.keystroke <> kESC) and (mn_environment.keystroke <> kTAB) then begin If transp_menu2 or (transpos < 9) then begin patt0 := pattern_patt; patt1 := patt0; end else begin patt0 := 0; patt1 := patterns; end; If NOT transp_menu2 then begin line0 := 0; line1 := PRED(songdata.patt_len); track0 := 1; track1 := songdata.nm_tracks; end else If (transpos < 9) then begin line0 := 0; line1 := PRED(songdata.patt_len); track0 := count_channel(pattern_hpos); track1 := track0; end else begin If tracing then begin patt0 := tracing_block_pattern; patt1 := patt0; end; line0 := block_y0; line1 := block_y1; track0 := block_x0; track1 := block_x1; end; Case transpos of 1,2, 5,6, 10..11, 14..15: If (transpos in [1..4,10..13]) then transpose_custom_area(ttTransposeUp, ttTransposeCurrentIns, patt0,patt1,track0,track1,line0,line1, factor[transpos]) else transpose_custom_area(ttTransposeUp, ttTransposeAllIns, patt0,patt1,track0,track1,line0,line1, factor[transpos]); 3,4, 7,8, 12..13, 16..17: If (transpos in [1..4,10..13]) then transpose_custom_area(ttTransposeDown, ttTransposeCurrentIns, patt0,patt1,track0,track1,line0,line1, factor[transpos]) else transpose_custom_area(ttTransposeDown, ttTransposeAllIns, patt0,patt1,track0,track1,line0,line1, factor[transpos]); end; end; until (mn_environment.keystroke <> kTAB); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); mn_setting.fixed_len := 0; mn_setting.terminate_keys[3] := 0; mn_environment.context := ''; mn_environment.ext_proc := NIL; mn_setting.text_attr := old_text_attr; end; function cstr2str(str: String): String; var temp: Byte; begin For temp := 1 to Length(str) do If (str[temp] = '~') then Delete(str,temp,1); cstr2str := str; end; var _remap_pos, _remap_inst_page_len, _remap_xstart, _remap_ystart: Byte; procedure _remap_refresh_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_remap_refresh_proc'; {$ENDIF} If (_remap_pos = 1) then ShowStr(centered_frame_vdest,_remap_xstart+8,_remap_ystart+1,'CURRENT iNSTRUMENT ('+ byte2hex(MenuLib1_mn_environment.curr_pos)+')', dialog_background+dialog_hi_text) else ShowStr(centered_frame_vdest,_remap_xstart+8,_remap_ystart+1,'CURRENT iNSTRUMENT ('+ byte2hex(MenuLib1_mn_environment.curr_pos)+')', dialog_background+dialog_text); If (_remap_pos = 2) then ShowStr(centered_frame_vdest,_remap_xstart+44,_remap_ystart+1,'NEW iNSTRUMENT ('+ byte2hex(MenuLib2_mn_environment.curr_pos)+')', dialog_background+dialog_hi_text) else ShowStr(centered_frame_vdest,_remap_xstart+44,_remap_ystart+1,'NEW iNSTRUMENT ('+ byte2hex(MenuLib2_mn_environment.curr_pos)+')', dialog_background+dialog_text); If (_remap_pos = 3) then ShowStr(centered_frame_vdest,_remap_xstart+18,_remap_ystart+_remap_inst_page_len+4,' PATTERN ', dialog_hi_text SHL 4) else If (remap_selection = 1) then ShowStr(centered_frame_vdest,_remap_xstart+18,_remap_ystart+_remap_inst_page_len+4,' PATTERN ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_remap_xstart+18,_remap_ystart+_remap_inst_page_len+4,' PATTERN ', dialog_background+dialog_text); If (_remap_pos = 4) then ShowStr(centered_frame_vdest,_remap_xstart+29,_remap_ystart+_remap_inst_page_len+4,' SONG ', dialog_hi_text SHL 4) else If (remap_selection = 2) then ShowStr(centered_frame_vdest,_remap_xstart+29,_remap_ystart+_remap_inst_page_len+4,' SONG ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_remap_xstart+29,_remap_ystart+_remap_inst_page_len+4,' SONG ', dialog_background+dialog_text); If (_remap_pos = 5) then ShowStr(centered_frame_vdest,_remap_xstart+37,_remap_ystart+_remap_inst_page_len+4,' TRACK ', dialog_hi_text SHL 4) else If (remap_selection = 3) then ShowStr(centered_frame_vdest,_remap_xstart+37,_remap_ystart+_remap_inst_page_len+4,' TRACK ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_remap_xstart+37,_remap_ystart+_remap_inst_page_len+4,' TRACK ', dialog_background+dialog_text); If (_remap_pos = 6) then ShowStr(centered_frame_vdest,_remap_xstart+46,_remap_ystart+_remap_inst_page_len+4,' BLOCK ', dialog_hi_text SHL 4) else If (remap_selection = 4) then ShowStr(centered_frame_vdest,_remap_xstart+46,_remap_ystart+_remap_inst_page_len+4,' BLOCK ', dialog_sel_itm_bck+dialog_sel_itm) else If marking then ShowStr(centered_frame_vdest,_remap_xstart+46,_remap_ystart+_remap_inst_page_len+4,' BLOCK ', dialog_background+dialog_text) else ShowStr(centered_frame_vdest,_remap_xstart+46,_remap_ystart+_remap_inst_page_len+4,' BLOCK ', dialog_background+dialog_item_dis); end; procedure REMAP_instr_control_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REMAP_instr_control_proc'; {$ENDIF} _remap_refresh_proc; If (remap_mtype = 1) then INSTRUMENT_test(MenuLib1_mn_environment.curr_pos,BYTE_NULL,count_channel(pattern_hpos), MenuLib1_mn_environment.keystroke,TRUE) else INSTRUMENT_test(MenuLib2_mn_environment.curr_pos,BYTE_NULL,count_channel(pattern_hpos), MenuLib2_mn_environment.keystroke,TRUE); end; procedure REMAP; var status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; var chunk: tCHUNK; temp,temp1,temp2,temp3: Byte; patt0,patt1,track0,track1,line0,line1: Byte; fkey: Word; patterns: Byte; qflag: Boolean; procedure reset_screen; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REMAP:reset_screen'; {$ENDIF} MenuLib1_mn_environment.ext_proc := NIL; MenuLib2_mn_environment.ext_proc := NIL; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := _remap_xstart; move_to_screen_area[2] := _remap_ystart; move_to_screen_area[3] := _remap_xstart+71+2; move_to_screen_area[4] := _remap_ystart+_remap_inst_page_len+5+1; move2screen; end; procedure override_frame(dest: tSCREEN_MEM_PTR; x,y: Byte; frame: String; attr: Byte); procedure override_attr(dest: tSCREEN_MEM_PTR; x,y: Byte; len: Byte; attr: Byte); begin asm mov al,MaxCol dec al xor ah,ah xor ebx,ebx mov bl,2 mul bl mov bx,ax mov edi,dword ptr [dest] mov al,x mov ah,y push eax push ebx mov al,MaxCol xor ah,ah xor ebx,ebx mov bl,y dec bl mul bl mov bl,x dec bl add eax,ebx mov edx,eax shl edx,1 pop ebx pop eax xor ecx,ecx mov cl,len jecxz @@2 add edi,edx mov al,attr @@1: inc edi stosb add edi,ebx loop @@1 @@2: end; end; begin ShowStr(dest,x,y,frame[1]+ExpStrL('',32,frame[2])+frame[3],attr); ShowVStr(dest,x,y+1,ExpStrL('',MAX_PATTERN_ROWS,frame[4]),attr); ShowStr(dest,x,y+MAX_PATTERN_ROWS+1,frame[6]+ExpStrL('',32,frame[7])+frame[8],attr); override_attr(dest,x+33,y+1,MAX_PATTERN_ROWS,attr); end; var temp_instr_names: array[1..255] of String[32]; label _jmp1; begin { REMAP } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REMAP'; {$ENDIF} If (remap_selection = 4) and NOT marking then remap_selection := 1; _remap_pos := 1; _remap_inst_page_len := MAX_PATTERN_ROWS; qflag := FALSE; MenuLib1_mn_setting.menu_attr := dialog_background+dialog_text; MenuLib2_mn_setting.menu_attr := dialog_background+dialog_text; _jmp1: If _force_program_quit then EXIT; For temp := 1 to 255 do temp_instr_names[temp] := ' '+Copy(cstr2str(songdata.instr_names[temp]),2,31); ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; count_patterns(patterns); ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(_remap_xstart,_remap_ystart,71,_remap_inst_page_len+5,' REMAP iNSTRUMENT ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); MenuLib1_mn_environment.curr_pos := remap_ins1; MenuLib2_mn_environment.curr_pos := remap_ins2; MenuLib1_mn_environment.v_dest := ptr_temp_screen; MenuLib2_mn_environment.v_dest := ptr_temp_screen; MenuLib1_mn_environment.ext_proc := REMAP_instr_control_proc; MenuLib2_mn_environment.ext_proc := REMAP_instr_control_proc; MenuLib1_mn_environment.unpolite := FALSE; MenuLib1_mn_environment.preview := TRUE; remap_ins1 := MenuLib1_Menu(temp_instr_names,_remap_xstart+2,_remap_ystart+2, remap_ins1,32,_remap_inst_page_len,255,''); MenuLib2_mn_environment.unpolite := FALSE; MenuLib2_mn_environment.preview := TRUE; remap_ins2 := MenuLib2_Menu(temp_instr_names,_remap_xstart+36,_remap_ystart+2, remap_ins2,32,_remap_inst_page_len,255,''); If (_remap_pos = 1) then override_frame(centered_frame_vdest,_remap_xstart+2,_remap_ystart+2, frame_double, dialog_background+dialog_hi_text) else override_frame(centered_frame_vdest,_remap_xstart+2,_remap_ystart+2, frame_single, dialog_background+dialog_text); If (_remap_pos = 2) then override_frame(centered_frame_vdest,_remap_xstart+36,_remap_ystart+2, frame_double,dialog_background+dialog_hi_text) else override_frame(centered_frame_vdest,_remap_xstart+36,_remap_ystart+2, frame_single, dialog_background+dialog_text); _remap_refresh_proc; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := _remap_xstart; move_to_screen_area[2] := _remap_ystart; move_to_screen_area[3] := _remap_xstart+71+2; move_to_screen_area[4] := _remap_ystart+_remap_inst_page_len+5+1; move2screen_alt; centered_frame_vdest := screen_ptr; MenuLib1_mn_environment.v_dest := screen_ptr; MenuLib2_mn_environment.v_dest := screen_ptr; If NOT _force_program_quit then Repeat If (_remap_pos = 1) then begin override_frame(screen_ptr,_remap_xstart+2,_remap_ystart+2, frame_double, dialog_background+dialog_hi_text); MenuLib1_mn_setting.menu_attr := dialog_background+dialog_hi_text; end else begin override_frame(screen_ptr,_remap_xstart+2,_remap_ystart+2, frame_single, dialog_background+dialog_text); MenuLib1_mn_setting.menu_attr := dialog_background+dialog_text; end; If (_remap_pos = 2) then begin override_frame(screen_ptr,_remap_xstart+36,_remap_ystart+2, frame_double, dialog_background+dialog_hi_text); MenuLib2_mn_setting.menu_attr := dialog_background+dialog_hi_text; end else begin override_frame(screen_ptr,_remap_xstart+36,_remap_ystart+2, frame_single, dialog_background+dialog_text); MenuLib2_mn_setting.menu_attr := dialog_background+dialog_text; end; Case _remap_pos of 1: begin remap_ins1 := MenuLib1_Menu(temp_instr_names,_remap_xstart+2,_remap_ystart+2, remap_ins1,32,_remap_inst_page_len,255,''); Case MenuLib1_mn_environment.keystroke of kShTAB,kLEFT: _remap_pos := 2+remap_selection; kRIGHT,kTAB: _remap_pos := 2; kESC: qflag := TRUE; kENTER: begin _remap_pos := 2+remap_selection; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 2: begin remap_ins2 := MenuLib2_Menu(temp_instr_names,_remap_xstart+36,_remap_ystart+2, remap_ins2,32,_remap_inst_page_len,255,''); Case MenuLib2_mn_environment.keystroke of kLEFT,kShTAB: _remap_pos := 1; kTAB,kRIGHT: _remap_pos := 2+remap_selection; kESC: qflag := TRUE; kENTER: begin _remap_pos := 2+remap_selection; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 3: begin fkey := getkey; Case fkey of kHOME: _remap_pos := 3; kEND,kLEFT: If marking then _remap_pos := 6 else _remap_pos := 5; kRIGHT: _remap_pos := 4; kTAB,kDOWN: _remap_pos := 1; kShTAB,kUP: _remap_pos := 2; kENTER: qflag := TRUE; kESC: begin _remap_pos := 1; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 4: begin fkey := getkey; Case fkey of kHOME: _remap_pos := 3; kEND: If marking then _remap_pos := 6 else _remap_pos := 5; kLEFT: _remap_pos := 3; kRIGHT: _remap_pos := 5; kTAB,kDOWN: _remap_pos := 1; kShTAB,kUP: _remap_pos := 2; kENTER: qflag := TRUE; kESC: begin _remap_pos := 1; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 5: begin fkey := getkey; Case fkey of kHOME: _remap_pos := 3; kEND: If marking then _remap_pos := 6 else _remap_pos := 5; kLEFT: _remap_pos := 4; kRIGHT: If marking then _remap_pos := 6 else _remap_pos := 3; kTAB,kDOWN: _remap_pos := 1; kShTAB,KUP: _remap_pos := 2; kENTER: qflag := TRUE; kESC: begin _remap_pos := 1; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 6: begin fkey := getkey; Case fkey of kHOME: _remap_pos := 3; kEND: _remap_pos := 6; kLEFT: _remap_pos := 5; kRIGHT: _remap_pos := 3; kTAB,kDOWN: _remap_pos := 1; kShTAB,kUP: _remap_pos := 2; kENTER: qflag := TRUE; kESC: begin _remap_pos := 1; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; end; If (_remap_pos < 3) then remap_mtype := _remap_pos else remap_selection := _remap_pos-2; _remap_refresh_proc; // draw_screen; until qflag; MenuLib1_mn_environment.ext_proc := NIL; MenuLib2_mn_environment.ext_proc := NIL; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := _remap_xstart; move_to_screen_area[2] := _remap_ystart; move_to_screen_area[3] := _remap_xstart+71+2; move_to_screen_area[4] := _remap_ystart+_remap_inst_page_len+5+1; move2screen; If qflag and (_remap_pos > 2) then begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; Case _remap_pos-2 of 1: begin patt0 := pattern_patt; patt1 := patt0; track0 := 1; track1 := songdata.nm_tracks; line0 := 0; line1 := PRED(songdata.patt_len); end; 2: begin patt0 := 0; patt1 := patterns; track0 := 1; track1 := songdata.nm_tracks; line0 := 0; line1 := PRED(songdata.patt_len); end; 3: begin patt0 := pattern_patt; patt1 := patt0; track0 := count_channel(pattern_hpos); track1 := track0; line0 := 0; line1 := PRED(songdata.patt_len); end; 4: begin patt0 := pattern_patt; patt1 := patt0; track0 := block_x0; track1 := block_x1; line0 := block_y0; line1 := block_y1; end; end; For temp3 := patt0 to patt1 do For temp2 := track0 to track1 do For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If (chunk.instr_def = remap_ins1) then begin chunk.instr_def := remap_ins2; put_chunk(temp3,temp1,temp2,chunk); end; end; replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; const _rearrange_track_pos: Byte = 1; _rearrange_pos: Byte = 1; _rearrange_tracklist_idx: array[1..20] of Byte = ( 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20); var _rearrange_xstart, _rearrange_ystart, _rearrange_nm_tracks: Byte; _rearrange_tracklist: array[1..18] of String[4]; procedure _rearrange_refresh_proc; var idx: Byte; attr: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_rearrange_refresh_proc'; {$ENDIF} If (_rearrange_pos <> 1) then attr := dialog_sel_itm_bck+dialog_sel_itm else attr := dialog_hi_text SHL 4; For idx := 1 to _rearrange_nm_tracks do If (idx = _rearrange_track_pos) then ShowCStr(centered_frame_vdest,_rearrange_xstart+1,_rearrange_ystart+idx, '~ '+ExpStrL(Num2str(idx,10),2,' ')+' ~'#16+_rearrange_tracklist[idx]+#17, attr, dialog_background+dialog_contxt_dis2) else ShowCStr(centered_frame_vdest,_rearrange_xstart+1,_rearrange_ystart+idx, '~ '+ExpStrL(Num2str(idx,10),2,' ')+' ~'+_rearrange_tracklist[idx]+' ', mn_setting.text_attr, dialog_background+dialog_contxt_dis2); If (_rearrange_pos = 2) then ShowStr(centered_frame_vdest,_rearrange_xstart+2,_rearrange_ystart+_rearrange_nm_tracks+2,' PATTERN ', dialog_hi_text SHL 4) else If (rearrange_selection = 1) then ShowStr(centered_frame_vdest,_rearrange_xstart+2,_rearrange_ystart+_rearrange_nm_tracks+2,' PATTERN ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_rearrange_xstart+2,_rearrange_ystart+_rearrange_nm_tracks+2,' PATTERN ', dialog_background+dialog_text); If (_rearrange_pos = 3) then ShowStr(centered_frame_vdest,_rearrange_xstart+13,_rearrange_ystart+_rearrange_nm_tracks+2,' SONG ', dialog_hi_text SHL 4) else If (rearrange_selection = 2) then ShowStr(centered_frame_vdest,_rearrange_xstart+13,_rearrange_ystart+_rearrange_nm_tracks+2,' SONG ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_rearrange_xstart+13,_rearrange_ystart+_rearrange_nm_tracks+2,' SONG ', dialog_background+dialog_text); end; procedure REARRANGE; var status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; var temp,temp1,temp2,temp3: Byte; temps: String; patt0,patt1: Byte; fkey: Word; patterns: Byte; qflag,reset_flag: Boolean; temp_pattern: array[1..20] of array[0..$0ff] of tCHUNK; procedure reset_screen; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REARRANGE:reset_screen'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := _rearrange_xstart; move_to_screen_area[2] := _rearrange_ystart; move_to_screen_area[3] := _rearrange_xstart+20+2; move_to_screen_area[4] := _rearrange_ystart+_rearrange_nm_tracks+3+1; move2screen; end; label _jmp1; begin { REARRANGE } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REARRANGE'; {$ENDIF} If (_rearrange_track_pos > songdata.nm_tracks) then _rearrange_track_pos := 1; If (rearrange_selection = 4) and NOT marking then rearrange_selection := 1; _rearrange_pos := 1; qflag := FALSE; If percussion_mode then _rearrange_nm_tracks := max(songdata.nm_tracks,15) else _rearrange_nm_tracks := songdata.nm_tracks; reset_flag := FALSE; For temp := 1 to _rearrange_nm_tracks do If (_rearrange_tracklist_idx[temp] > _rearrange_nm_tracks) then begin reset_flag := TRUE; BREAK; end; If reset_flag then begin For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[temp] := temp; _rearrange_track_pos := 1; end; For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist[temp] := ' '+ExpStrL(Num2str(_rearrange_tracklist_idx[temp],10),2,' ')+' '; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; count_patterns(patterns); ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(_rearrange_xstart,_rearrange_ystart,20,_rearrange_nm_tracks+3,' REARRANGE TRACKS ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(centered_frame_vdest,_rearrange_xstart+1,_rearrange_ystart+_rearrange_nm_tracks+1, ExpStrL('',19,#196), dialog_background+dialog_contxt_dis2); _rearrange_refresh_proc; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := _rearrange_xstart; move_to_screen_area[2] := _rearrange_ystart; move_to_screen_area[3] := _rearrange_xstart+20+2; move_to_screen_area[4] := _rearrange_ystart+_rearrange_nm_tracks+3+1; move2screen_alt; centered_frame_vdest := screen_ptr; If NOT _force_program_quit then Repeat Case _rearrange_pos of 1: begin fkey := getkey; Case fkey of kUP: If (_rearrange_track_pos > 1) then Dec(_rearrange_track_pos) else _rearrange_track_pos := _rearrange_nm_tracks; kDOWN: If (_rearrange_track_pos < _rearrange_nm_tracks) then Inc(_rearrange_track_pos) else _rearrange_track_pos := 1; kPgUP,kHOME: _rearrange_track_pos := 1; kPgDOWN,kEND: _rearrange_track_pos := _rearrange_nm_tracks; kCtPgUP: If (_rearrange_nm_tracks > 1) then If shift_pressed then begin temps := _rearrange_tracklist[1]; For temp := 1 to _rearrange_track_pos do _rearrange_tracklist[temp] := _rearrange_tracklist[temp+1]; _rearrange_tracklist[_rearrange_track_pos] := temps; end else If (_rearrange_track_pos > 1) then begin temps := _rearrange_tracklist[_rearrange_track_pos-1]; _rearrange_tracklist[_rearrange_track_pos-1] := _rearrange_tracklist[_rearrange_track_pos]; _rearrange_tracklist[_rearrange_track_pos] := temps; Dec(_rearrange_track_pos); end; kCtPgDN: If (_rearrange_track_pos < _rearrange_nm_tracks) then If shift_pressed then begin temps := _rearrange_tracklist[_rearrange_nm_tracks]; For temp := _rearrange_nm_tracks downto _rearrange_track_pos+1 do _rearrange_tracklist[temp] := _rearrange_tracklist[temp-1]; _rearrange_tracklist[_rearrange_track_pos] := temps; end else begin temps := _rearrange_tracklist[_rearrange_track_pos+1]; _rearrange_tracklist[_rearrange_track_pos+1] := _rearrange_tracklist[_rearrange_track_pos]; _rearrange_tracklist[_rearrange_track_pos] := temps; Inc(_rearrange_track_pos); end; kLEFT,kRIGHT,kTAB,kShTAB: _rearrange_pos := 1+rearrange_selection; kESC: qflag := TRUE; kENTER: begin _rearrange_pos := 1+rearrange_selection; qflag := TRUE; end; kF1: begin reset_screen; HELP('rearrange_dialog'); GOTO _jmp1; end; end; end; 2: begin fkey := getkey; Case fkey of kHOME: _rearrange_pos := 2; kEND,kLEFT: _rearrange_pos := 3; kRIGHT: _rearrange_pos := 3; kUP,kDOWN,kTAB,kShTAB: _rearrange_pos := 1; kENTER: qflag := TRUE; kESC: begin _rearrange_pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('rearrange_dialog'); GOTO _jmp1; end; end; end; 3: begin fkey := getkey; Case fkey of kHOME: _rearrange_pos := 2; kEND: _rearrange_pos := 3; kLEFT: _rearrange_pos := 2; kRIGHT: _rearrange_pos := 2; kUP,kDOWN,kTAB,kShTAB: _rearrange_pos := 1; kENTER: qflag := TRUE; kESC: begin _rearrange_pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('rearrange_dialog'); GOTO _jmp1; end; end; end; end; If (_rearrange_pos > 1) then rearrange_selection := _rearrange_pos-1; If (fkey <> kESC) then _rearrange_refresh_proc; // draw_screen; until qflag; reset_screen; For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[temp] := Str2num(CutStr(_rearrange_tracklist[temp]),10); If qflag and (_rearrange_pos > 1) then begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; _rearrange_track_pos := 1; Case rearrange_selection of 1: begin patt0 := pattern_patt; patt1 := patt0; end; 2: begin patt0 := 0; patt1 := patterns; end; end; For temp3 := patt0 to patt1 do begin For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to _rearrange_nm_tracks do get_chunk(temp3,temp2,_rearrange_tracklist_idx[temp1],temp_pattern[temp1][temp2]); For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to _rearrange_nm_tracks do put_chunk(temp3,temp2,temp1,temp_pattern[temp1][temp2]); end; For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[temp] := temp; replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; procedure REPLACE; type tCharSet = Set of Char; const _charset: array[1..11] of tCharSet = ( [], ['#','-'], ['1'..'9'], ['0'..'9','A'..'F'], ['0'..'9','A'..'F'], ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<'], ['0'..'9','A'..'F'], ['0'..'9','A'..'F'], ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<'], ['0'..'9','A'..'F'], ['0'..'9','A'..'F']); const _on_off: array[0..1] of Char = ' '#251; var status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; var chunk,old_chunk: tCHUNK; temp,temp1,temp2,temp3: Byte; patt0,patt1,track0,track1,line0,line1: Byte; pos: Byte; fkey: Word; xstart,ystart: Byte; patterns: Byte; qflag: Boolean; procedure refresh; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REPLACE:refresh'; {$ENDIF} If (pos in [1..11]) then ShowStr(centered_frame_vdest,xstart+2,ystart+1, 'NOTE,iNSTRUMENT,FX N'#249'1/N'#249'2 TO FiND', dialog_background+dialog_hi_text) else ShowStr(centered_frame_vdest,xstart+2,ystart+1, 'NOTE,iNSTRUMENT,FX N'#249'1/N'#249'2 TO FiND', dialog_background+dialog_text); If (pos in [12..22]) then ShowStr(centered_frame_vdest,xstart+2,ystart+4, 'NEW NOTE,iNSTRUMENT,FX N'#249'1/N'#249'2', dialog_background+dialog_hi_text) else ShowStr(centered_frame_vdest,xstart+2,ystart+4, 'NEW NOTE,iNSTRUMENT,FX N'#249'1/N'#249'2', dialog_background+dialog_text); ShowCStr2(centered_frame_vdest,xstart+2,ystart+2, '"'+FilterStr(replace_data.event_to_find.note,'?',#250)+'" '+ '"'+FilterStr(replace_data.event_to_find.inst,'?',#250)+'" '+ '"'+FilterStr(replace_data.event_to_find.fx_1,'?',#250)+'" '+ '"'+FilterStr(replace_data.event_to_find.fx_2,'?',#250)+'"', dialog_background+dialog_text, dialog_input_bckg+dialog_input); ShowCStr2(centered_frame_vdest,xstart+2,ystart+5, '"'+FilterStr(replace_data.new_event.note,'?',#250)+'" '+ '"'+FilterStr(replace_data.new_event.inst,'?',#250)+'" '+ '"'+FilterStr(replace_data.new_event.fx_1,'?',#250)+'" '+ '"'+FilterStr(replace_data.new_event.fx_2,'?',#250)+'"', dialog_background+dialog_text, dialog_input_bckg+dialog_input); If (pos = 27) then ShowC3Str(centered_frame_vdest,xstart+2,ystart+7, '~[~`'+_on_off[BYTE(replace_prompt)]+'`~]~ PROMPT ON REPLACE', dialog_background+dialog_hi_text, dialog_background+dialog_text, dialog_background+dialog_item) else ShowCStr(centered_frame_vdest,xstart+2,ystart+7, '[~'+_on_off[BYTE(replace_prompt)]+'~] PROMPT ON REPLACE', dialog_background+dialog_text, dialog_background+dialog_item); If (pos = 23) then ShowStr(centered_frame_vdest,xstart+2,ystart+9,' PATTERN ', dialog_hi_text SHL 4) else If (replace_selection = 1) then ShowStr(centered_frame_vdest,xstart+2,ystart+9,' PATTERN ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,xstart+2,ystart+9,' PATTERN ', dialog_background+dialog_text); If (pos = 24) then ShowStr(centered_frame_vdest,xstart+13,ystart+9,' SONG ', dialog_hi_text SHL 4) else If (replace_selection = 2) then ShowStr(centered_frame_vdest,xstart+13,ystart+9,' SONG ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,xstart+13,ystart+9,' SONG ', dialog_background+dialog_text); If (pos = 25) then ShowStr(centered_frame_vdest,xstart+21,ystart+9,' TRACK ', dialog_hi_text SHL 4) else If (replace_selection = 3) then ShowStr(centered_frame_vdest,xstart+21,ystart+9,' TRACK ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,xstart+21,ystart+9,' TRACK ', dialog_background+dialog_text); If (pos = 26) then ShowStr(centered_frame_vdest,xstart+30,ystart+9,' BLOCK ', dialog_hi_text SHL 4) else If (replace_selection = 4) then ShowStr(centered_frame_vdest,xstart+30,ystart+9,' BLOCK ', dialog_sel_itm_bck+dialog_sel_itm) else If marking then ShowStr(centered_frame_vdest,xstart+30,ystart+9,' BLOCK ', dialog_background+dialog_text) else ShowStr(centered_frame_vdest,xstart+30,ystart+9,' BLOCK ', dialog_background+dialog_item_dis); end; procedure reset_screen; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REPLACE:reset_screen'; {$ENDIF} HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+38+2; move_to_screen_area[4] := ystart+10+1; move2screen; end; function _find_note(layout: String): Byte; var temp: Byte; begin If (layout = note_keyoff_str[pattern_layout]) then temp := BYTE_NULL else For temp := 0 to 12*8+1 do If SameName(note_layout[temp],layout) then BREAK; _find_note := temp; end; function _find_fx(fx_str: Char): Byte; var result: Byte; begin asm lea edi,[fx_digits] mov ebx,edi mov al,fx_str mov ecx,NM_FX_DIGITS repnz scasb sub edi,ebx mov eax,edi dec eax mov result,al end; _find_fx := result; end; function _wildcard_str(wildcard,str: String): String; var temp: Byte; begin For temp := 1 to Length(wildcard) do If (wildcard[temp] = '?') then wildcard[temp] := str[temp]; _wildcard_str := wildcard; end; var _1st_choice,_replace_all, _cancel,_valid_note: Boolean; chr: Char; temp_note: Byte; temps: String; event_to_find: Record note: String[3]; inst: String[2]; fx_1: String[3]; fx_2: String[3]; end; new_event: Record note: String[3]; inst: String[2]; fx_1: String[3]; fx_2: String[3]; end; label _jmp1; begin { REPLACE } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REPLACE'; {$ENDIF} If (replace_selection = 4) and NOT marking then replace_selection := 1; pos := min(get_bank_position('?replace_window?pos',-1),1); qflag := FALSE; _charset[1] := ['A',UpCase(b_note),'C'..'G']; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; count_patterns(patterns); ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,38,10,' REPLACE ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+38+2; move_to_screen_area[4] := ystart+10+1; refresh; ShowStr(centered_frame_vdest,xstart+1,ystart+8, ExpStrL('',38-1,#20), dialog_background+dialog_context_dis); move2screen_alt; centered_frame_vdest := screen_ptr; If NOT _force_program_quit then Repeat If (pos in [1..22,27]) then ThinCursor else HideCursor; Case pos of 1..11: begin GotoXY(xstart+1+pos6[pos],ystart+2); fkey := getkey; Case fkey of kTAB, kDOWN: begin add_bank_position('?replace_window?posfx',-1,pos); Inc(pos,11); end; kShTAB, kUP: begin add_bank_position('?replace_window?posfx',-1,pos); pos := 22+replace_selection; end; kLEFT: If (pos > 1) then Dec(pos) else begin add_bank_position('?replace_window?posfx',-1,pos); pos := 22+replace_selection; end; kRIGHT: Inc(pos); kHOME: pos := 1; kEND: pos := 11; kESC: qflag := TRUE; kENTER: begin pos := 22+replace_selection; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; kCtrlK: If (pos in [1,2,3]) then begin replace_data.event_to_find.note := note_keyoff_str[pattern_layout]; pos := 4; end; else If (UpCase(CHAR(LO(fkey))) in _charset[pos]) or (fkey = kBkSPC) or (fkey = kDELETE) then begin Case fkey of kDELETE: chr := #250; kBkSPC: begin chr := #250; If (pos > 1) then Dec(pos); end; else chr := UpCase(CHAR(LO(fkey))); end; If (replace_data.event_to_find.note = note_keyoff_str[pattern_layout]) and (pos in [1,2,3]) then replace_data.event_to_find.note := #250#250#250; With replace_data.event_to_find do Case pos of 1: begin note[1] := chr; If (note[1] in ['E',UpCase(b_note)]) and (note[2] = '#') then note[2] := '-'; If (note[1] <> 'C') and (note[3] = '9') then note[3] := '8'; end; 2: If NOT ((note[1] in ['E',UpCase(b_note)]) and (chr = '#')) then note[2] := chr else note[2] := '-'; 3: If NOT ((note[1] <> 'C') and (chr = '9')) then note[3] := chr; 4: inst[1] := chr; 5: inst[2] := chr; 6: fx_1[1] := chr; 7: fx_1[2] := chr; 8: fx_1[3] := chr; 9: fx_2[1] := chr; 10: fx_2[2] := chr; 11: fx_2[3] := chr; end; Case fkey of kDELETE: ; kBkSPC: ; else If (pos < 22) then Inc(pos); end; end; end; end; 12..22: begin GotoXY(xstart+1+pos6[pos-11],ystart+5); fkey := getkey; Case fkey of kTAB, kDOWN: begin add_bank_position('?replace_window?posfx',-1,pos-11); pos := 27; end; kShTAB, kUP: begin add_bank_position('?replace_window?posfx',-1,pos-11); Dec(pos,11); end; kLEFT: Dec(pos); kRIGHT: If (pos < 22) then Inc(pos) else pos := 27; kHOME: pos := 12; kEND: pos := 22; kESC: qflag := TRUE; kENTER: begin pos := 22+replace_selection; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; kCtrlN: Case pos-11 of 1,2,3: begin replace_data.new_event.note := #7#7#7; pos := 11+4; end; 4,5: begin replace_data.new_event.inst := '00'; pos := 11+6; end; 6,7,8: begin replace_data.new_event.fx_1 := '000'; pos := 11+9; end; 9,10,11: begin replace_data.new_event.fx_2 := '000'; pos := 27; end; end; kCtrlK: If (pos-11 in [1,2,3]) then begin replace_data.new_event.note := note_keyoff_str[pattern_layout]; pos := 11+4; end; else If (UpCase(CHAR(LO(fkey))) in _charset[pos-11]) or (fkey = kBkSPC) or (fkey = kDELETE) then begin Case fkey of kDELETE: chr := #250; kBkSPC: begin chr := #250; Dec(pos); end; else chr := UpCase(CHAR(LO(fkey))); end; If ((replace_data.new_event.note = note_keyoff_str[pattern_layout]) or (replace_data.new_event.note = #7#7#7)) and (pos-11 in [1,2,3]) then replace_data.new_event.note := #250#250#250; With replace_data.new_event do Case pos-11 of 1: begin note[1] := chr; If (note[1] in ['E',UpCase(b_note)]) and (note[2] = '#') then note[2] := '-'; If (note[1] <> 'C') and (note[3] = '9') then note[3] := '8'; end; 2: If NOT ((note[1] in ['E',UpCase(b_note)]) and (chr = '#')) then note[2] := chr else note[2] := '-'; 3: If NOT ((note[1] <> 'C') and (chr = '9')) then note[3] := chr; 4: inst[1] := chr; 5: inst[2] := chr; 6: fx_1[1] := chr; 7: fx_1[2] := chr; 8: fx_1[3] := chr; 9: fx_2[1] := chr; 10: fx_2[2] := chr; 11: fx_2[3] := chr; end; Case fkey of kDELETE: ; kBkSPC: ; else If (pos < 22) then Inc(pos); end; end; end; end; 27: begin GotoXY(xstart+3,ystart+7); fkey := getkey; Case fkey of kUP,kShTAB: pos := get_bank_position('?replace_window?posfx',-1)+11; kLEFT: pos := 22; kTAB,kRIGHT,kDOWN: pos := 22+replace_selection; kENTER: qflag := TRUE; kSPACE: replace_prompt := NOT replace_prompt; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; 23: begin fkey := getkey; Case fkey of kTAB,kDOWN: pos := get_bank_position('?replace_window?posfx',-1); kShTAB,kUP: pos := 27; kHOME: pos := 23; kEND,kLEFT: If marking then pos := 26 else pos := 25; kRIGHT: pos := 24; kENTER: qflag := TRUE; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; 24: begin fkey := getkey; Case fkey of kTAB,kDOWN: pos := get_bank_position('?replace_window?posfx',-1); kShTAB,kUP: pos := 27; kHOME: pos := 23; kEND: If marking then pos := 26 else pos := 25; kLEFT: pos := 23; kRIGHT: pos := 25; kENTER: qflag := TRUE; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; 25: begin fkey := getkey; Case fkey of kTAB,kDOWN: pos := get_bank_position('?replace_window?posfx',-1); kShTAB,kUP: pos := 27; kHOME: pos := 23; kEND: If marking then pos := 26 else pos := 25; kLEFT: pos := 24; kRIGHT: If marking then pos := 26 else pos := 23; kENTER: qflag := TRUE; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; 26: begin fkey := getkey; Case fkey of kTAB,kDOWN: pos := get_bank_position('?replace_window?posfx',-1); kShTAB,kUP: pos := 27; kHOME: pos := 23; kEND: pos := 26; kLEFT: pos := 25; kRIGHT: pos := 23; kENTER: qflag := TRUE; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; end; Case fkey of kCtrlW: begin temps := replace_data.event_to_find.note; replace_data.event_to_find.note := replace_data.new_event.note; replace_data.new_event.note := temps; temps := replace_data.event_to_find.inst; replace_data.event_to_find.inst := replace_data.new_event.inst; replace_data.new_event.inst := temps; temps := replace_data.event_to_find.fx_1; replace_data.event_to_find.fx_1 := replace_data.new_event.fx_1; replace_data.new_event.fx_1 := temps; temps := replace_data.event_to_find.fx_2; replace_data.event_to_find.fx_2 := replace_data.new_event.fx_2; replace_data.new_event.fx_2 := temps; end; kCtBkSp: begin If (pos < 12) or shift_pressed then begin replace_data.event_to_find.note := #250#250#250; replace_data.event_to_find.inst := #250#250; replace_data.event_to_find.fx_1 := #250#250#250; replace_data.event_to_find.fx_2 := #250#250#250; end; If (pos >= 12) or shift_pressed then begin replace_data.new_event.note := #250#250#250; replace_data.new_event.inst := #250#250; replace_data.new_event.fx_1 := #250#250#250; replace_data.new_event.fx_2 := #250#250#250; end; end; end; If (pos in [23..26]) then replace_selection := pos-22; refresh; // draw_screen; If NOT qflag then add_bank_position('?replace_window?pos',-1,pos); until qflag; HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+38+2; move_to_screen_area[4] := ystart+10+1; move2screen; If qflag and (pos > 22) then begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; PATTERN_position_preview(BYTE_NULL,BYTE_NULL,BYTE_NULL,0); event_to_find.note := FilterStr(replace_data.event_to_find.note,#250,'?'); event_to_find.inst := FilterStr(replace_data.event_to_find.inst,#250,'?'); event_to_find.fx_1 := FilterStr(replace_data.event_to_find.fx_1,#250,'?'); event_to_find.fx_2 := FilterStr(replace_data.event_to_find.fx_2,#250,'?'); new_event.note := FilterStr(replace_data.new_event.note,#250,'?'); new_event.inst := FilterStr(replace_data.new_event.inst,#250,'?'); new_event.fx_1 := FilterStr(replace_data.new_event.fx_1,#250,'?'); new_event.fx_2 := FilterStr(replace_data.new_event.fx_2,#250,'?'); Case replace_selection of 1: begin patt0 := pattern_patt; patt1 := patt0; track0 := 1; track1 := songdata.nm_tracks; line0 := 0; line1 := PRED(songdata.patt_len); end; 2: begin patt0 := 0; patt1 := patterns; track0 := 1; track1 := songdata.nm_tracks; line0 := 0; line1 := PRED(songdata.patt_len); end; 3: begin patt0 := pattern_patt; patt1 := patt0; track0 := count_channel(pattern_hpos); track1 := track0; line0 := 0; line1 := PRED(songdata.patt_len); end; 4: begin patt0 := pattern_patt; patt1 := patt0; track0 := block_x0; track1 := block_x1; line0 := block_y0; line1 := block_y1; end; end; _replace_all := FALSE; _cancel := FALSE; _1st_choice := TRUE; For temp3 := patt0 to patt1 do For temp2 := track0 to track1 do For temp1 := line0 to line1 do If NOT _cancel then begin get_chunk(temp3,temp1,temp2,chunk); old_chunk := chunk; If SameName(event_to_find.inst,byte2hex(old_chunk.instr_def)) and SameName(event_to_find.fx_1,fx_digits[old_chunk.effect_def]+byte2hex(old_chunk.effect)) and SameName(event_to_find.fx_2,fx_digits[old_chunk.effect_def2]+byte2hex(old_chunk.effect2)) then begin _valid_note := FALSE; Case old_chunk.note of 0, 1..12*8+1: If SameName(event_to_find.note,note_layout[old_chunk.note]) then begin temp_note := _find_note(_wildcard_str(new_event.note,note_layout[old_chunk.note])); _valid_note := TRUE; end; fixed_note_flag+ 1.. fixed_note_flag+ 12*8+1: If SameName(event_to_find.note,note_layout[old_chunk.note-fixed_note_flag]) then begin If NOT (FilterStr(replace_data.new_event.note,'?',#250) = note_keyoff_str[pattern_layout]) then temp_note := fixed_note_flag+_find_note(_wildcard_str(new_event.note,note_layout[old_chunk.note-fixed_note_flag])) else temp_note := _find_note(new_event.note); _valid_note := TRUE; end; BYTE_NULL: If (replace_data.event_to_find.note = note_keyoff_str[pattern_layout]) then begin temp_note := _find_note(new_event.note); _valid_note := TRUE; end; end; If _valid_note and (new_event.note <> '???') then If (new_event.note <> #7#7#7) then chunk.note := temp_note else chunk.note := 0; If _valid_note and (new_event.inst <> '??') then chunk.instr_def := Str2num(_wildcard_str(new_event.inst,byte2hex(old_chunk.instr_def)),16); If _valid_note and (new_event.fx_1 <> '???') then begin chunk.effect_def := _find_fx(_wildcard_str(new_event.fx_1[1],fx_digits[old_chunk.effect_def])[1]); chunk.effect := Str2num(_wildcard_str(new_event.fx_1[2]+new_event.fx_1[3],byte2hex(old_chunk.effect)),16); end; If _valid_note and (new_event.fx_2 <> '???') then begin chunk.effect_def2 := _find_fx(_wildcard_str(new_event.fx_2[1],fx_digits[old_chunk.effect_def2])[1]); chunk.effect2 := Str2num(_wildcard_str(new_event.fx_2[2]+new_event.fx_2[3],byte2hex(old_chunk.effect2)),16); end; end; If NOT Compare(chunk,old_chunk,SizeOf(chunk)) then begin If replace_prompt and NOT _replace_all then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; If _1st_choice then temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'FOUND OCCURENCE$', '~R~EPLACE$REPLACE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' REPLACE ',1) else temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'FOUND OCCURENCE$', '~R~EPLACE$REPLACE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' REPLACE ',1); If (dl_environment.keystroke <> kESC) then begin _1st_choice := FALSE; If (temp = 2) then _replace_all := TRUE else If (temp = 3) then CONTINUE else If (temp in [4,5]) then begin _cancel := TRUE; BREAK; end; end else If NOT _1st_choice then CONTINUE else begin _cancel := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end; PATTERN_position_preview(BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; procedure POSITIONS_reset; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:POSITIONS_reset'; {$ENDIF} pattord_page := 0; pattord_hpos := 1; pattord_vpos := 1; instrum_page := 1; pattern_page := 0; pattern_hpos := 1; If (songdata.pattern_order[0] > $7f) then pattern_patt := 0 else pattern_patt := songdata.pattern_order[0]; chan_pos := 1; PATTERN_ORDER_page_refresh(0); PATTERN_page_refresh(0); end; const _perc_char: array[1..5] of Char = #160#161#162#163#164; _panning: array[0..3] of String = (#21#22,#21'`'#22'`','`'#21'`'#22,'`'#21#22'`'); _connection: array[0..1] of String = ('FM','AM'); _off_on: array[1..4,0..1] of Char = (#250'T',#250'V',#250'K',#250'S'); _win_title: array[Boolean] of String = (' DEBUG iNFO ',''); _contxt_str: String = ' LSHiFT/RSHiFT '#196#16' TOGGLE DETAiLS '; procedure DEBUG_INFO; const NOFX = ' '; function effect_str(effect_def,effect,effect_def2: Byte): String; begin Case effect_def of ef_Arpeggio: If (effect <> 0) then effect_str := 'Arpeggio' else effect_str := NOFX; ef_VolSlide: If (effect DIV 16 <> 0) then effect_str := 'VolSld'#24' ' else effect_str := 'VolSld'#25' '; ef_VolSlideFine: If (effect DIV 16 <> 0) then effect_str := 'VolSld'#18' ' else effect_str := 'VolSld'#23' '; ef_TPortamVolSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#13'VSl'#24'' else effect_str := 'Por'#13'VSl'#25; ef_VibratoVolSlide: If (effect DIV 16 <> 0) then effect_str := 'VibrVSl'#24'' else effect_str := 'VibrVSl'#25; ef_TPortamVSlideFine: If (effect DIV 16 <> 0) then effect_str := 'Por'#13'VSl'#18'' else effect_str := 'Por'#13'VSl'#23; ef_VibratoVSlideFine: If (effect DIV 16 <> 0) then effect_str := 'VibrVSl'#18'' else effect_str := 'VibrVSl'#23; ef_ArpggVSlide: If (effect DIV 16 <> 0) then effect_str := 'ArpgVSl'#24'' else effect_str := 'ArpgVSl'#25; ef_ArpggVSlideFine: If (effect DIV 16 <> 0) then effect_str := 'ArpgVSl'#18'' else effect_str := 'ArpgVSl'#23; ef_SetWaveform: If NOT (effect MOD 16 in [0..7]) then effect_str := 'SetW'#26'Car' else If NOT (effect DIV 16 in [0..7]) then effect_str := 'SetW'#26'Mod' else effect_str := 'SetWform'; ef_FSlideUpVSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#24'VSl'#24'' else effect_str := 'Por'#24'VSl'#25; ef_FSlUpVSlF: If (effect DIV 16 <> 0) then effect_str := 'Por'#24'VSl'#18'' else effect_str := 'Por'#24'VSl'#23; ef_FSlideDownVSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#25'VSl'#24'' else effect_str := 'Por'#25'VSl'#25; ef_FSlDownVSlF: If (effect DIV 16 <> 0) then effect_str := 'Por'#25'VSl'#18'' else effect_str := 'Por'#25'VSl'#23; ef_FSlUpFineVSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#18'VSl'#24'' else effect_str := 'Por'#18'VSl'#25; ef_FSlUpFineVSlF: If (effect DIV 16 <> 0) then effect_str := 'Por'#18'VSl'#18'' else effect_str := 'Por'#18'VSl'#23; ef_FSlDownFineVSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#23'VSl'#24'' else effect_str := 'Por'#23'VSl'#25; ef_FSlDownFineVSlF: If (effect DIV 16 <> 0) then effect_str := 'Por'#23'VSl'#18'' else effect_str := 'Por'#23'VSl'#23; ef_FSlideUp: effect_str := 'Porta'#24' '; ef_FSlideDown: effect_str := 'Porta'#25' '; ef_TonePortamento: effect_str := 'Porta'#13' '; ef_Vibrato: effect_str := 'Vibrato '; ef_FSlideUpFine: effect_str := 'Porta'#18' '; ef_FSlideDownFine: effect_str := 'Porta'#23' '; ef_SetCarrierVol: effect_str := 'SetCVol '; ef_SetModulatorVol: effect_str := 'SetMVol '; ef_PositionJump: effect_str := 'PosJump '; ef_SetInsVolume: effect_str := 'SetVol '; ef_PatternBreak: effect_str := 'PatBreak'; ef_SetTempo: effect_str := 'SetTempo'; ef_SetSpeed: effect_str := 'SetSpeed'; ef_RetrigNote: effect_str := 'Retrig'#13' '; ef_MultiRetrigNote: effect_str := 'MulRetr'#13; ef_Tremolo: effect_str := 'Tremolo '; ef_Tremor: effect_str := 'Tremor '; ef_SetGlobalVolume: effect_str := 'SetGlVol'; ef_ForceInsVolume: effect_str := 'ForceVol'; ef_Extended: Case effect DIV 16 of ef_ex_SetTremDepth: effect_str := 'SetTremD'; ef_ex_SetVibDepth: effect_str := 'SetVibrD'; ef_ex_SetAttckRateM: effect_str := '[A]DSR'#26'M'; ef_ex_SetDecayRateM: effect_str := 'A[D]SR'#26'M'; ef_ex_SetSustnLevelM: effect_str := 'AD[S]R'#26'M'; ef_ex_SetRelRateM: effect_str := 'ADS[R]'#26'M'; ef_ex_SetAttckRateC: effect_str := '[A]DSR'#26'C'; ef_ex_SetDecayRateC: effect_str := 'A[D]SR'#26'C'; ef_ex_SetSustnLevelC: effect_str := 'AD[S]R'#26'C'; ef_ex_SetRelRateC: effect_str := 'ADS[R]'#26'C'; ef_ex_SetFeedback: effect_str := 'SetFeedb'; ef_ex_PatternLoop: effect_str := 'PatLoop '; ef_ex_PatternLoopRec: effect_str := 'PatLoopR'; ef_ex_SetPanningPos: Case effect MOD 16 of 0: effect_str := 'SetPan'#26'C'; 1: effect_str := 'SetPan'#26'L'; 2: effect_str := 'SetPan'#26'R'; end; ef_ex_ExtendedCmd: Case effect MOD 16 of ef_ex_cmd_MKOffLoopDi: effect_str := #12'LoopOff'; ef_ex_cmd_MKOffLoopEn: effect_str := #12'LoopOn '; ef_ex_cmd_TPortaFKdis: effect_str := 'Porta'#13'K-'; ef_ex_cmd_TPortaFKenb: effect_str := 'Porta'#13'K+'; ef_ex_cmd_RestartEnv: effect_str := 'RstrtEnv'; ef_ex_cmd_4opVlockOff: effect_str := 'VLock'#4#3'-'; ef_ex_cmd_4opVlockOn: effect_str := 'VLock'#4#3'+'; end; ef_ex_ExtendedCmd2: Case effect MOD 16 of ef_ex_cmd2_RSS: effect_str := 'RelSS '; ef_ex_cmd2_ResetVol: effect_str := 'ResetVol'; ef_ex_cmd2_LockVol: effect_str := 'VolLock+'; ef_ex_cmd2_UnlockVol: effect_str := 'VolLock-'; ef_ex_cmd2_LockVP: effect_str := 'LockVP+ '; ef_ex_cmd2_UnlockVP: effect_str := 'LockVP- '; ef_ex_cmd2_VSlide_car: effect_str := 'VSld'#26'Car'; ef_ex_cmd2_VSlide_mod: effect_str := 'VSld'#26'Mod'; ef_ex_cmd2_VSlide_def: effect_str := 'VSld'#26'Def'; ef_ex_cmd2_LockPan: effect_str := 'PanLock+'; ef_ex_cmd2_UnlockPan: effect_str := 'PanLock-'; ef_ex_cmd2_VibrOff: effect_str := 'VibrOff '; ef_ex_cmd2_TremOff: effect_str := 'TremOff '; ef_ex_cmd2_FVib_FGFS: If NOT (effect_def2 in [ef_GlobalFSlideUp,ef_GlobalFSlideDown]) then effect_str := 'VibrFine' else effect_str := 'GlPortaF'; ef_ex_cmd2_FTrm_XFGFS: If NOT (effect_def2 in [ef_GlobalFSlideUp,ef_GlobalFSlideDown]) then effect_str := 'TremFine' else effect_str := 'GlPortXF'; ef_ex_cmd2_NoRestart: effect_str := 'ArpVibNR'; else effect_str := NOFX; end; else effect_str := NOFX; end; ef_Extended2: Case effect DIV 16 of ef_ex2_PatDelayFrame: effect_str := 'PatDelF '; ef_ex2_PatDelayRow: effect_str := 'PatDelR '; ef_ex2_NoteDelay: effect_str := 'Delay'#13' '; ef_ex2_NoteCut: effect_str := 'Cut'#13' '; ef_ex2_GlVolSlideUp: effect_str := 'GlVolSl'#24; ef_ex2_GlVolSlideDn: effect_str := 'GlVolSl'#25; ef_ex2_GlVolSlideUpF: effect_str := 'GlVolSl'#18; ef_ex2_GlVolSlideDnF: effect_str := 'GlVolSl'#23; ef_ex2_FineTuneUp: effect_str := 'FTune'#24' '; ef_ex2_FineTuneDown: effect_str := 'FTune'#25' '; ef_ex2_GlVolSldUpXF: effect_str := 'GVolSl'#12#18; ef_ex2_GlVolSldDnXF: effect_str := 'GVolSl'#12#23; ef_ex2_VolSlideUpXF: effect_str := 'VolSld'#12#18; ef_ex2_VolSlideDnXF: effect_str := 'VolSld'#12#23; ef_ex2_FreqSlideUpXF: effect_str := 'Porta'#12#18' '; ef_ex2_FreqSlideDnXF: effect_str := 'Porta'#12#23' '; end; ef_SwapArpeggio: effect_str := 'ArpT'#26+byte2hex(effect)+' '; ef_SwapVibrato: effect_str := 'VibT'#26+byte2hex(effect)+' '; ef_Extended3: Case effect DIV 16 of ef_ex3_SetConnection: If (effect MOD 16 = 0) then effect_str := 'Conct'#26'FM' else effect_str := 'Conct'#26'AM'; ef_ex3_SetMultipM: effect_str := 'Multip'#26'M'; ef_ex3_SetKslM: effect_str := 'KSL'#26'M '; ef_ex3_SetTremoloM: effect_str := 'Trem'#26'M '; ef_ex3_SetVibratoM: effect_str := 'Vibr'#26'M '; ef_ex3_SetKsrM: effect_str := 'KSR'#26'M '; ef_ex3_SetSustainM: effect_str := 'Sustn'#26'M '; ef_ex3_SetMultipC: effect_str := 'Multip'#26'C'; ef_ex3_SetKslC: effect_str := 'KSL'#26'C '; ef_ex3_SetTremoloC: effect_str := 'Trem'#26'C '; ef_ex3_SetVibratoC: effect_str := 'Vibr'#26'C '; ef_ex3_SetKsrC: effect_str := 'KSR'#26'C '; ef_ex3_SetSustainC: effect_str := 'Sustn'#26'C '; end; ef_ExtraFineArpeggio: effect_str := 'Arpggio'#12; ef_ExtraFineVibrato: effect_str := 'Vibrato'#12; ef_ExtraFineTremolo: effect_str := 'Tremolo'#12; ef_SetCustomSpeedTab: effect_str := 'SetCusST'; ef_GlobalFSlideUp: effect_str := 'GlPorta'#24; ef_GlobalFSlideDown: effect_str := 'GlPorta'#25; else effect_str := NOFX; end; end; function note_str(note,chan: Byte): String; begin If (note < 100) then note_str := note_layout[note]+' ' else If (note AND $7f <> 0) then note_str := note_layout[note AND $7f]+#12 else note_str := note_layout[0]+' '; end; function cstr2str(str: String): String; var temp: Byte; begin For temp := 1 to Length(str) do If (str[temp] = '~') then Delete(str,temp,1); cstr2str := str; end; function last_chan_pos: Byte; begin If (songdata.nm_tracks > MAX_TRACKS) then last_chan_pos := max(16,songdata.nm_tracks-MAX_TRACKS+1) else last_chan_pos := 1; end; function last_hpos: Byte; begin last_hpos := max(_pattedit_lastpos,songdata.nm_tracks*(_pattedit_lastpos DIV MAX_TRACKS)); end; function _macro_str(str: String; null_byte: Byte): String; begin If (null_byte <> 0) then _macro_str := str else _macro_str := ExpStrL('',C3StrLen(str),' '); end; function _freq_slide_str(value: Shortint): String; begin If (value = 0) then _freq_slide_str := '`'#10'`' else If (value > 0) then _freq_slide_str := #24 else _freq_slide_str := #25; end; const IDLE = $0fff; FINISHED = $0ffff; note_keyoff_str: array[Boolean] of String = ('`'#12'`',#12); function _macro_pos_str_fm(pos,len: Word; keyoff_pos,duration: Byte; retrig_note: Byte; freq_slide: Smallint): String; begin If (pos <= 255) then _macro_pos_str_fm := byte2hex(pos)+'/'+byte2hex(len)+':'+byte2hex(duration)+' '+macro_retrig_str[retrig_note]+ _freq_slide_str(freq_slide)+note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)]+'`'#251'`' else If (pos = IDLE) then _macro_pos_str_fm := #250#250#12#250#250':'#250#250' ' else _macro_pos_str_fm := byte2hex(len)+'/'+byte2hex(len)+':'+byte2hex(duration)+' '+macro_retrig_str[retrig_note]+ _freq_slide_str(freq_slide)+note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)]+#251; end; function _macro_pos_str_av(pos,len: Word; keyoff_pos: Byte; slide_str: String): String; begin If (pos <= 255) then _macro_pos_str_av := byte2hex(pos)+'/'+byte2hex(len)+' '+slide_str+ note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)] else If (pos = IDLE) then _macro_pos_str_av := #250#250#12#250#250' '+slide_str+ note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)] else _macro_pos_str_av := byte2hex(len)+'/'+byte2hex(len)+' '+slide_str+ note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)]; end; var temp,temp2,atr1,atr2,atr3,atr4,xstart,ystart: Byte; temps,temps2,temps3: String; old_debugging,old_replay_forbidden: Boolean; old_play_status: tPLAY_STATUS; _ctrl_alt_flag, _reset_state: Boolean; _win_attr: array[Boolean] of Byte; _details_flag,_macro_details_flag: Boolean; fkey: Word; bckg_attr,current_track: Byte; label _jmp1; begin { DEBUG_INFO } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:DEBUG_INFO'; {$ENDIF} _ctrl_alt_flag := ctrl_pressed AND alt_pressed; _win_attr[FALSE] := debug_info_bckg+debug_info_border2; _win_attr[TRUE] := debug_info_bckg+debug_info_border; _reset_state := FALSE; If NOT _ctrl_alt_flag then begin temp := get_bank_position('?debug_info?details_flag',-1); Case temp of 0: begin _details_flag := FALSE; _macro_details_flag := FALSE; end; 1: begin _details_flag := TRUE; _macro_details_flag := FALSE; end; 2: begin _details_flag := TRUE; _macro_details_flag := TRUE; end; end; end; _jmp1: ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; centered_frame(xstart,ystart,83,songdata.nm_tracks+6, _win_title[_ctrl_alt_flag],_win_attr[_ctrl_alt_flag], debug_info_bckg+debug_info_title, frame_double); Repeat If _ctrl_alt_flag then begin _details_flag := shift_pressed; _macro_details_flag := NOT left_shift_pressed and right_shift_pressed; end; If _ctrl_alt_flag then If NOT _details_flag then ShowStr(screen_ptr,xstart+83-Length(_contxt_str),ystart+songdata.nm_tracks+6, _contxt_str, debug_info_bckg+debug_info_topic) else ShowStr(screen_ptr,xstart+83-Length(_contxt_str),ystart+songdata.nm_tracks+6, ExpStrL('',Length(_contxt_str),#205), debug_info_bckg+debug_info_border); If space_pressed and (play_status <> isStopped) then If NOT _ctrl_alt_flag and ctrl_pressed and NOT alt_pressed and NOT shift_pressed then begin debugging := FALSE; _reset_state := FALSE; end else If NOT _reset_state then begin _reset_state := TRUE; old_debugging := debugging; old_play_status := play_status; old_replay_forbidden := replay_forbidden; debugging := TRUE; play_status := isPlaying; replay_forbidden := FALSE; STATUS_LINE_refresh; end; If NOT _details_flag then begin ShowCStr(screen_ptr,xstart+2,ystart+1, debug_win_str1[1], debug_info_bckg+debug_info_topic,debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+2, debug_win_str1[2], debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+songdata.nm_tracks+3, debug_win_str1[3], debug_info_bckg+debug_info_border); If NOT _ctrl_alt_flag then ShowCStr(screen_ptr,xstart+76,ystart+songdata.nm_tracks+6,' [~1/3~] ', _win_attr[_ctrl_alt_flag], debug_info_bckg+debug_info_topic); end else If NOT _macro_details_flag then begin ShowCStr(screen_ptr,xstart+2,ystart+1, debug_win_str2[1], debug_info_bckg+debug_info_topic,debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+2, debug_win_str2[2], debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+songdata.nm_tracks+3, debug_win_str2[3], debug_info_bckg+debug_info_border); If NOT _ctrl_alt_flag then ShowCStr(screen_ptr,xstart+76,ystart+songdata.nm_tracks+6,' [~2/3~] ', _win_attr[_ctrl_alt_flag], debug_info_bckg+debug_info_topic); end else begin ShowCStr(screen_ptr,xstart+2,ystart+1, debug_win_str3[1], debug_info_bckg+debug_info_topic,debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+2, debug_win_str3[2], debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+songdata.nm_tracks+3, debug_win_str3[3], debug_info_bckg+debug_info_border); If NOT _ctrl_alt_flag then ShowCStr(screen_ptr,xstart+76,ystart+songdata.nm_tracks+6,' [~3/3~] ', _win_attr[_ctrl_alt_flag], debug_info_bckg+debug_info_topic); end; If NOT play_single_patt and NOT replay_forbidden and repeat_pattern then temps := '~'#19'~' else temps := #19; If NOT play_single_patt then ShowCStr(screen_ptr, xstart+2,ystart+songdata.nm_tracks+4, '~ORDER/PATTERN/ROW~ '+byte2hex(current_order)+'/'+ byte2hex(current_pattern)+'/'+ byte2hex(current_line), debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt) else ShowCStr(screen_ptr, xstart+2,ystart+songdata.nm_tracks+4, '~ORDER/PATTERN/ROW~ --/'+ byte2hex(current_pattern)+'/'+ byte2hex(current_line), debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); ShowCStr(screen_ptr, xstart+30,ystart+songdata.nm_tracks+4, temps, debug_info_bckg+debug_info_txt_hid, debug_info_bckg+debug_info_txt); If (tempo < 100) then If (tempo = 18) and timer_fix then temps := num2str(tempo,10)+#5+#174 else temps := num2str(tempo,10)+#174 else temps := num2str(tempo,10)+#174; If (_macro_speedup = 1) then temps2 := temps else begin temp := calc_max_speedup(tempo); If (_macro_speedup <= temp) then temps2 := Num2str(tempo*_macro_speedup,10)+#174 else temps2 := Num2str(tempo*temp,10)+#174; end; ShowCStr(screen_ptr, xstart+2,ystart+songdata.nm_tracks+5, '~SPEED/TEMPO/MACROS~ '+byte2hex(speed)+'/'+ ExpStrR(temps+'/'+temps2,9,' '), debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); Case current_tremolo_depth of 0: temps := '1dB'; 1: temps := '4.8dB'; end; Case current_vibrato_depth of 0: temps2 := '7% '; 1: temps2 := '14% '; end; ShowCStr(screen_ptr, xstart+36,ystart+songdata.nm_tracks+4, '~TREMOLO/ViBRATO DEPTH~ '+ temps+'/'+temps2, debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); ShowCStr(screen_ptr, xstart+36,ystart+songdata.nm_tracks+5, '~GLOBAL VOLUME~ '+ ExpStrR(Num2str(global_volume,16),2,'0'), debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); temps := ' '+ ExpStrL(Num2str(song_timer DIV 60,10),2,'0')+':'+ ExpStrL(Num2str(song_timer MOD 60,10),2,'0')+'.'+ CHR(48+song_timer_tenths DIV 10)+' '; If (play_status <> isStopped) then temps := '~'+temps+'~'; ShowCStr(screen_ptr, xstart+74,ystart+songdata.nm_tracks+4, temps, debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); current_track := count_channel(pattern_hpos); For temp := 1 to songdata.nm_tracks do begin If NOT _ctrl_alt_flag and (temp = current_track) then bckg_attr := debug_info_bckg2 else bckg_attr := debug_info_bckg; If channel_flag[temp] then If event_new[temp] then atr1 := bckg_attr+debug_info_hi_txt else atr1 := bckg_attr+debug_info_txt else atr1 := bckg_attr+debug_info_txt_hid; If channel_flag[temp] then If event_new[temp] then atr2 := bckg_attr+debug_info_hi_txt else atr2 := bckg_attr+debug_info_txt else atr2 := bckg_attr+debug_info_txt_hid; If channel_flag[temp] then If event_new[temp] then atr3 := bckg_attr+debug_info_hi_car else atr3 := bckg_attr+debug_info_car else atr3 := bckg_attr+debug_info_txt_hid; If channel_flag[temp] then If event_new[temp] then atr4 := bckg_attr+debug_info_hi_mod else atr4 := bckg_attr+debug_info_mod else atr4 := bckg_attr+debug_info_txt_hid; If percussion_mode and (temp in [16..20]) then temps := _perc_char[temp-15] else Case temp of 1: If (songdata.flag_4op OR 1 = songdata.flag_4op) then temps := #172 else temps := ' '; 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then temps := #173 else temps := ' '; 3: If (songdata.flag_4op OR 2 = songdata.flag_4op) then temps := #172 else temps := ' '; 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then temps := #173 else temps := ' '; 5: If (songdata.flag_4op OR 4 = songdata.flag_4op) then temps := #172 else temps := ' '; 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then temps := #173 else temps := ' '; 10: If (songdata.flag_4op OR 8 = songdata.flag_4op) then temps := #172 else temps := ' '; 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then temps := #173 else temps := ' '; 12: If (songdata.flag_4op OR $10 = songdata.flag_4op) then temps := #172 else temps := ' '; 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then temps := #173 else temps := ' '; 14: If (songdata.flag_4op OR $20 = songdata.flag_4op) then temps := #172 else temps := ' '; 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then temps := #173 else temps := ' '; else temps := ' '; end; ShowStr(screen_ptr,xstart+1,ystart+temp+2, temps, bckg_attr+debug_info_perc); ShowCStr(screen_ptr,xstart+2,ystart+temp+2, ExpStrL(Num2str(temp,10),2,' '), atr1, bckg_attr+debug_info_txt_hid); If NOT _details_flag then If (event_table[temp].instr_def in [1..255]) then begin temps := ExpStrR(cstr2str(Copy(songdata.instr_names[event_table[temp].instr_def],2,30)),30,' '); Delete(temps,7,1); Insert('~'#247'~',temps,7); end else temps := ExpStrR(' ~'#247'~',30+2,' ') else If (event_table[temp].instr_def in [1..255]) then temps := 'i'+byte2hex(event_table[temp].instr_def) else temps := ExpStrR('',3,' '); If (play_status = isStopped) and NOT debugging then temp2 := 3 else temp2 := panning_table[temp]; Case (songdata.lock_flags[temp] SHR 2 AND 3) of 0: temps2 := #250#24#25; 1: temps2 := 'C'#24#25; 2: temps2 := 'M'#24#25; 3: temps2 := '&'#24#25; end; If (songdata.lock_flags[temp] SHR 2 AND 3 = 0) or ((play_status = isStopped) and NOT debugging) then temps2 := '`'+temps2+'`'; If lockvol and (songdata.lock_flags[temp] OR $10 = songdata.lock_flags[temp]) then temps2 := temps2+'~'#179'~V+' else temps2 := temps2+'~'#179'~`V+`'; If lockVP and (songdata.lock_flags[temp] OR $20 = songdata.lock_flags[temp]) then temps2 := temps2+'~'#179'~P+' else temps2 := temps2+'~'#179'~`P+`'; If NOT (is_4op_chan(temp) and (temp in _4op_tracks_hi)) then temps3 := ExpStrL(Num2str(freqtable2[temp],16),4,'0') else temps3 := ' '; If NOT _details_flag then begin If pan_lock[temp] then ShowC3Str(screen_ptr,xstart+4,ystart+temp+2, '~'#179'~'+_panning[temp2]+'~'#179'~', atr2, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid) else ShowC3Str(screen_ptr,xstart+4,ystart+temp+2, '~'#179'~'+_panning[temp2]+'~'#179'~', atr3, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid); ShowC3Str(screen_ptr,xstart+8,ystart+temp+2, temps2+'~'#179'~', atr2, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid); ShowCStr(screen_ptr,xstart+18,ystart+temp+2, temps+'~'#179'~'+ note_str(event_table[temp].note,temp)+'~'#179'~'+ effect_str(event_table[temp].effect_def, event_table[temp].effect, event_table[temp].effect_def2)+'~'#179'~'+ effect_str(event_table[temp].effect_def2, event_table[temp].effect2, event_table[temp].effect_def)+'~'#179'~'+ temps3+'~'#179'~', atr1, bckg_attr+debug_info_border); If NOT (percussion_mode and (temp in [17..20])) then ShowCStr(screen_ptr,xstart+77,ystart+temp+2, ExpStrL(Num2str(carrier_vol[temp],16),2,'0')+'~'#179'~', atr3, bckg_attr+debug_info_border) else ShowCStr(screen_ptr,xstart+77,ystart+temp+2, ExpStrL(Num2str(carrier_vol[temp],16),2,'0')+'~'#179'~', bckg_attr+bckg_attr SHR 4, bckg_attr+debug_info_border); end else begin If pan_lock[temp] then ShowC3Str(screen_ptr,xstart+4,ystart+temp+2, '~'#179'~'+_panning[temp2]+'~'#179'~', atr2, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid) else ShowC3Str(screen_ptr,xstart+4,ystart+temp+2, '~'#179'~'+_panning[temp2]+'~'#179'~', atr3, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid); If NOT _macro_details_flag then begin ShowCStr(screen_ptr,xstart+8,ystart+temp+2, temps+'~'#179'~'+ note_str(event_table[temp].note,temp)+'~'#179'~'+ effect_str(event_table[temp].effect_def, event_table[temp].effect, event_table[temp].effect_def2)+'~'#179'~'+ effect_str(event_table[temp].effect_def2, event_table[temp].effect2, event_table[temp].effect_def)+'~'#179'~'+ temps3+'~'#179'~', atr1,bckg_attr+debug_info_border); If NOT (percussion_mode and (temp in [17..20])) then ShowStr(screen_ptr,xstart+40,ystart+temp+2, _connection[fmpar_table[temp].connect]+' '+ Num2str(fmpar_table[temp].feedb,16)+' ', atr1) else ShowStr(screen_ptr,xstart+40,ystart+temp+2, ExpStrL('',5,' '), atr1); If NOT (percussion_mode and (temp in [17..20])) then ShowCStr(screen_ptr,xstart+45,ystart+temp+2, Num2str(fmpar_table[temp].adsrw_car.attck,16)+ Num2str(fmpar_table[temp].adsrw_car.dec,16)+ Num2str(fmpar_table[temp].adsrw_car.sustn,16)+ Num2str(fmpar_table[temp].adsrw_car.rel,16)+' '+ Num2str(fmpar_table[temp].adsrw_car.wform,16)+' '+ Num2str(fmpar_table[temp].kslC,16)+' '+ Num2str(fmpar_table[temp].multipC,16)+' '+ _off_on[1,fmpar_table[temp].tremC]+ _off_on[2,fmpar_table[temp].vibrC]+ _off_on[3,fmpar_table[temp].ksrC]+ _off_on[4,fmpar_table[temp].sustC]+'~'#179'~', atr3, bckg_attr+debug_info_border) else ShowCStr(screen_ptr,xstart+45,ystart+temp+2, Num2str(fmpar_table[temp].adsrw_car.attck,16)+ Num2str(fmpar_table[temp].adsrw_car.dec,16)+ Num2str(fmpar_table[temp].adsrw_car.sustn,16)+ Num2str(fmpar_table[temp].adsrw_car.rel,16)+' '+ Num2str(fmpar_table[temp].adsrw_car.wform,16)+' '+ Num2str(fmpar_table[temp].kslC,16)+' '+ Num2str(fmpar_table[temp].multipC,16)+' '+ _off_on[1,fmpar_table[temp].tremC]+ _off_on[2,fmpar_table[temp].vibrC]+ _off_on[3,fmpar_table[temp].ksrC]+ _off_on[4,fmpar_table[temp].sustC]+'~'#179'~', bckg_attr+bckg_attr SHR 4, bckg_attr+debug_info_border); ShowCStr(screen_ptr,xstart+61,ystart+temp+2, Num2str(fmpar_table[temp].adsrw_mod.attck,16)+ Num2str(fmpar_table[temp].adsrw_mod.dec,16)+ Num2str(fmpar_table[temp].adsrw_mod.sustn,16)+ Num2str(fmpar_table[temp].adsrw_mod.rel,16)+' '+ Num2str(fmpar_table[temp].adsrw_mod.wform,16)+' '+ Num2str(fmpar_table[temp].kslM,16)+' '+ Num2str(fmpar_table[temp].multipM,16)+' '+ _off_on[1,fmpar_table[temp].tremM]+ _off_on[2,fmpar_table[temp].vibrM]+ _off_on[3,fmpar_table[temp].ksrM]+ _off_on[4,fmpar_table[temp].sustM]+'~'#179'~', atr4, bckg_attr+debug_info_border); end else begin ShowCStr(screen_ptr,xstart+8,ystart+temp+2, temps+'~'#179'~'+ note_str(event_table[temp].note,temp)+'~'#179'~'+ effect_str(event_table[temp].effect_def, event_table[temp].effect, event_table[temp].effect_def2)+'~'#179'~'+ effect_str(event_table[temp].effect_def2, event_table[temp].effect2, event_table[temp].effect_def)+'~'#179'~', atr1,bckg_attr+debug_info_border); ShowC3Str(screen_ptr,xstart+35,ystart+temp+2, _macro_str(_macro_pos_str_fm(macro_table[temp].fmreg_pos, songdata.instr_macros[macro_table[temp].fmreg_table].length, songdata.instr_macros[macro_table[temp].fmreg_table].keyoff_pos, songdata.instr_macros[macro_table[temp].fmreg_table].data[macro_table[temp].fmreg_pos].duration, songdata.instr_macros[macro_table[temp].fmreg_table].data[macro_table[temp].fmreg_pos].fm_data.FEEDBACK_FM SHR 5, songdata.instr_macros[macro_table[temp].fmreg_table].data[macro_table[temp].fmreg_pos].freq_slide), songdata.instr_macros[macro_table[temp].fmreg_table].length)+'~'#179'~'+ _macro_str(byte2hex(macro_table[temp].arpg_table)+#246+ _macro_pos_str_av(macro_table[temp].arpg_pos, songdata.macro_table[macro_table[temp].arpg_table].arpeggio.length, songdata.macro_table[macro_table[temp].arpg_table].arpeggio.keyoff_pos, ''), macro_table[temp].arpg_table)+'~'#179'~'+ _macro_str(byte2hex(macro_table[temp].vib_table)+#246+ _macro_pos_str_av(macro_table[temp].vib_pos, songdata.macro_table[macro_table[temp].vib_table].vibrato.length, songdata.macro_table[macro_table[temp].vib_table].vibrato.keyoff_pos, _freq_slide_str(songdata.macro_table[macro_table[temp].vib_table].vibrato.data[macro_table[temp].vib_pos])), macro_table[temp].vib_table)+'~'#179'~'+ temps3+'~'#179'~', atr1, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid); end; If NOT (percussion_mode and (temp in [17..20])) then ShowCStr(screen_ptr,xstart+77,ystart+temp+2, ExpStrL(Num2str(carrier_vol[temp],16),2,'0')+'~'#179'~', atr3, bckg_attr+debug_info_border) else ShowCStr(screen_ptr,xstart+77,ystart+temp+2, ExpStrL(Num2str(carrier_vol[temp],16),2,'0')+'~'#179'~', bckg_attr+bckg_attr SHR 4, bckg_attr+debug_info_border); end; ShowCStr(screen_ptr,xstart+80,ystart+temp+2, ExpStrL(Num2str(modulator_vol[temp],16),2,'0')+' ', atr4,bckg_attr+debug_info_border); end; fkey := WORD_NULL; If _ctrl_alt_flag then If keypressed then keyboard_reset_buffer else else If keypressed then fkey := getkey; If scankey($39) { SPACE } then If (play_status = isStopped) then If (calc_pattern_pos(pattern_patt) <> BYTE_NULL) then begin fade_out_playback(FALSE); calibrate_player(calc_pattern_pos(pattern_patt), pattern_page,TRUE,TRUE); If (play_status <> isStopped) then begin debugging := TRUE; play_status := isPlaying; replay_forbidden := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); tracing := TRUE; end; end else If (calc_pattern_pos(pattern_patt) = BYTE_NULL) then begin fade_out_playback(FALSE); play_single_patt := TRUE; no_sync_playing := TRUE; start_pattern := pattern_patt; start_line := pattern_page; start_playing; debugging := TRUE; tracing := TRUE; end else else If NOT tracing then begin debugging := TRUE; tracing := TRUE; end; Case fkey of kCtLEFT: If NOT debugging and (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If NOT debugging and (play_status = isPlaying) then fast_forward := TRUE; kTAB: If NOT _details_flag then _details_flag := TRUE else If NOT _macro_details_flag then _macro_details_flag := TRUE else begin _details_flag := FALSE; _macro_details_flag := FALSE; end; kBkSPC: If NOT replay_forbidden then repeat_pattern := NOT repeat_pattern; kPgUP, kHOME: begin chan_pos := 1; pattern_hpos := 1; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kPgDOWN, kEND: begin chan_pos := last_chan_pos; pattern_hpos := last_hpos; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kUP: If (chan_pos > 1) then begin Dec(chan_pos); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (pattern_hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kDOWN: If (chan_pos < last_chan_pos) then begin Inc(chan_pos); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (pattern_hpos <= last_hpos-_pattedit_lastpos DIV MAX_TRACKS) then begin Inc(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kCHmins, kNPmins, kCtHOME: If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp > 0) and NOT (songdata.pattern_order[temp-1] < $80) do begin Dec(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp > 0) then begin Dec(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (fkey = kCtHOME) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCHplus, kNPplus, kCtEND: If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp < $7f) and (songdata.pattern_order[SUCC(temp)] > $80) do begin Inc(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp < $7f) then begin Inc(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (fkey = kCtEND) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCtENTR: If play_single_patt then begin current_line := 0; PATTERN_ORDER_page_refresh(0); PATTERN_page_refresh(0); end else begin no_status_refresh := TRUE; fade_out_playback(FALSE); If (current_order < $7f) and (play_status <> isStopped) then If (songdata.pattern_order[SUCC(current_order)] < $80) then calibrate_player(SUCC(current_order),0,FALSE,FALSE) else If (calc_following_order(SUCC(current_order)) <> -1) then calibrate_player(calc_following_order(SUCC(current_order)),0,FALSE,FALSE) else else If (calc_following_order(0) <> -1) then calibrate_player(calc_following_order(0),0,FALSE,FALSE); no_status_refresh := FALSE; end; kAstrsk, kNPastr: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} For temp := 1 to songdata.nm_tracks do begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltS: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} begin For temp := 1 to songdata.nm_tracks do channel_flag[temp] := FALSE; For temp := 1 to songdata.nm_tracks do If (temp = count_channel(pattern_hpos)) then begin channel_flag[temp] := TRUE; If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then channel_flag[SUCC(temp)] := TRUE else channel_flag[PRED(temp)] := TRUE; end; For temp := 1 to songdata.nm_tracks do If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltR: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} FillChar(channel_flag,songdata.nm_tracks,BYTE(TRUE)); kAlt1.. kAlt9: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} begin If shift_pressed then temp := HI(fkey)-$77+10 else temp := HI(fkey)-$77; If (temp <= songdata.nm_tracks) then begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then begin channel_flag[SUCC(temp)] := channel_flag[temp]; If NOT channel_flag[SUCC(temp)] then reset_chan_data(SUCC(temp)); end else If (temp in _4op_tracks_lo) then begin channel_flag[PRED(temp)] := channel_flag[temp]; If NOT channel_flag[PRED(temp)] then reset_chan_data(PRED(temp)); end; end; end; kAlt0: {$IFNDEF GO32V2} If (opl3_channel_recording_mode and (play_status <> isStopped)) then fkey := WORD_NULL else {$ENDIF} If (shift_pressed and (songdata.nm_tracks > 9)) or (songdata.nm_tracks = 10) then begin channel_flag[10] := NOT channel_flag[10]; If NOT channel_flag[10] then reset_chan_data(10); fkey := WORD_NULL; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (NOT _ctrl_alt_flag and ((fkey = kESC) or (fkey = kF1) or (fkey = kAlt0))) or (_ctrl_alt_flag and NOT (ctrl_pressed and alt_pressed)) or _force_program_quit; If NOT _ctrl_alt_flag then keyboard_reset_buffer; If NOT ((fkey = kF1) or (fkey = kAlt0)) and _reset_state then begin debugging := old_debugging; play_status := old_play_status; replay_forbidden := old_replay_forbidden; end; If NOT _ctrl_alt_flag then add_bank_position('?debug_info?details_flag',-1,ORD(_details_flag)+ORD(_macro_details_flag)); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+83+2; move_to_screen_area[4] := ystart+songdata.nm_tracks+6+1; move2screen; If (fkey = kF1) then begin realtime_gfx_poll_proc; no_step_debugging := TRUE; HELP('debug_info'); draw_screen; keyboard_reset_buffer; no_step_debugging := FALSE; IF NOT _force_program_quit then GOTO _jmp1; end; If (fkey = kAlt0) then {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} begin realtime_gfx_poll_proc; no_step_debugging := TRUE; If NOT percussion_mode then temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$1~6~$1~7~$1~8~$1~9~$2~0~$' else temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$16 ~B~D$17 ~S~D$18 ~T~T$19 T~C~$20 ~H~H$'; temps := FlipStr(temps); For temp := 10 to 20 do If (temp > songdata.nm_tracks) then begin Delete(temps,Pos('~',temps),1); Delete(temps,Pos('~',temps),1); end; temps := FlipStr(temps); If (Pos('~',temps) <> 0) then begin chpos := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO TOGGLE TRACK ON/OFF$', temps, ' TRACK ON/OFF ',chpos); If (dl_environment.keystroke <> kESC) then begin channel_flag[9+chpos] := NOT channel_flag[9+chpos]; If NOT channel_flag[9+chpos] then reset_chan_data(9+chpos); If is_4op_chan(9+chpos) then If (9+chpos in [10,12,14]) then begin channel_flag[SUCC(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[SUCC(9+chpos)] then reset_chan_data(SUCC(9+chpos)); end else If (9+chpos in [11,13,15]) then begin channel_flag[PRED(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[PRED(9+chpos)] then reset_chan_data(PRED(9+chpos)); end; end; end; draw_screen; keyboard_reset_buffer; no_step_debugging := FALSE; If NOT _force_program_quit then GOTO _jmp1; end; end; procedure LINE_MARKING_SETUP; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:LINE_MARKING_SETUP'; {$ENDIF} dl_setting.all_enabled := TRUE; mark_line := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS ~HOTKEY~ TO SETUP COUNTER$', '~1~$~2~$~3~$~4~$~5~$~6~$~7~$~8~$~9~$10$11$12$13$14$15$16$', ' LiNE MARKiNG SETUP ',mark_line); dl_setting.all_enabled := FALSE; end; procedure OCTAVE_CONTROL; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:OCTAVE_CONTROL'; {$ENDIF} current_octave := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO CHANGE OCTAVE$', '~1~$~2~$~3~$~4~$~5~$~6~$~7~$~8~$', ' OCTAVE CONTROL ',current_octave); end; procedure SONG_VARIABLES; const new_keys: array[1..7] of Word = (kF1,kESC,kENTER,kTAB,kShTAB,kUP,kDOWN); var old_keys: array[1..7] of Word; pos,pos_4op,temp,temp1,temp2,temp3: Byte; temps: String; xstart,ystart: Byte; attr: array[1..163] of Byte; status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; const _on_off: array[0..1] of Char = #250#251; _4op_str: array[1..6] of String = ('1 '#241'2 ','3 '#241'4 ','5 '#241'6 ', '10'#241'11 ','12'#241'13 ','14'#241'15 '); _pan_pos: array[0..2] of Byte = (1,0,2); _left_pos_pan: array[1..60] of Byte = (2, 18,19, {1} 87, 21,22, {2} 91, 24,25, {3} 3, 27,28, {4} 5, 30,31, {5} 17, 33,34, {6} 107,36,37, {7} 78, 39,40, {8} 79, 42,43, {9} 80, 45,46, {10} 81, 48,49, {11} 82, 51,52, {12} 83, 54,55, {13} 12, 57,58, {14} 139,60,61, {15} 13, 63,64, {16} 14, 66,67, {17} 151,69,70, {18} 15, 72,73, {19} 16, 75,76); {20} _left_pos_lck: array[1..80] of Byte = (20,84, 85, 86, {1} 23,88, 89, 90, {2} 26,92, 93, 94, {3} 29,96, 97, 98, {4} 32,100,101,102, {5} 35,104,105,106, {6} 38,108,109,110, {7} 41,112,113,114, {8} 44,116,117,118, {9} 47,120,121,122, {10} 50,124,125,126, {11} 53,128,129,130, {12} 56,132,133,134, {13} 59,136,137,138, {14} 62,140,141,142, {15} 65,144,145,146, {16} 68,148,149,150, {17} 71,152,153,154, {18} 74,156,157,158, {19} 77,160,161,162); {20} _right_pos_pan: array[1..60] of Byte = (19,20,84, {1} 22,23,88, {2} 25,26,92, {3} 28,29,96, {4} 31,32,100, {5} 34,35,104, {6} 37,38,108, {7} 40,41,112, {8} 43,44,116, {9} 46,47,120, {10} 49,50,124, {11} 52,53,128, {12} 55,56,132, {13} 58,59,136, {14} 61,62,140, {15} 64,65,144, {16} 67,68,148, {17} 70,71,152, {18} 73,74,156, {19} 76,77,160); {20} _right_pos_lck: array[1..80] of Byte = (85, 86, 87, 0, {1} 89, 90, 91, 0, {2} 93, 94, 95, 0, {3} 97, 98, 99, 0, {4} 101,102,103,0, {5} 105,106,107,0, {6} 109,110,111,0, {7} 113,114,115,0, {8} 117,118,119,0, {9} 121,122,123,0, {10} 125,126,127,0, {11} 129,130,131,0, {12} 133,134,135,0, {13} 137,138,139,0, {14} 141,142,143,0, {15} 145,146,147,0, {16} 149,150,151,0, {17} 153,154,155,0, {18} 157,158,159,0, {19} 161,162,163,1); {20} _up_pos_pan: array[1..60] of Byte = (2, 2, 2, {1} 18,19,20, {2} 21,22,23, {3} 24,25,26, {4} 27,28,29, {5} 30,31,32, {6} 33,34,35, {7} 36,37,38, {8} 39,40,41, {9} 42,43,44, {10} 45,46,47, {11} 48,49,50, {12} 51,52,53, {13} 54,55,56, {14} 57,58,59, {15} 60,61,62, {16} 63,64,65, {17} 66,67,68, {18} 69,70,71, {19} 72,73,74); {20} _down_pos_pan: array[1..60] of Byte = (0,0,0, {1} 0,0,0, {2} 0,0,0, {3} 0,0,0, {4} 0,0,0, {5} 0,0,0, {6} 0,0,0, {7} 0,0,0, {8} 0,0,0, {9} 0,0,0, {10} 0,0,0, {11} 0,0,0, {12} 0,0,0, {13} 0,0,0, {14} 0,0,0, {15} 0,0,0, {16} 0,0,0, {17} 0,0,0, {18} 0,0,0, {19} 1,1,1); {20} _down_pos_lck: array[1..80] of Byte = (0,0,0,0, {1} 0,0,0,0, {2} 0,0,0,0, {3} 0,0,0,0, {4} 0,0,0,0, {5} 0,0,0,0, {6} 0,0,0,0, {7} 0,0,0,0, {8} 0,0,0,0, {9} 0,0,0,0, {10} 0,0,0,0, {11} 0,0,0,0, {12} 0,0,0,0, {13} 0,0,0,0, {14} 0,0,0,0, {15} 0,0,0,0, {16} 0,0,0,0, {17} 0,0,0,0, {18} 0,0,0,0, {19} 1,1,1,1); {20} _up_pos_lck: array[1..80] of Byte = (2, 2, 2, 2, {1} 84, 85, 86, 87, {2} 88, 89, 90, 91, {3} 92, 93, 94, 95, {4} 96, 97, 98, 99, {5} 100,101,102,103, {6} 104,105,106,107, {7} 108,109,110,111, {8} 112,113,114,115, {9} 116,117,118,119, {10} 120,121,122,123, {11} 124,125,126,127, {12} 128,129,130,131, {13} 132,133,134,135, {14} 136,137,138,139, {15} 140,141,142,143, {16} 144,145,146,147, {17} 148,149,150,151, {18} 152,153,154,155, {19} 156,157,158,159); {20} _right_pos_lck_def: array[1..20-1] of Record variant1, variant2: Byte; end = ( (variant1: 21; variant2: 3), {1} (variant1: 24; variant2: 3), {2} (variant1: 3; variant2: 3), {3} (variant1: 4; variant2: 4), {4} (variant1: 17; variant2: 17), {5} (variant1: 36; variant2: 6), {6} (variant1: 6; variant2: 6), {7} (variant1: 7; variant2: 7), {8} (variant1: 8; variant2: 8), {9} (variant1: 81; variant2: 81), {10} (variant1: 82; variant2: 82), {11} (variant1: 9; variant2: 9), {12} (variant1: 10; variant2: 10), {13} (variant1: 60; variant2: 13), {14} (variant1: 13; variant2: 13), {15} (variant1: 14; variant2: 14), {16} (variant1: 69; variant2: 15), {17} (variant1: 15; variant2: 15), {18} (variant1: 16; variant2: 16)); {19} _down_pos_pan_def: array[1..20-1] of Record variant1, variant2: array[1..3] of Byte; end = ( (variant1: (21,22,23); variant2: (3, 3, 3 )), {1} (variant1: (24,25,26); variant2: (3, 3, 3 )), {2} (variant1: (27,28,29); variant2: (3, 3, 3 )), {3} (variant1: (30,31,32); variant2: (4, 4, 4 )), {4} (variant1: (33,34,35); variant2: (17,17,17)), {5} (variant1: (36,37,38); variant2: (6, 6, 6 )), {6} (variant1: (39,40,41); variant2: (6, 6, 6 )), {7} (variant1: (42,43,44); variant2: (7, 7, 7 )), {8} (variant1: (45,46,47); variant2: (8, 8, 8 )), {9} (variant1: (48,49,50); variant2: (81,81,81)), {10} (variant1: (51,52,53); variant2: (82,82,82)), {11} (variant1: (54,55,56); variant2: (9, 9, 9 )), {12} (variant1: (57,58,59); variant2: (10,10,10)), {13} (variant1: (60,61,62); variant2: (13,13,13)), {14} (variant1: (63,64,65); variant2: (13,13,13)), {15} (variant1: (66,67,68); variant2: (14,14,14)), {16} (variant1: (69,70,71); variant2: (15,15,15)), {17} (variant1: (72,73,74); variant2: (15,15,15)), {18} (variant1: (75,76,77); variant2: (16,16,16))); {19} _down_pos_lck_def: array[1..20-1] of Record variant1, variant2: array[1..4] of Byte; end = ( (variant1: (88, 89, 90, 91); variant2: (3, 3, 3, 3 )), {1} (variant1: (92, 93, 94, 95); variant2: (3, 3, 3, 3 )), {2} (variant1: (96, 97, 98, 99); variant2: (3, 3, 3, 3 )), {3} (variant1: (100,101,102,103); variant2: (4, 4, 4, 4 )), {4} (variant1: (104,105,106,107); variant2: (17,17,17,17)), {5} (variant1: (108,109,110,111); variant2: (6, 6, 6, 6 )), {6} (variant1: (112,113,114,115); variant2: (6, 6, 6, 6 )), {7} (variant1: (116,117,118,119); variant2: (7, 7, 7, 7 )), {8} (variant1: (120,121,122,123); variant2: (8, 8, 8, 8 )), {9} (variant1: (124,125,126,127); variant2: (81,81,81,81)), {10} (variant1: (128,129,130,131); variant2: (82,82,82,82)), {11} (variant1: (132,133,134,135); variant2: (9, 9, 9, 9 )), {12} (variant1: (136,137,138,139); variant2: (10,10,10,10)), {13} (variant1: (140,141,142,143); variant2: (13,13,13,13)), {14} (variant1: (144,145,146,147); variant2: (13,13,13,13)), {15} (variant1: (148,149,150,151); variant2: (14,14,14,14)), {16} (variant1: (152,153,154,155); variant2: (15,15,15,15)), {17} (variant1: (156,157,158,159); variant2: (15,15,15,15)), {18} (variant1: (160,161,152,163); variant2: (16,16,16,16))); {19} _left_pos_4op: array[1..6] of Byte = (6,7,8,0,0,11); _right_pos_4op: array[1..6] of Byte = (0,0,0,0,0,0); _up_pos_4op: array[1..6] of Byte = (0,78,79,80,81,82); _down_pos_4op: array[1..6] of Byte = (79,80,81,82,83,10); _right_pos_4op_def: array[1..6] of Record variant1, variant2: Byte; end = ( (variant1: 39; variant2: 7), (variant1: 42; variant2: 8), (variant1: 45; variant2: 81), (variant1: 48; variant2: 82), (variant1: 51; variant2: 9), (variant1: 54; variant2: 10)); function truncate_string(str: String): String; begin While (Length(str) > 0) and (str[Length(str)] in [#0,#32,#255]) do Delete(str,Length(str),1); truncate_string := str; end; label _jmp1,_end; begin { SONG_VARIABLES } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:SONG_VARIABLES'; {$ENDIF} songdata_crc := Update32(songdata,SizeOf(songdata),0); count_order(temp1); count_patterns(temp2); count_instruments(temp3); pos := min(get_bank_position('?song_variables_window?pos',-1),1); pos_4op := min(get_bank_position('?song_variables_window?pos_4op',-1),0); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,79,26,' SONG VARiABLES ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); centered_frame_vdest := screen_ptr; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+79+2; move_to_screen_area[4] := ystart+26+1; move2screen_alt; move_to_screen_area[1] := xstart+1; move_to_screen_area[2] := ystart+1; move_to_screen_area[3] := xstart+78; move_to_screen_area[4] := ystart+25; ShowCStr(ptr_temp_screen,xstart+2,ystart+6, 'iNSTRUMENTS: ~'+Num2str(temp3,10)+'/255~ ', dialog_background+dialog_text, dialog_background+dialog_context_dis); ShowCStr(ptr_temp_screen,xstart+25,ystart+6, 'PATTERNS: ~'+Num2str(temp2,10)+'/'+Num2str(max_patterns,10)+'~ ', dialog_background+dialog_text, dialog_background+dialog_context_dis); ShowCStr(ptr_temp_screen,xstart+2,ystart+7, 'ORDER LiST ENTRiES: ~'+Num2str(temp1,10)+'/128~ ', dialog_background+dialog_text, dialog_background+dialog_context_dis); ShowStr(ptr_temp_screen,xstart+51,ystart+2, 'iNiTiAL LOCK SETTiNGS', dialog_background+dialog_context_dis); ShowStr(ptr_temp_screen,xstart+51,ystart+3, ExpStrL('',27,#154), dialog_background+dialog_context_dis); Move(is_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,is_setting.terminate_keys,SizeOf(new_keys)); songdata.songname := truncate_string(songdata.songname); songdata.composer := truncate_string(songdata.composer); If NOT _force_program_quit then Repeat If (songdata.nm_tracks < 11) then _left_pos_4op[4] := 80 else _left_pos_4op[4] := 123; If (songdata.nm_tracks < 12) then _left_pos_4op[5] := 81 else _left_pos_4op[5] := 127; For temp := 1 to 6 do If (songdata.nm_tracks < 8+temp-1) then _right_pos_4op[temp] := _right_pos_4op_def[temp].variant2 else _right_pos_4op[temp] := _right_pos_4op_def[temp].variant1; If (songdata.nm_tracks < 7) then _up_pos_4op[1] := 17 else _up_pos_4op[1] := 36; For temp := 1 to 19 do If (songdata.nm_tracks < temp+1) then _right_pos_lck[(temp-1)*4+4] := _right_pos_lck_def[temp].variant2 else _right_pos_lck[(temp-1)*4+4] := _right_pos_lck_def[temp].variant1; For temp := 1 to 19 do If (songdata.nm_tracks < temp+1) then begin _down_pos_pan[(temp-1)*3+1] := _down_pos_pan_def[temp].variant2[1]; _down_pos_pan[(temp-1)*3+2] := _down_pos_pan_def[temp].variant2[2]; _down_pos_pan[(temp-1)*3+3] := _down_pos_pan_def[temp].variant2[3]; _down_pos_lck[(temp-1)*4+1] := _down_pos_lck_def[temp].variant2[1]; _down_pos_lck[(temp-1)*4+2] := _down_pos_lck_def[temp].variant2[2]; _down_pos_lck[(temp-1)*4+3] := _down_pos_lck_def[temp].variant2[3]; _down_pos_lck[(temp-1)*4+4] := _down_pos_lck_def[temp].variant2[4]; end else begin _down_pos_pan[(temp-1)*3+1] := _down_pos_pan_def[temp].variant1[1]; _down_pos_pan[(temp-1)*3+2] := _down_pos_pan_def[temp].variant1[2]; _down_pos_pan[(temp-1)*3+3] := _down_pos_pan_def[temp].variant1[3]; _down_pos_lck[(temp-1)*4+1] := _down_pos_lck_def[temp].variant1[1]; _down_pos_lck[(temp-1)*4+2] := _down_pos_lck_def[temp].variant1[2]; _down_pos_lck[(temp-1)*4+3] := _down_pos_lck_def[temp].variant1[3]; _down_pos_lck[(temp-1)*4+4] := _down_pos_lck_def[temp].variant1[4]; end; For temp2 := 1 to 17 do If (pos = temp2) then attr[temp2] := dialog_background+dialog_hi_text else attr[temp2] := dialog_background+dialog_text; If (pos = 4) then attr[5] := 0 else If (pos = 5) then attr[4] := 0 else attr[5] := 0; If (pos = 9) then attr[10] := 0 else If (pos = 10) then attr[9] := 0 else attr[10] := 0; If (pos = 11) then attr[12] := 0 else If (pos = 12) then attr[11] := 0 else attr[11] := 0; If (pos in [18..77]) then attr[18] := dialog_background+dialog_hi_text else attr[18] := dialog_background+dialog_text; If (pos in [78..83]) then attr[78] := dialog_background+dialog_hi_text else attr[78] := dialog_background+dialog_text; If (pos in [84,88,92,96,100,104,108,112,116,120, 124,128,132,136,140,144,148,152,156,160]) then attr[84] := dialog_background+dialog_hi_text else attr[84] := dialog_background+dialog_text; If (pos in [85,89,93,97,101,105,109,113,117,121, 125,129,133,137,141,145,149,153,157,161]) then attr[85] := dialog_background+dialog_hi_text else attr[85] := dialog_background+dialog_text; If (pos in [86,90,94,98,102,106,110,114,118,122, 126,130,134,138,142,146,150,154,158,162]) then attr[86] := dialog_background+dialog_hi_text else attr[86] := dialog_background+dialog_text; If (pos in [87,91,95,99,103,107,111,115,119,123, 127,131,135,139,143,147,151,155,159,163]) then attr[87] := dialog_background+dialog_hi_text else attr[87] := dialog_background+dialog_text; ShowStr(ptr_temp_screen,xstart+34,ystart+12,#4#3' TRACKS '#4#3'+',attr[78]); For temp := 1 to 6 do If (songdata.flag_4op OR (1 SHL PRED(temp)) = songdata.flag_4op) then ShowC3Str(ptr_temp_screen,xstart+34,ystart+13+temp-1, '[~'#251'~] '+_4op_str[temp]+'`[ ]`', dialog_background+dialog_text, dialog_background+dialog_item, dialog_background+dialog_text) else ShowC3Str(ptr_temp_screen,xstart+34,ystart+13+temp-1, '[~ ~] '+_4op_str[temp]+'`[ ]`', dialog_background+dialog_text, dialog_background+dialog_item, dialog_background+dialog_item_dis); ShowStr(ptr_temp_screen,xstart+51,ystart+4, 'PANNiNG', attr[18]); ShowStr(ptr_temp_screen,xstart+51,ystart+5, #170' c '#171, attr[18]); ShowVStr(ptr_temp_screen,xstart+64,ystart+4,'M'#31,attr[84]); ShowVStr(ptr_temp_screen,xstart+68,ystart+4,'C'#31,attr[85]); ShowVStr(ptr_temp_screen,xstart+72,ystart+4,'V'#31,attr[86]); ShowVStr(ptr_temp_screen,xstart+76,ystart+4,'P'#31,attr[87]); ShowVStr(ptr_temp_screen,xstart+65,ystart+4,#10, attr[84]); ShowVStr(ptr_temp_screen,xstart+69,ystart+4,#10, attr[85]); ShowVStr(ptr_temp_screen,xstart+73,ystart+4,'+', attr[86]); ShowVStr(ptr_temp_screen,xstart+77,ystart+4,'+', attr[87]); temps := ''; For temp := 1 to 6 do If (songdata.lock_flags[_4op_main_chan[temp]] OR $40 = songdata.lock_flags[_4op_main_chan[temp]]) or (songdata.lock_flags[PRED(_4op_main_chan[temp])] OR $40 = songdata.lock_flags[PRED(_4op_main_chan[temp])]) then temps := temps+#251 else temps := temps+' '; ShowVStr(ptr_temp_screen,xstart+46,ystart+13, temps, dialog_background++dialog_item); For temp := 1 to 20 do If (temp <= songdata.nm_tracks) then begin ShowCStr(ptr_temp_screen,xstart+51,ystart+6+temp-1, voice_pan_str[songdata.lock_flags[temp] AND 3], dialog_background+dialog_text, dialog_background+dialog_item); ShowCStr(ptr_temp_screen,xstart+60,ystart+6+temp-1, '~'+ExpStrL(Num2str(temp,10),2,' ')+'~ '+ _on_off[songdata.lock_flags[temp] SHR 3 AND 1]+' ~'#246'~ '+ _on_off[songdata.lock_flags[temp] SHR 2 AND 1]+' ~'#246'~ '+ _on_off[songdata.lock_flags[temp] SHR 4 AND 1]+' ~'#246'~ '+ _on_off[songdata.lock_flags[temp] SHR 5 AND 1], dialog_background+dialog_item, dialog_background+dialog_context_dis); end else ShowStr(ptr_temp_screen,xstart+51,ystart+6+temp-1, voice_pan_str[3]+' '+ExpStrL(Num2str(temp,10),2,' ')+ ' '#250' '#246' '#250' '#246' '#250' '#246' '#250, dialog_background+dialog_hid); temps := ''; For temp := 1 to songdata.nm_tracks do If percussion_mode and (temp in [16..20]) then temps := temps+_perc_char[temp-15] else Case temp of 1: If (songdata.flag_4op OR 1 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 3: If (songdata.flag_4op OR 2 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 5: If (songdata.flag_4op OR 4 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 10: If (songdata.flag_4op OR 8 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 12: If (songdata.flag_4op OR $10 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 14: If (songdata.flag_4op OR $20 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; else temps := temps+' '; end; ShowVStr(ptr_temp_screen,xstart+50,ystart+6, ExpStrR(temps,20,' '), dialog_background+dialog_context_dis); ShowStr(ptr_temp_screen,xstart+2,ystart+1, 'SONGNAME', attr[1]); ShowStr(ptr_temp_screen,xstart+2,ystart+3, 'COMPOSER', attr[2]); ShowStr(ptr_temp_screen,xstart+2,ystart+9, 'SONG TEMPO', attr[3]); ShowStr(ptr_temp_screen,xstart+2,ystart+10, 'SONG SPEED', attr[4]+attr[5]); ShowCStr(ptr_temp_screen,xstart+26,ystart+10, '[ ] ~RESET~', dialog_background+dialog_text, attr[4]+attr[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+11, '~MACRODEF.~ '#7, dialog_background+dialog_text, attr[17]); If speed_update then ShowStr(ptr_temp_screen,xstart+27,ystart+10, #251, dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+27,ystart+10, ' ', dialog_background+dialog_item); ShowCStr(ptr_temp_screen,xstart+2,ystart+13, '[ ] ~TRACK VOLUME LOCK~', dialog_background+dialog_text, attr[6]); ShowCStr(ptr_temp_screen,xstart+2,ystart+14, '[ ] ~TRACK PANNiNG LOCK~', dialog_background+dialog_text, attr[7]); ShowCStr(ptr_temp_screen,xstart+2,ystart+15, '[ ] ~VOLUME PEAK LOCK~', dialog_background+dialog_text, attr[8]); If lockvol then ShowStr(ptr_temp_screen,xstart+3,ystart+13,#251,dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+13,' ',dialog_background+dialog_item); If panlock then ShowStr(ptr_temp_screen,xstart+3,ystart+14,#251,dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+14,' ',dialog_background+dialog_item); If lockVP then ShowStr(ptr_temp_screen,xstart+3,ystart+15,#251,dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+15,' ',dialog_background+dialog_item); ShowStr(ptr_temp_screen,xstart+2,ystart+17, 'TREMOLO DEPTH',attr[9]+attr[10]); ShowStr(ptr_temp_screen,xstart+2,ystart+18, '( ) 1 dB',dialog_background+dialog_text); ShowStr(ptr_temp_screen,xstart+2,ystart+19, '( ) 4.8 dB',dialog_background+dialog_text); If (tremolo_depth = 0) then ShowVStr(ptr_temp_screen,xstart+3,ystart+18,#11' ',dialog_background+dialog_item) else ShowVStr(ptr_temp_screen,xstart+3,ystart+18,' '#11,dialog_background+dialog_item); ShowStr(ptr_temp_screen,xstart+18,ystart+17, 'ViBRATO DEPTH',attr[11]+attr[12]); ShowStr(ptr_temp_screen,xstart+18,ystart+18, '( ) 7%',dialog_background+dialog_text); ShowStr(ptr_temp_screen,xstart+18,ystart+19, '( ) 14%',dialog_background+dialog_text); If (vibrato_depth = 0) then ShowVStr(ptr_temp_screen,xstart+19,ystart+18,#11' ',dialog_background+dialog_item) else ShowVStr(ptr_temp_screen,xstart+19,ystart+18,' '#11,dialog_background+dialog_item); ShowStr(ptr_temp_screen,xstart+2,ystart+21, 'PATTERN LENGTH',attr[13]); ShowStr(ptr_temp_screen,xstart+2,ystart+22, 'NUMBER OF TRACKS',attr[14]); ShowCStr(ptr_temp_screen,xstart+2,ystart+24, '[ ] ~PERCUSSiON TRACK EXTENSiON ('#160','#161','#162','#163','#164')~', dialog_background+dialog_text,attr[15]); If percussion_mode then ShowStr(ptr_temp_screen,xstart+3,ystart+24,#251,dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+24,' ',dialog_background+dialog_item); ShowCStr(ptr_temp_screen,xstart+2,ystart+25, '[ ] ~VOLUME SCALiNG~',dialog_background+dialog_text,attr[16]); If volume_scaling then ShowStr(ptr_temp_screen,xstart+3,ystart+25, #251, dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+25, ' ', dialog_background+dialog_item); is_setting.append_enabled := TRUE; is_environment.locate_pos := 1; ShowStr(ptr_temp_screen,xstart+2,ystart+2, ExpStrR(songdata.songname,46,' '), dialog_input_bckg+dialog_input); ShowStr(ptr_temp_screen,xstart+2,ystart+4, ExpStrR(songdata.composer,46,' '), dialog_input_bckg+dialog_input); ShowCStr(ptr_temp_screen,xstart+13,ystart+9, ExpStrR(Num2str(songdata.tempo,10),4,' ')+ '~ {1..255}~', dialog_input_bckg+dialog_input, dialog_background+dialog_text); ShowCStr(ptr_temp_screen,xstart+13,ystart+10, ExpStrR(Num2str(songdata.speed,16),4,' ')+ '~ {1..FF}~', dialog_input_bckg+dialog_input, dialog_background+dialog_text); ShowCStr(ptr_temp_screen,xstart+13,ystart+11, '~'+ExpStrR(Num2str(songdata.macro_speedup,10),4,' ')+'~'+ ' {1..'+Num2str(calc_max_speedup(songdata.tempo),10)+'} ', dialog_background+dialog_text, dialog_input_bckg+dialog_input); ShowCStr(ptr_temp_screen,xstart+19,ystart+21, ExpStrR(Num2str(songdata.patt_len,10),3,' ')+ '~ {1..256}~', dialog_input_bckg+dialog_input, dialog_background+dialog_text); ShowCStr(ptr_temp_screen,xstart+19,ystart+22, ExpStrR(Num2str(songdata.nm_tracks,10),3,' ')+ '~ {1..20}~', dialog_input_bckg+dialog_input, dialog_background+dialog_text); move2screen_alt; Case pos of 1: begin is_setting.character_set := [#32..#255]; temps := InputStr(songdata.songname,xstart+2,ystart+2, 42,42, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); songdata.songname := truncate_string(temps); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 2 else If (is_environment.keystroke = kUP) then pos := 16 else If (is_environment.keystroke = kShTAB) then pos := 87; end; 2: begin is_setting.character_set := [#32..#255]; temps := InputStr(songdata.composer,xstart+2,ystart+4, 42,42, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); songdata.composer := truncate_string(temps); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then pos := 3 else If (is_environment.keystroke = kDOWN) then pos := 18 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 1; end; 3: begin is_setting.character_set := ['0'..'9']; Repeat temps := InputStr(Num2str(songdata.tempo,10), xstart+13,ystart+9,3,3, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,10) > 0) and (Str2num(temps,10) < 256)); If ((Str2num(temps,10) > 0) and (Str2num(temps,10) < 256)) then songdata.tempo := Str2num(temps,10); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 4 else If (is_environment.keystroke = kUP) then pos := 18+3*(max(3,songdata.nm_tracks)-1) else If (is_environment.keystroke = kShTAB) then pos := 2; end; 4: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(Num2str(songdata.speed,16), xstart+13,ystart+10,2,2, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or (Str2num(temps,16) in [1..255]); If (Str2num(temps,16) in [1..255]) then songdata.speed := Str2num(temps,16); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then pos := 5 else If (is_environment.keystroke = kDOWN) then pos := 17 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 3; end; 5: begin GotoXY(xstart+27,ystart+10); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP: pos := 3; kLEFT,kShTAB: pos := 4; kDOWN,kTAB,kENTER: pos := 17; kRIGHT: If (songdata.nm_tracks < 5) then pos := 17 else pos := 30; kSPACE: speed_update := NOT speed_update; end; end; 17: begin is_setting.character_set := ['0'..'9']; Repeat temps := InputStr(Num2str(songdata.macro_speedup,10), xstart+13,ystart+11,4,4, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= calc_max_speedup(songdata.tempo))); If ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= calc_max_speedup(songdata.tempo))) then songdata.macro_speedup := Str2num(temps,10); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then pos := 6 else If (is_environment.keystroke = kUP) then pos := 4 else If (is_environment.keystroke = kDOWN) then If (songdata.nm_tracks < 7) then pos := 6 else pos := 36 else If (is_environment.keystroke = kShTAB) then pos := 5; end; 6: begin GotoXY(xstart+3,ystart+13); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP,kLEFT: If (songdata.nm_tracks < 7) then pos := 17 else pos := 111; kShTAB: pos := 17; kDOWN,kTAB,kENTER: pos := 7; kRIGHT: pos := 78; kSPACE: lockvol := NOT lockvol; end; end; 7: begin GotoXY(xstart+3,ystart+14); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP,kShTAB: pos := 6; kLEFT: If (songdata.nm_tracks < 8) then pos := 78 else pos := 115; kTAB,kENTER: pos := 8; kDOWN: pos := 8; kRIGHT: pos := 79; kSPACE: panlock := NOT panlock; end; end; 8: begin GotoXY(xstart+3,ystart+15); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP: pos := 7; kLEFT: If (songdata.nm_tracks < 9) then pos := 79 else pos := 119; kShTAB: pos := 7; kDOWN: pos := 9; kTAB,kENTER: If (tremolo_depth = 0) then pos := 9 else pos := 10; kRIGHT: pos := 80; kSPACE: lockVP := NOT lockVP; end; end; 9: begin GotoXY(xstart+3,ystart+18); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP: pos := 8; kLEFT: If (songdata.nm_tracks < 12) then pos := 82 else pos := 131; kShTAB: pos := 8; kRIGHT,kTAB,kENTER: If (vibrato_depth = 0) then pos := 11 else pos := 12; kDOWN: pos := 10; kSPACE: tremolo_depth := 0; end; end; 10: begin GotoXY(xstart+3,ystart+19); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP: pos := 9; kShTAB: pos := 8; kDOWN: If (songdata.nm_tracks < 15) then pos := 13 else pos := 60; kTAB,kENTER: If (vibrato_depth = 0) then pos := 11 else pos := 12; kLEFT: If (songdata.nm_tracks < 13) then pos := 83 else pos := 135; kRIGHT: pos := 12; kSPACE: tremolo_depth := 1; end; end; 11: begin GotoXY(xstart+19,ystart+18); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP: pos := 8; kShTAB: If (tremolo_depth = 0) then pos := 9 else pos := 10; kDOWN: pos := 12; kTAB,kENTER: pos := 13; kLEFT: pos := 9; kRIGHT: pos := 83; kSPACE: vibrato_depth := 0; end; end; 12: begin GotoXY(xstart+19,ystart+19); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP: pos := 11; kShTAB: pos := 9; kDOWN: If (songdata.nm_tracks < 15) then pos := 13 else pos := 60; kTAB,kENTER: pos := 13; kLEFT: pos := 10; kRIGHT: If (songdata.nm_tracks < 14) then pos := 13 else pos := 57; kSPACE: vibrato_depth := 1; end; end; 13: begin is_setting.character_set := ['0'..'9']; Repeat temps := InputStr(Num2str(songdata.patt_len,10), xstart+19,ystart+21,3,3, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= 256)); If ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= 256)) then begin If (current_line <= Str2num(temps,10)) then songdata.patt_len := Str2num(temps,10) else begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; pattern_break := TRUE; next_line := 0; ticks := tick0; update_song_position; songdata.patt_len := Str2num(temps,10); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 14 else If (is_environment.keystroke = kUP) then If (songdata.nm_tracks < 15) then pos := 10 else pos := 60 else If (is_environment.keystroke = kShTAB) then If (vibrato_depth = 0) then pos := 11 else pos := 12; end; 14: begin is_setting.character_set := ['0'..'9']; Repeat temps := InputStr(Num2str(songdata.nm_tracks,10), xstart+19,ystart+22,2,2, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= 20)); If (Str2num(temps,10) >= 1) and (Str2num(temps,10) <= 20) then begin songdata.nm_tracks := Str2num(temps,10); If (songdata.nm_tracks > 18) and NOT percussion_mode then begin reset_player; percussion_mode := TRUE; _chan_n := _chpm_n; _chan_m := _chpm_m; _chan_c := _chpm_c; reset_player; end; If (songdata.nm_tracks < 15) and (songdata.flag_4op OR $20 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT $20; reset_player; end; If (songdata.nm_tracks < 13) and (songdata.flag_4op OR $10 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT $10; reset_player; end; If (songdata.nm_tracks < 11) and (songdata.flag_4op OR 8 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT 8; reset_player; end; If (songdata.nm_tracks < 6) and (songdata.flag_4op OR 4 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT 4; reset_player; end; If (songdata.nm_tracks < 4) and (songdata.flag_4op OR 2 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT 2; reset_player; end; If (songdata.nm_tracks < 2) and (songdata.flag_4op OR 1 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT 1; reset_player; end; force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then pos := 15 else If (is_environment.keystroke = kDOWN) then If (songdata.nm_tracks < 18) then pos := 15 else pos := 69 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 13; end; 15: begin GotoXY(xstart+3,ystart+24); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP: If (songdata.nm_tracks < 18) then pos := 14 else pos := 69; kLEFT: If (songdata.nm_tracks < 18) then pos := 14 else pos := 155; kRIGHT: If (songdata.nm_tracks < 19) then pos := 16 else pos := 72; kShTAB: pos := 14; kDOWN,kTAB,kENTER: pos := 16; end; If (is_environment.keystroke = kSPACE) then If NOT percussion_mode then begin reset_player; songdata.nm_tracks := 20; percussion_mode := TRUE; _chan_n := _chpm_n; _chan_m := _chpm_m; _chan_c := _chpm_c; reset_player; If (play_status = isStopped) then init_buffers; end else begin reset_player; If (songdata.nm_tracks > 18) then songdata.nm_tracks := 18; percussion_mode := FALSE; _chan_n := _chmm_n; _chan_m := _chmm_m; _chan_c := _chmm_c; reset_player; If (play_status = isStopped) then init_buffers; end; force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; 16: begin GotoXY(xstart+3,ystart+25); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kUP: pos := 15; kLEFT: If (songdata.nm_tracks < 19) then pos := 15 else pos := 159; kRIGHT: If (songdata.nm_tracks < 20) then pos := 1 else pos := 75; kShTAB: pos := 15; kDOWN: pos := 1; kTAB,kENTER: pos := 78; kSPACE: volume_scaling := NOT volume_scaling; end; end; 18.. 77: begin GotoXY(xstart+51+(pos-17-1) MOD 3*3,ystart+6+(pos-17-1) DIV 3); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kLEFT: pos := _left_pos_pan[pos-17]; kRIGHT: pos := _right_pos_pan[pos-17]; kUP: pos := _up_pos_pan[pos-17]; kDOWN,kENTER: pos := _down_pos_pan[pos-17]; kShTAB: pos := 78; kTAB: pos := 84; kSPACE: begin songdata.lock_flags[SUCC((pos-17-1) DIV 3)] := songdata.lock_flags[SUCC((pos-17-1) DIV 3)] AND NOT 3+ _pan_pos[(pos-17-1) MOD 3]; panlock := TRUE; end; end; end; 78.. 83: begin If (pos_4op <> 0) and NOT (songdata.flag_4op OR (1 SHL PRED(pos-77)) = songdata.flag_4op) then pos_4op := 0; GotoXY(xstart+35+pos_4op*11,ystart+13+pos-78); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kLEFT: If (pos_4op <> 0) then pos_4op := 0 else pos := _left_pos_4op[pos-77]; kRIGHT: If (pos_4op <> 1) and (songdata.flag_4op OR (1 SHL PRED(pos-77)) = songdata.flag_4op) then pos_4op := 1 else pos := _right_pos_4op[pos-77]; kUP: pos := _up_pos_4op[pos-77]; kDOWN: pos := _down_pos_4op[pos-77]; kShTAB: pos := 16; kTAB,kENTER: pos := 18; end; If (is_environment.keystroke = kSPACE) then Case pos_4op of 0: If (songdata.flag_4op OR (1 SHL PRED(pos-77)) <> songdata.flag_4op) then begin reset_player; Case (pos-77) of 1: songdata.nm_tracks := min(songdata.nm_tracks,2); 2: songdata.nm_tracks := min(songdata.nm_tracks,4); 3: songdata.nm_tracks := min(songdata.nm_tracks,6); 4: songdata.nm_tracks := min(songdata.nm_tracks,11); 5: songdata.nm_tracks := min(songdata.nm_tracks,13); 6: songdata.nm_tracks := min(songdata.nm_tracks,15); end; songdata.flag_4op := songdata.flag_4op OR (1 SHL PRED(pos-77)); reset_player; If (play_status = isStopped) then init_buffers; end else begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT (1 SHL PRED(pos-77)); reset_player; If (play_status = isStopped) then init_buffers; end; 1: begin songdata.lock_flags[_4op_main_chan[pos-77]] := songdata.lock_flags[_4op_main_chan[pos-77]] XOR $40; songdata.lock_flags[PRED(_4op_main_chan[pos-77])] := songdata.lock_flags[PRED(_4op_main_chan[pos-77])] XOR $40; end; end; force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; 84.. 163: begin GotoXY(xstart+64+(pos-83-1) MOD 4*4,ystart+6+(pos-83-1) DIV 4); ThinCursor; is_environment.keystroke := getkey; Case is_environment.keystroke of kLEFT: pos := _left_pos_lck[pos-83]; kRIGHT: pos := _right_pos_lck[pos-83]; kUP: pos := _up_pos_lck[pos-83]; kDOWN,kENTER: pos := _down_pos_lck[pos-83]; kShTAB: Case (pos-83-1) MOD 4 of 0: pos := 18; 1: pos := 84; 2: pos := 85; 3: pos := 86; end; kTAB: Case (pos-83-1) MOD 4 of 0: pos := 85; 1: pos := 86; 2: pos := 87; 3: pos := 1; end; kSPACE: Case (pos-83-1) MOD 4 of 0: songdata.lock_flags[SUCC((pos-83-1) DIV 4)] := songdata.lock_flags[SUCC((pos-83-1) DIV 4)] XOR 8; 1: songdata.lock_flags[SUCC((pos-83-1) DIV 4)] := songdata.lock_flags[SUCC((pos-83-1) DIV 4)] XOR 4; 2: begin songdata.lock_flags[SUCC((pos-83-1) DIV 4)] := songdata.lock_flags[SUCC((pos-83-1) DIV 4)] XOR $10; lockvol := TRUE; end; 3: begin songdata.lock_flags[SUCC((pos-83-1) DIV 4)] := songdata.lock_flags[SUCC((pos-83-1) DIV 4)] XOR $20; lockVP := TRUE; end; end; end; end; end; _end: {$IFDEF GO32V2} realtime_gfx_poll_proc; keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (is_environment.keystroke = kESC) or (is_environment.keystroke = kF1); If (nm_track_chan > songdata.nm_tracks) then nm_track_chan := songdata.nm_tracks; songdata.common_flag := BYTE(speed_update)+BYTE(lockvol) SHL 1+ BYTE(lockVP) SHL 2+ tremolo_depth SHL 3+ vibrato_depth SHL 4+ BYTE(panlock) SHL 5+ BYTE(percussion_mode) SHL 6+ BYTE(volume_scaling) SHL 7; If (Update32(songdata,SizeOf(songdata),0) <> songdata_crc) then module_archived := FALSE; If (play_status = isStopped) then begin current_tremolo_depth := tremolo_depth; current_vibrato_depth := vibrato_depth; end; add_bank_position('?song_variables_window?pos',-1,pos); add_bank_position('?song_variables_window?pos_4op',-1,pos_4op); HideCursor; Move(old_keys,is_setting.terminate_keys,SizeOf(old_keys)); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+79+2; move_to_screen_area[4] := ystart+26+1; move2screen; If (is_environment.keystroke = kF1) then begin HELP('song_variables'); GOTO _jmp1; end; end; procedure NUKE; var temp,temp1,temp2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:NUKE'; {$ENDIF} temp1 := Dialog('SO YOU THiNK iT REALLY SUCKS, DON''T YOU?$'+ 'WHAT DO YOU WANT TO BE NUKED?$', '~O~RDER$~P~ATTERNS$iNSTR [$~N~AMES$~R~EGS$~M~ACROS$]$ARP/~V~iB$~A~LL$', ' NUKE''M ',clearpos); clearpos := temp1; If (dl_environment.keystroke <> kESC) then begin If (temp1 = 1) then begin FillChar(songdata.pattern_order,SizeOf(songdata.pattern_order),$080); PATTERN_ORDER_page_refresh(pattord_page); end; If (temp1 = 2) then begin For temp := 1 to max_patterns DIV 8 do FillChar(pattdata^[PRED(temp)],8*PATTERN_SIZE,0); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); For temp2 := 0 to $7f do songdata.pattern_names[temp2] := ' PAT_'+byte2hex(temp2)+' '#247' '; pattern_list__page := 1; end; If (temp1 = 4) then begin For temp2 := 1 to 255 do begin FillChar(songdata.instr_names[temp2][2],SizeOf(songdata.instr_names[temp2])-2,0); songdata.instr_names[temp2] := songdata.instr_names[temp2][1]+ 'iNS_'+byte2hex(temp2)+#247' '; end; end; If (temp1 = 5) then begin FillChar(songdata.instr_data,SizeOf(songdata.instr_data),0); FillChar(songdata.ins_4op_flags,SizeOf(songdata.ins_4op_flags),0); update_4op_flag_marks; end; If (temp1 = 6) then begin FillChar(songdata.instr_macros,SizeOf(songdata.instr_macros),0); _macro_editor__pos[FALSE] := 1; _macro_editor__fmreg_hpos[FALSE] := 1; _macro_editor__fmreg_hpos[TRUE] := 1; _macro_editor__fmreg_page[FALSE] := 1; _macro_editor__fmreg_page[TRUE] := 1; _macro_editor__fmreg_left_margin[FALSE] := 1; _macro_editor__fmreg_left_margin[TRUE] := 1; _macro_editor__fmreg_cursor_pos[FALSE] := 1; _macro_editor__fmreg_cursor_pos[TRUE] := 1; add_bank_position('?internal_instrument_data?macro?pos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_page',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_hpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_vpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_left_margin',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_cursor_pos',-1,1); end; If (temp1 = 8) then begin FillChar(songdata.macro_table,SizeOf(songdata.macro_table),0); _macro_editor__pos[TRUE] := 8; _macro_editor__arpeggio_page[FALSE] := 1; _macro_editor__arpeggio_page[TRUE] := 1; _macro_editor__vibrato_hpos[FALSE] := 1; _macro_editor__vibrato_hpos[TRUE] := 1; _macro_editor__vibrato_page[FALSE] := 1; _macro_editor__vibrato_page[TRUE] := 1; add_bank_position('?internal_instrument_data?macro_av?pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?arp_pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?vib_pos',-1,1); end; If (temp1 = 9) then begin fade_out_playback(FALSE); stop_playing; tempo := init_tempo; speed := init_speed; init_songdata; POSITIONS_reset; songdata_title := 'noname.'; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); track_notes := FALSE; track_chan_start := 1; nm_track_chan := 1; remap_mtype := 1; remap_ins1 := 1; remap_ins2 := 1; remap_selection := 1; replace_selection := 1; replace_prompt := FALSE; replace_data.event_to_find.note := '???'; replace_data.event_to_find.inst := '??'; replace_data.event_to_find.fx_1 := '???'; replace_data.event_to_find.fx_2 := '???'; replace_data.new_event.note := '???'; replace_data.new_event.inst := '??'; replace_data.new_event.fx_1 := '???'; replace_data.new_event.fx_2 := '???'; current_inst := 1; pattern_list__page := 1; _macro_editor__pos[FALSE] := 1; _macro_editor__pos[TRUE] := 8; _macro_editor__fmreg_hpos[FALSE] := 1; _macro_editor__fmreg_hpos[TRUE] := 1; _macro_editor__fmreg_page[FALSE] := 1; _macro_editor__fmreg_page[TRUE] := 1; _macro_editor__fmreg_left_margin[FALSE] := 1; _macro_editor__fmreg_left_margin[TRUE] := 1; _macro_editor__fmreg_cursor_pos[FALSE] := 1; _macro_editor__fmreg_cursor_pos[TRUE] := 1; add_bank_position('?internal_instrument_data?macro?pos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_page',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_hpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_vpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_left_margin',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_cursor_pos',-1,1); _macro_editor__arpeggio_page[FALSE] := 1; _macro_editor__arpeggio_page[TRUE] := 1; _macro_editor__vibrato_hpos[FALSE] := 1; _macro_editor__vibrato_hpos[TRUE] := 1; _macro_editor__vibrato_page[FALSE] := 1; _macro_editor__vibrato_page[TRUE] := 1; add_bank_position('?internal_instrument_data?macro_av?pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?arp_pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?vib_pos',-1,1); add_bank_position('?song_variables_window?pos',-1,1); add_bank_position('?song_variables_window?pos_4op',-1,0); add_bank_position('?replace_window?pos',-1,1); add_bank_position('?replace_window?posfx',-1,1); add_bank_position('?message_board?hpos',-1,1); add_bank_position('?message_board?vpos',-1,1); For temp := 1 to 255 do begin add_bank_position('?instrument_editor?'+byte2hex(temp)+'?carrier',-1,1); add_bank_position('?instrument_editor?'+byte2hex(temp)+'?carrier?hpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(temp)+'?carrier?vpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(temp)+'?modulator?hpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(temp)+'?modulator?vpos',-1,1); end; For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[temp] := temp; _rearrange_track_pos := 1; end else module_archived := FALSE; end; end; procedure MESSAGE_BOARD; const new_keys: array[1..21] of Word = (kF1,kESC,kENTER,kUP,kDOWN,kLEFT,kRIGHT, kHOME,kEND,kPgUP,kPGDOWN,kCtHOME,kCtEND, kCtPgUP,kCtPgDN,kTAB,kCtBkSp, kCtrlY,kDELETE,kBkSPC,kSPACE); var old_keys: array[1..21] of Word; old_append_enabled: Boolean; idx,idx2,vpos,vpos2,ref_vpos,old_vpos,hpos: Byte; xstart,ystart: Byte; flag: Boolean; fkey: Word; temps: String; p_mb: pMESSAGE_BOARD_DATA; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:MESSAGE_BOARD'; {$ENDIF} p_mb := Addr(songdata.reserved_data); If Empty(songdata.reserved_data,SizeOf(songdata.reserved_data)) then p_mb^.signature := MB_SIGNATURE else If (p_mb^.signature <> MB_SIGNATURE) then EXIT; is_environment.insert_mode := TRUE; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,MB_HSIZE+3,MB_VSIZE+1,' MESSAGE BOARD ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+MB_HSIZE+3+2; move_to_screen_area[4] := ystart+MB_VSIZE+1+1; For idx := 1 to MB_VSIZE do ShowStr(centered_frame_vdest,xstart+2,ystart+1+idx-1, ExpStrR(p_mb^.data[idx],MB_HSIZE,' '), dl_setting.text_attr); move2screen_alt; centered_frame_vdest := screen_ptr; old_append_enabled := is_setting.append_enabled; is_setting.append_enabled := FALSE; Move(is_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,is_setting.terminate_keys,SizeOf(new_keys)); hpos := min(get_bank_position('?message_board?hpos',-1),1); vpos := min(get_bank_position('?message_board?vpos',-1),1); If NOT _force_program_quit then Repeat If (hpos > Length(p_mb^.data[vpos])+1) then hpos := Length(p_mb^.data[vpos])+1; is_setting.insert_mode := is_environment.insert_mode; is_environment.locate_pos := hpos; is_setting.character_set := [#32..#255]; p_mb^.data[vpos] := InputStr(p_mb^.data[vpos],xstart+2, ystart+1+vpos-1,MB_HSIZE,MB_HSIZE, dl_setting.text_attr,dl_setting.text_attr); hpos := is_environment.locate_pos; fkey := is_environment.keystroke; ref_vpos := vpos; Case fkey of kUP: If (vpos > 1) then Dec(vpos); kDOWN: If (vpos < MB_VSIZE) then Inc(vpos); kLEFT: If (hpos > 1) then Dec(hpos) else If (vpos > 1) then begin Dec(vpos); If (Length(p_mb^.data[vpos]) <> 0) then hpos := max(Length(p_mb^.data[vpos])+1,MB_HSIZE) else begin hpos := MB_HSIZE; p_mb^.data[vpos] := ExpStrR('',MB_HSIZE,' '); end; end; kRIGHT: If (hpos < MB_HSIZE) then Inc(hpos) else If (vpos < MB_VSIZE) then begin Inc(vpos); hpos := 1; end; kCtPgUP: vpos := 1; kCtPgDN: vpos := MB_VSIZE; kPgUP: begin old_vpos := vpos; If (vpos > 1) then Repeat Dec(vpos); until (vpos = 1) or (CutStr(p_mb^.data[vpos]) <> ''); If (vpos = old_vpos) then vpos := 1; end; kPgDOWN: begin old_vpos := vpos; If (vpos < MB_VSIZE) then Repeat Inc(vpos); until (vpos = MB_VSIZE) or (CutStr(p_mb^.data[vpos]) <> ''); If (vpos = old_vpos) then vpos := MB_VSIZE; end; kHOME: If (hpos > 1) then hpos := 1 else vpos := 1; kCtHOME: begin vpos := 1; hpos := 1; end; kEND: If (hpos < Length(CutStrR(p_mb^.data[vpos],0))+1) then hpos := Length(CutStrR(p_mb^.data[vpos],0))+1 else If (hpos < MB_HSIZE) then hpos := MB_HSIZE else vpos := MB_VSIZE; kCtEND: begin vpos := MB_VSIZE; hpos := Length(p_mb^.data[MB_VSIZE])+1; end; kENTER: If (vpos < MB_VSIZE) then begin If (CutStr(p_mb^.data[MB_VSIZE]) = '') then begin If (hpos < MB_HSIZE) then begin temps := Copy(p_mb^.data[vpos],hpos,Length(p_mb^.data[vpos])); If (temps <> '') then Delete(p_mb^.data[vpos],hpos,Length(p_mb^.data[vpos])); end else temps := ''; For idx := MB_VSIZE downto vpos+1 do p_mb^.data[idx] := p_mb^.data[idx-1]; p_mb^.data[vpos+1] := temps; end; Inc(vpos); hpos := 1; end; kDELETE: If ((hpos = Length(p_mb^.data[vpos])) and (p_mb^.data[vpos][Length(p_mb^.data[vpos])] <> ' ')) or NOT ((CutStr(p_mb^.data[vpos]) = '') or (hpos >= Length(p_mb^.data[vpos])) or (CutStrR(p_mb^.data[vpos],hpos) <> CutStrR(p_mb^.data[vpos],0))) then Delete(p_mb^.data[vpos],hpos,1) else If (vpos < MB_VSIZE) then begin If (Length(CutStrR(p_mb^.data[vpos],hpos))+ Length(CutStrR(p_mb^.data[vpos+1],0)) <= MB_HSIZE) then begin p_mb^.data[vpos] := CutStrR(p_mb^.data[vpos],hpos)+ CutStrR(p_mb^.data[vpos+1],0); If (Length(p_mb^.data[vpos]) > MB_HSIZE) then Delete(p_mb^.data[vpos],MB_HSIZE+1,Length(p_mb^.data[vpos])); For idx := vpos+1 to MB_VSIZE-1 do p_mb^.data[idx] := p_mb^.data[idx+1]; p_mb^.data[MB_VSIZE] := ''; end; end; kTAB: begin If (vpos > 1) then begin vpos2 := vpos; Repeat Dec(vpos2); temps := CutStr(Copy(p_mb^.data[vpos2],hpos+1,Length(p_mb^.data[vpos2])-hpos)); until (vpos2 = 1) or (temps <> ''); If (hpos <= Length(p_mb^.data[vpos2])) then begin idx2 := hpos+1; While (idx2 < Length(p_mb^.data[vpos2])) and (p_mb^.data[vpos2][idx2] <> ' ') do Inc(idx2); While (idx2 < Length(p_mb^.data[vpos2])) and (p_mb^.data[vpos2][idx2] = ' ') do Inc(idx2); If (idx2-hpos > 1) then begin Insert(ExpStrL('',idx2-hpos,' '),p_mb^.data[vpos],hpos); Inc(hpos,idx2-hpos); end end end; If (Length(p_mb^.data[vpos]) > MB_HSIZE) then Delete(p_mb^.data[vpos],MB_HSIZE+1,Length(p_mb^.data[vpos])); end; kSPACE: begin If NOT ctrl_pressed then idx2 := vpos else idx2 := MB_VSIZE; flag := FALSE; For idx := vpos to idx2 do If (Length(CutStrR(p_mb^.data[idx],0)) = MB_HSIZE) then begin flag := TRUE; BREAK; end; If NOT flag and is_environment.insert_mode then For idx := vpos to idx2 do begin Insert(' ',p_mb^.data[idx],hpos); If (Length(p_mb^.data[idx]) > MB_HSIZE) then Delete(p_mb^.data[idx],MB_HSIZE+1,Length(p_mb^.data[idx])); end else If NOT is_environment.insert_mode then p_mb^.data[idx][hpos] := ' '; If (NOT flag or NOT is_environment.insert_mode) and (hpos < MB_HSIZE) then Inc(hpos); end; kCtBkSp: If NOT shift_pressed then begin If (hpos = MB_HSIZE) and (BYTE(p_mb^.data[vpos][0]) > 0) then Dec(BYTE(p_mb^.data[vpos][0])); While (p_mb^.data[vpos][hpos-1] in is_setting.word_characters) and (hpos > 1) do begin Dec(hpos); Delete(p_mb^.data[vpos],hpos,1); end; While NOT (p_mb^.data[vpos][hpos-1] in is_setting.word_characters) and (hpos > 1) do begin Dec(hpos); Delete(p_mb^.data[vpos],hpos,1); end; end else If (hpos < MB_HSIZE) then begin Dec(hpos); If (hpos <> 0) then For idx := vpos to MB_VSIZE do Delete(p_mb^.data[idx],hpos,1) else hpos := 1; end else For idx := vpos to MB_VSIZE do If (BYTE(p_mb^.data[idx][0]) > 0) then Dec(BYTE(p_mb^.data[idx][0])); kBkSPC: If (hpos > 1) then If (hpos < MB_HSIZE) or (p_mb^.data[vpos][hpos] = ' ') then begin Dec(hpos); Delete(p_mb^.data[vpos],hpos,1); end else If (BYTE(p_mb^.data[vpos][0]) > 0) then Dec(BYTE(p_mb^.data[vpos][0])) else else If (vpos > 1) then If (Length(CutStrR(p_mb^.data[vpos-1],0))+ Length(CutStrR(p_mb^.data[vpos],0)) <= MB_HSIZE) then begin Dec(vpos); hpos := Length(p_mb^.data[vpos])+1; p_mb^.data[vpos] := CutStrR(p_mb^.data[vpos],0)+ CutStrR(p_mb^.data[vpos+1],0); If (Length(p_mb^.data[vpos]) > MB_HSIZE) then Delete(p_mb^.data[vpos],MB_HSIZE+1,Length(p_mb^.data[vpos])); For idx := vpos+1 to MB_VSIZE-1 do p_mb^.data[idx] := p_mb^.data[idx+1]; p_mb^.data[MB_VSIZE] := ''; end; kCtrlY: If NOT shift_pressed then begin For idx := vpos to MB_VSIZE-1 do p_mb^.data[idx] := p_mb^.data[idx+1]; p_mb^.data[MB_VSIZE] := ''; end; end; If (Length(p_mb^.data[vpos]) < hpos) then p_mb^.data[vpos] := ExpStrR(p_mb^.data[vpos],hpos,' '); If (ref_vpos <> vpos) then p_mb^.data[ref_vpos] := CutStrR(p_mb^.data[ref_vpos],0); For idx := 1 to MB_VSIZE do ShowStr(centered_frame_vdest,xstart+2,ystart+1+idx-1, ExpStrR(p_mb^.data[idx],MB_HSIZE,' '), dl_setting.text_attr); until (fkey = kESC) or (fkey = kF1) or _force_program_quit; is_setting.append_enabled := old_append_enabled; Move(old_keys,is_setting.terminate_keys,SizeOf(old_keys)); add_bank_position('?message_board?hpos',-1,hpos); add_bank_position('?message_board?vpos',-1,vpos); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+MB_HSIZE+3+2; move_to_screen_area[4] := ystart+MB_VSIZE+1+1; move2screen; If (fkey = kF1) then begin HELP('message_board'); GOTO _jmp1; end; end; procedure QUIT_request; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:QUIT_request'; {$ENDIF} If _force_program_quit then begin fkey := kESC; EXIT; end; temp := Dialog('...AND YOU WiLL KNOW MY NAME iS THE LORD, WHEN i LAY$'+ 'MY VENGEANCE UPON THEE...$', '~Q~UiT$~O~OOPS$', ' EZECHiEL 25:17 ',1); If (dl_environment.keystroke <> kESC) and (temp = 1) then begin fkey := kESC; _force_program_quit := TRUE; end else fkey := kENTER; end; procedure show_progress(value: Longint); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:show_progress'; {$ENDIF} If (progress_num_steps = 0) or (progress_value = 0) then EXIT; If (value <> DWORD_NULL) then begin If (progress_num_steps = 1) then progress_new_value := Round(40/progress_value*value) else progress_new_value := Round(40/progress_num_steps*PRED(progress_step)+ 40/progress_num_steps/progress_value*value); progress_new_value := max(progress_new_value,40); If (progress_new_value <> progress_old_value) then begin progress_old_value := progress_new_value; ShowStr(screen_ptr,progress_xstart+35,progress_ystart-1, ExpStrL(Num2Str(Round(100/40*progress_new_value),10)+'%',5,' '), dialog_background+dialog_hi_text); ShowCStr(screen_ptr, progress_xstart,progress_ystart, '~'+ExpStrL('',progress_new_value,#219)+'~'+ ExpStrL('',40-progress_new_value,#219), dialog_background+dialog_prog_bar1, dialog_background+dialog_prog_bar2); realtime_gfx_poll_proc; draw_screen; end; end else begin ShowStr(screen_ptr,progress_xstart+35,progress_ystart-1, ExpStrL('0%',5,' '), dialog_background+dialog_hi_text); ShowStr(screen_ptr, progress_xstart,progress_ystart, ExpStrL('',40,#219), dialog_background+dialog_prog_bar1); realtime_gfx_poll_proc; draw_screen; end; end; const last_dir: array[1..4] of String[DIR_SIZE] = ('','','',''); last_file: array[1..4] of String[FILENAME_SIZE] = ('FNAME:EXT','FNAME:EXT', 'FNAME:EXT','FNAME:EXT'); function FILE_open(masks: String; loadBankPossible: Boolean): Byte; var fname,temps: String; mpos,index: Byte; old_ext_proc: procedure; old_songdata_source: String; old_play_status: tPLAY_STATUS; old_tracing: Boolean; temp_marks: array[1..255] of Char; temp_marks2: array[0..$7f] of Char; xstart,ystart: Byte; flag: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:FILE_open:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; end; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:FILE_open'; {$ENDIF} flag := BYTE_NULL; old_play_status := play_status; old_tracing := tracing; If (Pos('a2i',Lower(masks)) = 0) and (Pos('a2f',Lower(masks)) = 0) and (Pos('a2w',Lower(masks)) = 0) then mpos := 1 else mpos := 2; For index := 1 to 255 do temp_marks[index] := songdata.instr_names[index][1]; For index := 0 to $7f do temp_marks2[index] := songdata.pattern_names[index][1]; _jmp1: If _force_program_quit then EXIT; old_songdata_source := songdata_source; If NOT quick_cmd then begin fs_environment.last_file := last_file[mpos]; fs_environment.last_dir := last_dir[mpos]; old_ext_proc := mn_environment.ext_proc; If (mpos = 2) then mn_environment.ext_proc := fselect_external_proc; fname := Fselect(masks); mn_environment.ext_proc := old_ext_proc; last_file[mpos] := fs_environment.last_file; last_dir[mpos] := fs_environment.last_dir; If (mn_environment.keystroke <> kENTER) then EXIT else If (mpos = 1) then songdata_source := fname else instdata_source := fname; end else If (mpos = 1) then fname := songdata_source else fname := instdata_source; load_flag := BYTE_NULL; limit_exceeded := FALSE; HideCursor; nul_volume_bars; no_status_refresh := TRUE; If (Lower(ExtOnly(fname)) = 'a2m') or (Lower(ExtOnly(fname)) = 'a2t') then begin ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; temps := Upper(ExtOnly(fname))+' FiLE'; centered_frame(xstart,ystart,43,3,' '+temps+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_num_steps := 1; progress_step := 1; If (Lower(ExtOnly(fname)) = 'a2m') then temps := 'MODULE' else temps := 'TiNY MODULE'; ShowCStr(screen_ptr,xstart+2,ystart+1, 'DECOMPRESSiNG '+temps+' DATA...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(DWORD_NULL); end; If (Lower(ExtOnly(fname)) = 'a2m') then a2m_file_loader; If (Lower(ExtOnly(fname)) = 'a2t') then a2t_file_loader; If (Lower(ExtOnly(fname)) = 'a2p') then a2p_file_loader; If (Lower(ExtOnly(fname)) = 'amd') then amd_file_loader; If (Lower(ExtOnly(fname)) = 'cff') then cff_file_loader; If (Lower(ExtOnly(fname)) = 'dfm') then dfm_file_loader; If (Lower(ExtOnly(fname)) = 'fmk') then fmk_file_loader; If (Lower(ExtOnly(fname)) = 'hsc') then hsc_file_loader; If (Lower(ExtOnly(fname)) = 'mtk') then mtk_file_loader; If (Lower(ExtOnly(fname)) = 'rad') then rad_file_loader; If (Lower(ExtOnly(fname)) = 's3m') then s3m_file_loader; If (Lower(ExtOnly(fname)) = 'sat') then sat_file_loader; If (Lower(ExtOnly(fname)) = 'sa2') then sa2_file_loader; If (Lower(ExtOnly(fname)) = 'xms') then amd_file_loader; If (Lower(ExtOnly(fname)) = 'a2i') then a2i_file_loader; If (Lower(ExtOnly(fname)) = 'a2f') then a2f_file_loader; If ((Lower(ExtOnly(fname)) = 'a2m') or (Lower(ExtOnly(fname)) = 'a2t')) and (load_flag = 1) then begin progress_num_steps := 1; progress_step := 1; progress_value := 1; progress_old_value := BYTE_NULL; _draw_screen_without_delay := TRUE; show_progress(1); // delay for awhile to show progress bar at 100% {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; end; If (Lower(ExtOnly(fname)) = 'a2b') then If shift_pressed and NOT ctrl_pressed and NOT alt_pressed then begin If loadBankPossible then begin index := Dialog('ALL UNSAVED INSTRUMENT DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2B LOADER ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then a2b_file_loader(FALSE,loadBankPossible); // w/o bank selector end else a2b_file_loader(TRUE,loadBankPossible); // w/ bank selector end else a2b_file_loader(TRUE,loadBankPossible); // w/ bank selector If (Lower(ExtOnly(fname)) = 'a2w') then If shift_pressed and NOT ctrl_pressed and NOT alt_pressed then begin If loadBankPossible then begin If _arp_vib_loader then index := Dialog('ALL UNSAVED ARPEGGiO/ViBRATO MACRO DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2W LOADER ',1) else index := Dialog('ALL UNSAVED iNSTRUMENT AND MACRO DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2W LOADER ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then a2w_file_loader(TRUE,_arp_vib_loader,FALSE,loadBankPossible,FALSE); // w/o bank selector end else a2w_file_loader(TRUE,_arp_vib_loader,TRUE,loadBankPossible,FALSE); // w/ bank selector _arp_vib_loader := FALSE; end else begin a2w_file_loader(TRUE,_arp_vib_loader,TRUE,loadBankPossible,FALSE); // w/ bank selector _arp_vib_loader := FALSE; end; If (Lower(ExtOnly(fname)) = 'bnk') then bnk_file_loader; If (Lower(ExtOnly(fname)) = 'cif') then cif_file_loader; If (Lower(ExtOnly(fname)) = 'fib') then fib_file_loader; If (Lower(ExtOnly(fname)) = 'fin') then fin_file_loader; If (Lower(ExtOnly(fname)) = 'ibk') then ibk_file_loader; If (Lower(ExtOnly(fname)) = 'ins') then ins_file_loader; If (Lower(ExtOnly(fname)) = 'sbi') then sbi_file_loader; If (Lower(ExtOnly(fname)) = 'sgi') then sgi_file_loader; // ThinCursor; If (mpos = 1) then Case load_flag of 0: If (old_songdata_source <> '') and (old_songdata_source <> songdata_source) then begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; index := Dialog('THERE WAS AN ERROR WHiLE LOADiNG NEW MODULE$'+ 'DO YOU WiSH TO RELOAD PREViOUS?$', '~Y~UP$~N~OPE$',' PATTERN EDiTOR ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then begin quick_cmd := TRUE; songdata_source := old_songdata_source; FILE_open('*.a2m$*.a2t$*.a2p$*.amd$*.cff$*.dfm$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); quick_cmd := FALSE; end; end else begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; index := Dialog('THERE WAS AN ERROR WHiLE LOADiNG NEW MODULE$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' PATTERN EDiTOR ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then else If (dl_environment.keystroke <> kESC) then init_songdata; end; 1: begin If limit_exceeded then If (old_songdata_source <> '') and (old_songdata_source <> songdata_source) then begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; index := Dialog('MODULE WAS NOT COMPLETELY LOADED DUE TO LACK OF MEMORY$'+ 'DO YOU WiSH TO RELOAD PREViOUS?$', '~Y~UP$~N~OPE$',' PATTERN EDiTOR ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then begin quick_cmd := TRUE; songdata_source := old_songdata_source; FILE_open('*.a2m$*.a2t$*.a2p$*.amd$*.cff$*.dfm$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); quick_cmd := FALSE; end; end else begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; index := Dialog('MODULE WAS NOT COMPLETELY LOADED DUE TO LACK OF MEMORY$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' PATTERN EDiTOR ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then else If (dl_environment.keystroke <> kESC) then init_songdata; end; speed_update := BOOLEAN(songdata.common_flag AND 1); lockvol := BOOLEAN(songdata.common_flag SHR 1 AND 1); lockVP := BOOLEAN(songdata.common_flag SHR 2 AND 1); tremolo_depth := songdata.common_flag SHR 3 AND 1; vibrato_depth := songdata.common_flag SHR 4 AND 1; panlock := BOOLEAN(songdata.common_flag SHR 5 AND 1); percussion_mode := BOOLEAN(songdata.common_flag SHR 6 AND 1); volume_scaling := BOOLEAN(songdata.common_flag SHR 7 AND 1); current_tremolo_depth := tremolo_depth; current_vibrato_depth := vibrato_depth; If NOT percussion_mode then begin _chan_n := _chmm_n; _chan_m := _chmm_m; _chan_c := _chmm_c; end else begin _chan_n := _chpm_n; _chan_m := _chpm_m; _chan_c := _chpm_c; end; init_buffers; If (Lower(ExtOnly(fname)) <> 'a2p') then For index := 1 to 255 do songdata.instr_names[index] := ' iNS_'+byte2hex(index)+#247' '+ Copy(songdata.instr_names[index],10,32); If (Lower(ExtOnly(fname)) <> 'a2p') then For index := 0 to $7f do songdata.pattern_names[index] := ' PAT_'+byte2hex(index)+' '#247' '+ Copy(songdata.pattern_names[index],12,30); If NOT quick_cmd then begin FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); track_notes := FALSE; track_chan_start := 1; nm_track_chan := 1; remap_mtype := 1; remap_ins1 := 1; remap_ins2 := 1; remap_selection := 1; replace_selection := 1; replace_prompt := FALSE; replace_data.event_to_find.note := '???'; replace_data.event_to_find.inst := '??'; replace_data.event_to_find.fx_1 := '???'; replace_data.event_to_find.fx_2 := '???'; replace_data.new_event.note := '???'; replace_data.new_event.inst := '??'; replace_data.new_event.fx_1 := '???'; replace_data.new_event.fx_2 := '???'; current_inst := 1; pattern_list__page := 1; _macro_editor__pos[FALSE] := 1; _macro_editor__pos[TRUE] := 8; _macro_editor__fmreg_hpos[FALSE] := 1; _macro_editor__fmreg_hpos[TRUE] := 1; _macro_editor__fmreg_page[FALSE] := 1; _macro_editor__fmreg_page[TRUE] := 1; _macro_editor__fmreg_left_margin[FALSE] := 1; _macro_editor__fmreg_left_margin[TRUE] := 1; _macro_editor__fmreg_cursor_pos[FALSE] := 1; _macro_editor__fmreg_cursor_pos[TRUE] := 1; add_bank_position('?internal_instrument_data?macro?pos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_page',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_hpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_vpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_left_margin',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_cursor_pos',-1,1); _macro_editor__arpeggio_page[FALSE] := 1; _macro_editor__arpeggio_page[TRUE] := 1; _macro_editor__vibrato_hpos[FALSE] := 1; _macro_editor__vibrato_hpos[TRUE] := 1; _macro_editor__vibrato_page[FALSE] := 1; _macro_editor__vibrato_page[TRUE] := 1; add_bank_position('?internal_instrument_data?macro_av?pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?arp_pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?vib_pos',-1,1); add_bank_position('?song_variables_window?pos',-1,1); add_bank_position('?song_variables_window?pos_4op',-1,0); add_bank_position('?replace_window?pos',-1,1); add_bank_position('?replace_window?posfx',-1,1); add_bank_position('?message_board?hpos',-1,1); add_bank_position('?message_board?vpos',-1,1); For index := 1 to 255 do begin add_bank_position('?instrument_editor?'+byte2hex(index)+'?carrier',-1,1); add_bank_position('?instrument_editor?'+byte2hex(index)+'?carrier?hpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(index)+'?carrier?vpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(index)+'?modulator?hpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(index)+'?modulator?vpos',-1,1); end; For index := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[index] := index; _rearrange_track_pos := 1; end else begin For index := 1 to 255 do songdata.instr_names[index][1] := temp_marks[index]; For index := 0 to $7f do songdata.pattern_names[index][1] := temp_marks2[index]; end; reset_player; If NOT quick_cmd or NOT keep_position then If (Lower(ExtOnly(fname)) <> 'a2p') and NOT (shift_pressed and (mpos = 1) and (load_flag <> BYTE_NULL) and NOT quick_cmd and (old_play_status = isPlaying)) then POSITIONS_reset; songdata_crc := Update32(songdata,SizeOf(songdata),0); If (Lower(ExtOnly(fname)) <> 'a2p') then begin module_archived := TRUE; songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); end; end end else If (load_flag <> BYTE_NULL) then module_archived := FALSE else If NOT quick_cmd then If (Lower(ExtOnly(fname)) = 'bnk') or (Lower(ExtOnly(fname)) = 'fib') or (Lower(ExtOnly(fname)) = 'ibk') then GOTO _jmp1; If (load_flag <> BYTE_NULL) then begin songdata.songname := FilterStr2(songdata.songname,_valid_characters,'_'); songdata.composer := FilterStr2(songdata.composer,_valid_characters,'_'); For index := 1 to 255 do songdata.instr_names[index] := Copy(songdata.instr_names[index],1,9)+ FilterStr2(Copy(cstr2str(songdata.instr_names[index]),10,32),_valid_characters,'_'); end; If shift_pressed and (mpos = 1) and (load_flag <> BYTE_NULL) and NOT quick_cmd and (old_play_status = isPlaying) then begin start_playing; tracing := old_tracing; If NOT quick_cmd or NOT keep_position then If (Lower(ExtOnly(fname)) <> 'a2p') and NOT tracing then POSITIONS_reset; end else begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; flag := 1; FillChar(ai_table,SizeOf(ai_table),0); no_status_refresh := FALSE; FILE_open := flag; end; function _a2m_saver: Byte; type tHEADER = Record ident: array[1..10] of Char; crc32: Longint; ffver: Byte; patts: Byte; b0len: Longint; b1len: array[0..15] of Longint; end; const id = '_A2module_'; var f: File; header: tHEADER; temp,index: Longint; xstart,ystart: Byte; temp_marks: array[1..255] of Char; temp_marks2: array[0..$7f] of Char; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2m_saver:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; progress_num_steps := 0; progress_value := 0; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2m_saver'; {$ENDIF} _a2m_saver := 0; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(songdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2M SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2m_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; FillChar(songdata.songname[SUCC(Length(songdata.songname))], PRED(SizeOf(songdata.songname))- Length(songdata.songname),0); FillChar(songdata.composer[SUCC(Length(songdata.composer))], PRED(SizeOf(songdata.composer))- Length(songdata.composer),0); For temp := 1 to 255 do FillChar(songdata.instr_names[temp][SUCC(Length(songdata.instr_names[temp]))], PRED(SizeOf(songdata.instr_names[temp]))- Length(songdata.instr_names[temp]),0); For temp := 0 to $7f do FillChar(songdata.pattern_names[temp][SUCC(Length(songdata.pattern_names[temp]))], PRED(SizeOf(songdata.pattern_names[temp]))- Length(songdata.pattern_names[temp]),0); FillChar(header,SizeOf(header),0); count_patterns(header.patts); header.crc32 := DWORD_NULL; header.ident := id; songdata.common_flag := BYTE(speed_update)+BYTE(lockvol) SHL 1+ BYTE(lockVP) SHL 2+ tremolo_depth SHL 3+ vibrato_depth SHL 4+ BYTE(panlock) SHL 5+ BYTE(percussion_mode) SHL 6+ BYTE(volume_scaling) SHL 7; header.ffver := FFVER_A2M; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; If (header.patts = 0) then header.patts := 1; centered_frame(xstart,ystart,43,3,' A2M FiLE ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_step := 1; progress_num_steps := (header.patts-1) DIV 8 +2; ShowCStr(screen_ptr,xstart+2,ystart+1, 'COMPRESSiNG MODULE DATA...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(DWORD_NULL); For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; Delete(songdata.instr_names[temp],1,9); FillChar(songdata.instr_names[temp][SUCC(Length(songdata.instr_names[temp]))], 32-Length(songdata.instr_names[temp]),0); end; For temp := 0 to $7f do begin temp_marks2[temp] := songdata.pattern_names[temp][1]; Delete(songdata.pattern_names[temp],1,11); FillChar(songdata.pattern_names[temp][SUCC(Length(songdata.pattern_names[temp]))], 32-Length(songdata.pattern_names[temp]),0); end; header.b0len := LZH_compress(songdata,buf1,SizeOf(songdata)); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); For temp := 0 to $7f do Insert(temp_marks2[temp]+ 'PAT_'+byte2hex(temp)+' '#247' ', songdata.pattern_names[temp],1); BlockWriteF(f,buf1,header.b0len,temp); Inc(progress_step); If NOT (temp = header.b0len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b0len,header.crc32); header.b1len[0] := LZH_compress(pattdata^[0],buf1,SizeOf(pattdata^[0])); BlockWriteF(f,buf1,header.b1len[0],temp); Inc(progress_step); If NOT (temp = header.b1len[0]) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b1len[0],header.crc32); For index := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(index)) then begin header.b1len[index] := LZH_compress(pattdata^[index],buf1,SizeOf(pattdata^[index])); BlockWriteF(f,buf1,header.b1len[index],temp); Inc(progress_step); If NOT (temp = header.b1len[index]) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b1len[index],header.crc32); end; header.crc32 := Update32(header.b0len,2,header.crc32); For index := 0 to 15 do header.crc32 := Update32(header.b1len[index],2,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; CloseF(f); _restore; songdata_title := NameOnly(songdata_source); songdata_crc := Update32(songdata,SizeOf(songdata),0); songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); module_archived := TRUE; end; function _a2t_saver: Byte; type tHEADER = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; patln: Word; nmtrk: Byte; mcspd: Word; is4op: Byte; locks: array[1..20] of Byte; b0len: Longint; b1len: Longint; b2len: Longint; b3len: Longint; b4len: Longint; b5len: array[0..15] of Longint; end; const id = '_A2tiny_module_'; var f: File; header: tHEADER; instruments: Byte; temp,temp2,index: Longint; temps: String; xstart,ystart: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2t_saver:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; progress_num_steps := 0; progress_value := 0; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2t_saver'; {$ENDIF} _a2t_saver := 0; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(songdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2T SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2t_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; FillChar(header,SizeOf(header),0); count_patterns(header.patts); header.crc32 := DWORD_NULL; header.ident := id; header.tempo := songdata.tempo; header.speed := songdata.speed; header.cflag := BYTE(speed_update)+BYTE(lockvol) SHL 1+ BYTE(lockVP) SHL 2+ tremolo_depth SHL 3+ vibrato_depth SHL 4+ BYTE(panlock) SHL 5+ BYTE(percussion_mode) SHL 6+ BYTE(volume_scaling) SHL 7; header.patln := songdata.patt_len; header.nmtrk := songdata.nm_tracks; header.mcspd := songdata.macro_speedup; header.is4op := songdata.flag_4op; Move(songdata.lock_flags,header.locks,SizeOf(header.locks)); header.ffver := FFVER_A2T; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; If (header.patts = 0) then header.patts := 1; temps := 'A2T FiLE'; centered_frame(xstart,ystart,43,3,' '+temps+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_step := 1; progress_num_steps := (header.patts-1) DIV 8 +6; ShowCStr(screen_ptr,xstart+2,ystart+1, 'COMPRESSiNG TiNY MODULE DATA...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(DWORD_NULL); count_instruments(instruments); instruments := min(instruments,1); Move(songdata.ins_4op_flags,buf2,SizeOf(songdata.ins_4op_flags)); temp2 := SizeOf(songdata.ins_4op_flags); Move(songdata.reserved_data,buf2[temp2],SizeOf(songdata.reserved_data)); Inc(temp2,SizeOf(songdata.reserved_data)); Move(songdata.instr_data,buf2[temp2],instruments*SizeOf(songdata.instr_data[1])); Inc(temp2,instruments*SizeOf(songdata.instr_data[1])); header.b0len := LZH_compress_ultra(buf2,buf1,temp2); BlockWriteF(f,buf1,header.b0len,temp); Inc(progress_step); If NOT (temp = header.b0len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b0len,header.crc32); temp := 0; temp2 := instruments*SizeOf(songdata.instr_macros[1]); If NOT Empty(songdata.instr_macros,temp2) then begin header.b1len := LZH_compress_ultra(songdata.instr_macros,buf1,temp2); BlockWriteF(f,buf1,header.b1len,temp); end else header.b1len := 0; Inc(progress_step); If NOT (temp = header.b1len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b1len,header.crc32); temp := 0; temp2 := SizeOf(songdata.macro_table); If NOT Empty(songdata.macro_table,temp2) then begin header.b2len := LZH_compress_ultra(songdata.macro_table,buf1,temp2); BlockWriteF(f,buf1,header.b2len,temp); end else header.b2len := 0; Inc(progress_step); If NOT (temp = header.b2len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b2len,header.crc32); temp := 0; temp2 := SizeOf(songdata.dis_fmreg_col); If NOT Empty(songdata.dis_fmreg_col,temp2) then begin header.b3len := LZH_compress_ultra(songdata.dis_fmreg_col,buf1,temp2); BlockWriteF(f,buf1,header.b3len,temp); end else header.b3len := 0; Inc(progress_step); If NOT (temp = header.b3len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b3len,header.crc32); temp2 := SizeOf(songdata.pattern_order); header.b4len := LZH_compress_ultra(songdata.pattern_order,buf1,temp2); BlockWriteF(f,buf1,header.b4len,temp); Inc(progress_step); If NOT (temp = header.b4len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b4len,header.crc32); If (header.patts < 1*8) then temp2 := header.patts*SizeOf(pattdata^[0][0]) else temp2 := SizeOf(pattdata^[0]); header.b5len[0] := LZH_compress_ultra(pattdata^[0],buf1,temp2); BlockWriteF(f,buf1,header.b5len[0],temp); Inc(progress_step); If NOT (temp = header.b5len[0]) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b5len[0],header.crc32); For index := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(index)) then begin If (header.patts < SUCC(index)*8) then temp2 := (header.patts-index*8)*SizeOf(pattdata^[index][0]) else temp2 := SizeOf(pattdata^[index]); header.b5len[index] := LZH_compress_ultra(pattdata^[index],buf1,temp2); BlockWriteF(f,buf1,header.b5len[index],temp); Inc(progress_step); If NOT (temp = header.b5len[index]) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b5len[index],header.crc32); end; header.crc32 := Update32(header.b0len,2,header.crc32); header.crc32 := Update32(header.b1len,2,header.crc32); header.crc32 := Update32(header.b2len,2,header.crc32); header.crc32 := Update32(header.b3len,2,header.crc32); header.crc32 := Update32(header.b4len,2,header.crc32); For index := 0 to 15 do header.crc32 := Update32(header.b5len[index],2,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; CloseF(f); _restore; songdata_title := NameOnly(songdata_source); songdata_crc := Update32(songdata,SizeOf(songdata),0); songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); module_archived := TRUE; end; function _a2i_saver: Byte; type tHEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Word; end; const id = '_A2ins_'; var f: File; header: tHEADER; temp,temp2,temp3: Longint; ins_4op: Word; crc: Word; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2i_saver'; {$ENDIF} _a2i_saver := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(instdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2i SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2i_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; progress_num_steps := 0; header.ident := id; header.ffver := FFVER_A2I; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; temp3 := 0; ins_4op := check_4op_to_test; If (ins_4op <> 0) then begin // 4OP 1/2 Move(songdata.instr_data[HI(ins_4op)],buf2[temp3], SizeOf(songdata.instr_data[HI(ins_4op)])); Inc(temp3,SizeOf(songdata.instr_data[HI(ins_4op)])); temp_str := Copy(songdata.instr_names[HI(ins_4op)],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); // 4OP 2/2 Move(songdata.instr_data[LO(ins_4op)],buf2[temp3], SizeOf(songdata.instr_data[LO(ins_4op)])); Inc(temp3,SizeOf(songdata.instr_data[LO(ins_4op)])); temp_str := Copy(songdata.instr_names[LO(ins_4op)],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); end else begin Move(songdata.instr_data[current_inst],buf2[temp3], SizeOf(songdata.instr_data[current_inst])); Inc(temp3,SizeOf(songdata.instr_data[current_inst])); temp_str := Copy(songdata.instr_names[current_inst],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); end; temp2 := LZH_compress(buf2,buf3,temp3); BlockWriteF(f,buf3,temp2,temp); If NOT (temp = temp2) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; header.b0len := temp; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf3,header.b0len,crc); header.crc16 := crc; ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; CloseF(f); end; function _a2f_saver: Byte; type tHEADER = Record ident: array[1..18] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; const id = '_a2ins_w/fm-macro_'; var f: File; header: tHEADER; temp,temp2,temp3: Longint; ins_4op: Word; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2f_saver'; {$ENDIF} _a2f_saver := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(instdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2F SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2f_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; progress_num_steps := 0; header.ident := id; header.ffver := FFVER_A2F; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; temp3 := 0; ins_4op := check_4op_to_test; If (ins_4op <> 0) then begin // 4OP 1/2 Move(songdata.instr_data[HI(ins_4op)],buf2[temp3], SizeOf(songdata.instr_data[HI(ins_4op)])); Inc(temp3,SizeOf(songdata.instr_data[HI(ins_4op)])); temp_str := Copy(songdata.instr_names[HI(ins_4op)],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); temp2 := 0; Move(songdata.instr_macros[HI(ins_4op)],buf3[temp2], SizeOf(songdata.instr_macros[HI(ins_4op)])); Inc(temp2,SizeOf(songdata.instr_macros[HI(ins_4op)])); tREGISTER_TABLE(Addr(buf3[temp2])^).arpeggio_table := 0; tREGISTER_TABLE(Addr(buf3[temp2])^).vibrato_table := 0; Move(songdata.dis_fmreg_col[HI(ins_4op)], buf3[temp2], SizeOf(songdata.dis_fmreg_col[HI(ins_4op)])); Inc(temp2,SizeOf(songdata.dis_fmreg_col[HI(ins_4op)])); Move(buf3,buf2[temp3],temp2); Inc(temp3,temp2); // 4OP 2/2 Move(songdata.instr_data[LO(ins_4op)],buf2[temp3], SizeOf(songdata.instr_data[LO(ins_4op)])); Inc(temp3,SizeOf(songdata.instr_data[LO(ins_4op)])); temp_str := Copy(songdata.instr_names[LO(ins_4op)],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); temp2 := 0; Move(songdata.instr_macros[LO(ins_4op)],buf3[temp2], SizeOf(songdata.instr_macros[LO(ins_4op)])); Inc(temp2,SizeOf(songdata.instr_macros[LO(ins_4op)])); tREGISTER_TABLE(Addr(buf3[temp2])^).arpeggio_table := 0; tREGISTER_TABLE(Addr(buf3[temp2])^).vibrato_table := 0; Move(songdata.dis_fmreg_col[LO(ins_4op)], buf3[temp2], SizeOf(songdata.dis_fmreg_col[LO(ins_4op)])); Inc(temp2,SizeOf(songdata.dis_fmreg_col[LO(ins_4op)])); Move(buf3,buf2[temp3],temp2); Inc(temp3,temp2); end else begin Move(songdata.instr_data[current_inst],buf2[temp3], SizeOf(songdata.instr_data[current_inst])); Inc(temp3,SizeOf(songdata.instr_data[current_inst])); temp_str := Copy(songdata.instr_names[current_inst],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); temp2 := 0; Move(songdata.instr_macros[current_inst],buf3[temp2], SizeOf(songdata.instr_macros[current_inst])); Inc(temp2,SizeOf(songdata.instr_macros[current_inst])); tREGISTER_TABLE(Addr(buf3[temp2])^).arpeggio_table := 0; tREGISTER_TABLE(Addr(buf3[temp2])^).vibrato_table := 0; Move(songdata.dis_fmreg_col[current_inst], buf3[temp2], SizeOf(songdata.dis_fmreg_col[current_inst])); Inc(temp2,SizeOf(songdata.dis_fmreg_col[current_inst])); Move(buf3,buf2[temp3],temp2); Inc(temp3,temp2); end; temp2 := LZH_compress(buf2,buf3,temp3); BlockWriteF(f,buf3,temp2,temp); If NOT (temp = temp2) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; header.b0len := temp; header.crc32 := DWORD_NULL; header.crc32 := Update32(header.b0len,1,header.crc32); header.crc32 := Update32(buf3,header.b0len,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; CloseF(f); end; function _a2p_saver: Byte; type tHEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; const id = '_A2pattern_'; var f: File; header: tHEADER; temp,temp2: Longint; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2p_saver'; {$ENDIF} _a2p_saver := 0; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(songdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2P SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2p_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; progress_num_steps := 0; header.crc32 := DWORD_NULL; header.ident := id; header.ffver := FFVER_A2P; If (pattern2use <> BYTE_NULL) then Move(pattdata^[pattern2use DIV 8][pattern2use MOD 8], buf2, PATTERN_SIZE) else Move(pattdata^[pattern_patt DIV 8][pattern_patt MOD 8], buf2, PATTERN_SIZE); If (pattern2use <> BYTE_NULL) then temp_str := Copy(songdata.pattern_names[pattern2use],12,30) else temp_str := Copy(songdata.pattern_names[pattern_patt],12,30); FillChar(temp_str[SUCC(Length(temp_str))],30-Length(temp_str),0); Move(temp_str,buf2[PATTERN_SIZE],Length(temp_str)+1); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; temp2 := PATTERN_SIZE+30+1; header.b0len := LZH_compress(buf2,buf1,temp2); BlockWriteF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b0len,header.crc32); header.crc32 := Update32(header.b0len,2,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; CloseF(f); end; function _a2b_saver: Byte; const id = '_A2insbank_'; type tHEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; var f: File; header: tHEADER; temp,temp2,temp3: Longint; crc: Longint; temp_marks: array[1..255] of Char; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2b_saver'; {$ENDIF} _a2b_saver := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(instdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2B SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2b_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; progress_num_steps := 0; header.ident := id; header.ffver := FFVER_A2B; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; Delete(songdata.instr_names[temp],1,9); FillChar(songdata.instr_names[temp][SUCC(Length(songdata.instr_names[temp]))], 32-Length(songdata.instr_names[temp]),0); end; temp3 := SizeOf(songdata.instr_names)+SizeOf(songdata.instr_data); Move(songdata.instr_names,buf2,temp3); Move(songdata.ins_4op_flags,buf2[temp3],SizeOf(songdata.ins_4op_flags)); Inc(temp3,SizeOf(songdata.ins_4op_flags)); temp2 := LZH_compress(buf2,buf1,temp3); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); BlockWriteF(f,buf1,temp2,temp); If NOT (temp = temp2) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; header.b0len := temp; crc := DWORD_NULL; crc := Update32(header.b0len,2,crc); crc := Update32(buf1,header.b0len,crc); header.crc32 := crc; ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; CloseF(f); end; function _a2w_saver: Byte; const id = '_A2insbank_w/macros_'; type tHEADER = Record ident: array[1..20] of Char; crc32: Longint; ffver: Byte; b0len: Longint; b1len: Longint; b2len: Longint; end; var f: File; header: tHEADER; temp,temp3: Longint; temp_marks: array[1..255] of Char; xstart,ystart: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2w_saver:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; progress_num_steps := 0; progress_value := 0; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2w_saver'; {$ENDIF} _a2w_saver := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(instdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2W SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2w_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; centered_frame(xstart,ystart,43,3,' A2W FiLE ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_step := 1; progress_num_steps := 3; ShowCStr(screen_ptr,xstart+2,ystart+1, 'COMPRESSiNG iNSTRUMENT BANK DATA...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(DWORD_NULL); header.crc32 := DWORD_NULL; header.ident := id; header.ffver := FFVER_A2W; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; Delete(songdata.instr_names[temp],1,9); FillChar(songdata.instr_names[temp][SUCC(Length(songdata.instr_names[temp]))], 32-Length(songdata.instr_names[temp]),0); end; temp3 := SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)+ SizeOf(songdata.instr_macros); Move(songdata.instr_names,buf2,temp3); Move(songdata.ins_4op_flags,buf2[temp3],SizeOf(songdata.ins_4op_flags)); Inc(temp3,SizeOf(songdata.ins_4op_flags)); header.b0len := LZH_compress(buf2,buf1,temp3); Inc(progress_step); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); BlockWriteF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b0len,header.crc32); header.b1len := LZH_compress(songdata.macro_table,buf1,SizeOf(songdata.macro_table)); Inc(progress_step); BlockWriteF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b1len,header.crc32); header.b2len := LZH_compress(songdata.dis_fmreg_col,buf1,SizeOf(songdata.dis_fmreg_col)); Inc(progress_step); BlockWriteF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b2len,header.crc32); header.crc32 := Update32(header.b0len,2,header.crc32); header.crc32 := Update32(header.b1len,2,header.crc32); header.crc32 := Update32(header.b2len,2,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; CloseF(f); progress_num_steps := 1; progress_step := 1; progress_value := 1; progress_old_value := BYTE_NULL; _draw_screen_without_delay := TRUE; show_progress(1); // delay for awhile to show progress bar at 100% {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; end; procedure FILE_save(ext: String); var quit_flag: Boolean; temp_str: String; temp,mpos: Byte; old_songdata_source, old_instdata_source: String; label _jmp1,_jmp2; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:FILE_save'; {$ENDIF} old_songdata_source := songdata_source; old_instdata_source := instdata_source; If (songdata_source <> '') then songdata_source := iCase_filename(PathOnly(songdata_source))+ Lower_filename(BaseNameOnly(songdata_source))+'.'+ext; If (instdata_source <> '') then instdata_source := iCase_filename(PathOnly(instdata_source))+ Lower_filename(BaseNameOnly(instdata_source))+'.'+ext; _jmp1: If quick_cmd then If ((Lower_filename(ext) = 'a2m') or (Lower_filename(ext) = 'a2t')) and (songdata_source <> '') then GOTO _jmp2; Repeat is_setting.append_enabled := TRUE; is_setting.character_set := [#32..#255]; dl_setting.center_text := FALSE; dl_setting.terminate_keys[3] := kTAB; is_setting.terminate_keys[3] := kTAB; is_environment.locate_pos := 1; dl_environment.context := ' TAB '#196#16' FiLE SELECTOR '; If (Lower_filename(ext) = 'a2i') then begin If NOT alt_ins_name then begin If (a2i_default_path = '') then dl_environment.input_str := instdata_source else dl_environment.input_str := iCase_filename(a2i_default_path)+NameOnly(instdata_source); end else dl_environment.input_str := iCase_filename(a2i_default_path)+ 'instr'+ExpStrL(Num2str(current_inst,10),3,'0')+'.a2i'; end; If (Lower_filename(ext) = 'a2f') then begin If NOT alt_ins_name then begin If (a2f_default_path = '') then dl_environment.input_str := instdata_source else dl_environment.input_str := iCase_filename(a2f_default_path)+NameOnly(instdata_source); end else dl_environment.input_str := iCase_filename(a2f_default_path)+ 'instr'+ExpStrL(Num2str(current_inst,10),3,'0')+'.a2f'; end; If (Lower_filename(ext) = 'a2b') then If (a2b_default_path = '') then dl_environment.input_str := instdata_source else dl_environment.input_str := iCase_filename(a2b_default_path)+NameOnly(instdata_source); If (Lower_filename(ext) = 'a2w') then If (a2w_default_path = '') then dl_environment.input_str := instdata_source else dl_environment.input_str := iCase_filename(a2w_default_path)+NameOnly(instdata_source); If (Lower_filename(ext) = 'a2m') then If (a2m_default_path = '') then dl_environment.input_str := songdata_source else dl_environment.input_str := iCase_filename(a2m_default_path)+NameOnly(songdata_source); If (Lower_filename(ext) = 'a2t') then If (a2t_default_path = '') then dl_environment.input_str := songdata_source else dl_environment.input_str := iCase_filename(a2t_default_path)+NameOnly(songdata_source); If (Lower_filename(ext) = 'a2p') then If (a2p_default_path = '') then dl_environment.input_str := songdata_source else dl_environment.input_str := iCase_filename(a2p_default_path)+NameOnly(songdata_source); Dialog('{PATH}[FiLENAME] EXTENSiON iS SET TO "'+iCase_filename(ext)+'"$', '%string_input%255$50'+ '$'+Num2str(dialog_input_bckg+dialog_input,16)+ '$'+Num2str(dialog_def_bckg+dialog_def,16)+ '$',' SAVE FiLE ',0); dl_setting.terminate_keys[3] := 0; is_setting.terminate_keys[3] := 0; dl_setting.center_text := TRUE; dl_environment.context := ''; If (dl_environment.keystroke = kESC) or ((dl_environment.keystroke <> kTAB) and (BaseNameOnly(dl_environment.input_str) = '')) then begin songdata_source := old_songdata_source; instdata_source := old_instdata_source; EXIT; end; If (dl_environment.keystroke = kENTER) then begin If (Lower_filename(ext) = 'a2m') then songdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2m'; If (Lower_filename(ext) = 'a2t') then songdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2t'; If (Lower_filename(ext) = 'a2p') then songdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2p'; If (Lower_filename(ext) = 'a2i') then instdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2i'; If (Lower_filename(ext) = 'a2f') then instdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2f'; If (Lower_filename(ext) = 'a2b') then instdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2b'; If (Lower_filename(ext) = 'a2w') then instdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2w'; end; quit_flag := TRUE; If (dl_environment.keystroke = kTAB) then begin If (Lower_filename(ext) <> 'a2i') and (Lower_filename(ext) <> 'a2f') and (Lower_filename(ext) <> 'a2b') and (Lower_filename(ext) <> 'a2w') then mpos := 3 else mpos := 4; fs_environment.last_file := last_file[mpos]; fs_environment.last_dir := last_dir[mpos]; temp_str := Fselect('*.'+ext+'$'); last_file[mpos] := fs_environment.last_file; last_dir[mpos] := fs_environment.last_dir; If (mn_environment.keystroke = kESC) then quit_flag := FALSE else begin If (Lower_filename(ext) = 'a2m') then songdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2m'; If (Lower_filename(ext) = 'a2t') then songdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2t'; If (Lower_filename(ext) = 'a2p') then songdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2p'; If (Lower_filename(ext) = 'a2i') then instdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2i'; If (Lower_filename(ext) = 'a2f') then instdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2f'; If (Lower_filename(ext) = 'a2b') then instdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2b'; If (Lower_filename(ext) = 'a2w') then instdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2w'; end; end; until quit_flag; If (dl_environment.keystroke = kESC) then begin songdata_source := old_songdata_source; instdata_source := old_instdata_source; EXIT; end; _jmp2: If (Lower_filename(ext) = 'a2i') or (Lower_filename(ext) = 'a2f') or (Lower_filename(ext) = 'a2b') or (Lower_filename(ext) = 'a2w') then temp_str := instdata_source; If (Lower_filename(ext) = 'a2m') or (Lower_filename(ext) = 'a2t') or (Lower_filename(ext) = 'a2p') then temp_str := songdata_source; If (Lower_filename(ext) = 'a2m') then temp := _a2m_saver; If (Lower_filename(ext) = 'a2t') then temp := _a2t_saver; If (Lower_filename(ext) = 'a2i') then temp := _a2i_saver; If (Lower_filename(ext) = 'a2f') then temp := _a2f_saver; If (Lower_filename(ext) = 'a2p') then temp := _a2p_saver; If (Lower_filename(ext) = 'a2b') then temp := _a2b_saver; If (Lower_filename(ext) = 'a2w') then temp := _a2w_saver; If (temp = BYTE_NULL) then GOTO _jmp1; end; end. adlibtracker2-2.4.23/ipattord.inc0000644000000000000000000014706013176573532015356 0ustar rootroot{ procedure pattern_list__proc; procedure PATTERN_LIST(page: Byte); function PATTERN_LIST_alt(page: Byte): Byte; procedure PATTERN_ORDER_page_refresh(page: Byte); procedure PATTERN_ORDER_edit(var page,hpos,vpos: Byte); } var _nm_patterns: Byte; procedure pattern_list__proc; var chunk: tCHUNK; temp,temp1,temp2, _1st,_2nd: Byte; temps: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:pattern_list__proc'; {$ENDIF} Case mn_environment.keystroke of kSPACE: If ctrl_pressed then For temp := 0 to $7f do If NOT shift_pressed then songdata.pattern_names[temp][1] := ' ' else If (songdata.pattern_names[temp][1] <> ' ') then songdata.pattern_names[temp][1] := ' ' else songdata.pattern_names[temp][1] := #16 else If (songdata.pattern_names[mn_environment.curr_pos-1][1] <> #16) then songdata.pattern_names[mn_environment.curr_pos-1][1] := #16 else songdata.pattern_names[mn_environment.curr_pos-1][1] := ' '; kAltC, kCtrlC: begin clipboard.object_type := objPattern; For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin get_chunk(mn_environment.curr_pos-1,temp2,temp1,chunk); clipboard.pattern[temp1][temp2] := chunk; end; clipboard._string := Copy(songdata.pattern_names[mn_environment.curr_pos-1],9,33); end; kAltP, kAltV, kCtrlV: If (clipboard.object_type = objPattern) then begin For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin If (mn_environment.keystroke <> kAltV) then put_chunk(mn_environment.curr_pos-1,temp2,temp1, clipboard.pattern[temp1][temp2]); If NOT (shift_pressed and (mn_environment.keystroke = kCtrlV)) then songdata.pattern_names[mn_environment.curr_pos-1] := Copy(songdata.pattern_names[mn_environment.curr_pos-1],1,8)+ clipboard._string; end; If NOT Empty(pattdata^[(mn_environment.curr_pos-1) DIV 8] [(mn_environment.curr_pos-1) MOD 8], PATTERN_SIZE) then begin songdata.pattern_names[mn_environment.curr_pos-1][9] := #15; Inc(_nm_patterns); end else songdata.pattern_names[mn_environment.curr_pos-1][9] := #14; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kCtrlN: If NOT shift_pressed then For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(mn_environment.curr_pos-1,temp2,temp1,chunk); end else For temp := 0 to $7f do If (songdata.pattern_names[temp][1] = #16) then For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(temp,temp2,temp1,chunk); end; kCtrlW: If (_patts_marked = 2) then begin _1st := 0; While (_1st < PRED(max_patterns)) and (songdata.pattern_names[_1st][1] = ' ') do Inc(_1st); _2nd := SUCC(_1st); While (_2nd < PRED(max_patterns)) and (songdata.pattern_names[_2nd][1] = ' ') do Inc(_2nd); Move(pattdata^[_1st DIV 8][_1st MOD 8], buf1, PATTERN_SIZE); temps := Copy(songdata.pattern_names[_1st],9,33); Move(pattdata^[_2nd DIV 8][_2nd MOD 8], pattdata^[_1st DIV 8][_1st MOD 8], PATTERN_SIZE); If shift_pressed then songdata.pattern_names[_1st] := Copy(songdata.pattern_names[_1st],1,8)+ Copy(songdata.pattern_names[_2nd],9,33); Move(buf1, pattdata^[_2nd DIV 8][_2nd MOD 8], PATTERN_SIZE); If shift_pressed then songdata.pattern_names[_2nd] := Copy(songdata.pattern_names[_2nd],1,8)+ temps; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kDELETE, kNPdel: If shift_pressed then begin For temp := mn_environment.curr_pos-1 to PRED(max_patterns)-1 do begin Move(pattdata^[SUCC(temp) DIV 8][SUCC(temp) MOD 8], pattdata^[temp DIV 8][temp MOD 8], PATTERN_SIZE); songdata.pattern_names[temp] := Copy(songdata.pattern_names[SUCC(temp)],1,1)+ Copy(songdata.pattern_names[temp],2,10)+ Copy(songdata.pattern_names[SUCC(temp)],12,30); songdata.pattern_names[temp][9] := songdata.pattern_names[SUCC(temp)][9]; end; FillChar(pattdata^[PRED(max_patterns) DIV 8][PRED(max_patterns) MOD 8], PATTERN_SIZE,0); songdata.pattern_names[PRED(max_patterns)] := ' '+ Copy(songdata.pattern_names[PRED(max_patterns)],2,10); songdata.pattern_names[PRED(max_patterns)][9] := #14; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kINSERT, kNPins: If shift_pressed then begin For temp := PRED(max_patterns)-1 downto mn_environment.curr_pos-1 do begin Move(pattdata^[temp DIV 8][temp MOD 8], pattdata^[SUCC(temp) DIV 8][SUCC(temp) MOD 8], PATTERN_SIZE); songdata.pattern_names[SUCC(temp)] := Copy(songdata.pattern_names[temp],1,1)+ Copy(songdata.pattern_names[SUCC(temp)],2,10)+ Copy(songdata.pattern_names[temp],12,30); songdata.pattern_names[SUCC(temp)][9] := songdata.pattern_names[temp][9]; end; FillChar(pattdata^[(mn_environment.curr_pos-1) DIV 8] [(mn_environment.curr_pos-1) MOD 8], PATTERN_SIZE,0); songdata.pattern_names[(mn_environment.curr_pos-1)] := ' '+ Copy(songdata.pattern_names[(mn_environment.curr_pos-1)],2,10); songdata.pattern_names[(mn_environment.curr_pos-1)][9] := #14; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; ShowC3Str(screen_ptr, mn_environment.xpos+13, mn_environment.desc_pos, ' [`USED`:~'+ ExpStrL(Num2str(_nm_patterns,10)+'~/'+ Num2str(max_patterns,10),8,' ')+']'+ ' [`MARKED`:~'+ ExpStrL(Num2str(_patts_marked,10),3,' ')+'~] ', dialog_background+dialog_context_dis, dialog_background+dialog_context, dialog_background+dialog_border); If NOT ((play_status <> isStopped) and tracing) then begin pattern_patt := mn_environment.curr_pos-1; PATTERN_page_refresh(pattern_page); end; mn_environment.do_refresh := TRUE; mn_environment.refresh; end; procedure PATTERN_LIST(page: Byte); const new_keys: array[1..8] of Word = (kESC,kENTER,kF1,kF2,kCtrlS, kF3,kCtrlL,kShF3); var temp: Byte; old_keys: array[1..8] of Word; temp_marks: array[0..$7f] of Char; crc2: Longint; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_LIST'; {$ENDIF} For temp := 0 to $7f do begin temp_marks[temp] := songdata.pattern_names[temp][1]; songdata.pattern_names[temp][1] := ' '; songdata.pattern_names[temp][9] := #14; end; songdata_crc := Update32(songdata.pattern_names,SizeOf(songdata.pattern_names),0); songdata_crc := Update32(pattdata^,SizeOf(pattdata^),songdata_crc); For temp := 0 to $7f do songdata.pattern_names[temp][1] := temp_marks[temp]; _jmp1: If _force_program_quit then EXIT; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); _nm_patterns := 0; For temp := 0 to PRED(max_patterns) do If NOT Empty(pattdata^[temp DIV 8][temp MOD 8],PATTERN_SIZE) then begin songdata.pattern_names[temp][9] := #15; Inc(_nm_patterns); end else songdata.pattern_names[temp][9] := #14; Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); mn_setting.center_box := TRUE; mn_setting.cycle_moves := FALSE; mn_environment.edit_pos := 11; mn_setting.edit_contents := TRUE; mn_environment.ext_proc := pattern_list__proc; mn_setting.terminate_keys[3] := kF1; mn_environment.hlight_chrs := 1; pattern_list__page := Menu(songdata.pattern_names,0,0,page,42,MAX_PATTERN_ROWS+4,max_patterns,' PATTERN LiST '); Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_setting.edit_contents := FALSE; mn_environment.ext_proc := NIL; mn_setting.terminate_keys[3] := 0; mn_environment.hlight_chrs := 0; Case mn_environment.keystroke of kF1: begin HELP('pattern_list'); GOTO _jmp1; end; kF2, kCtrlS: begin quick_cmd := FALSE; pattern2use := pattern_list__page-1; FILE_save('a2p'); pattern2use := BYTE_NULL; GOTO _jmp1; end; kF3, kShF3, kCtrlL: begin If (mn_environment.keystroke = kShF3) then quick_cmd := TRUE; pattern2use := pattern_list__page-1; FILE_open('*.a2p$',FALSE); pattern2use := BYTE_NULL; quick_cmd := FALSE; GOTO _jmp1; end; end; For temp := 0 to $7f do begin temp_marks[temp] := songdata.pattern_names[temp][1]; songdata.pattern_names[temp][1] := ' '; songdata.pattern_names[temp][9] := #14; end; crc2 := Update32(songdata.pattern_names,SizeOf(songdata.pattern_names),0); If (Update32(pattdata^,SizeOf(pattdata^),crc2) <> songdata_crc) then module_archived := FALSE; For temp := 0 to $7f do songdata.pattern_names[temp][1] := temp_marks[temp]; end; function PATTERN_LIST_alt(page: Byte): Byte; const obj_name: array[tCOPY_OBJECT] of String[10] = ( '', '','', '','', 'NOTE','iNSTRUMENT','1ST EFFECT','2ND EFFECT', 'LiNE','TRACK','PATTERN','BLOCK', '','','', ''); var temp: Byte; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_LIST_alt'; {$ENDIF} If NOT (clipboard.object_type in [objNote,objInstrumentDef,objEffect,objEffect2, objLine,objTrack,objPattern,objMarkedBlock]) then begin PATTERN_LIST_alt := BYTE_NULL; EXIT; end; _nm_patterns := 0; For temp := 0 to PRED(max_patterns) do If NOT Empty(pattdata^[temp DIV 8][temp MOD 8],PATTERN_SIZE) then begin songdata.pattern_names[temp][9] := #15; Inc(_nm_patterns); end else songdata.pattern_names[temp][9] := #14; _jmp1: If _force_program_quit then EXIT; mn_setting.center_box := TRUE; mn_setting.cycle_moves := FALSE; mn_environment.ext_proc := pattern_list__proc; mn_setting.terminate_keys[3] := kF1; pattern_list__page := Menu(songdata.pattern_names,0,0,page,42,22,max_patterns, ' PATTERN LiST | PASTE "'+obj_name[clipboard.object_type]+'" '); mn_environment.ext_proc := NIL; mn_setting.terminate_keys[3] := 0; If (mn_environment.keystroke = kF1) then begin HELP('pattern_list'); GOTO _jmp1; end; If (mn_environment.keystroke <> kESC) then PATTERN_LIST_alt := pattern_list__page else PATTERN_LIST_alt := BYTE_NULL; end; procedure PATTERN_ORDER_page_refresh(page: Byte); var attr: Word; temp1,temp2: Byte; xstart: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_ORDER_page_refresh'; {$ENDIF} show_str(25+6+PATTORD_xshift+(MAX_ORDER_COLS*7-1) DIV 2+(MAX_ORDER_COLS*7-1) MOD 2,02, byte2hex(pattord_vpos+4*(pattord_hpos+pattord_page-1)-1), order_background+order_border); xstart := 20+PATTORD_xshift; For temp1 := 1 to MAX_ORDER_COLS do For temp2 := 03 to 06 do begin If NOT tracing or play_single_patt then begin If (songdata.pattern_order[temp2-2+4*(temp1+page-1)-1] < $80) then attr := concw(order_background+order_hi_pattn,order_background+order_hi_entry) else attr := concw(order_background+order_entry,order_background+order_hi_entry); end else begin If (current_order = temp2-2+4*(temp1+page-1)-1) then attr := concw(order_hi_bckg+order_hi_pattn,order_hi_bckg+order_hi_entry) else If (songdata.pattern_order[temp2-2+4*(temp1+page-1)-1] < $80) then attr := concw(order_background+order_pattn,order_background+order_entry) else attr := concw(order_background+order_pattn_jump,order_background+order_entry); end; If (songdata.pattern_order[temp2-2+4*(temp1+page-1)-1] < $80) then begin If (current_order = temp2-2+4*(temp1+page-1)-1) and (play_status <> isStopped) and NOT play_single_patt then show_cstr(xstart+pos1[temp1]-1,temp2, byte2hex(temp2-2+4*(temp1+page-1)-1)+'~ ~', order_played_b+order_played,HI(attr)) else show_str(xstart+pos1[temp1]-1,temp2, byte2hex(temp2-2+4*(temp1+page-1)-1)+' ',HI(attr)); If NOT no_trace_pattord then show_str(xstart+pos1[temp1]-1+3,temp2, byte2hex(songdata.pattern_order[temp2-2+4*(temp1+page-1)-1]),LO(attr)); If NOT tracing then If (temp1 <= MAX_ORDER_COLS-1) then show_str(xstart+pos1[temp1]-1+5,temp2,#240,order_background+order_border); end else begin show_str(xstart+pos1[temp1]-1,temp2, byte2hex(temp2-2+4*(temp1+page-1)-1)+' ',HI(attr)); If NOT no_trace_pattord then show_str(xstart+pos1[temp1]-1+3,temp2, byte2hex(songdata.pattern_order[temp2-2+4*(temp1+page-1)-1]-$80),LO(attr)); If NOT tracing then If (temp1 <= MAX_ORDER_COLS-1) then show_str(xstart+pos1[temp1]-1+5,temp2,#240,order_background+order_border); end; end; temp1 := 0; If tracing then count_order(temp1); If scroll_bars then begin If (program_screen_mode <> 2) then If (temp1 <> 0) then scroll_pos0 := vscroll_bar(MAX_COLUMNS-2,02,6,temp1, (page+pattord_hpos-1)*4+pattord_vpos,scroll_pos0, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark) else scroll_pos0 := vscroll_bar(MAX_COLUMNS-2,02,6,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos1 := vscroll_bar(MAX_COLUMNS-1,02,6,$7f, (page+pattord_hpos-1)*4+pattord_vpos,scroll_pos1, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_2nd_mark); end else begin If (program_screen_mode <> 2) then scroll_pos0 := vscroll_bar(MAX_COLUMNS-2,02,6,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos1 := vscroll_bar(MAX_COLUMNS-1,02,6,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); end; end; procedure PATTERN_ORDER_edit(var page,hpos,vpos: Byte); var nope: Boolean; tstr,temps: String; temp: Byte; temp1: Word; xstart: Byte; procedure copy_object; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_ORDER_edit:copy_object'; {$ENDIF} Case clipboard.object_type of objPatternDef: clipboard.pattern_order[0] := songdata.pattern_order[(page+hpos-1)*4+vpos-1]; objPatternTable: Move(songdata.pattern_order, clipboard.pattern_order,SizeOf(songdata.pattern_order)); end; end; procedure paste_object; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_ORDER_edit:paste_object'; {$ENDIF} Case clipboard.object_type of objPatternDef: begin songdata.pattern_order[(page+hpos-1)*4+vpos-1] := clipboard.pattern_order[0]; If vpos < 4 then Inc(vpos) else If hpos < MAX_ORDER_COLS then begin Inc(hpos); vpos := 1; end else If page < (23-(MAX_ORDER_COLS-9)) then begin Inc(page); vpos := 1; end; end; objPatternTable: Move(clipboard.pattern_order, songdata.pattern_order,SizeOf(songdata.pattern_order)); end; end; label _end; begin { PATTERN_ORDER_edit } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_ORDER_edit'; {$ENDIF} songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); Repeat PATTERN_ORDER_page_refresh(page); PATTERN_page_refresh(pattern_page); xstart := 23+PATTORD_xshift; GotoXY(xstart+pos1[hpos]-1,03+vpos-1); If tracing then fkey := PATTERN_trace else ThinCursor; If ctrl_pressed and alt_pressed then begin DEBUG_INFO; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; nope := FALSE; If keypressed then fkey := getkey else GOTO _end; //CONTINUE; Case fkey of kLEFT: If hpos > 1 then Dec(hpos) else If page > 0 then Dec(page); kRIGHT: If hpos < MAX_ORDER_COLS then Inc(hpos) else If page < (23-(MAX_ORDER_COLS-9)) then Inc(page); kUP, kShTAB: If vpos > 1 then Dec(vpos) else If hpos > 1 then begin Dec(hpos); vpos := 4; end else If page > 0 then begin Dec(page); vpos := 4; end; kDOWN, kTAB: If vpos < 4 then Inc(vpos) else If hpos < MAX_ORDER_COLS then begin Inc(hpos); vpos := 1; end else If page < (23-(MAX_ORDER_COLS-9)) then begin Inc(page); vpos := 1; end; kPgUP: If page-8 > 0 then Dec(page,8) else begin If page > 0 then page := 0 else begin page := 0; hpos := 1; vpos := 1; end; end; kPgDOWN: If page+8 < (23-(MAX_ORDER_COLS-9)) then Inc(page,8) else begin If page < (23-(MAX_ORDER_COLS-9)) then page := (23-(MAX_ORDER_COLS-9)) else begin page := (23-(MAX_ORDER_COLS-9)); hpos := MAX_ORDER_COLS; vpos := 4; end; end; kHOME: begin page := 0; hpos := 1; vpos := 1; end; kEND: begin page := (23-(MAX_ORDER_COLS-9)); hpos := MAX_ORDER_COLS; vpos := 4; end; kCHmins, kNPmins: If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) then If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] > 0) then Dec(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) else else If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] > $80) then Dec(songdata.pattern_order[vpos+4*(hpos+page-1)-1]); kCHplus, kNPplus: If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) then If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $7f) then Inc(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) else else If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $ff) then begin If (vpos+4*(hpos+page-1)-1 = 0) and (songdata.pattern_order[vpos+4*(hpos+page-1)-1] = $80) then songdata.pattern_order[vpos+4*(hpos+page-1)-1] := 0 else Inc(songdata.pattern_order[vpos+4*(hpos+page-1)-1]); end; kAstrsk, kNPastr: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} For temp := 1 to songdata.nm_tracks do begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); end; kBkSPC: begin songdata.pattern_order[vpos+4*(hpos+page-1)-1] := $80; Case backspace_dir of 1: If (vpos < 4) then Inc(vpos) else If (hpos < MAX_ORDER_COLS) then begin vpos := 1; Inc(hpos); end else If (page < (23-(MAX_ORDER_COLS-9))) then begin hpos := MAX_ORDER_COLS; Inc(page); vpos := 1; end; 2: If (vpos > 1) then Dec(vpos) else If (hpos > 1) then begin Dec(hpos); vpos := 4; end else If (page > 0) then begin Dec(page); vpos := 4; end; end; end; kSPACE: If ctrl_pressed then If (vpos+4*(hpos+page-1)-1 < $7f) then begin songdata.pattern_order[vpos+4*(hpos+page-1)-1] := $80+vpos+4*(hpos+page-1); If (vpos < 4) then Inc(vpos) else If (hpos < MAX_ORDER_COLS) then begin vpos := 1; Inc(hpos); end else If (page < (23-(MAX_ORDER_COLS-9))) then begin hpos := MAX_ORDER_COLS; Inc(page); vpos := 1; end; end else begin songdata.pattern_order[vpos+4*(hpos+page-1)-1] := $80; If (vpos < 4) then Inc(vpos) else If (hpos < MAX_ORDER_COLS) then begin vpos := 1; Inc(hpos); end else If (page < (23-(MAX_ORDER_COLS-9))) then begin hpos := MAX_ORDER_COLS; Inc(page); vpos := 1; end; end; kAltL: begin LINE_MARKING_SETUP; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltM: If (mark_line <> 0) then begin mark_lines := NOT mark_lines; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltS: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} begin For temp := 1 to songdata.nm_tracks do channel_flag[temp] := FALSE; For temp := 1 to songdata.nm_tracks do If (temp = count_channel(pattern_hpos)) then begin channel_flag[temp] := TRUE; If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then channel_flag[SUCC(temp)] := TRUE else channel_flag[PRED(temp)] := TRUE; end; For temp := 1 to songdata.nm_tracks do If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltR: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} FillChar(channel_flag,songdata.nm_tracks,BYTE(TRUE)); kAlt1.. kAlt0: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} If (fkey <> kAlt0) then begin If shift_pressed then temp := HI(fkey)-$77+10 else temp := HI(fkey)-$77; If (temp <= songdata.nm_tracks) then begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then begin channel_flag[SUCC(temp)] := channel_flag[temp]; If NOT channel_flag[SUCC(temp)] then reset_chan_data(SUCC(temp)); end else If (temp in _4op_tracks_lo) then begin channel_flag[PRED(temp)] := channel_flag[temp]; If NOT channel_flag[PRED(temp)] then reset_chan_data(PRED(temp)); end; end; end else If shift_pressed or (10 in [chan_pos..chan_pos+MAX_TRACKS-1]) or (songdata.nm_tracks = 10) then begin channel_flag[10] := NOT channel_flag[10]; If NOT channel_flag[10] then reset_chan_data(10); If is_4op_chan(10) then begin channel_flag[11] := channel_flag[10]; If NOT channel_flag[11] then reset_chan_data(11); end; end else begin If NOT percussion_mode then temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$1~6~$1~7~$1~8~$1~9~$2~0~$' else temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$16 ~B~D$17 ~S~D$18 ~T~T$19 T~C~$20 ~H~H$'; temps := FlipStr(temps); For temp := 10 to 20 do If (temp > songdata.nm_tracks) then begin Delete(temps,Pos('~',temps),1); Delete(temps,Pos('~',temps),1); end; temps := FlipStr(temps); If (Pos('~',temps) <> 0) then begin chpos := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO TOGGLE TRACK ON/OFF$', temps, ' TRACK ON/OFF ',chpos); If (dl_environment.keystroke <> kESC) then begin channel_flag[9+chpos] := NOT channel_flag[9+chpos]; If NOT channel_flag[9+chpos] then reset_chan_data(9+chpos); If is_4op_chan(9+chpos) then If (9+chpos in [10,12,14]) then begin channel_flag[SUCC(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[SUCC(9+chpos)] then reset_chan_data(SUCC(9+chpos)); end else If (9+chpos in [11,13,15]) then begin channel_flag[PRED(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[PRED(9+chpos)] then reset_chan_data(PRED(9+chpos)); end; end; end; end; kINSERT: begin For temp := $7f downto (page+hpos-1)*4+vpos do songdata.pattern_order[temp] := songdata.pattern_order[temp-1]; songdata.pattern_order[(page+hpos-1)*4+vpos-1] := 0; end; kDELETE: begin For temp := (page+hpos-1)*4+vpos-1 to $7f-1 do songdata.pattern_order[temp] := songdata.pattern_order[temp+1]; songdata.pattern_order[$7f] := $080; end; kCtrlC: begin clipboard.object_type := objPatternDef; copy_object; end; kAltC: begin mn_setting.cycle_moves := TRUE; temp := Menu(copy_menu_str3,01,01,copypos3,30,15,15,' COPY OBJECT '); If (mn_environment.keystroke <> kESC) then begin copypos3 := temp; clipboard.object_type := tCOPY_OBJECT(temp); copy_object; end; end; kAltP, kCtrlV: paste_object; kCtrlT: TRANSPOSE; kCtrlR: REMAP; kCtrlB: MESSAGE_BOARD; kCtrlD: DEBUG_INFO; kCtrlO: OCTAVE_CONTROL; kCtrlP: If NOT ((play_status <> isStopped) and tracing) then PATTERN_LIST(pattern_patt+1) else begin PATTERN_LIST(old_pattern_patt+1); old_pattern_patt := pattern_list__page-1; end; kCtrlF: SONG_VARIABLES; kCtrlH: REPLACE; kCtrlI: INSTRUMENT_CONTROL; kCtrlE: INSTRUMENT_CONTROL_edit; kCtrlQ: MACRO_EDITOR(current_inst,FALSE); kCtrlG: MACRO_EDITOR(current_inst,TRUE); kCtrlM: MACRO_BROWSER(TRUE,TRUE); kCtrlX: REARRANGE; kCtLEFT: If (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If (play_status = isPlaying) then fast_forward := TRUE; kCtENTR: If play_single_patt then current_line := 0 else begin no_status_refresh := TRUE; fade_out_playback(FALSE); If (current_order < $7f) and (play_status <> isStopped) then If (songdata.pattern_order[SUCC(current_order)] < $80) then calibrate_player(SUCC(current_order),0,FALSE,FALSE) else If (calc_following_order(SUCC(current_order)) <> -1) then calibrate_player(calc_following_order(SUCC(current_order)),0,FALSE,FALSE) else else If (calc_following_order(0) <> -1) then calibrate_player(calc_following_order(0),0,FALSE,FALSE); no_status_refresh := FALSE; end; {$IFDEF GO32V2} kF1: HELP('pattern_order'); {$ELSE} kF1: If (sdl_opl3_emulator = 1) and ((play_status = isPlaying) or opl3_channel_recording_mode) then HELP('wav_recorder') else HELP('pattern_order'); {$ENDIF} kF2, kShF2, kCtrlS: begin If (fkey = kShF2) then quick_cmd := TRUE; FILE_save('a2m'); quick_cmd := FALSE; end; kCtrlF2: FILE_save('a2t'); kF3, kCtrlL: FILE_open('*.a2m$*.a2t$*.amd$*.cff$*.dfm$*.fmk$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); kF4, kCtrlA: NUKE; kF5, kAltF5, kShF5: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; isStopped: begin If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; start_playing; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF6: Case play_status of isPlaying: begin replay_forbidden := TRUE; play_status := isPaused; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; end; end; kShF6: If NOT replay_forbidden then begin debugging := TRUE; play_status := isPlaying; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If NOT play_single_patt and (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin fade_out_playback(FALSE); calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); If (play_status <> isStopped) then begin debugging := TRUE; play_status := isPlaying; replay_forbidden := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; kF7: begin fade_out_playback(FALSE); stop_playing; If (play_status <> isStopped) then FillChar(ai_table,SizeOf(ai_table),0); end; kF8, kAltF8, kShF8: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin stop_playing; calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); end; end; isStopped: If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); repeat_pattern := FALSE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF9, kAltF9, kShF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin stop_playing; calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); repeat_pattern := TRUE; end; end; isStopped: If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF10, kESC: begin QUIT_request; If (fkey = kESC) then nope := TRUE; end; kENTER: nope := TRUE; else nope := TRUE; end; If nope and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then begin no_trace_pattord := TRUE; nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; is_environment.locate_pos := 2; is_setting.terminate_keys[3] := kUp; is_setting.terminate_keys[4] := kDown; is_setting.terminate_keys[5] := kTAB; is_setting.terminate_keys[6] := kShTAB; tstr := CHAR(LO(fkey)); Repeat tstr := ExpStrL(InputStr(tstr,xstart+pos1[hpos]-1,03+vpos-1, 2,2,order_input_bckg+order_input, order_input_warn+order_input),2,'0'); is_setting.append_enabled := TRUE; If (Str2num(tstr,16) in [0..$0ff]) and (is_environment.keystroke <> kESC) then begin If (Str2num(tstr,16) > $7f) and (Str2num(tstr,16)-$80 = vpos+4*(hpos+page-1)-1) then GOTO _end; //CONTINUE; nope := TRUE; songdata.pattern_order[vpos+4*(hpos+page-1)-1] := Str2num(tstr,16); If (is_environment.keystroke = kENTER) then If (vpos < 4) then Inc(vpos) else If hpos < MAX_ORDER_COLS then begin vpos := 1; Inc(hpos); end else If page < (23-(MAX_ORDER_COLS-9)) then begin hpos := MAX_ORDER_COLS; Inc(page); vpos := 1; end; end; until (is_environment.keystroke = kESC) or (is_environment.keystroke = kUp) or (is_environment.keystroke = kDown) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB) or nope; no_trace_pattord := FALSE; nope := FALSE; Case is_environment.keystroke of kUP, kShTAB: If vpos > 1 then Dec(vpos) else If hpos > 1 then begin Dec(hpos); vpos := 4; end else If page > 0 then begin Dec(page); vpos := 4; end; kDOWN, kTAB: If vpos < 4 then Inc(vpos) else If hpos < MAX_ORDER_COLS then begin Inc(hpos); vpos := 1; end else If page < (23-(MAX_ORDER_COLS-9)) then begin Inc(page); vpos := 1; end; end; is_setting.terminate_keys[3] := 0; is_setting.terminate_keys[4] := 0; is_setting.terminate_keys[5] := 0; is_setting.terminate_keys[6] := 0; end; If (Update32(songdata.pattern_order,SizeOf(songdata.pattern_order),0) <> songdata_crc_ord) then module_archived := FALSE; _end: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} If scankey(SC_F11) and NOT ctrl_pressed and NOT alt_pressed and NOT shift_pressed then begin If (command_typing <> 0) then Case command_typing of 1: If cycle_pattern then begin command_typing := 2; cycle_pattern := FALSE; end else cycle_pattern := TRUE; 2: begin command_typing := 1; cycle_pattern := FALSE; end; end; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; If scankey(SC_F12) and NOT ctrl_pressed and NOT alt_pressed then begin If NOT shift_pressed then linefeed := NOT linefeed else jump_mark_mode := NOT jump_mark_mode; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; until (nope and ((fkey = kENTER) or (fkey = kESC) or (fkey = kF10))) or _force_program_quit; PATTERN_ORDER_page_refresh(page); end; adlibtracker2-2.4.23/typcons1.inc0000644000000000000000000011074713176573532015312 0ustar rootrootconst NULL = $0ffffffff; BYTE_NULL = BYTE(NULL); WORD_NULL = WORD(NULL); DWORD_NULL = LONGINT(NULL); const FFVER_A2M = 13; FFVER_A2T = 13; FFVER_A2I = 10; FFVER_A2F = 2; FFVER_A2P = 11; FFVER_A2B = 10; FFVER_A2W = 3; const GENERIC_IO_BUFFER_SIZE = 1500*1024; // 1.5MB I/O Buffer type pGENERIC_IO_BUFFER = ^tGENERIC_IO_BUFFER; tGENERIC_IO_BUFFER = array[0..PRED(GENERIC_IO_BUFFER_SIZE)] of Byte; type tFM_INST_DATA = Record AM_VIB_EG_modulator, AM_VIB_EG_carrier, KSL_VOLUM_modulator, KSL_VOLUM_carrier, ATTCK_DEC_modulator, ATTCK_DEC_carrier, SUSTN_REL_modulator, SUSTN_REL_carrier, WAVEFORM_modulator, WAVEFORM_carrier, FEEDBACK_FM: Byte; end; type tADTRACK2_INS = Record fm_data: tFM_INST_DATA; panning: Byte; fine_tune: Shortint; perc_voice: Byte; end; type tOLD_ADTRACK2_INS = Record fm_data: tFM_INST_DATA; panning: Byte; fine_tune: Shortint; end; type tARPEGGIO_TABLE = Record length, speed, loop_begin, loop_length, keyoff_pos: Byte; data: array[1..255] of Byte; end; type tVIBRATO_TABLE = Record length, speed, delay, loop_begin, loop_length, keyoff_pos: Byte; data: array[1..255] of Shortint; end; type tREGISTER_TABLE_DEF = Record fm_data: tFM_INST_DATA; freq_slide: Smallint; panning: Byte; duration: Byte; end; type tREGISTER_TABLE = Record length, loop_begin, loop_length, keyoff_pos, arpeggio_table, vibrato_table: Byte; data: array[1..255] of tREGISTER_TABLE_DEF; end; type tMACRO_TABLE = Record arpeggio: tARPEGGIO_TABLE; vibrato: tVIBRATO_TABLE; end; type tARP_VIB_MACRO_TABLE = array[1..255] of tMACRO_TABLE; type tFM_PARAMETER_TABLE = Record adsrw_car, adsrw_mod: Record attck,dec,sustn,rel, wform: Byte; end; connect, feedb, multipM,kslM,tremM,vibrM,ksrM,sustM, multipC,kslC,tremC,vibrC,ksrC,sustC: Byte; end; type tDIS_FMREG_COL = array[0..27] of Boolean; type tINS_4OP_FLAGS = Record num_4op: Byte; idx_4op: array[1..128] of Byte; end; type pOLD_FIXED_SONGDATA = ^tOLD_FIXED_SONGDATA; tOLD_FIXED_SONGDATA = Record songname: String[42]; composer: String[42]; instr_names: array[1..250] of String[32]; instr_data: array[1..250] of tOLD_ADTRACK2_INS; pattern_order: array[0..$7f] of Byte; tempo: Byte; speed: Byte; common_flag: Byte; end; const MB_SIGNATURE = 'MB_1'; // Message Board v1.0 MB_HSIZE = 50; // 50x20 chr MB_VSIZE = 20; type pMESSAGE_BOARD_DATA = ^tMESSAGE_BOARD_DATA; tMESSAGE_BOARD_DATA = Record signature: array[0..3] of Char; data: array[1..MB_VSIZE] of String[MB_HSIZE]; end; type pFIXED_SONGDATA = ^tFIXED_SONGDATA; tFIXED_SONGDATA = Record songname: String[42]; composer: String[42]; instr_names: array[1..255] of String[42]; instr_data: array[1..255] of tADTRACK2_INS; instr_macros: array[1..255] of tREGISTER_TABLE; macro_table: tARP_VIB_MACRO_TABLE; pattern_order: array[0..$7f] of Byte; tempo: Byte; speed: Byte; common_flag: Byte; patt_len: Word; nm_tracks: Byte; macro_speedup: Word; flag_4op: Byte; lock_flags: array[1..20] of Byte; pattern_names: array[0..$7f] of String[42]; dis_fmreg_col: array[1..255] of tDIS_FMREG_COL; ins_4op_flags: tINS_4OP_FLAGS; reserved_data: array[0..PRED(1024)] of Byte; end; type tOLD_CHUNK = Record note: Byte; instr_def: Byte; effect_def: Byte; effect: Byte; end; type tCHUNK = Record note: Byte; instr_def: Byte; effect_def: Byte; effect: Byte; effect_def2: Byte; effect2: Byte; end; type tOLD_VARIABLE_DATA1 = array[0..$0f] of array[0..$3f] of array[1..9] of tOLD_CHUNK; type tOLD_VARIABLE_DATA2 = array[0..7] of array[1..18] of array[0..$3f] of tOLD_CHUNK; type tVARIABLE_DATA = array[0..7] of array[1..20] of array[0..$0ff] of tCHUNK; type tPATTERN_DATA = array[0..15] of tVARIABLE_DATA; type tCOPY_OBJECT = (objNone, objPatternDef,objPatternTable, objInstrument,objInstrumentBank, objNote,objInstrumentDef,objEffect,objEffect2, objLine,objTrack,objPattern,objMarkedBlock, objMacroTableLine,objMacroTableColumn,objMacroTable, objInstrumentWithMacros); type tMACRO_TABLE_TYPE = (mttFM_reg_table,mttArpeggio_table,mttVibrato_table); type tCLIPBOARD = Record object_type: tCOPY_OBJECT; block_hsize: Byte; block_vsize: Byte; pattern_order: array[0..$7f] of Byte; pattern: array[1..20] of array[0..$0ff] of tCHUNK; instrument: Record names: array[1..255] of String[32]; data: array[1..255] of tADTRACK2_INS; macros: array[1..255] of tREGISTER_TABLE; arpvib: array[1..255] of tMACRO_TABLE; dis_fmreg_col: array[1..255] of tDIS_FMREG_COL; end; mcrtab_type: tMACRO_TABLE_TYPE; fmreg_table: tREGISTER_TABLE; macro_table: tMACRO_TABLE; fmtab_def_typ: Byte; _string: String; end; type tDECAY_BAR = Record dir1: Integer; dir2: Integer; lvl1: Real; lvl2: Real; end; type tVOLUM_BAR = Record dir: Integer; lvl: Real; end; type tPLAY_STATUS = (isPlaying,isPaused,isStopped); type {$IFDEF GO32V2} tRGB = Record r,g,b: Byte end; {$ELSE} tRGB = Record r,g,b,a: Byte end; {$ENDIF} type tByteSet = Set of Byte; const INSTRUMENT_SIZE = SizeOf(tADTRACK2_INS); CHUNK_SIZE = SizeOf(tCHUNK); PATTERN_SIZE = 20*256*CHUNK_SIZE; const status_layout: array[tPLAY_STATUS] of String[10] = ('PLAYiNG ', 'PAUSED ', 'STOPPED '); {$IFDEF UNIX} const PATHSEP: Char = '/'; WILDCARD_ASTERISK: String = '*'; {$ELSE} const PATHSEP: Char = '\'; WILDCARD_ASTERISK: String = '*.*'; {$ENDIF} const kF1 = $3b00; kLEFT = $4b00; kENTER = $1c0d; kWeird = $2960; kF2 = $3c00; kShLEFT = $4b34; kCtENTR = $1c0a; kCtrlE = $1205; kShF2 = $5500; kCtLEFT = $7300; kESC = $011b; kCtrlG = $2207; kF3 = $3d00; kRIGHT = $4d00; kTAB = $0f09; kCtrlQ = $1011; kShF3 = $5600; kShRGHT = $4d36; kShTAB = $0f00; kCtLbr = $1a1b; kF4 = $3e00; kCtRGHT = $7400; kSPACE = $3920; kCtRbr = $1b1d; kF5 = $3f00; kUP = $4800; kBkSPC = $0e08; kCtrlF3 = $6000; kShF5 = $5800; kNPUp = $4838; kNPastr = $372a; kAltV = $2f00; kF6 = $4000; kDOWN = $5000; kNPplus = $4e2b; kAstrsk = $092a; kShF6 = $5900; kNPDown = $5032; kNPmins = $4a2d; kNPins = $5230; kF7 = $4100; kPgUP = $4900; kAlt1 = $7800; kNPdel = $532e; kF8 = $4200; kNPPgUP = $4939; kAlt2 = $7900; kCHastr = $092a; kShF8 = $5b00; kCtPgUP = $8400; kAlt3 = $7a00; kCtrlP = $1910; kF9 = $4300; kPgDOWN = $5100; kAlt4 = $7b00; kCtBkSp = $0e7f; kShF9 = $5c00; kNPPgDN = $5133; kAlt5 = $7c00; kAltF5 = $6c00; kF10 = $4400; kCtPgDN = $7600; kAlt6 = $7d00; kAltF6 = $6d00; kCtrlB = $3002; kHOME = $4700; kAlt7 = $7e00; kAltF8 = $6f00; kCtrlC = $2e03; kNPHOME = $4737; kAlt8 = $7f00; kAltF9 = $7000; kCtrlD = $2004; kCtHOME = $7700; kAlt9 = $8000; kCtrlY = $1519; kCtrlF = $2106; kEND = $4f00; kAlt0 = $8100; kAltE = $1200; kCtrlI = $1709; kNPEND = $4f31; kAltB = $3000; kAltZ = $2c00; kCtrlK = $250b; kCtEND = $7500; kAltC = $2e00; kCtrlM = $320d; kINSERT = $5200; kAltD = $2000; kCtrlN = $310e; kDELETE = $5300; kAltF = $2100; kCtrlO = $180f; kCtrlL = $260c; kAltK = $2500; kCtrlV = $2f16; kCtrlS = $1f13; kAltM = $3200; kCtrlX = $2d18; kCtrlA = $1e01; kAltN = $3100; kCtrlZ = $2c1a; kAltF2 = $6900; kAltO = $1800; kAltL = $2600; kAltA = $1e00; kAltP = $1900; kCtrlF2 = $5f00; kCHplus = $0d2b; kAltQ = $1000; kAltX = $2d00; kCHmins = $0c2d; kAltR = $1300; kCtrlT = $1414; kCHlbrk = $1a5b; kAltS = $1f00; kCtrlR = $1312; kCHrbrk = $1b5d; kAltT = $1400; kCtrlW = $1117; kCtrlH = $2308; kAltW = $1100; kSlash = $352f; kCtrlF8 = $6500; kSlashR = $2b5c; kCtrlF9 = $6600; const SC_ESCAPE = $01; SC_1 = $02; SC_2 = $03; SC_3 = $04; SC_4 = $05; SC_5 = $06; SC_6 = $07; SC_7 = $08; SC_8 = $09; SC_9 = $0A; SC_0 = $0B; SC_MINUS = $0C; SC_EQUALS = $0D; SC_BACKSPACE = $0E; SC_TAB = $0F; SC_Q = $10; SC_W = $11; SC_E = $12; SC_R = $13; SC_T = $14; SC_Y = $15; SC_U = $16; SC_I = $17; SC_O = $18; SC_P = $19; SC_LEFTBRACKET = $1A; SC_RIGHTBRACKET = $1B; SC_ENTER = $1C; {$IFDEF GO32V2} SC_CTRL = $1D; {$ENDIF} SC_A = $1E; SC_S = $1F; SC_D = $20; SC_F = $21; SC_G = $22; SC_H = $23; SC_J = $24; SC_K = $25; SC_L = $26; SC_SEMICOLON = $27; SC_QUOTE = $28; SC_TILDE = $29; SC_LSHIFT = $2A; SC_BACKSLASH = $2B; SC_Z = $2C; SC_X = $2D; SC_C = $2E; SC_V = $2F; SC_B = $30; SC_N = $31; SC_M = $32; SC_COMMA = $33; SC_PERIOD = $34; SC_SLASH = $35; SC_RSHIFT = $36; SC_MULTIPLY = $37; {$IFDEF GO32V2} SC_ALT = $38; {$ENDIF} SC_SPACE = $39; SC_CAPSLOCK = $3A; SC_F1 = $3B; SC_F2 = $3C; SC_F3 = $3D; SC_F4 = $3E; SC_F5 = $3F; SC_F6 = $40; SC_F7 = $41; SC_F8 = $42; SC_F9 = $43; SC_F10 = $44; SC_NUMLOCK = $45; SC_SCROLLLOCK = $46; SC_HOME = $47; SC_UP = $48; SC_PAGEUP = $49; SC_MINUS2 = $4A; SC_LEFT = $4B; SC_RIGHT = $4D; SC_PLUS = $4E; SC_END = $4F; SC_DOWN = $50; SC_PAGEDOWN = $51; SC_INSERT = $52; SC_DELETE = $53; SC_F11 = $57; SC_F12 = $58; SC_LWIN = $7D; SC_RWIN = $7E; SC_MENU = $7F; {$IFNDEF GO32V2} { Fictive scan codes } SC_LALT = $FC; { Left ALT } SC_RALT = $FD; { Right ALT } SC_LCTRL = $FE; { Left CTRL } SC_RCTRL = $FF; { Right CTRL } {$ENDIF} const inst_vpos_max = 21; inst_hpos_max = 7; const inst_hpos: array[1..inst_vpos_max,1..inst_hpos_max] of Byte = ( {1} (+15,+0,+0,+0,+0,+0,+0), {2} (+15,+52,+0,+0,+0,+0,+0), {3} (+52,+0,+0,+0,+0,+0,+0), {4} (+15,+52,+0,+0,+0,+0,+0), {5} (+15,+52,+0,+0,+0,+0,+0), {6} (+52,+0,+0,+0,+0,+0,+0), {7} (+15,+52,+0,+0,+0,+0,+0), {8} (+52,+0,+0,+0,+0,+0,+0), {9} (+52,+0,+0,+0,+0,+0,+0), {10}(+2,+0,+0,+0,+0,+0,+0), {11}(+2,+0,+0,+0,+0,+0,+0), {12}(+0,+0,+0,+0,+0,+0,+0), {13}(+0,+0,+0,+0,+0,+0,+0), {14}(+0,+0,+0,+0,+0,+0,+0), {15}(+0,+0,+0,+0,+0,+0,+0), {16}(+0,+0,+0,+0,+0,+0,+0), {17}(+0,+0,+0,+0,+0,+0,+0), {18}(+2,+0,+0,+0,+0,+0,+0), {19}(+2,+29,+36,+43,+50,+57,+64), {20}(+2,+29,+36,+43,+50,+57,+64), {21}(+2,+29,+36,+43,+50,+0,+0)); const inst_hpos_ext_2op: array[1..6,1..inst_hpos_max] of Byte = ( {12}(+2,+22,+51,+0,+0,+0,+0), {13}(+2,+22,+0,+0,+0,+0,+0), {14}(+0,+0,+0,+0,+0,+0,+0), {15}(+0,+0,+0,+0,+0,+0,+0), {16}(+0,+51,+0,+0,+0,+0,+0), {17}(+1,+9,+17,+0,+0,+0,+0)); const inst_hpos_ext_perc: array[1..6,1..inst_hpos_max] of Byte = ( {12}(+2,+0,+0,+0,+0,+0,+0), {13}(+2,+0,+0,+0,+0,+0,+0), {14}(+0,+0,+0,+0,+0,+0,+0), {15}(+0,+0,+0,+0,+0,+0,+0), {16}(+0,+51,+0,+0,+0,+0,+0), {17}(+1,+9,+17,+0,+0,+0,+0)); const inst_hpos_ext_4op: array[1..6,1..inst_hpos_max] of Byte = ( {12}(+2,+0,+51,+0,+0,+0,+0), {13}(+2,+0,+0,+0,+0,+0,+0), {14}(+22,+0,+0,+0,+0,+0,+0), {15}(+22,+0,+0,+0,+0,+0,+0), {16}(+22,+51,+0,+0,+0,+0,+0), {17}(+1,+9,+17,+22,+0,+0,+0)); const inst_vpos: array[1..inst_vpos_max] of Byte = (+1,+2,+3,+4,+5,+6,+7,+8,+9,+10,+11,+12,+13,+14,+15,+16, +17,+20,+21,+22,+23); const note_layout: array[0..12*8+1] of String[3] = ( ' ', 'C-1','C#1','D-1','D#1','E-1','F-1','F#1','G-1','G#1','A-1','A#1','%-1', 'C-2','C#2','D-2','D#2','E-2','F-2','F#2','G-2','G#2','A-2','A#2','%-2', 'C-3','C#3','D-3','D#3','E-3','F-3','F#3','G-3','G#3','A-3','A#3','%-3', 'C-4','C#4','D-4','D#4','E-4','F-4','F#4','G-4','G#4','A-4','A#4','%-4', 'C-5','C#5','D-5','D#5','E-5','F-5','F#5','G-5','G#5','A-5','A#5','%-5', 'C-6','C#6','D-6','D#6','E-6','F-6','F#6','G-6','G#6','A-6','A#6','%-6', 'C-7','C#7','D-7','D#7','E-7','F-7','F#7','G-7','G#7','A-7','A#7','%-7', 'C-8','C#8','D-8','D#8','E-8','F-8','F#8','G-8','G#8','A-8','A#8','%-8', 'C-9'); const board_scancodes: array[1..29] of Byte = ( $2c,$1f,$2d,$20,$2e,$2f,$22,$30,$23,$31,$24,$32, $10,$03,$11,$04,$12,$13,$06,$14,$07,$15,$08,$16,$17,$0a,$18,$0b,$19); const fx_digits: array[0..47] of Char = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ&%!@=#$~^`><'; NM_FX_DIGITS = SizeOf(fx_digits); const b_note: Char = 'b'; connection_str: array[0..1] of String[2] = ('FM','AM'); macro_retrig_str: array[0..7] of String = (#250,#159,#11,#250,#13,#250,#250,#250); const pos1: array[1..22] of Byte = (+07,+14,+21,+28,+35,+42,+49,+56,+63,+70,+77,+84,+91,+98,+105,+112,+119,+126,+133,+140,+147,+154); pos2: array[1..13] of Byte = (+00,+01,+03,+04,+06,+07,+09,+10,+12,+13,+14,+15,+16); { 0123456789ABCDEF } { ... 00 000 000 } { ^ ^ ^ ^ } pos3: array[1..44] of Byte = (+00,+04,+07,+11, {1} +15,+19,+22,+26, {2} +30,+34,+37,+41, {3} +45,+49,+52,+56, {4} +60,+64,+67,+71, {5} +75,+79,+82,+86, {6} +90,+94,+97,+101, {7} +105,+109,+112,+116, {8} +120,+124,+127,+131, {9} +135,+139,+142,+146, {10} +150,+154,+157,+161); {11} { 0123456789ABCDEF } { ... 00 000 000 } { ^ ^ ^^ ^^^ ^^^ } pos4: array[1..110] of Byte = (+00,+02,+04,+05,+07,+08,+09,+11,+12,+13, {1} +15,+17,+19,+20,+22,+23,+24,+26,+27,+28, {2} +30,+32,+34,+35,+37,+38,+39,+41,+42,+43, {3} +45,+47,+49,+50,+52,+53,+54,+56,+57,+58, {4} +60,+62,+64,+65,+67,+68,+69,+71,+72,+73, {5} +75,+77,+79,+80,+82,+83,+84,+86,+87,+88, {6} +90,+92,+94,+95,+97,+98,+99,+101,+102,+103, {7} +105,+107,+109,+110,+112,+113,+114,+116,+117,+118, {8} +120,+122,+124,+125,+127,+128,+129,+131,+132,+133, {9} +135,+137,+139,+140,+142,+143,+144,+146,+147,+148, {10} +150,+152,+154,+155,+157,+158,+159,+161,+162,+163); {11} pos5: array[1..35] of Byte = (+1,+3,+5,+7,+9,+11,+12,+14,+16,+18, +19,+20,+21,+23,+25,+27,+29,+31,+33,+34, +36,+38,+40,+41,+42,+43,+45,+47, +49,+50,+51,+52,+54,+56,+57); pos5vw: array[1..35] of Byte = (+1,+3,+5,+7,+9,+11,+11,+14,+16,+18, +19,+20,+21,+23,+25,+27,+29,+31,+33,+33, +36,+38,+40,+41,+42,+43,+45,+47, +49,+49,+49,+49,+54,+56,+56); pos6: array[1..11] of Byte = (+1,+2,+3,+5,+6,+8,+9,+10,+12,+13,+14); const _valid_characters: Set of Char = [#0,#32..#127,#176..#223,#254,#255]; _valid_characters_fname: Set of Char = [#0,#32..#127,#255]; const _panning: array[0..2] of Byte = ($30,$10,$20); const _instr_data_ofs: array[1..13] of Byte = (1,0,3,2,5,4,7,6,9,8,10,11,12); _instr: array[0..11] of Byte = ($20, $20, $40, $40, $60, $60, $80, $80, $0e0,$0e0, $0c0, $0bd); type tTRACK_ADDR = array[1..20] of Word; const { 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 } _chmm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$006,$007,$008,$103,$100,$104,$101,$105,$102,$106,$107,$108,BYTE_NULL,BYTE_NULL); _chmm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$010,$011,$012,$108,$100,$109,$101,$10a,$102,$110,$111,$112,BYTE_NULL,BYTE_NULL); _chmm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$013,$014,$015,$10b,$103,$10c,$104,$10d,$105,$113,$114,$115,BYTE_NULL,BYTE_NULL); { BD SD TT TC HH } _chpm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$106,$107,$108,$103,$100,$104,$101,$105,$102,$006,$007,$008,$008,$007); _chpm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$110,$111,$112,$108,$100,$109,$101,$10a,$102,$010,$014,$012,$015,$011); _chpm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$113,$114,$115,$10b,$103,$10c,$104,$10d,$105,$013,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL); const _4op_tracks_hi: Set of Byte = [1,3,5,10,12,14]; _4op_tracks_lo: Set of Byte = [2,4,6,11,13,15]; const _4op_main_chan: array[1..6] of Byte = (2,4,6,11,13,15); _perc_sim_chan: array[19..20] of Byte = (18,17); var _chan_n: tTRACK_ADDR; _chan_m: tTRACK_ADDR; _chan_c: tTRACK_ADDR; _ch_tmp: tTRACK_ADDR; const fade_delay_tab: array[0..63] of Byte = ( 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4, 5,5,5,5); const tracing: Boolean = FALSE; track_notes: Boolean = FALSE; marking: Boolean = FALSE; debugging: Boolean = FALSE; quick_cmd: Boolean = FALSE; const ef_Arpeggio = 0; ef_FSlideUp = 1; ef_FSlideDown = 2; ef_TonePortamento = 3; ef_Vibrato = 4; ef_TPortamVolSlide = 5; ef_VibratoVolSlide = 6; ef_FSlideUpFine = 7; ef_FSlideDownFine = 8; ef_SetModulatorVol = 9; ef_VolSlide = 10; ef_PositionJump = 11; ef_SetInsVolume = 12; ef_PatternBreak = 13; ef_SetTempo = 14; ef_SetSpeed = 15; ef_TPortamVSlideFine = 16; ef_VibratoVSlideFine = 17; ef_SetCarrierVol = 18; ef_SetWaveform = 19; ef_VolSlideFine = 20; ef_RetrigNote = 21; ef_Tremolo = 22; ef_Tremor = 23; ef_ArpggVSlide = 24; ef_ArpggVSlideFine = 25; ef_MultiRetrigNote = 26; ef_FSlideUpVSlide = 27; ef_FSlideDownVSlide = 28; ef_FSlUpFineVSlide = 29; ef_FSlDownFineVSlide = 30; ef_FSlUpVSlF = 31; ef_FSlDownVSlF = 32; ef_FSlUpFineVSlF = 33; ef_FSlDownFineVSlF = 34; ef_Extended = 35; ef_Extended2 = 36; ef_SetGlobalVolume = 37; ef_SwapArpeggio = 38; ef_SwapVibrato = 39; ef_ForceInsVolume = 40; ef_Extended3 = 41; ef_ExtraFineArpeggio = 42; ef_ExtraFineVibrato = 43; ef_ExtraFineTremolo = 44; ef_SetCustomSpeedTab = 45; ef_GlobalFSlideUp = 46; ef_GlobalFSlideDown = 47; ef_ex_SetTremDepth = 0; ef_ex_SetVibDepth = 1; ef_ex_SetAttckRateM = 2; ef_ex_SetDecayRateM = 3; ef_ex_SetSustnLevelM = 4; ef_ex_SetRelRateM = 5; ef_ex_SetAttckRateC = 6; ef_ex_SetDecayRateC = 7; ef_ex_SetSustnLevelC = 8; ef_ex_SetRelRateC = 9; ef_ex_SetFeedback = 10; ef_ex_SetPanningPos = 11; ef_ex_PatternLoop = 12; ef_ex_PatternLoopRec = 13; ef_ex_ExtendedCmd = 14; ef_ex_cmd_MKOffLoopDi = 0; ef_ex_cmd_MKOffLoopEn = 1; ef_ex_cmd_TPortaFKdis = 2; ef_ex_cmd_TPortaFKenb = 3; ef_ex_cmd_RestartEnv = 4; ef_ex_cmd_4opVlockOff = 5; ef_ex_cmd_4opVlockOn = 6; ef_ex_ExtendedCmd2 = 15; ef_ex_cmd2_RSS = 0; ef_ex_cmd2_ResetVol = 1; ef_ex_cmd2_LockVol = 2; ef_ex_cmd2_UnlockVol = 3; ef_ex_cmd2_LockVP = 4; ef_ex_cmd2_UnlockVP = 5; ef_ex_cmd2_VSlide_mod = 6; ef_ex_cmd2_VSlide_car = 7; ef_ex_cmd2_VSlide_def = 8; ef_ex_cmd2_LockPan = 9; ef_ex_cmd2_UnlockPan = 10; ef_ex_cmd2_VibrOff = 11; ef_ex_cmd2_TremOff = 12; ef_ex_cmd2_FVib_FGFS = 13; ef_ex_cmd2_FTrm_XFGFS = 14; ef_ex_cmd2_NoRestart = 15; ef_ex2_PatDelayFrame = 0; ef_ex2_PatDelayRow = 1; ef_ex2_NoteDelay = 2; ef_ex2_NoteCut = 3; ef_ex2_FineTuneUp = 4; ef_ex2_FineTuneDown = 5; ef_ex2_GlVolSlideUp = 6; ef_ex2_GlVolSlideDn = 7; ef_ex2_GlVolSlideUpF = 8; ef_ex2_GlVolSlideDnF = 9; ef_ex2_GlVolSldUpXF = 10; ef_ex2_GlVolSldDnXF = 11; ef_ex2_VolSlideUpXF = 12; ef_ex2_VolSlideDnXF = 13; ef_ex2_FreqSlideUpXF = 14; ef_ex2_FreqSlideDnXF = 15; ef_ex3_SetConnection = 0; ef_ex3_SetMultipM = 1; ef_ex3_SetKslM = 2; ef_ex3_SetTremoloM = 3; ef_ex3_SetVibratoM = 4; ef_ex3_SetKsrM = 5; ef_ex3_SetSustainM = 6; ef_ex3_SetMultipC = 7; ef_ex3_SetKslC = 8; ef_ex3_SetTremoloC = 9; ef_ex3_SetVibratoC = 10; ef_ex3_SetKsrC = 11; ef_ex3_SetSustainC = 12; const ef_fix1 = $80; ef_fix2 = $90; const home_dir_path: String = ''; a2m_default_path: String = ''; a2t_default_path: String = ''; a2i_default_path: String = ''; a2f_default_path: String = ''; a2p_default_path: String = ''; a2b_default_path: String = ''; a2w_default_path: String = ''; {$IFDEF GO32V2} screen_mode: Byte = 0; comp_text_mode: Byte = 0; fps_down_factor: Byte = 0; mouse_hspeed: Word = 50; mouse_vspeed: Word = 50; mouse_threshold: Word = 0; typematic_rate: Byte = 0; typematic_delay: Byte = 0; mouse_disabled: Boolean = FALSE; custom_svga_mode: Boolean = FALSE; {$ELSE} sdl_screen_mode: Byte = 0; sdl_opl3_emulator: Byte = 0; {$IFNDEF UNIX} sdl_wav_directory: String = 'wav_files\'; {$ELSE} sdl_wav_directory: String = 'wav_files/'; {$ENDIF} sdl_sample_rate: Longint = 49716; sdl_sample_buffer: Longint = 2048; sdl_frame_rate: Byte = 100; {$IFNDEF GO32V2} sdl_timer_slowdown: Byte = 2; {$ENDIF} sdl_typematic_delay: Longint = 250; sdl_typematic_rate: Longint = 30; {$ENDIF} init_tempo: Byte = 50; init_speed: Byte = 6; init_macro_speedup: Word = 1; midiboard: Boolean = TRUE; default_octave: Byte = 4; patt_len: Word = 64; nm_tracks: Byte = 18; mod_description: Boolean = FALSE; highlight_controls: Boolean = TRUE; use_H_for_B: Boolean = FALSE; linefeed: Boolean = TRUE; update_ins: Boolean = FALSE; cycle_pattern: Boolean = TRUE; keep_track_pos: Boolean = FALSE; remember_ins_pos: Boolean = TRUE; command_typing: Byte = 1; backspace_dir: Byte = 1; mark_line: Byte = 4; scroll_bars: Boolean = TRUE; fforward_factor: Byte = 1; rewind_factor: Byte = 1; ssaver_time: Longint = 300; timer_fix: Boolean = TRUE; decay_bar_rise: Real = 3.00; decay_bar_fall: Real = 0.30; force_ins: Byte = 0; pattern_layout: Byte = 0; trace_by_default: Boolean = TRUE; nosync_by_default: Boolean = FALSE; keep_position: Boolean = TRUE; alt_ins_name: Boolean = TRUE; adjust_tracks: Boolean = TRUE; mark_lines: Boolean = FALSE; accurate_conv: Boolean = FALSE; fix_c_note_bug: Boolean = TRUE; analyzer_bckg: Byte = $010; analyzer: Byte = $03; analyzer_ovrllvol: Byte = $03; analyzer_volumelvl: Byte = $07; analyzer_modulator: Byte = $02; analyzer_carrier: Byte = $03; pattern_bckg: Byte = $010; pattern_border: Byte = $0f; pattern_pos_indic: Byte = $0b; pattern_pan_indic: Byte = $03; pattern_gpan_indic: Byte = $0f; pattern_lock_indic: Byte = $07; pattern_4op_indic: Byte = $0e; pattern_perc_indic: Byte = $0f; pattern_chan_indic: Byte = $0e; pattern_row_bckg: Byte = $050; pattern_row_bckg_p: Byte = $0c0; pattern_row_bckg_m: Byte = $0b0; pattern_block_bckg: Byte = $020; pattern_line: Byte = $03; pattern_line_p: Byte = $00; pattern_line_m: Byte = $0b; pattern_hi_line: Byte = $0b; pattern_hi_line_m: Byte = $03; pattern_note: Byte = $07; pattern_hi_note: Byte = $0f; pattern_note0: Byte = $03; pattern_hi_note0: Byte = $0c; pattern_note_hid: Byte = $09; pattern_hi_note_h: Byte = $07; pattern_inst: Byte = $02; pattern_hi_inst: Byte = $0a; pattern_inst0: Byte = $02; pattern_hi_inst0: Byte = $0a; pattern_cmnd: Byte = $07; pattern_hi_cmnd: Byte = $0f; pattern_cmnd0: Byte = $03; pattern_hi_cmnd0: Byte = $0b; pattern_note_m: Byte = $09; pattern_note0_m: Byte = $09; pattern_note_hid_m: Byte = $0d; pattern_inst_m: Byte = $02; pattern_inst0_m: Byte = $02; pattern_cmnd_m: Byte = $09; pattern_cmnd0_m: Byte = $09; pattern_note_b: Byte = $0f; pattern_note0_b: Byte = $0b; pattern_note_hid_b: Byte = $05; pattern_inst_b: Byte = $0a; pattern_inst0_b: Byte = $0a; pattern_cmnd_b: Byte = $0f; pattern_cmnd0_b: Byte = $0b; pattern_fix_note: Byte = $0b; pattern_hi_fx_note: Byte = $0e; pattern_fix_note_m: Byte = $0e; pattern_fix_note_b: Byte = $0e; pattern_cmnd_ctrl: Byte = $0d; pattern_input_bckg: Byte = $0b0; pattern_input: Byte = $00; pattern_input_warn: Byte = $080; debug_info_bckg: Byte = $040; debug_info_bckg2: Byte = $090; debug_info_border: Byte = $05; debug_info_border2: Byte = $0f; debug_info_title: Byte = $0b; debug_info_topic: Byte = $0e; debug_info_txt: Byte = $07; debug_info_hi_txt: Byte = $0f; debug_info_txt_hid: Byte = $06; debug_info_mod: Byte = $02; debug_info_hi_mod: Byte = $0a; debug_info_car: Byte = $03; debug_info_hi_car: Byte = $0b; debug_info_4op: Byte = $08; debug_info_perc: Byte = $08; help_background: Byte = $040; help_title: Byte = $0b; help_border: Byte = $0f; help_topic: Byte = $0c; help_text: Byte = $07; help_hi_text: Byte = $0c; help_keys: Byte = $0f; help_indicators: Byte = $0e; dialog_background: Byte = $040; dialog_title: Byte = $0b; dialog_border: Byte = $0f; dialog_text: Byte = $0d; dialog_hi_text: Byte = $0e; dialog_hid: Byte = $06; dialog_item: Byte = $0f; dialog_short: Byte = $0e; dialog_item_dis: Byte = $05; dialog_sel_itm_bck: Byte = $070; dialog_sel_itm: Byte = $00; dialog_sel_short: Byte = $04; dialog_context: Byte = $0e; dialog_context_dis: Byte = $07; dialog_contxt_dis2: Byte = $09; dialog_input_bckg: Byte = $070; dialog_input: Byte = $00; dialog_def_bckg: Byte = $0c0; dialog_def: Byte = $00; dialog_prog_bar1: Byte = $09; dialog_prog_bar2: Byte = $0b; dialog_topic: Byte = $0d; dialog_hi_topic: Byte = $0e; dialog_mod_text: Byte = $0a; dialog_car_text: Byte = $0b; macro_background: Byte = $040; macro_title: Byte = $0b; macro_border: Byte = $0f; macro_topic: Byte = $0c; macro_topic2: Byte = $0d; macro_hi_topic: Byte = $0e; macro_text: Byte = $0d; macro_hi_text: Byte = $0e; macro_text_dis: Byte = $06; macro_text_loop: Byte = $0c; macro_text_keyoff: Byte = $03; macro_current_bckg: Byte = $050; macro_current: Byte = $0d; macro_current_dis: Byte = $00; macro_current_loop: Byte = $0c; macro_current_koff: Byte = $0b; macro_input_bckg: Byte = $070; macro_input: Byte = $00; macro_def_bckg: Byte = $0c0; macro_def: Byte = $00; macro_scrbar_bckg: Byte = $070; macro_scrbar_text: Byte = $00; macro_scrbar_mark: Byte = $0f; macro_hint: Byte = $07; macro_item: Byte = $0f; macro_short: Byte = $0e; macro_item_dis: Byte = $07; macro_sel_itm_bck: Byte = $070; macro_sel_itm: Byte = $00; macro_sel_short: Byte = $04; macro_context: Byte = $0e; macro_context_dis: Byte = $07; scrollbar_bckg: Byte = $030; scrollbar_text: Byte = $00; scrollbar_mark: Byte = $0b; scrollbar_2nd_mark: Byte = $0f; main_background: Byte = $010; main_title: Byte = $0b; main_border: Byte = $0b; main_stat_line: Byte = $03; main_hi_stat_line: Byte = $0b; main_dis_stat_line: Byte = $05; main_behavior: Byte = $0d; main_behavior_dis: Byte = $05; status_background: Byte = $010; status_border: Byte = $0e; status_static_txt: Byte = $0b; status_dynamic_txt: Byte = $0f; status_play_state: Byte = $07; status_text_dis: Byte = $05; order_background: Byte = $010; order_hi_bckg: Byte = $050; order_border: Byte = $0a; order_entry: Byte = $03; order_hi_entry: Byte = $0b; order_pattn: Byte = $07; order_pattn_jump: Byte = $02; order_hi_pattn: Byte = $0f; order_played_b: Byte = $0c0; order_played: Byte = $00; order_input_bckg: Byte = $0b0; order_input: Byte = $00; order_input_warn: Byte = $0c0; instrument_bckg: Byte = $040; instrument_title: Byte = $0b; instrument_border: Byte = $0f; instrument_text: Byte = $07; instrument_hi_text: Byte = $0f; instrument_glob: Byte = $0d; instrument_hi_glob: Byte = $0f; instrument_hid: Byte = $06; instrument_mod: Byte = $02; instrument_car: Byte = $03; instrument_hi_mod: Byte = $0a; instrument_hi_car: Byte = $0b; instrument_context: Byte = $0e; instrument_con_dis: Byte = $05; instrument_adsr: Byte = $60; instrument_ai_off: Byte = $06; instrument_ai_on: Byte = $0d; instrument_ai_trig: Byte = $0e; {$IFDEF GO32V2} const rgb_color: array[0..15] of tRGB = ( (r: 00; g: 00; b: 00), (r: 05; g: 10; b: 30), (r: 00; g: 30; b: 30), (r: 00; g: 30; b: 40), (r: 00; g: 00; b: 20), (r: 15; g: 25; b: 35), (r: 00; g: 10; b: 25), (r: 20; g: 30; b: 40), (r: 45; g: 35; b: 50), (r: 10; g: 20; b: 30), (r: 20; g: 40; b: 40), (r: 20; g: 40; b: 50), (r: 25; g: 35; b: 50), (r: 30; g: 35; b: 45), (r: 35; g: 60; b: 60), (r: 40; g: 50; b: 55)); {$ELSE} const rgb_color: array[0..15] of tRGB = ( (r: 00 SHL 2; g: 00 SHL 2; b: 00 SHL 2; a: 00), (r: 05 SHL 2; g: 10 SHL 2; b: 30 SHL 2; a: 00), (r: 00 SHL 2; g: 30 SHL 2; b: 30 SHL 2; a: 00), (r: 00 SHL 2; g: 30 SHL 2; b: 40 SHL 2; a: 00), (r: 00 SHL 2; g: 00 SHL 2; b: 20 SHL 2; a: 00), (r: 15 SHL 2; g: 25 SHL 2; b: 35 SHL 2; a: 00), (r: 00 SHL 2; g: 10 SHL 2; b: 25 SHL 2; a: 00), (r: 20 SHL 2; g: 30 SHL 2; b: 40 SHL 2; a: 00), (r: 45 SHL 2; g: 35 SHL 2; b: 50 SHL 2; a: 00), (r: 10 SHL 2; g: 20 SHL 2; b: 30 SHL 2; a: 00), (r: 20 SHL 2; g: 40 SHL 2; b: 40 SHL 2; a: 00), (r: 20 SHL 2; g: 40 SHL 2; b: 50 SHL 2; a: 00), (r: 25 SHL 2; g: 35 SHL 2; b: 50 SHL 2; a: 00), (r: 30 SHL 2; g: 35 SHL 2; b: 45 SHL 2; a: 00), (r: 35 SHL 2; g: 60 SHL 2; b: 60 SHL 2; a: 00), (r: 40 SHL 2; g: 50 SHL 2; b: 55 SHL 2; a: 00)); const vga_rgb_color: array[0..15] of tRGB = ( (r: $000; g: $000; b: $000; a: 00), (r: $000; g: $000; b: $0aa; a: 00), (r: $000; g: $0aa; b: $000; a: 00), (r: $000; g: $0aa; b: $0aa; a: 00), (r: $0aa; g: $000; b: $000; a: 00), (r: $0aa; g: $000; b: $0aa; a: 00), (r: $0aa; g: $055; b: $000; a: 00), (r: $0aa; g: $0aa; b: $0aa; a: 00), (r: $055; g: $055; b: $055; a: 00), (r: $055; g: $055; b: $0ff; a: 00), (r: $055; g: $0ff; b: $055; a: 00), (r: $055; g: $0ff; b: $0ff; a: 00), (r: $0ff; g: $055; b: $055; a: 00), (r: $0ff; g: $055; b: $0ff; a: 00), (r: $0ff; g: $0ff; b: $055; a: 00), (r: $0ff; g: $0ff; b: $0ff; a: 00)); {$ENDIF} adlibtracker2-2.4.23/dialogio.pas0000644000000000000000000017341013176573532015327 0ustar rootrootunit DialogIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface uses DOS, {$IFDEF GO32V2} GO32, {$ENDIF} {$IFDEF WINDOWS} WINDOWS, {$ENDIF} AdT2unit,AdT2sys,AdT2keyb,AdT2text, TxtScrIO,StringIO,ParserIO; type tDIALOG_SETTING = Record frame_type: String; shadow_enabled: Boolean; title_attr: Byte; box_attr: Byte; text_attr: Byte; text2_attr: Byte; keys_attr: Byte; keys2_attr: Byte; short_attr: Byte; short2_attr: Byte; disbld_attr: Byte; contxt_attr: Byte; contxt2_attr: Byte; xstart: Byte; ystart: Byte; center_box: Boolean; center_text: Boolean; cycle_moves: Boolean; all_enabled: Boolean; terminate_keys: array[1..50] of Word; end; type tMENU_SETTING = Record frame_type: String; frame_enabled: Boolean; shadow_enabled: Boolean; posbar_enabled: Boolean; title_attr: Byte; menu_attr: Byte; text_attr: Byte; text2_attr: Byte; default_attr: Byte; short_attr: Byte; short2_attr: Byte; disbld_attr: Byte; contxt_attr: Byte; contxt2_attr: Byte; topic_attr: Byte; hi_topic_attr: Byte; topic_mask_chr: Set of Char; center_box: Boolean; cycle_moves: Boolean; edit_contents: Boolean; reverse_use: Boolean; show_scrollbar: Boolean; topic_len: Byte; fixed_len: Byte; homing_pos: Longint; terminate_keys: array[1..50] of Word; end; type tDIALOG_ENVIRONMENT = Record keystroke: Word; context: String; input_str: String; end; type tMENU_ENVIRONMENT = Record v_dest: tSCREEN_MEM_PTR; keystroke: Word; context: String; unpolite: Boolean; winshade: Boolean; intact_area: Boolean; edit_pos: Byte; curr_page: Word; curr_pos: Word; curr_item: String; ext_proc: procedure; ext_proc_rt: procedure; refresh: procedure; do_refresh: Boolean; own_refresh: Boolean; preview: Boolean; fixed_start: Byte; descr_len: Byte; descr: Pointer; is_editing: Boolean; xpos,ypos: Byte; xsize,ysize: Byte; desc_pos: Byte; hlight_chrs: Byte; end; const {$IFDEF GO32V2} FILENAME_SIZE = 12; DIR_SIZE = 80; PATH_SIZE = 80; {$ELSE} FILENAME_SIZE = 255; DIR_SIZE = 170; PATH_SIZE = 255; {$ENDIF} type tFSELECT_ENVIRONMENT = Record last_file: String[FILENAME_SIZE]; last_dir: String[DIR_SIZE]; end; const dl_setting: tDIALOG_SETTING = (frame_type: frame_single; shadow_enabled: TRUE; title_attr: $0f; box_attr: $07; text_attr: $07; text2_attr: $0f; keys_attr: $07; keys2_attr: $70; short_attr: $0f; short2_attr: $70; disbld_attr: $07; contxt_attr: $0f; contxt2_attr: $07; xstart: 01; ystart: 01; center_box: TRUE; center_text: TRUE; cycle_moves: TRUE; all_enabled: FALSE; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); const mn_setting: tMENU_SETTING = (frame_type: frame_single; frame_enabled: TRUE; shadow_enabled: TRUE; posbar_enabled: TRUE; title_attr: $0f; menu_attr: $07; text_attr: $07; text2_attr: $70; default_attr: $0f; short_attr: $0f; short2_attr: $70; disbld_attr: $07; contxt_attr: $0f; contxt2_attr: $07; topic_attr: $07; hi_topic_attr: $0f; topic_mask_chr: []; center_box: TRUE; cycle_moves: TRUE; edit_contents: FALSE; reverse_use: FALSE; show_scrollbar: TRUE; topic_len: 0; fixed_len: 0; homing_pos: 0; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); var dl_environment: tDIALOG_ENVIRONMENT; mn_environment: tMENU_ENVIRONMENT; fs_environment: tFSELECT_ENVIRONMENT; function Dialog(text,keys,title: String; spos: Byte): Byte; function Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; function Fselect(mask: String): String; function HScrollBar(dest: tSCREEN_MEM_PTR; x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Word; function VScrollBar(dest: tSCREEN_MEM_PTR; x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Word; procedure DialogIO_Init; implementation type tDBUFFR = array[1.. 100] of Record str: String; pos: Byte; key: Char; use: Boolean; end; type tMBUFFR = array[1..16384] of Record key: Char; use: Boolean; end; var idx,idx2,idx3,pos,max,mx2,num,nm2, xstart,ystart,count, ln,ln1,len2b,atr1,atr2, page,first,last,temp,temp2,opage,opos: Word; old_fr_shadow_enabled: Boolean; key: Word; str: String; solid: Boolean; qflg: Boolean; dbuf: tDBUFFR; mbuf: tMBUFFR; contxt: String; function OutStr(var queue; len: Byte; order: Word): String; begin asm mov esi,[queue] mov edi,@RESULT xor ecx,ecx mov cx,order dec ecx xor eax,eax mov al,len inc eax jecxz @@2 @@1: add esi,eax loop @@1 @@2: xor ecx,ecx mov cl,al rep movsb end; end; function OutKey(str: String): Char; var result: Char; begin If (SYSTEM.Pos('~',str) = 0) then result := '~' else If (str[SYSTEM.Pos('~',str)+2] <> '~') then result := '~' else result := str[SYSTEM.Pos('~',str)+1]; OutKey := result; end; function ReadChunk(str: String; pos: Byte): String; var result: String; begin Delete(str,1,pos-1); If (SYSTEM.Pos('$',str) = 0) then result := '' else result := Copy(str,1,SYSTEM.Pos('$',str)-1); ReadChunk := result; end; function Dialog(text,keys,title: String; spos: Byte): Byte; procedure SubPos(var p: Word); var temp: Word; begin temp := p; If (temp > 1) and dbuf[temp-1].use then Dec(temp) else If (temp > 1) then begin Dec(temp); SubPos(temp); end; If dbuf[temp].use then p := temp; end; procedure AddPos(var p: Word); var temp: Word; begin temp := p; If (temp < nm2) and dbuf[temp+1].use then Inc(temp) else If (temp < nm2) then begin Inc(temp); AddPos(temp); end; If dbuf[temp].use then p := temp; end; procedure ShowItem; begin If (idx2 = 0) then EXIT; If (idx2 <> idx3) then ShowCStr(screen_ptr,dbuf[idx3].pos,ystart+num+1,dbuf[idx3].str, dl_setting.keys_attr,dl_setting.short_attr); ShowCStr(screen_ptr,dbuf[idx2].pos,ystart+num+1,dbuf[idx2].str, dl_setting.keys2_attr,dl_setting.short2_attr); idx3 := idx2; end; function RetKey(code: Byte): Word; var temp: Byte; begin RetKey := 0; For temp := 1 to nm2 do If (UpCase(dbuf[temp].key) = UpCase(CHR(code))) then begin RetKey := temp; BREAK; end; end; function CurrentKey(pos: Byte): Byte; var idx,temp: Byte; begin temp := 0; For idx := 1 to nm2 do If (pos in [dbuf[idx].pos,dbuf[idx].pos+CStrLen(dbuf[idx].str)-1]) then temp := idx; CurrentKey := temp; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:Dialog'; {$ENDIF} pos := 1; max := Length(title); num := 0; ScreenMemCopy(screen_ptr,ptr_scr_backup); HideCursor; Repeat str := ReadChunk(text,pos); Inc(pos,Length(str)+1); If (CStrLen(str) > max) then max := CStrLen(str); If (str <> '') then Inc(num); until (pos >= Length(text)) or (str = ''); pos := 1; mx2 := 0; nm2 := 0; If (Copy(keys,1,14) = '%string_input%') then begin Inc(pos,14); str := ReadChunk(keys,pos); ln := Str2num(str,10); If (str = '') then EXIT; Inc(pos,Length(str)+1); str := ReadChunk(keys,pos); ln1 := Str2num(str,10); mx2 := ln1; If (str = '') then EXIT; Inc(pos,Length(str)+1); str := ReadChunk(keys,pos); atr1 := Str2num(str,16); If (str = '') then EXIT; Inc(pos,Length(str)+1); str := ReadChunk(keys,pos); atr2 := Str2num(str,16); If (str = '') then EXIT; Inc(pos,Length(str)+1); end else begin Repeat str := ReadChunk(keys,pos); Inc(pos,Length(str)+1); If (str <> '') then begin Inc(nm2); dbuf[nm2].str := ' '+str+' '; dbuf[nm2].key := OutKey(str); If NOT dl_setting.all_enabled then dbuf[nm2].use := dbuf[nm2].key <> '~' else dbuf[nm2].use := TRUE; If (nm2 > 1) then begin dbuf[nm2].pos := dbuf[nm2-1].pos+CStrLen(dbuf[nm2-1].str)+1; Inc(mx2,CStrLen(dbuf[nm2].str)+1); end else begin dbuf[nm2].pos := 1; Inc(mx2,CStrLen(dbuf[nm2].str)); end; end; until (pos >= Length(keys)) or (str = ''); end; If (max < mx2) then max := mx2 else begin ln1 := max; If (ln < max) then ln := max; end; If dl_setting.center_box then begin xstart := (work_MaxCol-(max+4)) DIV 2+(work_MaxCol-(max+4)) MOD 2; ystart := (work_MaxLn -(num+2)) DIV 2+(work_MaxLn -(num+2)) MOD 2; end else begin xstart := dl_setting.xstart; ystart := dl_setting.ystart; end; old_fr_shadow_enabled := fr_setting.shadow_enabled; fr_setting.shadow_enabled := dl_setting.shadow_enabled; Frame(screen_ptr,xstart,ystart,xstart+max+3,ystart+num+2, dl_setting.box_attr,title,dl_setting.title_attr, dl_setting.frame_type); fr_setting.shadow_enabled := old_fr_shadow_enabled; pos := 1; contxt := DietStr(dl_environment.context,max+ (Length(dl_environment.context)-CStrLen(dl_environment.context))); ShowCStr(screen_ptr,xstart+max+3-CStrLen(contxt),ystart+num+2, contxt,dl_setting.contxt_attr,dl_setting.contxt2_attr); For idx := 1 to num do begin str := ReadChunk(text,pos); Inc(pos,Length(str)+1); If dl_setting.center_text then ShowCStr(screen_ptr,xstart+2,ystart+idx, ExpStrL(str,Length(str)+(max-CStrLen(str)) DIV 2,' '), dl_setting.text_attr,dl_setting.text2_attr) else ShowCStr(screen_ptr,xstart+2,ystart+idx, str,dl_setting.text_attr,dl_setting.text2_attr); end; If (Copy(keys,1,14) = '%string_input%') then begin ThinCursor; str := InputStr(dl_environment.input_str, xstart+2,ystart+num+1,ln,ln1,atr1,atr2); If is_environment.keystroke = kENTER then dl_environment.input_str := str; dl_environment.keystroke := is_environment.keystroke; HideCursor; end else begin For idx := 1 to nm2 do begin Inc(dbuf[idx].pos,xstart+(max-mx2) DIV 2+1); If dbuf[idx].use then ShowCStr(screen_ptr,dbuf[idx].pos,ystart+num+1, dbuf[idx].str,dl_setting.keys_attr,dl_setting.short_attr) else ShowCStr(screen_ptr,dbuf[idx].pos,ystart+num+1, dbuf[idx].str,dl_setting.disbld_attr,dl_setting.disbld_attr); end; If (spos < 1) then spos := 1; If (spos > nm2) then spos := nm2; idx2 := spos; idx3 := 1; If NOT dbuf[idx2].use then begin SubPos(idx2); If NOT dbuf[idx2].use then AddPos(idx2); end; ShowItem; ShowItem; qflg := FALSE; If (keys = '$') then EXIT; Repeat key := getkey; If LookUpKey(key,dl_setting.terminate_keys,50) then qflg := TRUE; If NOT qflg then If (LO(key) in [$20..$0ff]) then begin idx := RetKey(LO(key)); If (idx <> 0) then begin qflg := TRUE; idx2 := idx; end; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then Case key of kLEFT: If (idx2 > 1) or NOT dl_setting.cycle_moves then SubPos(idx2) else begin idx2 := nm2; If NOT dbuf[idx2].use then SubPos(idx2); end; kRIGHT: If (idx2 < nm2) or NOT dl_setting.cycle_moves then begin temp := idx2; AddPos(idx2); If (idx2 = temp) then begin idx2 := 1; If NOT dbuf[idx2].use then AddPos(idx2); end; end else begin idx2 := 1; If NOT dbuf[idx2].use then AddPos(idx2); end; kHOME: begin idx2 := 1; If NOT dbuf[idx2].use then AddPos(idx2); end; kEND: begin idx2 := nm2; If NOT dbuf[idx2].use then SubPos(idx2); end; end; ShowItem; {$IFNDEF GO32V2} draw_screen; {$ENDIF} until qflg or _force_program_quit; Dialog := idx2; dl_environment.keystroke := key; end; If Addr(move_to_screen_routine) <> NIL then begin move_to_screen_data := ptr_scr_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+max+3+2; move_to_screen_area[4] := ystart+num+2+1; move_to_screen_routine; end else ScreenMemCopy(ptr_scr_backup,screen_ptr); end; var mnu_x,mnu_y,mnu_len,mnu_len2,mnu_topic_len: Byte; mnu_data: Pointer; mnu_count: Word; var vscrollbar_pos: Word; function pstr(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:pstr'; {$ENDIF} If (item <= mnu_count) then Move(POINTER(Ptr(0,Ofs(mnu_data^)+(item-1)*(mnu_len+1)))^,temp,mnu_len+1) else temp := ''; If NOT solid then pstr := ExpStrR(temp,mnu_len-2,' ') else pstr := ExpStrR(temp,mnu_len,' '); end; function pstr2(item: Word): String; var idx: Byte; temp,result: String; begin If (item <= mnu_count) then Move(POINTER(Ptr(0,Ofs(mnu_data^)+(item-1)*(mnu_len+1)))^,temp,mnu_len+1) else temp := ''; If NOT solid then temp := ExpStrR(temp,mnu_len-2,' ') else temp := ExpStrR(temp,mnu_len,' '); If (mn_setting.fixed_len <> 0) then result := temp else begin result := ''; For idx := 1 to Length(temp) do If (temp[idx] in mn_setting.topic_mask_chr) then result := result+'`'+temp[idx]+'`' else result := result+temp[idx]; end; pstr2 := result; end; function pdes(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:pdes'; {$ENDIF} If (mn_environment.descr <> NIL) and (item <= mnu_count) then Move(POINTER(Ptr(0,Ofs(mn_environment.descr^)+ (item-1)*(mn_environment.descr_len+1)))^,temp,mn_environment.descr_len+1) else temp := ''; pdes := ExpStrR(temp,mn_environment.descr_len,' '); end; procedure refresh; procedure ShowCStr_clone(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); var temp, len,len2: Byte; highlighted: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:refresh:ShowCStr_clone'; {$ENDIF} If NOT (mn_setting.fixed_len <> 0) then begin ShowC3Str(dest,x,y,str,atr1,atr2,atr1 AND $0f0+mn_setting.topic_attr AND $0f); EXIT; end; highlighted := FALSE; len := 0; len2 := 0; For temp := 1 to Length(str) do If (str[temp] = '~') then highlighted := NOT highlighted else begin If (temp >= mn_environment.fixed_start) and (len < mn_setting.fixed_len) then begin If NOT highlighted then ShowStr(dest,x+len2,y,str[temp],atr1) else ShowStr(dest,x+len2,y,str[temp],atr2); Inc(len); Inc(len2); end else begin If NOT highlighted then ShowStr(dest,x+len2,y,str[temp],atr3) else ShowStr(dest,x+len2,y,str[temp],atr4); If (temp >= mn_environment.fixed_start) then Inc(len); Inc(len2); end end; end; var item_str,item_str_alt, item_str2,item_str2_alt: String; desc_str,desc_str2,desc_str3: String; begin { refresh } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:refresh'; {$ENDIF} If (page = opage) and (idx2 = opos) and NOT mn_environment.do_refresh then EXIT else begin opage := page; opos := idx2; mn_environment.do_refresh := FALSE; end; If NOT mn_environment.own_refresh then For idx := page to mnu_len2+page-1 do begin item_str := pstr(idx-page+1); item_str_alt := pstr(idx); item_str2 := pstr2(idx2+page-1); item_str2_alt := pstr2(idx); desc_str := pdes(idx-page+1); desc_str2 := pdes(idx); desc_str3 := pdes(idx2+page-1); If (mn_environment.hlight_chrs <> 0) and (item_str <> '') then item_str := '~'+Copy(item_str,1,mn_environment.hlight_chrs)+ '~'+Copy(item_str,mn_environment.hlight_chrs+1,Length(item_str)-mn_environment.hlight_chrs); If (mn_environment.hlight_chrs <> 0) and (item_str_alt <> '') then item_str_alt := '~'+Copy(item_str_alt,1,mn_environment.hlight_chrs)+ '~'+Copy(item_str_alt,mn_environment.hlight_chrs+1,Length(item_str_alt)-mn_environment.hlight_chrs); If (mn_environment.hlight_chrs <> 0) and (item_str2 <> '') then item_str2 := '~'+Copy(item_str2,1,mn_environment.hlight_chrs)+ '~'+Copy(item_str2,mn_environment.hlight_chrs+1,Length(item_str2)-mn_environment.hlight_chrs); If (mn_environment.hlight_chrs <> 0) and (item_str2_alt <> '') then item_str2_alt := '~'+Copy(item_str2_alt,1,mn_environment.hlight_chrs)+ '~'+Copy(item_str2_alt,mn_environment.hlight_chrs+1,Length(item_str2_alt)-mn_environment.hlight_chrs); If (idx = idx2+page-1) then ShowCStr_clone(mn_environment.v_dest,mnu_x+1,mnu_y+idx2, ExpStrR(item_str2+desc_str3, max+(Length(item_str2)+Length(desc_str3)- (C3StrLen(item_str2)+CStrLen(desc_str3))),' '), mn_setting.text2_attr, mn_setting.short2_attr, mn_setting.text_attr, mn_setting.short_attr) else If (idx-page+1 <= mnu_topic_len) then ShowCStr(mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(item_str+desc_str, max+(Length(item_str)+Length(desc_str3)- CStrLen(item_str+desc_str)),' '), mn_setting.topic_attr, mn_setting.hi_topic_attr) else If mbuf[idx].use then ShowC3Str(mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(item_str2_alt+desc_str2, max+(Length(item_str2_alt)+Length(desc_str3)- (C3StrLen(item_str2_alt)+CStrLen(desc_str2))),' '), mn_setting.text_attr, mn_setting.short_attr, mn_setting.topic_attr) else ShowCStr(mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(item_str_alt+desc_str2, max+(Length(item_str_alt)+Length(desc_str3)- CStrLen(item_str_alt+desc_str2)),' '), mn_setting.disbld_attr, mn_setting.disbld_attr); end; If mn_setting.show_scrollbar then vscrollbar_pos := VScrollBar(mn_environment.v_dest,mnu_x+max+1,mnu_y+1-mn_setting.topic_len, temp2,mnu_count,idx2+page-1, vscrollbar_pos,mn_setting.menu_attr,mn_setting.menu_attr); end; function Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure SubPos(var p: Word); var temp: Word; begin temp := p; If (temp > 1) and mbuf[temp+page-2].use then Dec(temp) else If (temp > 1) then begin Dec(temp); SubPos(temp); end else If (page > first) then Dec(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 > first) then SubPos(temp); end; procedure AddPos(var p: Word); var temp: Word; begin temp := p; If (temp < len2) and (temp < last) and mbuf[temp+page].use then Inc(temp) else If (temp < len2) and (temp < last) then begin Inc(temp); AddPos(temp); end else If (page+temp <= last) then Inc(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 < last) then AddPos(temp); end; function RetKey(code: Byte): Word; var temp: Byte; begin RetKey := 0; For temp := 1 to count do If (UpCase(mbuf[temp].key) = UpCase(CHR(code))) then begin RetKey := temp; BREAK; end; end; procedure edit_contents(item: Word); var item_str,temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:Menu:edit_contents'; {$ENDIF} is_setting.append_enabled := TRUE; is_setting.character_set := [' '..'_','a'..'}',#128..#255]; // exclude ` and ~ characters is_environment.locate_pos := 1; item_str := pstr(item); If (mn_environment.edit_pos > 0) and (mn_environment.edit_pos < max-2) then temp := Copy(item_str,mn_environment.edit_pos+1, Length(item_str)-mn_environment.edit_pos+1) else temp := CutStr(item_str); mn_environment.is_editing := TRUE; While (temp <> '') and (temp[Length(temp)] = ' ') do Delete(temp,Length(temp),1); temp := InputStr(temp,x+1+mn_environment.edit_pos,y+idx2, max-2-mn_environment.edit_pos+1, max-2-mn_environment.edit_pos+1, mn_setting.text2_attr,mn_setting.default_attr); mn_environment.is_editing := FALSE; HideCursor; If (is_environment.keystroke = kENTER) then begin If (mn_environment.edit_pos > 0) and (mn_environment.edit_pos < max-2) then temp := Copy(item_str,1,mn_environment.edit_pos)+temp else temp := CutStr(temp); Move(temp,POINTER(Ptr(0,Ofs(data)+(item-1)*(len+1)))^,len+1); end; mn_environment.do_refresh := TRUE; refresh; end; begin { Menu } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:Menu'; {$ENDIF} If (count = 0) then begin Menu := 0; EXIT; end; max := Length(title); mnu_data := Addr(data); mnu_count := count; mnu_len := len; If NOT mn_environment.unpolite then ScreenMemCopy(mn_environment.v_dest,ptr_scr_backup2); If (count < 1) then EXIT; vscrollbar_pos := WORD_NULL; If NOT mn_environment.preview then HideCursor; temp := 0; For idx := 1 to count do begin mbuf[idx].key := OutKey(pstr(idx)); If NOT mn_setting.reverse_use then mbuf[idx].use := mbuf[idx].key <> '~' else mbuf[idx].use := NOT (mbuf[idx].key <> '~'); If mbuf[idx].use then temp := 1; end; solid := FALSE; If (temp = 0) then begin For temp := 1 to count do mbuf[temp].use := TRUE; solid := TRUE; end; For idx := 1 to count do If (max < CStrLen(pstr(idx))+mn_environment.descr_len) then max := CStrLen(pstr(idx))+mn_environment.descr_len; If mn_setting.center_box then begin x := (work_MaxCol-max-2) DIV 2+(work_MaxCol-max-2) MOD 2; y := (work_MaxLn-len2-1) DIV 2+(work_MaxLn-len2-1) MOD 2; end; mnu_x := x; mnu_y := y; len2b := len2; mn_environment.xpos := x; mn_environment.ypos := y; mn_environment.xsize := max+1; mn_environment.ysize := len2+1; mn_environment.desc_pos := y+len2+1; If NOT mn_environment.unpolite then begin old_fr_shadow_enabled := fr_setting.shadow_enabled; fr_setting.shadow_enabled := mn_setting.shadow_enabled; If mn_environment.intact_area then fr_setting.update_area := FALSE; If mn_setting.frame_enabled then Frame(mn_environment.v_dest,x,y,x+max+1,y+len2+1,mn_setting.menu_attr, title,mn_setting.title_attr,mn_setting.frame_type); If mn_environment.intact_area then fr_setting.update_area := TRUE; fr_setting.shadow_enabled := old_fr_shadow_enabled; contxt := DietStr(mn_environment.context,max+ (Length(mn_environment.context)-CStrLen(mn_environment.context))); If mn_setting.frame_enabled then ShowC3Str(mn_environment.v_dest,x+1,y+len2+1, '`'+ExpStrL('',max-CStrLen(contxt), mn_setting.frame_type[2])+'`'+ contxt, mn_setting.contxt_attr, mn_setting.contxt2_attr, mn_setting.menu_attr); temp2 := len2; mnu_len2 := len2; If (len2 > count) then len2 := count; If (len2 < 1) then len2 := 1; If (spos < 1) then spos := 1; If (spos > count) then spos := count; mn_environment.refresh := refresh; first := 1; last := count; While NOT mbuf[first].use do Inc(first); While NOT mbuf[last].use do Dec(last); If (first <= mn_setting.topic_len) then first := SUCC(mn_setting.topic_len); If (spos < first) or (spos > last) then spos := first; idx2 := 1; page := 1; opage := WORD_NULL; opos := WORD_NULL; While (idx2+page-1 < spos) do AddPos(idx2); end; mnu_topic_len := mn_setting.topic_len; If (mnu_topic_len <> 0) then begin mn_setting.topic_len := 0; refresh; mn_setting.topic_len := mnu_topic_len; mnu_topic_len := 0; mnu_data := POINTER(Ofs(data)+SUCC(len)*mn_setting.topic_len); Inc(mnu_y,mn_setting.topic_len); Dec(len2,mn_setting.topic_len); Dec(mnu_len2,mn_setting.topic_len); Move(mbuf[SUCC(mn_setting.topic_len)],mbuf[1], (count-mn_setting.topic_len)*SizeOf(mbuf[1])); For temp := 1 to mn_setting.topic_len do SubPos(idx2); Dec(count,mn_setting.topic_len); Dec(mnu_count,mn_setting.topic_len); Dec(first,mn_setting.topic_len); Dec(last,mn_setting.topic_len); refresh; end else refresh; mn_environment.curr_page := page; mn_environment.curr_pos := idx2+page-1; mn_environment.curr_item := CutStr(pstr(idx2+page-1)); mn_environment.keystroke := WORD_NULL; If (Addr(mn_environment.ext_proc) <> NIL) then mn_environment.ext_proc; qflg := FALSE; If mn_environment.preview then begin mn_environment.preview := FALSE; mn_environment.unpolite := TRUE; end else begin Repeat mn_environment.keystroke := key; key := getkey; If NOT qflg then If (LO(key) in [$20..$0ff]) then begin idx := RetKey(LO(key)); If (idx <> 0) then begin refresh; idx2 := idx; If NOT ((key = mn_setting.terminate_keys[2]) and mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx); end; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then Case key of kUP: If (page+idx2-1 > first) or NOT mn_setting.cycle_moves then SubPos(idx2) else begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kDOWN: If (page+idx2-1 < last) or NOT mn_setting.cycle_moves then AddPos(idx2) else begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kHOME: begin If (mn_setting.homing_pos = 0) then begin idx2 := 1; page := 1; end else If (idx2+page-1 > mn_setting.homing_pos) and (mn_setting.homing_pos < count) then Repeat SubPos(idx2) until (idx2+page-1 <= mn_setting.homing_pos) else begin idx2 := 1; page := 1; end; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kEND: begin If (mn_setting.homing_pos = 0) then begin idx2 := len2; page := count-len2+1; end else If (idx2+page-1 < mn_setting.homing_pos) and (mn_setting.homing_pos < count) then Repeat AddPos(idx2); until (idx2+page-1 >= mn_setting.homing_pos) else begin idx2 := len2; page := count-len2+1; end; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kPgUP: If (idx2+page-1-(len2-1) > mn_setting.homing_pos) or (idx2+page-1 <= mn_setting.homing_pos) or (mn_setting.homing_pos = 0) or NOT (mn_setting.homing_pos < count) then For temp := 1 to len2-1 do SubPos(idx2) else Repeat SubPos(idx2); until (idx2+page-1 <= mn_setting.homing_pos); kPgDOWN: If (idx2+page-1+(len2-1) < mn_setting.homing_pos) or (idx2+page-1 >= mn_setting.homing_pos) or (mn_setting.homing_pos = 0) or NOT (mn_setting.homing_pos < count) then For temp := 1 to len2-1 do AddPos(idx2) else Repeat AddPos(idx2); until (idx2+page-1 >= mn_setting.homing_pos); end; If LookUpKey(key,mn_setting.terminate_keys,50) then If NOT ((key = mn_setting.terminate_keys[2]) and mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx2+page-1); mn_environment.curr_page := page; mn_environment.curr_pos := idx2+page-1; mn_environment.curr_item := CutStr(pstr(idx2+page-1)); refresh; mn_environment.keystroke := key; If (Addr(mn_environment.ext_proc) <> NIL) then mn_environment.ext_proc; {$IFNDEF GO32V2} draw_screen; {$ENDIF} until qflg or _force_program_quit; end; If mn_environment.winshade and NOT mn_environment.unpolite then begin If (Addr(move_to_screen_routine) <> NIL) then begin move_to_screen_data := ptr_scr_backup2; move_to_screen_area[1] := x; move_to_screen_area[2] := y; move_to_screen_area[3] := x+max+1+2; move_to_screen_area[4] := y+len2b+1+1; move_to_screen_routine; end else ScreenMemCopy(ptr_scr_backup2,mn_environment.v_dest); end; Menu := idx2+page-1; end; const MAX_FILES = 4096; UPDIR_STR = #19'updir'; {$IFDEF UNIX} DRIVE_DIVIDER = 0; {$ELSE} DRIVE_DIVIDER = 1; {$ENDIF} type tSEARCH = Record name: String[FILENAME_SIZE]; attr: Word; info: String; size: Longint; end; type tSTREAM = Record stuff: array[1..MAX_FILES] of tSEARCH; count: Word; drive_count: Word; match_count: Word; end; type {$IFDEF GO32V2} tMNUDAT = array[1..MAX_FILES] of String[1+12+1]; {$ELSE} tMNUDAT = array[1..MAX_FILES] of String[1+23+1]; {$ENDIF} type tDSCDAT = array[1..MAX_FILES] of String[20]; var menudat: tMNUDAT; descr: tDSCDAT; masks: array[1..20] of String; fstream: tSTREAM; {$IFNDEF GO32V2} drive_list: array[0..128] of Char; {$ENDIF} function LookUpMask(filename: String): Boolean; var temp: Byte; okay: Boolean; begin okay := FALSE; For temp := 1 to count do {$IFDEF GO32V2} If SameName(Upper(masks[temp]),Upper(filename)) then {$ELSE} If (Upper(Copy(masks[temp],3,Length(masks[temp]))) = Upper(ExtOnly(filename))) then {$ENDIF} begin okay := TRUE; BREAK; end; LookUpMask := okay; end; {$IFDEF GO32V2} function valid_drive(drive: Char): Boolean; function phantom_drive(drive: Char): Boolean; var regs: tRealRegs; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:phantom_drive'; regs.ax := $440e; regs.bl := BYTE(UpCase(drive))-$40; RealIntr($21,regs); If Odd(regs.flags) then phantom_drive := FALSE else If (regs.al = 0) then phantom_drive := FALSE else phantom_drive := (regs.al <> BYTE(UpCase(drive))-$40); end; var regs: tRealRegs; dos_sel,dos_seg: Word; dos_mem_adr: Dword; dos_data: array[0..PRED(40)] of Byte; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:valid_drive'; dos_mem_adr := global_dos_alloc(40); dos_sel := WORD(dos_mem_adr); dos_seg := WORD(dos_mem_adr SHR 16); dos_data[0] := BYTE(UpCase(drive)); dos_data[1] := BYTE(':'); dos_data[2] := 0; dosmemput(dos_seg,0,dos_data,40); regs.ax := $2906; regs.si := 0; regs.di := 3; regs.ds := dos_seg; regs.es := dos_seg; RealIntr($21,regs); global_dos_free(dos_sel); valid_drive := (regs.al <> BYTE_NULL) and NOT phantom_drive(drive); end; {$ELSE} function valid_drive(drive: Char; var info: String): Boolean; var idx: Byte; begin valid_drive := FALSE; info := ''; {$IFNDEF UNIX} idx := 0; For idx := 0 to 128 do If (drive_list[idx] = drive) then begin info := 'DRiVE'; BREAK; end; {$ENDIF} If (info <> '') then valid_drive := TRUE; end; {$ENDIF} procedure make_stream(path,mask: String; var stream: tSTREAM); var search: SearchRec; count1,count2: Word; drive: Char; {$IFNDEF GO32V2} type tCOMPARE_STR_RESULT = (isLess,isMore,isEqual); function CompareStr(str1,str2: String): tCOMPARE_STR_RESULT; var idx,len: Byte; result: tCOMPARE_STR_RESULT; begin If (str1 = UPDIR_STR) then result := isLess else If (str2 = UPDIR_STR) then result := isMore else result := isEqual; If (result <> isEqual) then begin CompareStr := result; EXIT; end; str1 := Upper(FilterStr2(str1,_valid_characters_fname,'_')); str2 := Upper(FilterStr2(str2,_valid_characters_fname,'_')); If (Length(str1) > Length(str2)) then len := Length(str1) else len := Length(str2); For idx := 1 to len do If (FilterStr2(str1[idx],_valid_characters,#01) > FilterStr2(str2[idx],_valid_characters,#01)) then begin result := isMore; BREAK; end else If (str1[idx] < str2[idx]) then begin result := isLess; BREAK; end; If (result = isEqual) then If (Length(str1) < Length(str2)) then result := isLess else If (Length(str1) > Length(str2)) then result := isMore; CompareStr := result; end; {$ENDIF} procedure QuickSort(l,r: Word); var i,j: Word; cmp: String; tmp: tSEARCH; begin If (l >= r) then EXIT; cmp := stream.stuff[(l+r) DIV 2].name; i := l; j := r; Repeat {$IFDEF GO32V2} While (i < r) and (stream.stuff[i].name < cmp) do Inc(i); While (j > l) and (stream.stuff[j].name > cmp) do Dec(j); {$ELSE} While (i < r) and (CompareStr(stream.stuff[i].name,cmp) = isLess) do Inc(i); While (j > l) and (CompareStr(stream.stuff[j].name,cmp) = isMore) do Dec(j); {$ENDIF} If (i <= j) then begin tmp := stream.stuff[i]; stream.stuff[i] := stream.stuff[j]; stream.stuff[j] := tmp; Inc(i); Dec(j); end; until (i > j); If (l < j) then QuickSort(l,j); If (i < r) then QuickSort(i,r); end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:make_stream'; {$ELSE} {$IFNDEF UNIX} GetLogicalDriveStrings(SizeOf(drive_list),drive_list); {$ENDIF} {$ENDIF} count1 := 0; For drive := 'A' to 'Z' do {$IFDEF GO32V2} If valid_drive(drive) then {$ELSE} If valid_drive(drive,stream.stuff[SUCC(count1)].info) then {$ENDIF} begin Inc(count1); stream.stuff[count1].name := drive; stream.stuff[count1].attr := volumeid; stream.stuff[count1].size := 0; end; Inc(count1); stream.stuff[count1].name := '~'+#255+'~'; stream.stuff[count1].attr := volumeid; count2 := 0; stream.drive_count := count1; {$IFDEF GO32V2} If (DiskSize(ORD(UpCase(path[1]))-ORD('A')+1) > 0) then begin {$ENDIF} FindFirst(path+WILDCARD_ASTERISK,anyfile-volumeid,search); While (DOSerror = 0) and (count1 < MAX_FILES) do begin If (search.attr AND directory <> 0) and (search.name = '.') then begin FindNext(search); CONTINUE; end else If (search.attr AND directory <> 0) and NOT ((search.name = '..') and (Length(path) = 3)) then begin If (search.name <> '..') then search.name := search.name else search.name := UPDIR_STR; Inc(count1); stream.stuff[count1].name := search.name; stream.stuff[count1].attr := search.attr; end; FindNext(search); end; {$IFNDEF GO32V2} If (Length(path) > 3) and (count1 = stream.drive_count) then begin Inc(count1); stream.stuff[count1].name := UPDIR_STR; stream.stuff[count1].attr := search.attr; end; {$ENDIF} FindFirst(path+WILDCARD_ASTERISK,anyfile-volumeid-directory,search); While (DOSerror = 0) and (count1+count2 < MAX_FILES) do begin If LookUpMask(search.name) then begin search.name := Lower_filename(search.name); Inc(count2); stream.stuff[count1+count2].name := search.name; stream.stuff[count1+count2].attr := search.attr; stream.stuff[count1+count2].size := search.size; end; FindNext(search); end; {$IFDEF GO32V2} end; {$ENDIF} QuickSort(stream.drive_count+DRIVE_DIVIDER,count1); QuickSort(count1+DRIVE_DIVIDER,count1+count2); stream.count := count1+count2; stream.match_count := count2; end; var path: array[1..26] of String[PATH_SIZE]; old_fselect_external_proc: Procedure; procedure new_fselect_external_proc; begin mn_environment.curr_item := fstream.stuff[mn_environment.curr_pos].name; If (@old_fselect_external_proc <> NIL) then old_fselect_external_proc; end; function Fselect(mask: String): String; var {$IFNDEF GO32V2} temp1: Longint; {$ENDIF} temp2: Longint; temp3,temp4: String; temp5: Longint; temp6,temp7: String; temps: String; temp8: Longint; lastp: Longint; idx: Byte; function path_filter(path: String): String; begin If (Length(path) > 3) and (path[Length(path)] = PATHSEP) then Delete(path,Length(path),1); path_filter := Upper_filename(path); end; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:Fselect'; {$ENDIF} _jmp1: idx := 1; count := 0; Repeat temp6 := Upper(ReadChunk(mask,idx)); Inc(idx,Length(temp6)+1); If NOT (temp6 = '') then begin Inc(count); masks[count] := temp6; end; until (idx >= Length(mask)) or (temp6 = ''); {$i-} GetDir(0,temp6); {$i+} If (IOresult <> 0) then temp6 := fs_environment.last_dir; If (fs_environment.last_dir <> '') then begin {$i-} ChDir(fs_environment.last_dir); {$i+} If (IOresult <> 0) then begin {$i-} ChDir(temp6); {$i+} If (IOresult <> 0) then ; fs_environment.last_file := 'FNAME:EXT'; end; end; {$i-} GetDir(0,temp3); {$i+} If (IOresult <> 0) then temp3 := temp6; If (temp3[Length(temp3)] <> PATHSEP) then temp3 := temp3+PATHSEP; mn_setting.cycle_moves := FALSE; temp4 := ''; mn_environment.descr_len := 20; mn_environment.descr := Addr(descr); mn_environment.winshade := FALSE; ScreenMemCopy(screen_ptr,ptr_scr_backup); Repeat path[SUCC(ORD(UpCase(temp3[1]))-ORD('A'))] := path_filter(temp3); make_stream(temp3,mask,fstream); {$IFDEF GO32V2} For temp2 := 1 to fstream.count do If (fstream.stuff[temp2].name <> UPDIR_STR) then begin menudat[temp2] := ' '+ExpStrR(BaseNameOnly( FilterStr2(fstream.stuff[temp2].name,_valid_characters,'_')),8,' ')+' '+ ExpStrR(ExtOnly( fstream.stuff[temp2].name),3,' ')+' '; If (fstream.stuff[temp2].attr AND directory <> 0) then menudat[temp2] := iCASE(menudat[temp2]); end else begin menudat[temp2] := ExpStrR(' ..',mn_environment.descr_len,' '); fstream.stuff[temp2].name := '..'; end; For temp2 := 1 to fstream.count do If (fstream.stuff[temp2].attr = volumeid) then begin If (fstream.stuff[temp2].name = '~'+#255+'~') then descr[temp2] := '' else descr[temp2] := '[~DRiVE~]'; end else If (fstream.stuff[temp2].attr AND directory <> 0) then begin If fstream.stuff[temp2].name = '..' then descr[temp2] := ExpStrL('[UP-DiR]',mn_environment.descr_len-1,' ') else descr[temp2] := ExpStrL('[DiR]',mn_environment.descr_len-1,' ') end else begin temp7 := Num2str(fstream.stuff[temp2].size,10); descr[temp2] := ''; For temp8 := 1 to Length(temp7) do If (temp8 MOD 3 <> 0) or (temp8 = Length(temp7)) then descr[temp2] := temp7[Length(temp7)-temp8+1]+descr[temp2] else descr[temp2] := ','+temp7[Length(temp7)-temp8+1]+descr[temp2]; descr[temp2] := ExpStrL(descr[temp2],mn_environment.descr_len-1,' '); end; {$ELSE} For temp2 := 1 to fstream.count do If (fstream.stuff[temp2].attr AND directory <> 0) then If (fstream.stuff[temp2].name = UPDIR_STR) then begin menudat[temp2] := ' '+ExpStrR('..',24,' ')+' '; descr[temp2] := ExpStrL('[UP-DiR]',mn_environment.descr_len-1,' '); fstream.stuff[temp2].name := '..'; end else begin temp1 := 24+(mn_environment.descr_len-1-10); temp7 := iCASE_filename(DietStr(FilterStr2(fstream.stuff[temp2].name,_valid_characters_fname,'_'),temp1)); If (Length(temp7) < 24) then begin menudat[temp2] := ' '+ExpStrR(temp7,24,' ')+' '; descr[temp2] := ExpStrR('',mn_environment.descr_len-1-10,' '); end else begin menudat[temp2] := ' '+iCASE_filename(ExpStrR(Copy(temp7,1,24),24,' ')); descr[temp2] := ExpStrR(Copy(temp7,25,Length(temp7)-23),mn_environment.descr_len-1-10,' '); end; descr[temp2] := descr[temp2]+ExpStrL('[DiR]',10,' '); end else menudat[temp2] := ' '+ExpStrR(DietStr(BaseNameOnly( FilterStr2(fstream.stuff[temp2].name,_valid_characters_fname,'_')),23),23,' ')+' '; For temp2 := 1 to fstream.count do If (fstream.stuff[temp2].attr = volumeid) then begin If (fstream.stuff[temp2].name = '~'+#255+'~') then descr[temp2] := '' else descr[temp2] := '[~'+fstream.stuff[temp2].info+'~]'; end else If NOT (fstream.stuff[temp2].attr AND directory <> 0) then begin temp7 := Num2str(fstream.stuff[temp2].size,10); descr[temp2] := ''; For temp8 := 1 to Length(temp7) do If (temp8 MOD 3 <> 0) or (temp8 = Length(temp7)) then descr[temp2] := temp7[Length(temp7)-temp8+1]+descr[temp2] else descr[temp2] := ','+temp7[Length(temp7)-temp8+1]+descr[temp2]; descr[temp2] := ExpStrR(Copy(ExtOnly( fstream.stuff[temp2].name),1,3),3,' ')+' '+ ExpStrL(DietStr(descr[temp2],mn_environment.descr_len-1-4), mn_environment.descr_len-1-4,' '); end; {$ENDIF} For temp2 := 1 to fstream.count do If (SYSTEM.Pos('~',fstream.stuff[temp2].name) <> 0) and (fstream.stuff[temp2].name <> '~'+#255+'~') then While (SYSTEM.Pos('~',menudat[temp2]) <> 0) do menudat[temp2][SYSTEM.Pos('~',menudat[temp2])] := PATHSEP; temp5 := fstream.drive_count+DRIVE_DIVIDER; While (temp5 <= fstream.count) and (temp4 <> '') and (temp4 <> fstream.stuff[temp5].name) do Inc(temp5); If (temp5 > fstream.count) then temp5 := 1; For temp2 := 1 to fstream.count do If (Lower_filename(fstream.stuff[temp2].name) = fs_environment.last_file) and NOT (fstream.stuff[temp2].attr AND volumeid <> 0) then begin lastp := temp2; BREAK; end; If (Lower_filename(fstream.stuff[temp2].name) <> fs_environment.last_file) then lastp := 0; If (lastp = 0) or (lastp > MAX_FILES) then lastp := temp5; mn_setting.reverse_use := TRUE; mn_environment.context := ' ~'+Num2str(fstream.match_count,10)+' FiLES FOUND~ '; mn_setting.terminate_keys[3] := kBkSPC; {$IFDEF UNIX} mn_setting.terminate_keys[4] := kSlash; {$ELSE} mn_setting.terminate_keys[4] := kSlashR; {$ENDIF} mn_setting.terminate_keys[5] := kF1; old_fselect_external_proc := mn_environment.ext_proc; mn_environment.ext_proc := new_fselect_external_proc; temp := 1; While (temp < fstream.count) and (SYSTEM.Pos('[UP-DiR]',descr[temp]) = 0) do Inc(temp); If (temp < fstream.count) then mn_setting.homing_pos := temp else mn_setting.homing_pos := fstream.drive_count+DRIVE_DIVIDER; {$IFDEF UNIX} Dec(fstream.count); {$ENDIF} {$IFDEF GO32V2} temp2 := Menu(menudat,01,01,lastp, 1+12+1,AdT2unit.max(work_MaxLn-7,30),fstream.count,' '+ iCASE(DietStr(path_filter(temp3),28)+' ')); {$ELSE} temp2 := Menu(menudat,01,01,lastp, 1+23+1,AdT2unit.max(work_MaxLn-5,30),fstream.count,' '+ iCASE(DietStr(FilterStr2(path_filter(temp3),_valid_characters_fname,'_'),38))+' '); {$ENDIF} mn_environment.ext_proc := old_fselect_external_proc; mn_setting.reverse_use := FALSE; mn_environment.context := ''; mn_setting.terminate_keys[3] := 0; mn_setting.terminate_keys[4] := 0; mn_setting.terminate_keys[5] := 0; If (mn_environment.keystroke = kENTER) and (fstream.stuff[temp2].attr AND directory <> 0) then begin fs_environment.last_file := 'FNAME:EXT'; mn_environment.keystroke := WORD_NULL; If (fstream.stuff[temp2].name = '..') then begin Delete(temp3,Length(temp3),1); temp4 := NameOnly(temp3); While (temp3[Length(temp3)] <> PATHSEP) do Delete(temp3,Length(temp3),1); fs_environment.last_file := Lower_filename(temp4); end else begin temp3 := temp3+fstream.stuff[temp2].name+PATHSEP; temp4 := ''; fs_environment.last_file := temp4; end; {$i-} ChDir(Copy(temp3,1,Length(temp3)-1)); {$i+} If (IOresult <> 0) then ; end else If (mn_environment.keystroke = kENTER) and (fstream.stuff[temp2].attr AND volumeid <> 0) then begin fs_environment.last_file := 'FNAME:EXT'; mn_environment.keystroke := WORD_NULL; {$i-} ChDir(path[SUCC(ORD(UpCase(fstream.stuff[temp2].name[1]))-ORD('A'))]); {$i+} If (IOresult <> 0) then temp3 := path[SUCC(ORD(UpCase(fstream.stuff[temp2].name[1]))-ORD('A'))] else begin {$i-} GetDir(0,temp3); {$i+} If (IOresult <> 0) then temp3 := temp6; end; If (temp3[Length(temp3)] <> PATHSEP) then temp3 := temp3+PATHSEP; temp4 := ''; fs_environment.last_file := temp4; end else If (mn_environment.keystroke = kBkSPC) then If shift_pressed then begin If (home_dir_path <> '') then temps := home_dir_path else temps := PathOnly(ParamStr(0)); If (temps[Length(temps)] <> PATHSEP) then temps := temps+'\'; {$i-} ChDir(Copy(temps,1,Length(temps)-1)); {$i+} If (IOresult = 0) then begin temp3 := temps; temp4 := '..'; end else begin {$i-} ChDir(temp3); {$i+} If (IOresult <> 0) then ; end; end else If (SYSTEM.Pos(PATHSEP,Copy(temp3,3,Length(temp3)-3)) <> 0) then begin Delete(temp3,Length(temp3),1); temp4 := NameOnly(temp3); While (temp3[Length(temp3)] <> PATHSEP) do Delete(temp3,Length(temp3),1); fs_environment.last_file := Lower_filename(temp4); {$i-} ChDir(Copy(temp3,1,Length(temp3)-1)); {$i+} If (IOresult <> 0) then ; end else {$IFDEF UNIX} else If (mn_environment.keystroke = kSlash) then {$ELSE} else If (mn_environment.keystroke = kSlashR) then {$ENDIF} begin temp3 := Copy(temp3,1,3); temp4 := ''; fs_environment.last_file := temp4; {$i-} ChDir(Copy(temp3,1,Length(temp3)-1)); {$i+} If (IOresult <> 0) then ; end else fs_environment.last_file := Lower_filename(fstream.stuff[temp2].name); until (mn_environment.keystroke = kENTER) or (mn_environment.keystroke = kESC) or (mn_environment.keystroke = kF1); mn_environment.descr_len := 0; mn_environment.descr := NIL; mn_environment.winshade := TRUE; mn_setting.frame_enabled := TRUE; mn_setting.shadow_enabled := TRUE; mn_setting.homing_pos := 0; move_to_screen_data := ptr_scr_backup; move_to_screen_area[1] := mn_environment.xpos; move_to_screen_area[2] := mn_environment.ypos; move_to_screen_area[3] := mn_environment.xpos+mn_environment.xsize+2+1; move_to_screen_area[4] := mn_environment.ypos+mn_environment.ysize+1; move2screen; If (mn_environment.keystroke = kF1) then begin HELP('file_browser'); GOTO _jmp1; end; Fselect := temp3+fstream.stuff[temp2].name; fs_environment.last_dir := path[SUCC(ORD(UpCase(temp3[1]))-ORD('A'))]; {$i-} ChDir(temp6); {$i+} If (IOresult <> 0) then ; If (mn_environment.keystroke = kESC) then Fselect := ''; end; function _partial(max,val: Word; base: Byte): Word; var temp1,temp2: Real; temp3: Word; begin temp1 := max/base; temp2 := (max/base)/2; temp3 := 0; While (temp2 < val) do begin temp2 := temp2+temp1; Inc(temp3); end; _partial := temp3; end; function HScrollBar(dest: tSCREEN_MEM_PTR; x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Word; var temp: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:HScrollBar'; {$ENDIF} If (size > work_MaxCol-x) then size := work_MaxCol-x; If (size < 5) then size := 5; If (size-2-1 < 10) then temp := _partial(len1,len2,size-2-1) else temp := _partial(len1,len2,size-2-1-2); If (pos = temp) then begin HScrollBar := temp; EXIT; end; If (size < len1) then begin pos := temp; ShowStr(dest,x,y,#17+ExpStrL('',size-2,#176)+#16,atr1); If (size-2-1 < 10) then ShowStr(dest,x+1+temp,y,#178,atr2) else ShowStr(dest,x+1+temp,y,#178#178#178,atr2); end else ShowCStr(dest,x,y,'~'#17'~'+ExpStrL('',size-2,#177)+'~'#16'~',atr2,atr1); HScrollBar := pos; end; function VScrollBar(dest: tSCREEN_MEM_PTR; x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Word; var temp: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:VScrollBar'; {$ENDIF} If (size > work_MaxLn-y) then size := work_MaxLn-y; If (size < 5) then size := 5; If (size-2-1 < 10) then temp := _partial(len1,len2,size-2-1) else temp := _partial(len1,len2,size-2-1-2); If (pos = temp) then begin VScrollBar := temp; EXIT; end; If (size < len1) then begin pos := temp; ShowVStr(dest,x,y,#30+ExpStrL('',size-2,#176)+#31,atr1); If (size-2-1 < 10) then ShowStr(dest,x,y+1+temp,#178,atr2) else ShowVStr(dest,x,y+1+temp,#178#178#178,atr2); end else ShowVCStr(dest,x,y,'~'#30'~'+ExpStrL('',size-2,#177)+'~'#31'~',atr2,atr1); VScrollBar := pos; end; procedure DialogIO_Init; var index: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:DialogIO_Init'; {$ENDIF} dl_setting.frame_type := frame_double; dl_setting.title_attr := dialog_background+dialog_title; dl_setting.box_attr := dialog_background+dialog_border; dl_setting.text_attr := dialog_background+dialog_text; dl_setting.text2_attr := dialog_background+dialog_hi_text; dl_setting.keys_attr := dialog_background+dialog_item; dl_setting.keys2_attr := dialog_sel_itm_bck+dialog_sel_itm; dl_setting.short_attr := dialog_background+dialog_short; dl_setting.short2_attr := dialog_sel_itm_bck+dialog_sel_short; dl_setting.disbld_attr := dialog_background+dialog_item_dis; dl_setting.contxt_attr := dialog_background+dialog_context; dl_setting.contxt2_attr := dialog_background+dialog_context_dis; mn_setting.frame_type := frame_double; mn_setting.title_attr := dialog_background+dialog_title; mn_setting.menu_attr := dialog_background+dialog_border; mn_setting.text_attr := dialog_background+dialog_item; mn_setting.text2_attr := dialog_sel_itm_bck+dialog_sel_itm; mn_setting.default_attr := dialog_def_bckg+dialog_def; mn_setting.short_attr := dialog_background+dialog_short; mn_setting.short2_attr := dialog_sel_itm_bck+dialog_sel_short; mn_setting.disbld_attr := dialog_background+dialog_item_dis; mn_setting.contxt_attr := dialog_background+dialog_context; mn_setting.contxt2_attr := dialog_background+dialog_context_dis; mn_setting.topic_attr := dialog_background+dialog_topic; mn_setting.hi_topic_attr := dialog_background+dialog_hi_topic; mn_setting.topic_mask_chr := []; mn_environment.v_dest := screen_ptr; dl_environment.keystroke := $0000; mn_environment.keystroke := $0000; dl_environment.context := ''; mn_environment.context := ''; mn_environment.unpolite := FALSE; dl_environment.input_str := ''; mn_environment.winshade := TRUE; mn_environment.intact_area := FALSE; mn_environment.ext_proc := NIL; mn_environment.ext_proc_rt := NIL; mn_environment.refresh := NIL; mn_environment.do_refresh := FALSE; mn_environment.own_refresh := FALSE; mn_environment.preview := FALSE; mn_environment.fixed_start := 0; mn_environment.descr_len := 0; mn_environment.descr := NIL; mn_environment.is_editing := FALSE; fs_environment.last_file := 'FNAME:EXT'; fs_environment.last_dir := ''; mn_environment.xpos := 0; mn_environment.xpos := 0; mn_environment.xsize := 0; mn_environment.ysize := 0; mn_environment.desc_pos := 0; mn_environment.hlight_chrs := 0; For index := 1 to 26 do path[index] := CHR(ORD('a')+PRED(index))+':'+PATHSEP; end; end. adlibtracker2-2.4.23/adt2text.pas0000644000000000000000000023351613176573532015303 0ustar rootrootunit AdT2text; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const {__AT2VER__}at2ver = '2.3.56'; {__AT2DAT__}at2date = '07-01-2017'; {__AT2LNK__}at2link = '1:03pm'; const _ADT2_TITLE_STRING_ = '/´DLiB TR/´CK3R ]['; {$IFDEF GO32V2} _PLATFORM_STR_ = 'DOS'; {$ELSE} _PLATFORM_STR_ = 'SDL'; {$ENDIF} const {$IFDEF GO32V2} HELP_LINES = 1129; {$ELSE} HELP_LINES = 1157; {$ENDIF} {$IFDEF GO32V2} const ascii_line_01 = ' Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-¿'; ascii_line_02 = ' ³ ~Û~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛÛÛ~`²`° ~ÛÛÛÛÛÛ~`²`° ³'; ascii_line_03 = ' ³ ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_04 = ' ù ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_05 = ' ú ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_06 = ' ~Û~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛ~`²`° ~Û~`²`° ~ÛÛ~`²`° ³'; ascii_line_07 = ' ~Û~`²`° ~ÛÛÛÛ~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_08 = ' ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_09 = ' ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_10 = ' ú ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_11 = ' ù ~Û~`²`° ~ÛÛÛÛÛÛÛÛ~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛÛÛÛ~`²`° ³'; ascii_line_12 = ' À-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄ-Äùú úù-ÄÄÄÄ-Ù'; ascii_line_13 = ' .:: ~THE ULTiMATE FM-TRACKiNG TOOL~ ::. '; ascii_line_14 = ' Ú-Ä--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-¿'; ascii_line_15 = ' ³ `code:` ~ÄÂÄ ÄÄ~ ù'; ascii_line_16 = ' ³ ~subz3ro/Altair~ ~/´DLiB³R/´CK3R ³³ G3~ ú'; ascii_line_17 = ' ³ `additional ideas:` ~³ ³ ÄÄ~ '; ascii_line_18 = ' ³ ~Malfunction/Altair~ ~'+at2ver+'~ '; ascii_line_19 = ' ³ ~Diode Millimpere~ ú'; ascii_line_20 = ' ³ `special thanks:` ú'; ascii_line_21 = ' ³ ~encore~ HOMEPAGE www.adlibtracker.net ³'; ascii_line_22 = ' ³ ~Maan M. Hamze~ EMAiL subz3ro.altair@gmail.com ³'; ascii_line_23 = ' À-ÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù'; procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte); {$ELSE} const ascii_line_01 = 'Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-¿'; ascii_line_02 = '³ ~Û~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛÛÛ~`²`° ~ÛÛÛÛÛÛ~`²`° ³'; ascii_line_03 = '³ ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_04 = 'ù ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_05 = 'ú ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_06 = ' ~Û~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛ~`²`° ~Û~`²`° ~ÛÛ~`²`° ³'; ascii_line_07 = ' ~Û~`²`° ~ÛÛÛÛ~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_08 = ' ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_09 = ' ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_10 = 'ú ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_11 = 'ù ~Û~`²`° ~ÛÛÛÛÛÛÛÛ~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛÛÛÛ~`²`° ³'; ascii_line_12 = 'À-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄ-Äùú úù-ÄÄÄÄ-Ù'; ascii_line_13 = ' .:: ~THE ULTiMATE FM-TRACKiNG TOOL~ ::. '; ascii_line_14 = 'Ú-Ä--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-¿'; ascii_line_15 = '³ `code:` ~ÄÂÄ ÄÄ~ ù'; ascii_line_16 = '³ ~subz3ro/Altair~ ~/´DLiB³R/´CK3R ³³ SDL~ ú'; ascii_line_17 = '³ `additional ideas:` ~³ ³ ÄÄ~ '; ascii_line_18 = '³ ~Malfunction/Altair~ ~'+at2ver+'~ '; ascii_line_19 = '³ ~Diode Milliampere~'; ascii_line_20 = '³ `special thanks:` ù'; ascii_line_21 = '³ ~Dmitry Smagin~ ú'; ascii_line_22 = '³ ~Windfisch~ HOMEPAGE www.adlibtracker.net ³'; ascii_line_23 = '³ ~insane/Altair~ EMAiL subz3ro.altair@gmail.com ³'; ascii_line_24 = 'À-ÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù'; procedure C3WriteLn(posX,PosY: Byte; str: String; atr1,atr2,atr3: Byte); {$ENDIF} const help_data: array[1..HELP_LINES] of String[128] = ( '@topic:general', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `GENERAL KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~F1~ Help', '~F2 (^S)~ Save file', '~F3 (^L)~ Load file', '~F4 (^A)~ Toggle Nuke''m dialog', '~F5~ Play', '~F6~ Pause', '~F7~ Stop', '~F8~ Play song from current pattern or order', '~F9~ Play current pattern or order only', '~[Ctrl] F8~ @F8 from current line ¿ ', '~[Ctrl] F9~ @F9 from current line à (Pattern Editor)', '~[Alt] F6~ Single-play pattern Ù (~Shift~ toggles trace)', '~[Alt] F5~ @F5 ¿', '@input:alt_f8', '~[Alt] F9~ @F9 Ù', '~[Shift] F2~ Quick Save', '~[Shift] F3~ Quick Load', '@input:shift_f5', '~[Shift] F6~ Toggle Debug mode from position at cursor', '@input:shift_f8', '@input:shift_f9', '~[Shift] Space~ Toggle MidiBoard mode ON/OFF', '~^Space~ Toggle Note Recorder mode ON/OFF', '~[Ctrl] Home,End~ Skip to previous/next pattern while Tracing', '~+,-~ Same as above; play pattern from start', '', '@topic:note_recorder', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `WHEN iN NOTE RECORDER MODE` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~[Ctrl] ,'#26'~ Select group of tracks for recording ³', '³ ~[Alt] Q~ Quick reset last selected group of tracks ³', '³ ~Enter~ Start recording from current position ~(*)~ ³', '³ ~Space~ `Toggle` using custom instrument for all tracks ¿ ³@@spec_attr:01@@', '³ ~[Alt] Space~ `Toggle` using present instruments in tracks ö ref. ³@@spec_attr:02@@', '³ ~MBoard keys~ Write notes to corresponding tracks ø ~(*)~ ³', '³ ~F8,F9~ Toggle pattern repeat OFF/ON Ù ³', '³ ~Backspace~ Clear note/instrument sequence in tracks ³', '³ ~^Backspace~ Clear complete note/instrument columns ³', '³ ~,~ Rewind/Fast-Forward while recording ³', '³ ~[Shift] ,~ Increase/Decrease row correction for writing notes ³', '³ ~[Shift] F6~ Continue in Debug mode from position at cursor ³', '³ ~F7~ Stop recording and reset starting position; ³', '³ current group of tracks can be modified ³', '³ ~[Alt] 1..9,0~ Toggle track channel ON/OFF (~Shift~ toggles 1`X`) ³', '³ ~[Alt] R~ Reset flags on all tracks ³', '³ ~*~ Reverse ON/OFF on all tracks ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ In case you need non-continuos track selection, you can choose ³', '³ from already selected group a subset of tracks where notes will be ³', '³ written by manipulating track ON/OFF flags. ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `iF SONG iS PLAYED WiTH TRACE, iT CAN BE REMOVED WHiLE...` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~Enter~ Playback is paused and cursor stays on position ³', '³ ~Esc~ Cursor jumps to last position and playback continues ³', '³ ~[Shift] Esc~ Cursor stays on position and playback continues ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', '~^Enter~ Play next pattern according to order', '~[Ctrl]  ()~ Rewind current pattern (with Trace)', '~[Ctrl] '#26' ()~ Fast-Forward (with Trace)', '~[Ctrl][Alt] ~ Temporarily show Debug Info window', '~^B~ Toggle Message Board window', '~^D~ Toggle Debug Info window', '~^Q~ Toggle Instrument Macro Editor window', '~^G~ Toggle Arpeggio/Vibrato Macro Editor window', '~^M~ Toggle Macro Browser window', '~^F~ Toggle Song Variables window', '~^H~ Toggle Replace window', '~^I~ Toggle Instrument Control panel', '~^E~ Toggle Instrument Editor window', '~^O~ Toggle Octave Control panel', '~^P~ Toggle Pattern List window', '~^R~ Toggle Remap Instrument window', '~^T~ Toggle Transpose window', '~^X~ Toggle Rearrange Tracks window', '~^1..^8~ Quick-set octave', '~[Alt]{Shift} +,- {,}~ Adjust volume level of sound output', '~[Alt] C~ Copy object to clipboard (with selection)', '~[Alt] P~ Paste object from clipboard', '~[Alt] M~ Toggle marking lines ON/OFF', '~[Alt] L~ Toggle Line Marking Setup window', '~[Alt] 1..9,0~ Toggle track channel ON/OFF (~Shift~ toggles 1`X`)', '~[Alt] S~ Set all OFF except current track (solo)', '~[Alt] R~ Reset flags on all tracks', '~*~ Reverse ON/OFF on all tracks', '~F10~ Quit program', '~F11~ Toggle typing mode in Pattern Editor (`AT`'#26'`FT`'#26'`ST`)', '~F12~ Toggle `line feed` in Pattern Editor', '~[Shift] F12~ Toggle `jump to marked line` in Pattern Editor', {$IFDEF GO32V2} '~[Ctrl][Tab] [...] (*)~ Scroll screen content (if necessary)', '', '~(*) ,,,'#26',PgUp,PgDown,Home,End~', {$ELSE} '~[Ctrl][Tab] [...] (*)~ Scroll Volume Analyzer section (if necessary)', '', '~(*) ,,PgUp,PgDown~', '', '@topic:wav_recorder', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `WAV RECORDER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '', '~[Alt|Ctrl]{Shift} F11~ Toggle WAV recording ON', '~[Alt|Ctrl]{Shift} F12~ Toggle WAV recording OFF', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `FUNCTiONALiTY OF ALTERNATiVE KEYS` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~Alt~ Toggle normal recording mode ³', '³ ~Ctrl~ Toggle ''per track'' recording mode ³', '³ ~Shift~ Toggle Fade in / Fade out sound processing ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ POSSiBLE COMBiNATiONS: Alt,Ctrl,Alt+Shift,Ctrl+Shift ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', 'If ''per track'' recording mode is activated and song playback is stopped,', 'you can exclude/include corresponding tracks from/to being recorded', 'with ordinary track selection procedure:', '', '~[Alt] 1..9,0~ Toggle track channel ON/OFF (~Shift~ toggles 1`X`)', '~[Alt] S~ Set all OFF except current track (solo)', '~[Alt] R~ Reset flags on all tracks', {$ENDIF} '', '@topic:pattern_order', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `PATTERN ORDER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26'~ Cursor navigation', '~PgUp,PgDn~ Move up/down 32 patterns', '~Home,End~ Move to the top/end of pattern order', '~Tab,[Shift] Tab~ Move to next/previous entry', '~Insert~ Insert entry', '~Delete~ Delete entry', '~Backspace~ Clear entry', '~^Space~ Enter skip mark', '~^C~ Copy entry to clipboard', '~^V~ Paste entry from clipboard', '~+,-~ Adjust entry', '~^F2~ Save module in tiny format', '~Enter~ Switch to Pattern Editor', '', 'ORDER ENTRiES: 0-7F', ' 80-FF = jump to pattern order 0-7F', ' syntax: order_number[hex](+80h); e.g. "9A" jumps to order 1A', '', '@topic:pattern_editor', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `PATTERN EDiTOR KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26'~ Cursor navigation', '~PgUp,PgDn~ Move up/down 16 lines', '~Home,End~ Move to the top/end of current pattern', '~Tab,[Shift] Tab~ Move to next/previous track', '~[Shift] PgDn,PgUp (+,-)~ Move to next/previous pattern', '~[Shift] Home,End~ Move fwd./bckwd. to the first/last pattern', '~^Home,^End~ Move to the end/top of previous/next pattern', '~Space~ Advance to next row', '~^PgUp,^PgDn~ Transpose note or block halftone up/down', '~Backspace~ Remove note or clear attributes', '~Insert~ Insert new line (within track only)', '~Delete~ Delete line (within track only)', '~[Shift] Insert~ Insert new line', '~[Shift] Delete~ Delete line', '~[Shift] Enter~ Toggle fixed and regular note', '~^K~ Insert Key-Off', '~^C~ Copy object at cursor to clipboard', '~^V~ Paste object from clipboard', '~[Alt][Shift] P~ Paste object from clipboard to more patterns', '~^Z~ Undo last operation (if possible)', '~{Ctrl} "[","]"~ Change current instrument', '~[Alt] F2~ Save current pattern to file', '~^F2~ Save module in tiny format', '~[Shift] F3~ Quick load recent pattern data', '~Enter~ Switch to Pattern Order', '', 'NOTE SYSTEM: C,C#,D,D#,E,F,F#,G,G#,A,A#,B(H)', 'VALiD NOTE ENTRiES: C,C-,C#,C1,C-1,C#1...', '', '@topic:block_operations', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `BLOCK OPERATiONS iN PATTERN EDiTOR` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ Starting to mark a block: ~[Shift] ,,,'#26'~ ³', '³ When at least one row in one track is marked, you can continue ³', '³ marking also with ~PgUp,PgDn,Home,End~ (~Shift~ is still held down!) ³', '³ Quick mark: ~[Alt] Q~ (1x-2x-3x) track Ä pattern Ä discard ³', '³ Toggle last marked block: ~[Alt] B~ ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~^B~ Blank block (Insert blank block to pattern) ³', '³ ~^C~ Copy block (Copy block to clipboard) ³', '³ ~^D~ Delete block (Remove block from pattern) ³', '³ ~^N~ Nuke block (Clear block contents) ³', '³ ~^V~ Paste block (Paste block from clipboard to pattern) ~(*)~ ³', '³ ~^X~ Cut block (Combine both Copy and Delete operation) ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ `(*) PASTE BLOCK OPERATiON VARiANTS` ³', '³ œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœ ³', '³ "Paste block" operation has three other functional variants ³', '³ with different key shortcuts for activation: ³', '³ 1) ~[Alt] V~ toggles "Mix block" operation, when block data ³', '³ from clipboard is applied without overwriting existing data; ³', '³ 2) ~[Shift] ^V~ toggles "Selective paste block" operation, ³', '³ when only block data from clipboard corresponding to current ³', '³ cursor position is being applied (i.e. note, instrument, ³', '³ 1st effect or 2nd effect); ³', '³ 3) ~[Alt][Shift] V~ toggles "Flipped paste block" operation, ³', '³ when block data from clipboard is applied vertically flipped. ³', '³ ³', '³ `MANiPULATiON WiTH FX VOLUME iNFORMATiON` ³', '³ œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœ ³', '³ When there is block marked, which contains some effect ³', '³ commands carrying volume information, you can increase/decrease ³', '³ their values with ~+~/~-~ keys. ³', '³ Effect commands are processed with following priority: ³', '³ 1) Set instrument volume (~Cxx~), ³', '³ Force instrument volume (~=xx~) ³', '³ 2) Set modulator volume (~9xx~) ³', '³ 3) Set carrier volume (~Ixx~) ³', '³ 4) Set global volume (~%xx~) ³', '³ If effect command with higher priority has been processed, ³', '³ all remaining effect commands with lower priority are skipped. ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', '@topic:pattern_list', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `PATTERN LiST WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,~ Cursor navigation', '~PgUp,PgDn~ Move up/down 20 patterns', '~Home,End~ Move to the top/end of pattern list', '~Space~ Mark/Unmark pattern', '~^Space~ Unmark all marked patterns', '~[Shift] ^Space~ Reverse marks on all patterns', '~[Alt] C (^C)~ Copy pattern to clipboard', '~[Alt] P (^V)~ Paste pattern from clipboard', '~[Shift] ^V~ Paste pattern data from clipboard', '~[Alt] V~ Paste pattern name(s) from clipboard', '~^N~ Nuke current pattern', '~[Shift] ^N~ Nuke all marked patterns', '~^W~ Swap marked patterns', '~[Shift] ^W~ Swap marked patterns w/o names', '~[Shift] Insert~ Insert new pattern', '~[Shift] Delete~ Delete current pattern', '~Enter~ Rename pattern / Multiple paste', '~[Shift] F3~ Quick load recent pattern data', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:instrument_control', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT CONTROL PANEL KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,~ Cursor navigation', '~PgUp,PgDn~ Move up/down 16 instruments', '~Home,End~ Move to the top/end of instrument list', '~Space~ Mark/Unmark instrument', '~Enter~ Rename instrument', '~^C~ Copy instrument to clipboard', '~[Shift] ^C~ Copy instrument also with macro-definitions', '~^V~ Paste instrument(s) from clipboard', '~[Shift] ^V~ Paste instrument data from clipboard', '~[Alt] V~ Paste instrument name(s) from clipboard', '~^W~ Swap marked instruments', '~[Shift] ^W~ Swap marked instruments w/o names', '~Tab~ Toggle Instrument Editor window', '~[Shift] Tab~ Toggle Macro Editor window', '~[Shift] O~ Toggle operator mode  / ', '~[Shift] M,B,S,T,C,H~ Toggle `m`elodic and percussion (`B`D,`S`D,`T`T,T`C`,`H`H)', '~[Shift] F2~ Save instrument w/ fm-register macro to file', '~[Alt] F2~ Save instrument bank to file', '~^F2~ Save instrument bank w/ all macros to file', '~[Shift] F3~ Quick load recent instrument data', '~MBoard keys ~ Preview instrument', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:instrument_editor', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT EDiTOR WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~[Alt]
~ Jump to section', '~Tab~ Jump to next setting', '~[Shift] Tab~ Jump to previous setting', '~PgUp,PgDn (+,-)~ Adjust value', '~Space~ Select item', '~^Space~ `(opt.)` Toggle ADSR preview ON/OFF', '~[Ctrl] "[","]"~ Change current instrument', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~[Alt]{Shift} 1..4,0~ Set operators for instrument preview ~(*)~', '~Enter~ Toggle carrier/modulator/ slot settings', '~[Shift] O~ Toggle operator mode  / ', '~[Shift] M,B,S,T,C,H~ Toggle `m`elodic and percussion (`B`D,`S`D,`T`T,T`C`,`H`H)', '~[Shift] F2~ Save instrument w/ fm-register macro to file', '~[Shift] Enter~ Copy values from carrier/modulator slot', '~MBoard keys ~ Preview instrument', '~Esc~ Return to Instrument Control panel', '', '~(*) [Alt] 1..4~ Set solo operator', ' ~[Alt][Shift] 1..4~ Toggle operator ON/OFF', ' ~[Alt] 0~ Reset', '', '@topic:macro_editor', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT MACRO EDiTOR WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~PgUp,PgDown~ Move up/down 16 lines', '~Tab (Enter)~ Jump to next field in order', '~[Shift] Tab~ Jump to previous field in order', '~[Shift] ,~ Synchronous navigation within tables', '~[Shift] Home,End~ Move to the start/end of current line in table', '~[Ctrl] ,'#26'~ Switch between macro tables', '~[Ctrl][Shift] ,'#26'~ Navigate to start/end of macro table', '~^PgUp,^PgDown~ Change current arpeggio/vibrato table', '~[Ctrl] "[","]"~ Change current instrument', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~[Alt]{Shift} 1..4,0~ Set operators for instrument preview ~(*)~', '~[Alt] ^C~ Copy values from carrier column', '~[Alt] ^M~ Copy values from modulator column', '~^C~ Copy line in table (whole table respectively)', '~[Shift] ^C~ Copy column in table', '~^V~ Paste object from clipboard', '~^Enter~ Paste data from instrument registers', '~[Shift] Enter~ Paste data to instrument registers', '~[Shift] ^Enter~ Paste data from instrument registers w/ selection', '~Backspace~ Clear current item in table', '~[Shift] Backspace~ Clear line in table', '~+,-~ Adjust value at cursor / current item in table', '~^Home,^End~ Quick-adjust table length', '~[Shift] ^Home,^End~ Quick-adjust loop begin position', '~[Shift] ^PgUp,^PgDown~ Quick-adjust loop length', '~Insert~ Insert new line in table', '~Delete~ Delete line in table', '~^E~ Toggle envelope restart ON/OFF ¿', '~^N~ Toggle note retrigger ON/OFF ö', '~^Z~ Toggle ZERO frequency ON/OFF ö', '~[Alt] ^E,^N,^Z~ Reset all alike flags in table ö FM-register', '~^Backspace~ Toggle corresponding column ON/OFF ø table', '~[Alt] S~ Set all OFF except current column ö', '~[Alt] R~ Reset flags on all columns ö', '~*~ Reverse ON/OFF on all columns Ù', '~\~ Toggle current item (switch types only)', '~Space~ Toggle macro-preview mode', '~^Space~ Toggle Key-Off loop within macro-preview mode', '~^F2~ Save instrument bank w/ all macros to file', '~Esc~ Leave Instrument Macro Editor window', '', '~(*) [Alt] 1..4~ Set solo operator', ' ~[Alt][Shift] 1..4~ Toggle operator ON/OFF', ' ~[Alt] 0~ Reset', '', '@topic:macro_editor_(av)', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `APREGGiO/ViBRATO MACRO EDiTOR WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~PgUp,PgDown~ Move up/down 16 lines', '~Tab (Enter)~ Jump to next field in order', '~[Shift] Tab~ Jump to previous field in order', '~[Shift] ,~ Synchronous navigation within tables', '~[Ctrl] ,'#26'~ Switch between macro tables', '~[Ctrl][Shift] ,'#26'~ Navigate to start/end of macro table', '~^PgUp,^PgDown~ Change current arpeggio/vibrato table', '~[Ctrl] "[","]"~ Change current instrument', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~[Alt]{Shift} 1..4,0~ Set operators for instrument preview ~(*)~', '~^C~ Copy line in table (whole table respectively)', '~[Shift] ^C~ Copy column in table', '~^V~ Paste object from clipboard', '~Backspace~ Clear current item in table', '~[Shift] Backspace~ Clear line in table', '~+,-~ Adjust value at cursor / current item in table', '~^Home,^End~ Quick-adjust table length', '~[Shift] ^Home,^End~ Quick-adjust loop begin position', '~[Shift] ^PgUp,^PgDown~ Quick-adjust loop length', '~Space~ Toggle macro-preview mode', '~^Space~ Toggle Key-Off loop within macro-preview mode', '~[Shift] Esc~ Apply table indexes to current instrument', '~Esc~ Leave Arpeggio/Vibrato Macro Editor window', '', '~(*) [Alt] 1..4~ Set solo operator', ' ~[Alt][Shift] 1..4~ Toggle operator ON/OFF', ' ~[Alt] 0~ Reset', '', '@topic:macro_browser', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT MACRO BROWSER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~[Shift] ,~ Move up/down in macro table', '~[Shift] ,'#26'~ Move left/right in macro table', '~[Shift] PgUp,PgDown~ Move page up/down in macro table', '~[Shift] Home,End~ Move to the start/end of macro table', '~[Ctrl] Home,End~ Move to the start/end of line in macro table', '~Enter~ Load selected macro data', '~^Enter~ `(opt.)` Load all macro data from bank', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~MBoard keys ~ Preview instrument with selected macro data', '~Tab~ `(opt.)` Switch to Arpeggio/Vibrato Macro Browser window', '~Esc~ Leave Instrument Macro Browser window', '', '@topic:macro_browser_av', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `ARPEGGiO/ViBRATO MACRO BROWSER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,PgUp,PgDown,~', '~Home,End~ Cursor navigation', '~[Shift] ,'#26'~ Move left/right in arpeggio table ¿', '~[Shift] PgUp,PgDown~ Move page left/right in arpeggio table ö', '~[Ctrl] ,'#26'~ Move left/right in vibrato table ö refer to', '~^PgUp,^PgDown~ Move page left/right in vibrato table ø ~(*)~', '~[Shift]{Alt} Space~ Toggle arpeggio table selection ~(**)~ ö', '~[Ctrl] {Alt} Space~ Toggle vibrato table selection ~(**)~ Ù', '~[Shift] Home,End~ Navigate to start/end of arpeggio table', '~^Home,^End~ Navigate to start/end of vibrato table', '~[Ctrl] "[","]"~ Change current instrument', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~MBoard keys ~ Preview instrument with selected macro data', '~Enter~ Load selected macro data', '~^Enter~ `(opt.)` Load all macro data from bank', '~Esc~ Leave Arpeggio/Vibrato Macro Browser window', '', '~(*)~ Key combination with ~Ctrl+Shift~ applies action to both tables', '~(**)~ ~Alt~ key invokes no arpeggio resp. vibrato table (index value reset)', '', '@topic:debug_info', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `DEBUG iNFO WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,PgUp,PgDown,~', '~Home,End~ Change current track', '~Tab~ Toggle details', '~Backspace~ Toggle pattern repeat', '~Space~ Enter Debug mode / Proceed step', '~^Space~ Exit Debug mode', '~[Ctrl] Home,End~ Skip to previous/next pattern', '~+,-~ Same as above; play pattern from start', '~^Enter~ Play next pattern according to order', '~[Ctrl] ,'#26'~ Rewind/Fast-Forward current pattern', '~[Alt] 1..9,0~ Toggle track channel ON/OFF (~Shift~ toggles 1`X`)', '~[Alt] S~ Set all OFF except current track (solo)', '~[Alt] R~ Reset flags on all tracks', '~*~ Reverse ON/OFF on all tracks', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:remap_dialog', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `REMAP iNSTRUMENT WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~PgUp,PgDown~ Move up/down 16 instruments', '~Tab~ Jump to next selection', '~[Shift] Tab~ Jump to previous selection', '~MBoard keys ~ Preview instrument', '~Enter~ Remap', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:rearrange_dialog', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `REARRANGE TRACKS WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~Tab~ Jump to next selection', '~[Shift] Tab~ Jump to previous selection', '~^PgUp,^PgDown~ Shift track at cursor up/down in the track list', '~[Shift] ^PgUp,^PgDown~ Rotate track list from cursor upside/downside', '~Enter~ Rearrange', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:replace_dialog', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `REPLACE WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~Tab~ Jump to next selection', '~[Shift] Tab~ Jump to previous selection', '~^K~ Insert Key-Off in note column', '~^N~ Mark "new" field to clear found item', '~^W~ Swap "to find" and "replace" mask content', '~Delete,Backspace~ Delete current/previous character', '~^Backspace~ Delete "to find" or "replace" mask content', '~[Shift] ^Backspace~ Delete content of both masks', '~Enter~ Replace', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:song_variables', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `SONG VARiABLES WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26'~ Cursor navigation', '~Tab (Enter)~ Jump to next variable field', '~[Shift] Tab~ Jump to previous variable field', '~Space~ Select item', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:file_browser', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `FiLE BROWSER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26'~', '~PgUp,PgDown,Home,End~ Cursor navigation', {$IFDEF UNIX} '~/~ Navigate to root directory', {$ELSE} '~\~ Navigate to drive root', {$ENDIF} '~Backspace~ Navigate to parent directory', '~[Shift] Backspace~ Navigate to program home directory', '~MBoard keys ~ Preview instrument (instrument files only)', '~Enter~ Choose file under cursor / read instrument bank', '~Esc~ Leave without choosing file', '', '@topic:message_board', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `MESSAGE BOARD WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',^PgUp,^PgDown,~', '~Home,End,^Home,^End~ Cursor navigation', '~PgUp,PgDown~ Move backwards/forwards over text', '~[Ctrl] ,'#26'~ Move word left/right', '~Backspace,Delete~ Delete character left/right', '~^Backspace,^T~ Delete word left/right', '~^K~ Delete characters to end', '~^Y~ Delete current line', '~Tab~ Indent current line', '~^Space~ Insert row for text at cursor', '~[Shift] ^Backspace~ Delete row for text at cursor', '~Insert~ Toggle input and overwrite mode', '~Enter~ Wrap line of text', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:input_field', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNPUT FiELD KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,'#26',Home,End~ Cursor navigation', '~[Ctrl] ,'#26'~ Move word left/right', '~Backspace,Delete~ Delete character left/right', '~^Backspace,^T~ Delete word left/right', '~^K~ Delete characters to end', '~^Y~ Delete string', '~Insert~ Toggle input and overwrite mode', '', '@topic:midiboard', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `MiDiBOARD KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '', ' C# D# F# G# A# C# D# F# G# A# C# D#', '', ' ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ', ' ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ', ' ÞÛÛ ~S~ÞÛ ~D~ÞÛÛÞÛÛ ~G~ÞÛ ~H~ÞÛ ~J~ÞÛÛÞÛÛ ~2~ÞÛ ~3~ÞÛÛÞÛÛ ~5~ÞÛ ~6~ÞÛ ~7~ÞÛÛÞÛÛ ~9~ÞÛ ~0~ÞÛÛ', ' ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ', ' ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ', ' ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ', ' ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ', ' ÞÝ~Z~ÞÞÝ~X~ÞÞÝ~C~ÞÞÝ~V~ÞÞÝ~B~ÞÞÝ~N~ÞÞÝ~M~ÞÞÝ~Q~ÞÞÝ~W~ÞÞÝ~E~ÞÞÝ~R~ÞÞÝ~T~ÞÞÝ~Y~ÞÞÝ~U~ÞÞÝ~I~ÞÞÝ~O~ÞÞÝ~P~Þ', ' ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ', ' ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ', '', ' C D E F G A B C D E F G A B C D E', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `WHiLE TRACKER iS iN MiDiBOARD MODE` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~MBoard key~ copies note in note field, plays it, and advances song ³', '³ to next row. If used with ~Left-Shift~ key and line marking toggled ON, ³', '³ it advances song to next highlighted row. ³', '³ If used with ~Right-Shift~ key, it makes a fixed note. ³', '³ ~Space~ plays row and advances song by one row. ³', '³ ~@@` inserts Key-Off, releases playing note and advances to next row. ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', '@topic:instrument_registers', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT REGiSTERS` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~Attack rate~', 'Indicates how fast the sound volume goes to maximum.', '1=slow, 15=fast. 0 means no attack phase.', '', '~Decay rate~', 'Indicates how fast the sound goes from maximum level to sustain level.', '1=slow, 15=fast. 0 means no decay phase.', '', '~Sustain level~', 'Indicates the sustain level.', '1=loudest, 15=softest. 0 means no sustain phase.', '', '~Release rate~', 'Indicates how fast the sound goes from sustain level to zero level.', '1=slow, 15=fast. 0 means no release phase.', '', '~Output level~', 'Ranges from 0 to 63, indicates the attenuation according to the', 'envelope generator output. In Additive synthesis, varying', 'the output level of any operator varies the volume of its corresponding', 'channel. In FM synthesis, varying the output level of carrier varies', 'the volume of its corresponding channel, but varying the output of', 'the modulator will change the frequency spectrum produced by the carrier.', '', '~Waveform select~', 'Specifies the output waveform type.', 'The first is closest to pure sine wave, the last is most distorted.', '', '`[0] SiNE`', '', ' ', ' ³', ' ³ __ __', ' ³ / \ / \', ' ³ / \ / \', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³ \ / \ /', ' ³ \ / \ /', ' ³ ', ' ³ 1/2 1 3/2 2 pi', '', '', '`[1] HALF-SiNE`', '', ' ', ' ³', ' ³ __ __', ' ³ / \ / \', ' ³ / \ / \', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³', ' ³ 1/2 1 3/2 2 pi', ' ³', ' ³', '', '', '`[2] ABS-SiNE`', '', ' ', ' ³', ' ³ __ __ __ __', ' ³ / \ / \ / \ / \', ' ³ / \ / \ / \ / \', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³', ' ³ 1/2 1 3/2 2 pi', ' ³', ' ³', '', '', '`[3] PULSE-SiNE`', '', ' ', ' ³', ' ³ _ _ _ _', ' ³ / | / | / | / |', ' ³/ | / | / | / |', ' ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ', ' ³', ' ³ 1/4 1/2 3/4 1 5/4 3/2 7/4 2 pi', ' ³', ' ³', '', '', '`[4] SiNE, EVEN PERiODS ONLY (EPO)`', '', ' ', ' ³', ' ³', ' ³ /\ /\', ' ³/ \ / \', ' ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ', ' ³ \ / \ /', ' ³ \_/ \_/', ' ³', ' ³ 1/4 1/2 3/4 1 5/4 3/2 7/4 2 pi', '', '', '`[5] ABS-SiNE, EVEN PERiODS ONLY (EPO)`', '', ' ', ' ³', ' ³', ' ³ /\ /\ /\ /\', ' ³/ \ / \ / \ / \', ' ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ', ' ³', ' ³ 1/4 1/2 3/4 1 5/4 3/2 7/4 2 pi', ' ³', ' ³', '', '', '`[6] SQUARE`', '', ' ', ' ³', ' ³', ' Ã-----------¿ Ú-----------¿', ' ñ ñ ñ ñ', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³ ñ ñ ñ ñ', ' ³ À-----------Ù À-----------Ù', ' ³', ' ³ 1/2 1 3/2 2 pi', '', '', '`[7] DERiVED SQUARE`', '', ' ', ' ³', ' ³', ' ñ\__ ñ\__', ' ñ ÄÄÄ__ ñ ÄÄ__', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³ ÄÄÄ___ ñ ÄÄ____ ñ', ' ³ \ñ \ñ', ' ³', ' ³ 1/2 1 3/2 2 pi', '', '', '~Key scaling level (KSL)~', 'When set, makes the sound softer at higher frequencies.', 'With musical instruments, volume decreases as pitch increases.', 'Level key scaling values are used to simulate this effect.', 'If any (not zero), the diminishing factor can be 1.5 dB/octave,', '3.0 dB/octave, or 6.0 dB/octave.', '', '~Panning~', 'Gives you ability of controlling output, going to left or right channel,', 'standing in the middle respectively.', 'The parameter corresponds either with carrier and modulator, therefore', 'it is listed only once (within the carrier slot).', '', '~Fine-tune~', 'This is not a hardware parameter.', 'Ranges from -127 to 127, it indicates the number of frequency units', 'shifted up or down for any note playing with the corresponding instrument.', 'The parameter corresponds either with carrier and modulator, therefore', 'it is listed only once (within the carrier slot).', '', '~Feedback strength~', 'Ranges from 0 to 7, it indicates the modulation depth', 'for the modulator slot FM feedback.', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿', '³ `FEEDBACK` º `[0]` ³ `[1]` ³ `[2]` ³ `[3]` ³ `[4]` ³ `[5]` ³ `[6]` ³ `[7]` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄ´', '³ `MODULATiON` º 0 ³1/16 ³ 1/8 ³ 1/4 ³ 1/2 ³ 1 ³ 2 ³ 4 ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÙ', '', 'The parameter corresponds either with carrier and modulator, therefore', 'it is listed only once (within the carrier slot).', '', '~Connection type~', 'Frequency modulation means that the modulator slot modulates the carrier.', 'Additive synthesis means that both slots produce sound on their own.', '', '`[FM] FREQUENCY MODULATiON`', '', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³ ÉÍÍÍÍ»', ' P1 ÄÄ(+)Äĺ MO ÇÄÄÁÄÄ(+)Äĺ CA ÇÄÄ OUT', ' ÈÍÍÍͼ  ÈÍÍÍͼ', ' ³', '', ' P2', '', '`[ADDiTiVE SYNTHESiS] AM`', '', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³', ' P1 ÄÄ(+)Äĺ MO ÇÄÄÁÄÄÄÄ¿', ' ÈÍÍÍͼ ³', ' ', ' (+)ÄÄ OUT', ' ', ' ÉÍÍÍÍ» ³', ' P2 ÄÄÄÄÄÄÄĺ CA ÇÄÄÄÄÄÄÄÙ', ' ÈÍÍÍͼ', '', 'The parameter corresponds either with carrier and modulator, therefore', 'it is listed only once (within the carrier slot).', 'This parameter is also very important when making 4-op instruments,', 'because the combination of two instrument connections specifies', 'the connection of the 4-op instrument as shown below:', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄ¿', '³ `SLOT` º M1 ³ C1 ³ M2 ³ C2 ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´', '³ `OPERATOR` º 1 ³ 2 ³ 3 ³ 4 ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÙ', '', '', '`[FM/FM]`', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³ ÉÍÍÍÍ» ÉÍÍÍÍ» ÉÍÍÍÍ»', ' P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄ(+)Äĺ C1 ÇÄÄ(+)Äĺ M2 ÇÄÄ(+)Äĺ C2 ÇÄÄ OUT', ' ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ', ' ³ ³ ³', '', ' P2 P3 P4', '', '`[FM/AM]` ~(*)~', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³ ÉÍÍÍÍ»', ' P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄ(+)Äĺ C1 ÇÄÄÄÄ¿', ' ÈÍÍÍͼ  ÈÍÍÍͼ ³', ' ³ ³', ' ', ' P2 (+)ÄÄ OUT', ' ', ' ³', ' ÉÍÍÍÍ» ÉÍÍÍÍ» ³', ' P3 ÄÄÄÄÄÄÄĺ M2 ÇÄÄÄÄÄ(+)Äĺ C2 ÇÄÄÄÄÙ', ' ÈÍÍÍͼ  ÈÍÍÍͼ', ' ³', '', ' P4', '', '`[AM/FM]` ~(*)~', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³', ' P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ÈÍÍÍͼ ³', ' ³', ' ³', ' ³', ' ÉÍÍÍÍ» ÉÍÍÍÍ» ÉÍÍÍÍ» ', ' P2 ÄÄÄÄÄÄÄĺ C1 ÇÄÄÄÄÄ(+)Äĺ M2 ÇÄÄ(+)Äĺ C2 ÇÄÄ(+)ÄÄ OUT', ' ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ', ' ³ ³', '', ' P3 P4', '', '`[AM/AM]`', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³', ' P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ÈÍÍÍͼ ³', ' ³', ' ³', ' ³', ' ÉÍÍÍÍ» ÉÍÍÍÍ» ', ' P2 ÄÄÄÄÄÄÄÄĺ C1 ÇÄÄÄÄÄ(+)Äĺ M2 ÇÄÄ(+)ÄÄ OUT', ' ÈÍÍÍͼ  ÈÍÍÍͼ ', ' ³ ³', ' ³', ' P3 ³', ' ÉÍÍÍÍ» ³', ' P4 ÄÄÄÄÄÄÄĺ C2 ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', ' ÈÍÍÍͼ', '', '', '~(*)~ `REMARK ABOUT  CONNECTiONS`', 'Please note, that since order of  tracks in the tracker is õ and ô,', 'these non-symmetrical instrument connections are reversed.', 'The preview diagrams in the Instrument Editor window show actual order,', 'but here this information is kept in conformity with the official', 'Yamaha YMF262 data specification to prevent further confusion.', '', '', '~Tremolo (Amplitude modulation)~', 'When set, turns tremolo (volume vibrato) ON for the corresponding slot.', 'The repetition rate is 3.7®, the depth is optional (1dB/4.8dB).', '', '~Vibrato~', 'When set, turns frequency vibrato ON for the corresponding slot.', 'The repetition rate is 6.1®, the depth is optional (7%/14%).', '', '~Key scale rate (KSR)~', 'When set, makes the sound shorter at higher frequencies.', 'With normal musical instruments, the attack and decay rate becomes faster', 'as the pitch increases. The key scale rate controls simulation of', 'this effect. An offset (rof) is added to the individual attack, decay,', 'and release rates depending on the following formula:', '', 'actual_rate = (rate  4) + rof', '', 'The "rof" values for corresponding "rate" value and KSR state are shown', 'in the following table:', '', 'ÚÄÄÄÄÄÄÄÄÒÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿', '³ `%rate%` º 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ³ 8 ³ 9 ³ A ³ B ³ C ³ D ³ E ³ F ³', 'ÆÍÍÍÍÍÍÍÍÎÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍ͵', '³ `[OFF]` º 0 ³ 0 ³ 0 ³ 0 ³ 1 ³ 1 ³ 1 ³ 1 ³ 2 ³ 2 ³ 2 ³ 2 ³ 3 ³ 3 ³ 3 ³ 3 ³', 'ÃÄÄÄÄÄÄÄÄ×ÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´', '³ `[ON]` º 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ³ 8 ³ 9 ³ A ³ B ³ C ³ D ³ E ³ F ³', 'ÀÄÄÄÄÄÄÄÄÐÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ', '', '~Sustain (Envelope generator type)~', 'When set, the sustain level of the voice is maintained until released.', 'When clear, the sound begins to decay immediately after hitting', 'the sustain phase.', '', '`[OFF]` /\ DR', ' / \', ' / ...\...SL', ' AR / \', ' / \ RR', ' / \', ' _ _/ \_ _ _', ' .', ' :', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ', ' ÄÄÄÙ KEY ON', '', '', '`[ON]` /\ DR', ' / \ SL', ' / \ _ _ _ _ _', ' AR / \', ' / : \ RR', ' / : \', ' _ _/ : \_ _ _', ' . :', ' : :', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ KEY OFF', ' ÄÄÄÙ KEY ON ÀÄÄÄÄÄÄÄÄÄÄÄÄ', '', '', '~Frequency data multiplier~', 'Sets the multiplier for the frequency data specified by block and', 'F-number. This multiplier is applied to the FM carrier or modulation', 'frequencies. The multiplication factor and corresonding harmonic types are', 'shown in the following table:', '', 'ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `MULT.` ³ `` ³ `HARMONiC` ³', 'ÆÍÍÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵', '³ `[0]` ³ 0.5 ³ 1 octave below ³', '³ `[1]` ³ 1 ³ at the voice''s specified frequency ³', '³ `[2]` ³ 2 ³ 1 octave above ³', '³ `[3]` ³ 3 ³ 1 octave and a 5th above ³', '³ `[4]` ³ 4 ³ 2 octaves above ³', '³ `[5]` ³ 5 ³ 2 octaves and a Major 3rd above ³', '³ `[6]` ³ 6 ³ 2 octaves and a 5th above ³', '³ `[7]` ³ 7 ³ 2 octaves and a Minor 7th above ³', '³ `[8]` ³ 8 ³ 3 octaves above ³', '³ `[9]` ³ 9 ³ 3 octaves and a Major 2nd above ³', '³ `[A]` ³ 10 ³ 3 octaves and a Major 3rd above ³', '³ `[B]` ³ 10 ³ ... ³', '³ `[C]` ³ 12 ³ 3 octaves and a 5th above ³', '³ `[D]` ³ 12 ³ ... ³', '³ `[E]` ³ 15 ³ 3 octaves and a Major 7th above ³', '³ `[F]` ³ 15 ³ ... ³', 'ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', '@topic:effects_page1', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `SUPPORTED EFFECTS` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '`0`xy ÄÄ ARPEGGiO xy=1st_tone|2nd_tone [1-F]', '`1`xx ÄÄ FREQUENCY SLiDE UP xx=speed_of_slide [1-FF]', '`2`xx ÄÄ FREQUENCY SLiDE DOWN xx=speed_of_slide [1-FF]', '`3`xx ÄÄ TONE PORTAMENTO xx=speed_of_slide [1-FF] ~C~', '`4`xy ÄÄ ViBRATO xy=speed|depth [1-F] ~C~', '`5`xy ÄÄ ~3xx~ & VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`6`xy ÄÄ ~4xy~ & VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`7`xx ÄÄ FiNE FREQUENCY SLiDE UP xx=speed_of_slide [1-FF]', '`8`xx ÄÄ FiNE FREQUENCY SLiDE DOWN xx=speed_of_slide [1-FF]', '`9`xx ÄÄ SET MODULATOR VOLUME xx=volume_level [0-3F]', '`A`xy ÄÄ VOLUME SLiDE xy=up_speed|down_speed [1-F]', '`B`xx ÄÄ POSiTiON JUMP xx=position_in_order [0-7F]', '`C`xx ÄÄ SET iNSTRUMENT VOLUME xx=volume_level [0-3F]', '`D`xx ÄÄ PATTERN BREAK xx=line_in_next_pattern [0-FF]', '`E`xx ÄÄ SET TEMPO xx=bpm_in_® [1-FF]', '`F`xx ÄÄ SET SPEED xx=frames_per_row [1-FF]', '`G`xy ÄÄ ~3xx~ & FiNE VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`H`xy ÄÄ ~4xy~ & FiNE VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`I`xx ÄÄ SET CARRiER VOLUME xx=volume_level [0-3F]', '`J`xy ÄÄ SET WAVEFORM xy=carrier|modulator [0-7,F=NiL]', '@topic:effects_page2', '`K`xy ÄÄ FiNE VOLUME SLiDE xy=up_speed|down_speed [1-F]', '`L`xx ÄÄ RETRiG NOTE xx=interval [1-FF]', '`M`xy ÄÄ TREMOLO xy=speed|depth [1-F] ~C~', '`N`xy ÄÄ TREMOR xy=on_time|off_time [1-F]', '`O`xy ÄÄ ~0xy~ & VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`P`xy ÄÄ ~0xy~ & FiNE VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`Q`xy ÄÄ MULTi RETRiG NOTE xy=interval|vol_change [1-F]', '', '`Q`x? `0` = None `8` = Unused', ' `1` = -1 `9` = +1', ' `2` = -2 `A` = +2', ' `3` = -4 `B` = +4', ' `4` = -8 `C` = +8', ' `5` = -16 `D` = +16', ' `6` = 2/3 `E` = 3/2', ' `7` = 1/2 `F` = 2', '', '`R`xy ÄÄ ~1xx~ ¿ ¿', '`S`xy ÄÄ ~2xx~ ö & ö', '`T`xy ÄÄ ~7xx~ ø VOLUME SLiDE ö', '`U`xy ÄÄ ~8xx~ Ù ö', '`V`xy ÄÄ ~1xx~ ¿ ø xy=up_speed|down_speed [1-F] ~C~', '`W`xy ÄÄ ~2xx~ ö & ö', '`X`xy ÄÄ ~7xx~ ø FiNE VOLUME SLiDE ö', '`Y`xy ÄÄ ~8xx~ Ù Ù', '', '@topic:effects_page3', '`Z`?? `0`x SET TREMOLO DEPTH x=1dB/4.8dB [0-1] ~I~', ' `1`x SET ViBRATO DEPTH x=7%/14% [0-1] ~I~', ' `2`x SET ATTACK RATE ¿ x=attack_rate [0-F] ~I~', ' `3`x SET DECAY RATE ö MOD. x=decay_rate [0-F] ~I~', ' `4`x SET SUSTAiN LEVEL ø x=sustain_level [0-F] ~I~', ' `5`x SET RELEASE RATE Ù x=release_rate [0-F] ~I~', ' `6`x SET ATTACK RATE ¿ x=attack_rate [0-F] ~I~', ' `7`x SET DECAY RATE ö CAR. x=decay_rate [0-F] ~I~', ' `8`x SET SUSTAiN LEVEL ø x=sustain_level [0-F] ~I~', ' `9`x SET RELEASE RATE Ù x=release_rate [0-F] ~I~', ' `A`x SET FEEDBACK STRENGTH x=feedback_strength [0-7] ~I~', ' `B`x SET PANNiNG POSiTiON x=panning_position [0-2] ~I~', ' `C`x PATTERN LOOP x=parameter [0-F]', ' `D`x RECURSiVE PATTERN LOOP x=parameter [0-F]', ' `E`x EXTENDED COMMANDS (1)', ' `F`x EXTENDED COMMANDS (2)', '', '`ZB`? `0` = Center', ' `1` = Left', ' `2` = Right', '`ZC`?', '`ZD`? `0` = Set loopback point', ' x = Loop ~x~ times', '', '@topic:effects_page4', '`ZE`? `0`/`1` DiSABLE/ENABLE MACRO KEY-OFF LOOP', ' `2`/`3` DiSABLE/ENABLE RESTART ENVELOPE WiTH TONE PORTAMENTO', ' `4` PERFORM RESTART ENVELOPE', ' `5`/`6` DiSABLE/ENABLE '#4#3' TRACK VOLUME LOCK', '', '`ZF`? `0` RELEASE SUSTAiNiNG SOUND', ' `1` RESET iNSTRUMENT VOLUME', ' `2`/`3` LOCK/UNLOCK TRACK VOLUME', ' `4`/`5` LOCK/UNLOCK VOLUME PEAK', ' `6` TOGGLE MODULATOR VOLUME SLiDES', ' `7` TOGGLE CARRiER VOLUME SLiDES', ' `8` TOGGLE DEFAULT VOLUME SLiDES', ' `9`/`A` LOCK/UNLOCK TRACK PANNiNG', ' `B` ViBRATO OFF', ' `C` TREMOLO OFF', ' `D` FORCE FiNE ViBRATO', ' FORCE FiNE GLOBAL FREQ. SLiDE', ' `E` FORCE FiNE TREMOLO', ' FORCE EXTRA FiNE GLOBAL FREQ. SLiDE', ' `F` FORCE NO RESTART FOR MACRO TABLES', '', '@topic:effects_page5', '`#`?? `0`x SET CONNECTiON TYPE x=FM/AM [0-1] ~I~', ' `1`x SET MULTiPLiER ¿ x=multiplier [0-F] ~I~', ' `2`x SET KSL ö x=scaling_level [0-3] ~I~', ' `3`x SET TREMOLO ö MOD. x=off/on [0-1] ~I~', ' `4`x SET ViBRATO ø x=off/on [0-1] ~I~', ' `5`x SET KSR ö x=off/on [0-1] ~I~', ' `6`x SET SUSTAiN Ù x=off/on [0-1] ~I~', ' `7`x SET MULTiPLiER ¿ x=multiplier [0-F] ~I~', ' `8`x SET KSL ö x=scaling_level [0-3] ~I~', ' `9`x SET TREMOLO ö CAR. x=off/on [0-1] ~I~', ' `A`x SET ViBRATO ø x=off/on [0-1] ~I~', ' `B`x SET KSR ö x=off/on [0-1] ~I~', ' `C`x SET SUSTAiN Ù x=off/on [0-1] ~I~', '', '@topic:effects_page6', '`&`?? `0`x PATTERN DELAY (FRAMES) x=interval [1-F]', ' `1`x PATTERN DELAY (ROWS) x=interval [1-F]', ' `2`x NOTE DELAY x=interval [1-F]', ' `3`x NOTE CUT x=interval [1-F]', ' `4`x FiNE-TUNE UP x=freq_shift [1-F]', ' `5`x FiNE-TUNE DOWN x=freq_shift [1-F]', ' `6`x GLOBAL VOLUME SLiDE UP x=speed_of_slide [1-F]', ' `7`x GLOBAL VOLUME SLiDE DOWN x=speed_of_slide [1-F]', ' `8`x FiNE ~&6x~ x=speed_of_slide [1-F]', ' `9`x FiNE ~&7x~ x=speed_of_slide [1-F]', ' `A`x EXTRA FiNE ~&6x~ x=speed_of_slide [1-F]', ' `B`x EXTRA FiNE ~&7x~ x=speed_of_slide [1-F]', ' `C`x EXTRA FiNE VSLiDE UP x=speed_of_slide [1-F]', ' `D`x EXTRA FiNE VSLiDE DOWN x=speed_of_slide [1-F]', ' `E`x EXTRA FiNE FSLiDE UP x=speed_of_slide [1-F]', ' `F`x EXTRA FiNE FSLiDE DOWN x=speed_of_slide [1-F]', '', '@topic:effects_page7', '`$`xy ÄÄ EXTRA FiNE ARPEGGiO xy=1st_tone|2nd_tone [1-F]', '`@@~xy ÄÄ EXTRA FiNE ViBRATO xy=speed|depth [1-F] ~C~', '`^`xy ÄÄ EXTRA FiNE TREMOLO xy=speed|depth [1-F] ~C~', '`!`xx ÄÄ SWAP ARPEGGiO TABLE xx=table_number [0-FF]', '`@`xx ÄÄ SWAP ViBRATO TABLE xx=table_number [0-FF]', '`=`xx ÄÄ FORCE iNSTRUMENT VOLUME xx=volume_level [0-3F]', '`%`xx ÄÄ SET GLOBAL VOLUME xx=volume_level [0-3F]', '`>`xx ÄÄ GLOBAL FREQ. SLiDE UP xx=speed_of_slide [1-FF]', '`<`xx ÄÄ GLOBAL FREQ. SLiDE DOWN xx=speed_of_slide [1-FF]', '`@@`xx ÄÄ SET CUSTOM SPEED TABLE xx=parameter [0-FF]', '', '`@@`?? `00` Reset default speed table', ' `01`-`FF` Calculate custom speed table with parameters', ' `table size`, `maximum value` and `processing speed factor`', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ¿', ' ³ PARAMETER ³ `SiZE` ³ `MAX.` ³ `FACTOR` ³', ' ÆÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͵', ' ³ `[01]`..`[EF]` ³ 32 ³ ~01~..~EF~ ³ '#7'1 ³', ' ³ `[F0]`..`[F3]` ³ ~32~ ³ FF ³ ~'#7'1~..~'#7'4~ ³', ' ³ `[F4]`..`[F7]` ³ ~64~ ³ FF ³ ~'#7'1~..~'#7'4~ ³', ' ³ `[F8]`..`[FB]` ³ ~128~ ³ FF ³ ~'#7'1~..~'#7'4~ ³', ' ³ `[FC]`..`[FF]` ³ ~256~ ³ FF ³ ~'#7'1~..~'#7'4~ ³', ' ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÙ', '', '`FURTHER NOTES:`', '', '1) Effects marked as ~C~ in the above list of commands can be continued', ' in subsequent lines by setting the parameter value to 0.', '', '2) Effects marked as ~I~ in the above list of commands do apply', ' to currently played instrument only.', '', 'For detailed information on effect commands, see the ~adtrack2.doc~ file.', '', '', ' ÄÂÄ ÄÄ', {$IFDEF GO32V2} ' /´DLiB³R/´CK3R ³³ G3', {$ELSE} ' /´DLiB³R/´CK3R ³³ SDL', {$ENDIF} ' ³ ³ ÄÄ', ' '+at2ver, '', '', '`Get the latest version from:`', 'http://www.adlibtracker.net', '', '`Contact information:`', 'E-MAiL subz3ro.altair@gmail.com', 'iCQ# 58622796', '', '`Credits:`', {$IFDEF GO32V2} 'Florian Klaempfl and others [Free Pascal Compiler 2.6.4]', 'Karoly Balogh [GO32V2 Timer Services Unit 1.1.0]', 'Haruhiko Okomura & Haruyasu Yoshizaki [LZH algorithm]', 'Markus Oberhumer, Laszlo Molnar & John Reiser [UPX 3.91d]', {$ELSE} 'Florian Klaempfl and others [Free Pascal Compiler 2.6.4]', 'Simple DirectMedia Layer [SDL 1.2.15]', 'Daniel F. Moisset [SDL4Freepascal-1.2.0.0]', 'Alexey Khokholov [NukedOPL3 1.6]', 'Haruhiko Okomura & Haruyasu Yoshizaki [LZH algorithm]', 'Markus Oberhumer, Laszlo Molnar & John Reiser [UPX 3.91w]', {$ENDIF} '', '`Honest ''thank you'' to the following people:`', 'Slawomir Bubel (Malfunction/Altair), Daniel Illgen (insane/Altair),', 'Mikkel Hastrup (encore), Florian Jung (Windfisch), Dmitry Smagin,', 'David Cohen (Diode Milliampere), Nick Balega,', 'Cecill Etheredge (ijsf), Sven Renner (NeuralNET),', 'Tyler Montbriand (Corona688), Janwillem Jagersma, PissMasterPlus,', 'and Mr. Maan M. Hamze :-)', '', '`Greetz fly to the following people:`', 'Dragan Espenschied (drx/Bodenstandig 2000), Carl Peczynski (OxygenStar),', 'Hubert Lamontagne (Madbrain), Jason Karl Warren (Televicious),', 'Vojta Nedved (nula), and all members of AT2 user group on Facebook'); procedure HELP(topic: String); procedure ShowStartMessage; implementation uses AdT2unit,AdT2sys,AdT2keyb,AdT2data, TxtScrIO,StringIO,DialogIO,ParserIO; const key_comment_B = ' C D E F G A B C D E F G A B C D E'; key_comment_H = ' C D E F G A H C D E F G A H C D E'; const shift_f5_1 = '~[Shift] F5~ @F5 with Trace'; shift_f8_1 = '~[Shift] F8~ @F8 with Trace'; shift_f9_1 = '~[Shift] F9~ @F9 with Trace'; alt_f8_1 = '~[Alt] F8~ @F8 à without synchronization'; const shift_f5_2 = '~[Shift] F5~ @F5 with no Trace'; shift_f8_2 = '~[Shift] F8~ @F8 with no Trace'; shift_f9_2 = '~[Shift] F9~ @F9 with no Trace'; alt_f8_2 = '~[Alt] F8~ @F8 à with synchronization'; procedure HELP(topic: String); var spec_attr_table: array[1..255] of Byte; temps: String; page,temp,fkey: Word; temp2: Byte; xstart,ystart,ypos,page_len: Byte; mpos: Byte; mchr: Char; new_atr1, new_atr2, new_atr3: Byte; temp_pos_atr1: Byte; temp_pos_atr2: Byte; procedure ListCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); begin temp_pos_atr1 := Pos('@@attr:',str); temp_pos_atr2 := Pos('@@spec_attr:',str); If (Pos('~@@',str) <> 0) then begin mpos := Pos('~@@',str); mchr := str[mpos+3]; Delete(str,mpos,4); Insert(' ',str,mpos); ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), atr1,atr2,atr3); ShowStr(dest,x+mpos-1,y,mchr,atr2); end else If (Pos('`@@',str) <> 0) then begin mpos := Pos('`@@',str); mchr := str[mpos+3]; Delete(str,mpos,4); Insert(' ',str,mpos); ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), atr1,atr2,atr3); ShowStr(dest,x+mpos-1,y,mchr,atr3); end else If (temp_pos_atr1 <> 0) and SameName('@@attr:??,??,??@@',Copy(str,temp_pos_atr1,17)) then begin new_atr1 := Str2num(Copy(str,temp_pos_atr1+7,2),16); If (new_atr1 = 0) then new_atr1 := atr1; new_atr2 := Str2num(Copy(str,temp_pos_atr1+10,2),16); If (new_atr2 = 0) then new_atr2 := atr2; new_atr3 := Str2num(Copy(str,temp_pos_atr1+13,2),16); If (new_atr3 = 0) then new_atr3 := atr3; Delete(str,temp_pos_atr1,17); ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), new_atr1,new_atr2,new_atr3); end else If (temp_pos_atr2 <> 0) and SameName('@@spec_attr:??@@',Copy(str,temp_pos_atr2,16)) then begin temp2 := Str2num(Copy(str,temp_pos_atr2+12,2),16); If (temp2 = 0) or (spec_attr_table[temp2] = 0) then new_atr3 := atr3 else new_atr3 := spec_attr_table[temp2]; Delete(str,temp_pos_atr2,16); ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), atr1,atr2,new_atr3); end else ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), atr1,atr2,atr3); end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2TEXT.PAS:Help'; {$ENDIF} ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; // assign special attribute values FillChar(spec_attr_table,SizeOf(spec_attr_table),0); spec_attr_table[1] := main_behavior SHL 4 AND $0f0; spec_attr_table[2] := main_hi_stat_line SHL 4 AND $0f0; HideCursor; page_len := MAX_PATTERN_ROWS+6; centered_frame(xstart,ystart,77,page_len+2,' HELP ', help_background+help_border, help_background+help_title, frame_double); page := 1; While (page <= HELP_LINES-24) and ((Copy(help_data[page],1,6) <> '@topic') or (Copy(help_data[page],8,Length(help_data[page])-7) <> topic)) do Inc(page); If (page < 1) then page := 1; If (page > HELP_LINES-page_len) then page := HELP_LINES-page_len; Repeat If (page > 1) then temps := '' else temps := '-'; If (page < HELP_LINES-page_len) then temps := temps+'' else temps := temps+'-'; ShowCStr(screen_ptr,xstart+1+74-Length(temps),ystart+page_len+2, '[~'+temps+'~]', help_background+help_border, help_background+help_indicators); ypos := ystart+1; temp := page; While (ypos <= ystart+page_len+1) and (temp <= HELP_LINES) do begin If (Copy(help_data[temp],1,6) <> '@topic') and (Copy(help_data[temp],1,6) <> '@input') then begin If (Copy(help_data[temp],1,3) <> ' º ') then ListCStr(screen_ptr,xstart+2,ypos, help_data[temp], help_background+help_text, help_background+help_keys, help_background+help_hi_text) else ListCStr(screen_ptr,xstart+2,ypos, help_data[temp], help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'key_comment') then begin If NOT use_H_for_B then ListCStr(screen_ptr,xstart+2,ypos, key_comment_B, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, key_comment_H, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'shift_f5') then begin If NOT trace_by_default then ListCStr(screen_ptr,xstart+2,ypos, shift_f5_1, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, shift_f5_2, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'shift_f8') then begin If NOT trace_by_default then ListCStr(screen_ptr,xstart+2,ypos, shift_f8_1, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, shift_f8_2, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'shift_f9') then begin If NOT trace_by_default then ListCStr(screen_ptr,xstart+2,ypos, shift_f9_1, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, shift_f9_2, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'alt_f8') then begin If NOT nosync_by_default then ListCStr(screen_ptr,xstart+2,ypos, alt_f8_1, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, alt_f8_2, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end; Inc(temp); end; fkey := getkey; Case fkey of kUP: begin If (page > 1) then Dec(page); If (Copy(help_data[page-1],1,6) = '@topic') and (page > 1) then Dec(page); end; kDOWN: begin If (Copy(help_data[page],1,6) = '@topic') and (page < HELP_LINES-page_len) then Inc(page); If (page < HELP_LINES-page_len) then Inc(page); end; kPgUP: begin If (page > page_len) then Dec(page,page_len) else page := 1; If (Copy(help_data[page-1],1,6) = '@topic') and (page > 1) then Dec(page); end; kPgDOWN: begin If (Copy(help_data[page],1,6) = '@topic') and (page < HELP_LINES-page_len) then Inc(page); If (page+page_len <= HELP_LINES-page_len) then Inc(page,page_len) else page := HELP_LINES-page_len; end; kHOME: page := 1; kEND: page := HELP_LINES-page_len; end; // draw_screen; until (fkey = kENTER) or (fkey = kESC) or _force_program_quit; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+77+2; move_to_screen_area[4] := ystart+page_len+1; move2screen; end; {$IFDEF GO32V2} procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte); begin ShowC3Str(screen_ptr,WhereX,WhereY, str, atr1,atr2,atr3); WriteLn; end; {$ELSE} procedure C3WriteLn(posX,posY: Byte; str: String; atr1,atr2,atr3: Byte); begin ShowC3Str(screen_ptr,posX,posY, str, atr1,atr2,atr3); end; {$ENDIF} procedure ShowStartMessage; begin {$IFDEF GO32V2} WriteLn; WriteLn(_ADT2_TITLE_STRING_,' coded by subz3ro/Altair'); WriteLn(' ',at2ver,' ',at2date,' ',at2link,''); WriteLn; {$ENDIF} end; end. adlibtracker2-2.4.23/parserio.pas0000644000000000000000000001660513176573532015366 0ustar rootrootunit ParserIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface function Scan(var buf; skip,size: Longint; str: String): Longint; function SensitiveScan(var buf; skip,size: Longint; str: String): Longint; function Compare(var buf1,buf2; size: Longint): Boolean; function Empty(var buf; size: Longint): Boolean; function CountLines(var buf; size: Longint): Longint; function Update16(var buf; size: Longint; crc: Word): Word; function Update32(var buf; size: Longint; crc: Longint): Longint; implementation uses StringIO; var CRC16_table: array[BYTE] of Word; CRC32_table: array[BYTE] of Longint; function Scan(var buf; skip,size: Longint; str: String): Longint; var result: Longint; begin asm lea edi,[str] mov esi,edi xor eax,eax lodsb stosb xor ecx,ecx mov ecx,eax xor ebx,ebx mov ebx,eax jecxz @@9 @@1: lodsb cmp al,'a' jb @@2 cmp al,'z' ja @@2 sub al,20h @@2: stosb loop @@1 sub edi,ebx mov esi,[buf] add esi,skip mov ecx,size sub ecx,skip jecxz @@8 cld sub ecx,ebx jb @@8 inc ecx @@4: mov ah,[edi] and ah,NOT 20h @@5: lodsb and al,NOT 20h cmp al,ah loopne @@5 jne @@8 dec esi mov edx,ecx mov ecx,ebx @@6: repe cmpsb je @@10 mov al,[esi-1] cmp al,'a' jb @@7 cmp al,'z' ja @@7 sub al,20h @@7: cmp al,[edi-1] je @@6 sub ecx,ebx add esi,ecx add edi,ecx inc esi mov ecx,edx jne @@4 @@8: xor eax,eax jmp @@11 @@9: mov eax,1 jmp @@11 @@10: sub esi,ebx mov eax,esi sub eax,dword ptr [buf] inc eax @@11: dec eax mov result,eax end; Scan := result; end; function SensitiveScan(var buf; skip,size: Longint; str: String): Longint; var result: Longint; begin asm mov edi,[buf] add edi,skip lea esi,[str] mov ecx,size sub ecx,skip xor eax,eax jecxz @@3 cld lodsb cmp al,1 jb @@5 ja @@1 lodsb repne scasb jne @@3 jmp @@5 @@1: xor ah,ah mov ebx,eax dec ebx mov edx,ecx sub edx,eax jb @@3 lodsb add edx,2 @@2: dec edx mov ecx,edx repne scasb jne @@3 mov edx,ecx mov ecx,ebx rep cmpsb je @@4 sub ecx,ebx add esi,ecx add edi,ecx inc edi or edx,edx jne @@2 @@3: xor eax,eax jmp @@6 @@4: sub edi,ebx @@5: mov eax,edi sub eax,dword ptr [buf] @@6: dec eax mov result,eax end; SensitiveScan := result; end; function Compare(var buf1,buf2; size: Longint): Boolean; var result: Boolean; begin asm xor edx,edx mov eax,size cmp eax,16 jb @@3 mov ecx,4 div ecx mov ecx,eax jecxz @@1 mov esi,[buf1] mov edi,[buf2] cld repz cmpsd jnz @@2 mov ecx,edx jecxz @@1 repz cmpsb jnz @@2 @@1: mov result,TRUE jmp @@6 @@2: mov result,FALSE jmp @@6 @@3: mov ecx,size jecxz @@4 mov esi,[buf1] mov edi,[buf2] cld repz cmpsb jnz @@5 @@4: mov result,TRUE jmp @@6 @@5: mov result,FALSE @@6: end; Compare := result; end; function Empty(var buf; size: Longint): Boolean; var result: Boolean; begin asm xor edx,edx mov eax,size cmp eax,16 jb @@3 mov ecx,4 div ecx mov ecx,eax jecxz @@1 mov edi,[buf] xor eax,eax repz scasd jnz @@2 mov ecx,edx jecxz @@1 repz scasb jnz @@2 @@1: mov result,TRUE jmp @@6 @@2: mov result,FALSE jmp @@6 @@3: mov ecx,size jecxz @@4 mov edi,[buf] xor eax,eax repz scasb jnz @@5 @@4: mov result,TRUE jmp @@6 @@5: mov result,FALSE @@6: end; Empty := result; end; function CountLines(var buf; size: Longint): Longint; var result: Longint; begin asm mov edi,[buf] mov ecx,size mov edx,edi add edx,ecx xor ebx,ebx jecxz @@3 @@1: mov al,0dh repnz scasb jnz @@3 cmp byte ptr [edi],0ah jnz @@2 inc edi inc ebx @@2: cmp edi,edx jb @@1 @@3: mov eax,ebx mov result,eax end; CountLines := result; end; function Update16(var buf; size: Longint; crc: Word): Word; var result: Word; begin asm mov esi,[buf] lea edi,[CRC16_table] mov bx,crc mov ecx,size jecxz @@2 @@1: xor ax,ax lodsb mov dl,bh xor dh,dh xor bh,bh xor bx,ax and ebx,000000ffh shl ebx,1 mov bx,[edi+ebx] xor bx,dx loop @@1 @@2: mov ax,bx mov result,ax end; Update16 := result; end; function Update32(var buf; size: Longint; crc: Longint): Longint; var result: Longint; begin asm mov esi,[buf] lea edi,[CRC32_table] mov ebx,crc mov ecx,size jecxz @@2 @@1: xor eax,eax lodsb xor ebx,eax mov edx,ebx and ebx,000000ffh shl ebx,2 mov ebx,[edi+ebx] shr edx,8 and edx,00ffffffh xor ebx,edx loop @@1 @@2: mov eax,ebx mov result,eax end; Update32 := result; end; procedure make_table_16bit; var crc: Word; n,index: Byte; begin For index := 0 to 255 do begin crc := index; For n := 1 to 8 do If Odd(crc) then crc := crc SHR 1 XOR $0a001 else crc := crc SHR 1; CRC16_table[index] := crc; end; end; procedure make_table_32bit; var crc: Dword; n,index: Byte; begin For index := 0 to 255 do begin crc := index; For n := 1 to 8 do If Odd(crc) then crc := crc SHR 1 XOR $0edb88320 else crc := crc SHR 1; CRC32_table[index] := crc; end; end; begin make_table_16bit; make_table_32bit; end. adlibtracker2-2.4.23/adt2pack.pas0000644000000000000000000007642413176573532015240 0ustar rootrootunit AdT2pack; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface function LZH_compress(var source,dest; size: Dword): Dword; function LZH_compress_ultra(var source,dest; size: Dword): Dword; function LZH_decompress(var source,dest; size: Dword): Dword; implementation uses AdT2sys,AdT2extn,AdT2unit; const { DEFAULT COMPRESSION: buffer 4k, dictionary 8kb } WIN_SIZE_DEF = 1 SHL 12; DIC_SIZE_DEF = 1 SHL 13; { ULTRA COMPRESSION: buffer 32k, dictionary 16kb } WIN_SIZE_MAX = 1 SHL 15; DIC_SIZE_MAX = 1 SHL 14; const MATCH_BIT = 8; MAX_MATCH = 1 SHL MATCH_BIT; THRESHOLD = 2; PBIT = 14; TBIT = 15; CBIT = 16; DIC_BIT = 14; CODE_BIT = 16; NC = 255 + MAX_MATCH + 2 - THRESHOLD; NP = DIC_BIT + 1; NT = CODE_BIT + 3; MAX_HASH_VAL = 3 * (1 SHL DIC_BIT) + ((1 SHL DIC_BIT) SHR 9 + 1) * 255; PERC_FLAG = 32768; const WIN_SIZE: Word = WIN_SIZE_DEF; DIC_SIZE: Word = DIC_SIZE_DEF; type pWORD = ^tWORD; tWORD = array[0..PRED((1 SHL DIC_BIT))] of Integer; pBYTE = ^tBYTE; tBYTE = array[0..PRED(2*(1 SHL DIC_BIT))] of Byte; var l_tree,r_tree: array[0..2*(NC-1)] of Word; p_table: array[0..255] of Word; p_len: array[0..PRED(NT)] of Byte; c_table: array[0..4095] of Word; c_len: array[0..PRED(NC)] of Byte; heap: array[0..NC] of Word; len_count: array[0..16] of Word; c_freq: array[0..2*(NC-1)] of Word; p_freq: array[0..2*(NP-1)] of Word; t_freq: array[0..2*(NT-1)] of Word; c_code: array[0..PRED(NC)] of Word; p_code: array[0..PRED(NT)] of Word; var freq,sort_ptr,pos_ptr: pWORD; buf,len,stream,child_count,level: pBYTE; parent,previous,next: pWORD; bits,heap_size,remain, dec_counter,match_len: Integer; bit_buf,sbit_buf,bit_count, block_size,depth,c_pos,pos,out_pos, match_pos,dec_ptr,out_mask,avail: Word; input_buffer,output_buffer: pGENERIC_IO_BUFFER; input_buffer_idx,output_buffer_idx: Dword; size_unpacked,input_buffer_size: Dword; function ReadDataBlock(ptr: Pointer; size: Word): Word; var result: Word; begin If (input_buffer_size-input_buffer_idx >= size) then result := size else result := input_buffer_size-input_buffer_idx; Move(input_buffer^[input_buffer_idx],ptr^,result); Inc(input_buffer_idx,result); ReadDataBlock := result; If NOT really_no_status_refresh then show_progress(input_buffer_idx); end; procedure WriteDataBlock(ptr: Pointer; size: Word); begin Move(ptr^,output_buffer^[output_buffer_idx],size); Inc(output_buffer_idx,size); If NOT really_no_status_refresh then show_progress(output_buffer_idx); end; procedure FillBitBuffer(bits: Integer); begin bit_buf := (bit_buf SHL bits); While (bits > bit_count) do begin Dec(bits,bit_count); bit_buf := bit_buf OR (sbit_buf SHL bits); If (input_buffer_idx <= input_buffer_size) then begin sbit_buf := input_buffer^[input_buffer_idx]; Inc(input_buffer_idx); end else sbit_buf := 0; bit_count := 8; end; Dec(bit_count,bits); bit_buf := bit_buf OR (sbit_buf SHR bit_count); end; function GetBits(bits: Integer): Word; begin GetBits := bit_buf SHR (16-bits); FillBitBuffer(bits); end; procedure PutBits(bits: Integer; xbits: Word); begin If (bits < bit_count) then begin Dec(bit_count,bits); sbit_buf := sbit_buf OR (xbits SHL bit_count); end else begin Dec(bits,bit_count); output_buffer^[output_buffer_idx] := sbit_buf OR (xbits SHR bits); Inc(output_buffer_idx); If (bits < 8) then begin bit_count := 8-bits; sbit_buf := xbits SHL bit_count; end else begin output_buffer^[output_buffer_idx] := xbits SHR (bits-8); Inc(output_buffer_idx); bit_count := 16-bits; sbit_buf := xbits SHL bit_count; end; end; end; procedure MakeTable(n_char: Integer; bit_len: pBYTE; bits: Integer; table: pWORD); var count,weight: array[1..16] of Word; start: array[1..17] of Word; idx,idx2,len,chr,j_bits,avail,next_c,mask: Integer; ptr: pWORD; begin FillChar(count,SizeOf(count),0); FillChar(weight,SizeOf(weight),0); FillChar(start,SizeOf(start),0); For idx := 0 to PRED(n_char) do Inc(count[bit_len^[idx]]); start[1] := 0; For idx := 1 to 16 do start[SUCC(idx)] := start[idx]+(count[idx] SHL (16-idx)); j_bits := 16-bits; For idx := 1 to bits do begin start[idx] := start[idx] SHR j_bits; weight[idx] := 1 SHL (bits-idx); end; idx := SUCC(bits); While (idx <= 16) do begin weight[idx] := 1 SHL (16-idx); Inc(idx); end; idx := start[SUCC(bits)] SHR j_bits; If (idx <> 0) then begin idx2 := 1 SHL bits; If (idx <> idx2) then begin FillWord(table^[idx],idx2-idx,0); idx := idx2; end; end; avail := n_char; mask := 1 SHL (15-bits); For chr := 0 to PRED(n_char) do begin len := bit_len^[chr]; If (len = 0) then CONTINUE; idx2 := start[len]; next_c := idx2+weight[len]; If (len <= bits) then For idx := idx2 to PRED(next_c) do table^[idx] := chr else begin ptr := Addr(table^[WORD(idx2) SHR j_bits]); idx := len-bits; While (idx <> 0) do begin If (ptr^[0] = 0) then begin r_tree[avail] := 0; l_tree[avail] := 0; ptr^[0] := avail; Inc(avail); end; If (idx2 AND mask <> 0) then ptr := Addr(r_tree[ptr^[0]]) else ptr := Addr(l_tree[ptr^[0]]); idx2 := idx2 SHL 1; Dec(idx); end; ptr^[0] := chr; end; start[len] := next_c; end; end; procedure ReadPtrLen(n_char,n_bit,i_bit: Integer); var idx,chr,bits: Integer; mask: Word; begin bits := GetBits(n_bit); If (bits = 0) then begin chr := GetBits(n_bit); FillChar(p_len,SizeOf(p_len),0); FillWord(p_table,SizeOf(p_table) DIV 2,chr); end else begin idx := 0; While (idx < bits) do begin chr := bit_buf SHR (16-3); If (chr = 7) then begin mask := 1 SHL (16-4); While (mask AND bit_buf <> 0) do begin mask := mask SHR 1; Inc(chr); end; end; If (chr < 7) then FillBitBuffer(3) else FillBitBuffer(chr-3); p_len[idx] := chr; Inc(idx); If (idx = i_bit) then begin chr := PRED(GetBits(2)); While (chr >= 0) do begin p_len[idx] := 0; Inc(idx); Dec(chr); end; end; end; If (idx < n_char) then begin FillWord(p_len[idx],n_char-idx,0); idx := n_char; end; MakeTable(n_char,@p_len,8,@p_table); end; end; procedure ReadCharLen; var idx,chr,bits: Integer; mask: Word; begin bits := GetBits(CBIT); If (bits = 0) then begin chr := GetBits(CBIT); FillChar(c_len,SizeOf(c_len),0); FillWord(c_table,SizeOf(c_table) DIV 2,chr); end else begin idx := 0; While (idx < bits) do begin chr := p_table[bit_buf SHR (16-8)]; If (chr >= NT) then begin mask := 1 SHL (16-9); Repeat If (bit_buf AND mask <> 0) then chr := r_tree[chr] else chr := l_tree[chr]; mask := mask SHR 1; until (chr < NT); end; FillBitBuffer(p_len[chr]); If (chr <= 2) then begin If (chr = 1) then chr := 2+GetBits(4) else If (chr = 2) then chr := 19+GetBits(CBIT); While (chr >= 0) do begin c_len[idx] := 0; Inc(idx); Dec(chr); end; end else begin c_len[idx] := chr-2; Inc(idx); end; end; While (idx < NC) do begin c_len[idx] := 0; Inc(idx); end; MakeTable(NC,@c_len,12,@c_table); end; end; function DecodeChar: Word; var chr,mask: Word; begin If (block_size = 0) then begin block_size := GetBits(16); ReadPtrLen(NT,TBIT,3); ReadCharLen; ReadPtrLen(NP,PBIT,-1); end; Dec(block_size); chr := c_table[bit_buf SHR (16-12)]; If (chr >= NC) then begin mask := 1 SHL (16-13); Repeat If (bit_buf AND mask <> 0) then chr := r_tree[chr] else chr := l_tree[chr]; mask := mask SHR 1; until (chr < NC); end; FillBitBuffer(c_len[chr]); DecodeChar := chr; end; function DecodePtr: Word; var ptr,mask: Word; begin ptr := p_table[bit_buf SHR (16-8)]; If (ptr >= NP) then begin mask := 1 SHL (16-9); Repeat If (bit_buf AND mask <> 0) then ptr := r_tree[ptr] else ptr := l_tree[ptr]; mask := mask SHR 1; until (ptr < NP); end; FillBitBuffer(p_len[ptr]); If (ptr <> 0) then begin Dec(ptr); ptr := (1 SHL ptr)+GetBits(ptr); end; DecodePtr := ptr; end; procedure DecodeBuffer(count: Word; buffer: pBYTE); var idx,idx2: Word; begin idx2 := 0; Dec(dec_counter); While (dec_counter >= 0) do begin buffer^[idx2] := buffer^[dec_ptr]; dec_ptr := SUCC(dec_ptr) AND PRED(DIC_SIZE); Inc(idx2); If (idx2 = count) then EXIT; Dec(dec_counter); end; Repeat idx := DecodeChar; If (idx <= 255) then begin buffer^[idx2] := idx; Inc(idx2); If (idx2 = count) then EXIT; end else begin dec_counter := idx-(256-THRESHOLD); dec_ptr := (idx2-DecodePtr-1) AND PRED(DIC_SIZE); Dec(dec_counter); While (dec_counter >= 0) do begin buffer^[idx2] := buffer^[dec_ptr]; dec_ptr := SUCC(dec_ptr) AND PRED(DIC_SIZE); Inc(idx2); If (idx2 = count) then EXIT; Dec(dec_counter); end; end; until FALSE; end; function LZH_decompress(var source,dest; size: Dword): Dword; var ptr: pBYTE; size_temp: Dword; ultra_compression_flag: Boolean; begin LZH_decompress := 0; input_buffer := Addr(source); input_buffer_idx := 0; ultra_compression_flag := BOOLEAN(input_buffer^[input_buffer_idx]); Inc(input_buffer_idx); input_buffer_size := size; output_buffer := Addr(dest); output_buffer_idx := 0; Move(input_buffer^[input_buffer_idx],size_unpacked,SizeOf(size_unpacked)); Inc(input_buffer_idx,SizeOf(size_unpacked)); size := size_unpacked; progress_old_value := BYTE_NULL; progress_value := size; If ultra_compression_flag then begin WIN_SIZE := WIN_SIZE_MAX; DIC_SIZE := DIC_SIZE_MAX; end else begin WIN_SIZE := WIN_SIZE_DEF; DIC_SIZE := DIC_SIZE_DEF; end; GetMem(ptr,DIC_SIZE); bit_buf := 0; sbit_buf := 0; bit_count := 0; FillBitBuffer(16); block_size := 0; dec_counter := 0; While (size > 0) do begin If (size > DIC_SIZE) then size_temp := DIC_SIZE else size_temp := size; DecodeBuffer(size_temp,ptr); WriteDataBlock(ptr,size_temp); Dec(size,size_temp); end; FreeMem(ptr,DIC_SIZE); LZH_decompress := size_unpacked; end; procedure CountLen(idx: Integer); begin If (idx < bits) then If (depth < 16) then Inc(len_count[depth]) else Inc(len_count[16]) else begin Inc(depth); CountLen(l_tree[idx]); CountLen(r_tree[idx]); Dec(depth); end; end; procedure MakeLen(root: Integer); var idx,idx2: Integer; sum: Word; begin FillChar(len_count,SizeOf(len_count),0); CountLen(root); sum := 0; For idx := 16 downto 1 do Inc(sum,len_count[idx] SHL (16-idx)); While (sum <> 0) do begin Dec(len_count[16]); For idx := 15 downto 1 do If (len_count[idx] <> 0) then begin Dec(len_count[idx]); Inc(len_count[SUCC(idx)],2); BREAK; end; Dec(sum); end; For idx := 16 downto 1 do begin idx2 := PRED(len_count[idx]); While (idx2 >= 0) do begin Dec(idx2); len^[sort_ptr^[0]] := idx; sort_ptr := Addr(sort_ptr^[1]); end; end; end; procedure DownHeap(idx: Integer); var idx2,idx3: Integer; begin idx2 := heap[idx]; idx3 := idx SHL 1; While (idx3 <= heap_size) do begin If (idx3 < heap_size) and (freq^[heap[idx3]] > freq^[heap[SUCC(idx3)]]) then Inc(idx3); If (freq^[idx2] <= freq^[heap[idx3]]) then BREAK; heap[idx] := heap[idx3]; idx := idx3; idx3 := idx SHL 1; end; heap[idx] := idx2; end; procedure MakeCode(bits: Integer; len: pBYTE; code: pWORD); var idx,idx2: Integer; start: array[0..17] of Word; begin start[1] := 0; For idx := 1 to 16 do start[SUCC(idx)] := (start[idx]+len_count[idx]) SHL 1; For idx := 0 to PRED(bits) do begin idx2 := len^[idx]; code^[idx] := start[idx2]; Inc(start[idx2]); end; end; function MakeTree(n_par: Integer; f_par: pWORD; l_par: pBYTE; c_par: pWORD): Integer; var idx,idx2,idx3,avail: Integer; begin bits := n_par; freq := f_par; len := l_par; avail := bits; heap_size := 0; heap[1] := 0; For idx := 0 to PRED(bits) do begin len^[idx] := 0; If (freq^[idx] <> 0) then begin Inc(heap_size); heap[heap_size] := idx; end; end; If (heap_size < 2) then begin c_par^[heap[1]] := 0; MakeTree := heap[1]; EXIT; end; For idx := (heap_size DIV 2) downto 1 do DownHeap(idx); sort_ptr := c_par; Repeat idx := heap[1]; If (idx < bits) then begin sort_ptr^[0] := idx; sort_ptr := Addr(sort_ptr^[1]); end; heap[1] := heap[heap_size]; Dec(heap_size); DownHeap(1); idx3 := heap[1]; If (idx3 < bits) then begin sort_ptr^[0] := idx3; sort_ptr := Addr(sort_ptr^[1]); end; idx2 := avail; Inc(avail); freq^[idx2] := freq^[idx]+freq^[idx3]; heap[1] := idx2; DownHeap(1); l_tree[idx2] := idx; r_tree[idx2] := idx3; until (heap_size <= 1); sort_ptr := c_par; MakeLen(idx2); MakeCode(n_par,l_par,c_par); MakeTree := idx2; end; procedure CountFreq; var idx,idx2,bits,count: Integer; begin For idx := 0 to PRED(NT) do t_freq[idx] := 0; bits := NC; While (bits > 0) and (c_len[PRED(bits)] = 0) do Dec(bits); idx := 0; While (idx < bits) do begin idx2 := c_len[idx]; Inc(idx); If (idx2 = 0) then begin count := 1; While (idx < bits) and (c_len[idx] = 0) do begin Inc(idx); Inc(count); end; If (count <= 2) then Inc(t_freq[0],count) else If (count <= 18) then Inc(t_freq[1]) else If (count = 19) then begin Inc(t_freq[0]); Inc(t_freq[1]); end else Inc(t_freq[2]); end else Inc(t_freq[idx2+2]); end; end; procedure WritePtrLen(bits,n_bit,s_bit: Integer); var idx,idx2: Integer; begin While (bits > 0) and (p_len[PRED(bits)] = 0) do Dec(bits); PutBits(n_bit,bits); idx := 0; While (idx < bits) do begin idx2 := p_len[idx]; Inc(idx); If (idx2 <= 6) then PutBits(3,idx2) else begin Dec(idx2,3); PutBits(idx2,(1 SHL idx2)-2); end; If (idx = s_bit) then begin While (idx < 6) and (p_len[idx] = 0) do Inc(idx); PutBits(2,(idx-3) AND 3); end; end; end; procedure WriteCharLen; var idx,idx2,bits,count: Integer; begin bits := NC; While (bits > 0) and (c_len[PRED(bits)] = 0) do Dec(bits); PutBits(CBIT,bits); idx := 0; While (idx < bits) do begin idx2 := c_len[idx]; Inc(idx); If (idx2 = 0) then begin count := 1; While (idx < bits) and (c_len[idx] = 0) do begin Inc(idx); Inc(count); end; If (count <= 2) then For idx2 := 0 to PRED(count) do PutBits(p_len[0],p_code[0]) else If (count <= 18) then begin PutBits(p_len[1],p_code[1]); PutBits(4,Count-3); end else If (count = 19) then begin PutBits(p_len[0],p_code[0]); PutBits(p_len[1],p_code[1]); PutBits(4,15); end else begin PutBits(p_len[2],p_code[2]); PutBits(CBIT,count-20); end; end else PutBits(p_len[idx2+2],p_code[idx2+2]); end; end; procedure EncodePtr(ptr: Word); var idx,idx2: Word; begin idx := 0; idx2 := ptr; While (idx2 <> 0) do begin idx2 := idx2 SHR 1; Inc(idx); end; PutBits(p_len[idx],p_code[idx]); If (idx > 1) then PutBits(PRED(idx),ptr AND (PRED(1 SHL 16) SHR (17-idx))); end; procedure SendBlock; var idx,idx2,flags, root,pos,size: Word; begin root := MakeTree(NC,@c_freq,@c_len,@c_code); Size := c_freq[root]; PutBits(16,size); If (root >= NC) then begin CountFreq; root := MakeTree(NT,@t_freq,@p_len,@p_code); If (root >= NT) then WritePtrLen(NT,TBIT,3) else begin PutBits(TBIT,0); PutBits(TBIT,root); end; WriteCharLen; end else begin PutBits(TBIT,0); PutBits(TBIT,0); PutBits(CBIT,0); PutBits(CBIT,root); end; root := MakeTree(NP,@p_freq,@p_len,@p_code); If (root >= NP) then WritePtrLen(NP,PBIT,-1) else begin PutBits(PBIT,0); PutBits(PBIT,root); end; pos := 0; For idx := 0 to PRED(size) do begin If (idx AND 7 = 0) then begin flags := buf^[pos]; Inc(pos); end else flags:=flags SHL 1; If (flags AND (1 SHL 7) <> 0) then begin idx2 := buf^[pos]+(1 SHL 8); Inc(pos); PutBits(c_len[idx2],c_code[idx2]); idx2 := buf^[pos] SHL 8; Inc(pos); Inc(idx2,buf^[pos]); Inc(pos); EncodePtr(idx2); end else begin idx2 := buf^[pos]; Inc(pos); PutBits(c_len[idx2],c_code[idx2]); end; end; For idx := 0 to PRED(NC) do c_freq[idx] := 0; For idx := 0 to PRED(NP) do p_freq[idx] := 0; end; procedure Output(code,c_ptr: Word); begin out_mask := out_mask SHR 1; If (out_mask = 0) then begin out_mask := 1 SHL 7; If (out_pos >= WIN_SIZE-24) then begin SendBlock; out_pos := 0; end; c_pos := out_pos; Inc(out_pos); buf^[c_pos] := 0; end; buf^[out_pos] := code; Inc(out_pos); Inc(c_freq[code]); If (code >= 1 SHL 8) then begin buf^[c_pos] := buf^[c_pos] OR out_mask; buf^[out_pos] := c_ptr SHR 8; Inc(out_pos); buf^[out_pos] := c_ptr; Inc(out_pos); code := 0; While (c_ptr <> 0) do begin c_ptr := c_ptr SHR 1; Inc(code); end; Inc(p_freq[code]); end; end; procedure InitSlide; var idx: Word; begin For idx := DIC_SIZE to (DIC_SIZE+255) do begin level^[idx] := 1; pos_ptr^[idx] := 0; end; For idx := DIC_SIZE to PRED(2*DIC_SIZE) do parent^[idx] := 0; avail := 1; For idx := 1 to DIC_SIZE-2 do next^[idx] := SUCC(idx); next^[PRED(DIC_SIZE)] := 0; For idx := (2*DIC_SIZE) to MAX_HASH_VAL do next^[idx] := 0; end; function Child(pnode: Integer; chr: Byte): Integer; var node: Integer; begin node := next^[pnode+(chr SHL (DIC_BIT-9))+2*DIC_SIZE]; parent^[0] := pnode; While (parent^[node] <> pnode) do node := next^[node]; Child := node; end; procedure MakeChild(p_node: Integer; chr: Byte; c_node: Integer); var idx,idx2: Integer; begin idx := p_node+(chr SHL (DIC_BIT-9))+2*DIC_SIZE; idx2 := next^[idx]; next^[idx] := c_node; next^[c_node] := idx2; previous^[idx2] := c_node; previous^[c_node] := idx; parent^[c_node] := p_node; Inc(child_count^[p_node]); end; procedure SplitTree(old: Integer); var new,idx: Integer; begin new := avail; avail := next^[new]; child_count^[new] := 0; idx := previous^[old]; previous^[new] := idx; next^[idx] := new; idx := next^[old]; next^[new] := idx; previous^[idx] := new; parent^[new] := parent^[old]; level^[new] := match_len; pos_ptr^[new] := pos; MakeChild(new,stream^[match_pos+match_len],old); MakeChild(new,stream^[pos+match_len],pos); end; procedure InsertNode; var idx,idx2,idx3,idx4: Integer; chr: Byte; ptr1,ptr2: pCHAR; begin If (match_len >= 4) then begin Dec(match_len); idx2 := SUCC(match_pos) OR DIC_SIZE; idx := parent^[idx2]; While (idx = 0) do begin idx2 := next^[idx2]; idx := parent^[idx2]; end; While (level^[idx] >= match_len) do begin idx2 := idx; idx :=parent^[idx]; end; idx4 := idx; While (pos_ptr^[idx4] < 0) do begin pos_ptr^[idx4] := pos; idx4 := parent^[idx4]; end; If (idx4 < DIC_SIZE) then pos_ptr^[idx4] := pos OR PERC_FLAG; end else begin idx := stream^[pos]+DIC_SIZE; chr := stream^[SUCC(pos)]; idx2 := Child(idx,chr); If (idx2 = 0) then begin MakeChild(idx,chr,pos); match_len := 1; EXIT; end; match_len := 2; end; Repeat If (idx2 >= DIC_SIZE) then begin idx3 := MAX_MATCH; match_pos := idx2; end else begin idx3 := level^[idx2]; match_pos := pos_ptr^[idx2] AND NOT (1 SHL 15); end; If (match_pos >= pos) then Dec(match_pos,DIC_SIZE); ptr1 := Addr(stream^[pos+match_len]); ptr2 := Addr(stream^[match_pos+match_len]); While (match_len < idx3) do begin If (ptr1^ <> ptr2^) then begin SplitTree(idx2); EXIT; end; Inc(match_len); Inc(ptr1); Inc(ptr2); end; If (match_len >= MAX_MATCH) then BREAK; pos_ptr^[idx2] := pos; idx := idx2; idx2 := Child(idx,ORD(ptr1^)); If (idx2 = 0) then begin MakeChild(idx,ORD(ptr1^),pos); EXIT; end; Inc(match_len); until FALSE; idx4 := previous^[idx2]; previous^[pos] := idx4; next^[idx4] := pos; idx4 := next^[idx2]; next^[pos] := idx4; previous^[idx4] := pos; parent^[pos] := idx; parent^[idx2] := 0; next^[idx2] := pos; end; procedure DeleteNode; var idx,idx2,idx3,idx4: Integer; perc_idx: Integer; begin If (parent^[pos] = 0) then EXIT; idx := previous^[pos]; idx2 := next^[pos]; next^[idx] := idx2; previous^[idx2] := idx; idx := parent^[pos]; parent^[pos] := 0; Dec(child_count^[idx]); If (idx >= DIC_SIZE) or (child_count^[idx] > 1) then EXIT; idx3 := pos_ptr^[idx] AND NOT PERC_FLAG; If (idx3 >= pos) then Dec(idx3,DIC_SIZE); idx2 := idx3; perc_idx := parent^[idx]; idx4 := pos_ptr^[perc_idx]; While (idx4 AND PERC_FLAG <> 0) do begin idx4 := idx4 AND NOT PERC_FLAG; If (idx4 >= pos) then Dec(idx4,DIC_SIZE); If (idx4 > idx2) then idx2 := idx4; pos_ptr^[perc_idx] := idx2 OR DIC_SIZE; perc_idx := parent^[perc_idx]; idx4 := pos_ptr^[perc_idx]; end; If (perc_idx < DIC_SIZE) then begin If (idx4 >= pos) then Dec(idx4,DIC_SIZE); If (idx4 > idx2) then idx2 := idx4; pos_ptr^[perc_idx] := idx2 OR DIC_SIZE OR PERC_FLAG; end; idx2 := Child(idx,stream^[idx3+level^[idx]]); idx3 := previous^[idx2]; idx4 := next^[idx2]; next^[idx3] := idx4; previous^[idx4] := idx3; idx3 := previous^[idx]; next^[idx3] := idx2; previous^[idx2] := idx3; idx3 := next^[idx]; previous^[idx3] := idx2; next^[idx2] := idx3; parent^[idx2] := parent^[idx]; parent^[idx] := 0; next^[idx] := avail; avail := idx; end; procedure GetNextMatch; var bits: Integer; begin Dec(remain); Inc(pos); If (pos = 2*DIC_SIZE) then begin Move(stream^[DIC_SIZE],stream^[0],DIC_SIZE+MAX_MATCH); bits := ReadDataBlock(Addr(stream^[DIC_SIZE+MAX_MATCH]),DIC_SIZE); Inc(remain,bits); pos := DIC_SIZE; end; DeleteNode; InsertNode; end; function LZH_compress(var source,dest; size: Dword): Dword; var last_match_len,last_match_pos: Integer; begin LZH_compress := 0; input_buffer := Addr(source); input_buffer_idx := 0; input_buffer_size := size; output_buffer := Addr(dest); output_buffer_idx := 0; output_buffer^[input_buffer_idx] := 0; // set 'default' compression flag Inc(output_buffer_idx); Move(size,output_buffer^[output_buffer_idx],SizeOf(size)); Inc(output_buffer_idx,SizeOf(size)); progress_old_value := BYTE_NULL; progress_value := size; WIN_SIZE := WIN_SIZE_DEF; DIC_SIZE := DIC_SIZE_DEF; GetMem(stream,2*DIC_SIZE+MAX_MATCH); GetMem(level,DIC_SIZE+256); GetMem(child_count,DIC_SIZE+256); GetMem(pos_ptr,(DIC_SIZE+256) SHL 1); GetMem(parent,(DIC_SIZE*2) SHL 1); GetMem(previous,(DIC_SIZE*2) SHL 1); GetMem(next,(MAX_HASH_VAL+1) SHL 1); depth := 0; InitSlide; GetMem(buf,WIN_SIZE); buf^[0] := 0; FillChar(c_freq,SizeOf(c_freq),0); FillChar(p_freq,SizeOf(p_freq),0); out_pos := 0; out_mask := 0; bit_count := 8; sbit_buf := 0; remain := ReadDataBlock(Addr(stream^[DIC_SIZE]),DIC_SIZE+MAX_MATCH); match_len := 0; pos := DIC_SIZE; InsertNode; If (match_len > remain) then match_len := remain; While (remain > 0) do begin last_match_len := match_len; last_match_pos := match_pos; GetNextMatch; If (match_len > remain) then match_len := remain; If (match_len > last_match_len) or (last_match_len < THRESHOLD) then Output(stream^[PRED(pos)],0) else begin Output(last_match_len+(256-THRESHOLD),(pos-last_match_pos-2) AND PRED(DIC_SIZE)); Dec(last_match_len); While (last_match_len > 0) do begin GetNextMatch; Dec(last_match_len); end; If (match_len > remain) then match_len := remain; end; end; SendBlock; PutBits(7,0); FreeMem(buf,WIN_SIZE); FreeMem(next,(MAX_HASH_VAL+1) SHL 1); FreeMem(previous,(DIC_SIZE*2) SHL 1); FreeMem(parent,(DIC_SIZE*2) SHL 1); FreeMem(pos_ptr,(DIC_SIZE+256) SHL 1); FreeMem(child_count,DIC_SIZE+256); FreeMem(level,DIC_SIZE+256); FreeMem(stream,2*DIC_SIZE+MAX_MATCH); LZH_compress := output_buffer_idx; end; function LZH_compress_ultra(var source,dest; size: Dword): Dword; var last_match_len,last_match_pos: Integer; begin LZH_compress_ultra := 0; input_buffer := Addr(source); input_buffer_idx := 0; input_buffer_size := size; output_buffer := Addr(dest); output_buffer_idx := 0; output_buffer^[input_buffer_idx] := 1; // set 'ultra' compression flag Inc(output_buffer_idx); Move(size,output_buffer^[output_buffer_idx],SizeOf(size)); Inc(output_buffer_idx,SizeOf(size)); progress_old_value := BYTE_NULL; progress_value := size; WIN_SIZE := WIN_SIZE_MAX; DIC_SIZE := DIC_SIZE_MAX; GetMem(stream,2*DIC_SIZE+MAX_MATCH); GetMem(level,DIC_SIZE+256); GetMem(child_count,DIC_SIZE+256); GetMem(pos_ptr,(DIC_SIZE+256) SHL 1); GetMem(parent,(DIC_SIZE*2) SHL 1); GetMem(previous,(DIC_SIZE*2) SHL 1); GetMem(next,(MAX_HASH_VAL+1) SHL 1); depth := 0; InitSlide; GetMem(buf,WIN_SIZE); buf^[0] := 0; FillChar(c_freq,SizeOf(c_freq),0); FillChar(p_freq,SizeOf(p_freq),0); out_pos := 0; out_mask := 0; bit_count := 8; sbit_buf := 0; remain := ReadDataBlock(Addr(stream^[DIC_SIZE]),DIC_SIZE+MAX_MATCH); match_len := 0; pos := DIC_SIZE; InsertNode; If (match_len > remain) then match_len := remain; While (remain > 0) do begin last_match_len := match_len; last_match_pos := match_pos; GetNextMatch; If (match_len > remain) then match_len := remain; If (match_len > last_match_len) or (last_match_len < THRESHOLD) then Output(stream^[PRED(pos)],0) else begin Output(last_match_len+(256-THRESHOLD),(pos-last_match_pos-2) AND PRED(DIC_SIZE)); Dec(last_match_len); While (last_match_len > 0) do begin GetNextMatch; Dec(last_match_len); end; If (match_len > remain) then match_len := remain; end; end; SendBlock; PutBits(7,0); FreeMem(buf,WIN_SIZE); FreeMem(next,(MAX_HASH_VAL+1) SHL 1); FreeMem(previous,(DIC_SIZE*2) SHL 1); FreeMem(parent,(DIC_SIZE*2) SHL 1); FreeMem(pos_ptr,(DIC_SIZE+256) SHL 1); FreeMem(child_count,DIC_SIZE+256); FreeMem(level,DIC_SIZE+256); FreeMem(stream,2*DIC_SIZE+MAX_MATCH); LZH_compress_ultra := output_buffer_idx; end; end. adlibtracker2-2.4.23/lgpl-2.1.txt0000644000000000000000000006461713176573532015040 0ustar rootroot GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! adlibtracker2-2.4.23/adt2keyb.pas0000644000000000000000000006612313176573532015247 0ustar rootrootunit AdT2keyb; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface {$IFDEF GO32V2} {$MODE FPC} const keyboard_sleep: Boolean = FALSE; CTRL_ALT_DEL_pressed: Boolean = FALSE; _ctrl_pressed: Boolean = FALSE; _2x_ctrl_pressed: Boolean = FALSE; {$ENDIF} procedure keyboard_init; procedure keyboard_done; procedure keyboard_reset_buffer; procedure wait_until_F11_F12_released; procedure keyboard_poll_input; function keypressed: Boolean; function getkey: Word; function scankey(scancode: Byte): Boolean; function CapsLock: Boolean; function NumLock: Boolean; function shift_pressed: Boolean; function left_shift_pressed: Boolean; function right_shift_pressed: Boolean; function alt_pressed: Boolean; function ctrl_pressed: Boolean; function ctrl_tab_pressed: Boolean; function LookUpKey(key: Word; var table; size: Byte): Boolean; procedure screen_saver; {$IFDEF GO32V2} procedure keyboard_reset_buffer_alt; procedure keyboard_toggle_sleep; function ScrollLock: Boolean; function both_shifts_pressed: Boolean; {$ENDIF} implementation uses {$IFNDEF UNIX} CRT, {$ENDIF} DOS, {$IFDEF GO32V2} GO32, {$ELSE} SDL_Types,SDL_Timer,SDL_Events,SDL_Keyboard, {$ENDIF} AdT2unit,AdT2sys,AdT2ext2, TxtScrIO,DialogIO,ParserIO; var {$IFDEF GO32V2} keydown: array[0..127] of Boolean; {$ELSE} keydown: array[0..255] of Boolean; {$ENDIF} {$IFDEF GO32V2} var oldint09_handler: tSegInfo; newint09_handler: tSegInfo; user_proc_ptr: Pointer; backupDS_adt2keyb: Word; EXTERNAL NAME '___v2prt0_ds_alias'; procedure newint09_proc; assembler; asm cli push ds push es push fs push gs pushad mov ax,cs:[backupDS_adt2keyb] mov ds,ax mov es,ax mov ax,DosMemSelector mov fs,ax call dword ptr [user_proc_ptr] popad pop gs pop fs pop es pop ds jmp cs:[oldint09_handler] end; procedure newint09_proc_end; begin end; procedure int09_user_proc; forward; procedure int09_user_proc_end; forward; {$ELSE} const _numlock: Boolean = FALSE; _capslock: Boolean = FALSE; var keystate: ^BoolArray; varnum: Longint; {$ENDIF} procedure keyboard_init; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:keyboard_init'; FillChar(keydown,SizeOf(keydown),FALSE); user_proc_ptr := @int09_user_proc; lock_data(user_proc_ptr,SizeOf(user_proc_ptr)); lock_data(DosMemSelector,SizeOf(DosMemSelector)); lock_code(@int09_user_proc,DWORD(@int09_user_proc_end)-DWORD(@int09_user_proc)); lock_code(@newint09_proc,DWORD(@newint09_proc_end)-DWORD(@newint09_proc)); newint09_handler.offset := @newint09_proc; newint09_handler.segment := get_cs; get_pm_interrupt($09,oldint09_handler); set_pm_interrupt($09,newint09_handler); {$ELSE} SDL_EnableKeyRepeat(sdl_typematic_delay,sdl_typematic_rate); keystate := SDL_GetKeyState(varnum); {$ENDIF} end; procedure keyboard_done; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:keyboard_done'; set_pm_interrupt($09,oldint09_handler); unlock_data(DosMemSelector,SizeOf(DosMemSelector)); unlock_data(user_proc_ptr,SizeOf(user_proc_ptr)); unlock_code(@int09_user_proc,DWORD(@int09_user_proc_end)-DWORD(@int09_user_proc)); lock_code(@newint09_proc,DWORD(@newint09_proc_end)-DWORD(@newint09_proc)); keyboard_reset_buffer; {$ENDIF} end; {$IFDEF GO32V2} function keypressed: Boolean; begin realtime_gfx_poll_proc; draw_screen; // filter out CTRL+TAB combo as it is handled within timer routine If ctrl_tab_pressed then begin keyboard_reset_buffer; keypressed := FALSE; end else keypressed := CRT.KeyPressed; end; function getkey: Word; var result: Word; key_c,scan_c: Byte; begin no_status_refresh := FALSE; While NOT keypressed do begin realtime_gfx_poll_proc; draw_screen; If (seconds_counter >= ssaver_time) then screen_saver; end; key_c := BYTE(CRT.ReadKey); If (key_c = 0) then result := BYTE(CRT.ReadKey) SHL 8 else begin scan_c := inportb($60); If (scan_c > $80) then scan_c := scan_c-$80; result := key_c+(scan_c SHL 8); end; getkey := result; end; function scankey(scancode: Byte): Boolean; begin scankey := keydown[scancode]; end; {$ASMMODE INTEL} procedure int09_user_proc; assembler; asm push eax push ebx push es push ds call process_global_keys pop ds pop es mov dword ptr [seconds_counter],0 in al,60h xor ebx,ebx mov bx,ax and bx,007fh and al,80h jz @@4 @@1: mov byte ptr keydown[ebx],0 cmp ebx,1dh // [Ctrl] jnz @@3 cmp byte ptr [_ctrl_pressed],1 jnz @@2 mov byte ptr [_2x_ctrl_pressed],1 @@2: mov byte ptr [_ctrl_pressed],1 @@3: jmp @@5 @@4: mov byte ptr keydown[ebx],1 cmp ebx,1dh // [Ctrl] jz @@5 mov byte ptr [_ctrl_pressed],0 mov byte ptr [_2x_ctrl_pressed],0 @@5: cmp keyboard_sleep,1 jz @@10 cmp byte ptr keydown[1dh],1 // [Ctrl] jnz @@6 cmp byte ptr keydown[38h],1 // [Alt] jnz @@6 cmp byte ptr keydown[4ah],1 // *[-] jz @@10 cmp byte ptr keydown[4eh],1 // *[+] jz @@10 @@6: cmp byte ptr keydown[1dh],1 // [Ctrl] jnz @@7 cmp byte ptr keydown[38h],1 // [Alt] jnz @@7 cmp byte ptr keydown[53h],1 // [Del] jz @@9 @@7: cmp byte ptr keydown[1dh],1 // [Ctrl] jnz @@8 cmp byte ptr keydown[02h],1 // *[1] jz @@10 cmp byte ptr keydown[03h],1 // *[2] jz @@10 cmp byte ptr keydown[04h],1 // *[3] jz @@10 cmp byte ptr keydown[05h],1 // *[4] jz @@10 cmp byte ptr keydown[06h],1 // *[5] jz @@10 cmp byte ptr keydown[07h],1 // *[6] jz @@10 cmp byte ptr keydown[08h],1 // *[7] jz @@10 cmp byte ptr keydown[09h],1 // *[8] jz @@10 @@8: jmp @@11 @@9: mov CTRL_ALT_DEL_pressed,1 @@10: in al,61h mov ah,al or al,80h out 61h,al xchg ah,al out 61h,al mov al,20h out 20h,al pop ebx pop eax jmp @@12 @@11: pop ebx pop eax @@12: end; procedure int09_user_proc_end; begin end; procedure keyboard_toggle_sleep; begin keyboard_sleep := NOT keyboard_sleep; end; procedure keyboard_reset_buffer; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:keyboard_reset_buffer'; {$ENDIF} MEMW[0:$041c] := MEMW[0:$041a]; end; procedure keyboard_reset_buffer_alt; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:keyboard_reset_buffer_alt'; {$ENDIF} If (MEMW[0:$041c]-MEMW[0:$041a] > 5) then MEMW[0:$041c] := MEMW[0:$041a]; end; procedure wait_until_F11_F12_released; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:wait_until_key_released'; {$ENDIF} Repeat realtime_gfx_poll_proc; draw_screen; keyboard_reset_buffer; If (inportb($60) > $80) then FillChar(keydown,SizeOf(keydown),0); until NOT keydown[$57] and NOT keydown[$58]; end; procedure keyboard_poll_input; begin // relevant for SDL version only end; var temp_buf: array[1..32,1..255] of Record r,g,b: Byte; end; procedure screen_saver; procedure fadeout; var r,g,b: Byte; index: Byte; depth: Byte; function min0(val: Integer): Integer; begin If (val <= 0) then min0 := 0 else min0 := val; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:screen_saver:fadeout'; {$ENDIF} For depth := 1 to 32 do begin For index := 1 to 255 do begin GetRGBitem(index,r,g,b); temp_buf[depth][index].r := r; temp_buf[depth][index].g := g; temp_buf[depth][index].b := b; SetRGBitem(index,min0(r-1),min0(g-1),min0(b-1)); end; WaitRetrace; realtime_gfx_poll_proc; If (depth MOD 4 = 0) then draw_screen; keyboard_reset_buffer; end; end; procedure fadein; var index: Byte; depth: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:screen_saver:fadein'; {$ENDIF} For depth := 32 downto 1 do begin For index := 1 to 255 do SetRGBitem(index,temp_buf[depth][index].r, temp_buf[depth][index].g, temp_buf[depth][index].b); If (depth MOD 4 <> 0) then WaitRetrace; realtime_gfx_poll_proc; If (depth MOD 4 = 0) then draw_screen; keyboard_reset_buffer; end; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:screen_saver'; {$ENDIF} If (ssaver_time = 0) then EXIT; fadeout; Repeat realtime_gfx_poll_proc; draw_screen; until (seconds_counter = 0); fadein; end; var keyboard_flag: Byte ABSOLUTE 0:$0417; function CapsLock: Boolean; begin CapsLock := (keyboard_flag OR $40 = keyboard_flag); end; function NumLock: Boolean; begin NumLock := (keyboard_flag OR $20 = keyboard_flag); end; function ScrollLock: Boolean; begin ScrollLock := (keyboard_flag OR $10 = keyboard_flag); end; function shift_pressed: Boolean; begin shift_pressed := (keyboard_flag OR 1 = keyboard_flag) or (keyboard_flag OR 2 = keyboard_flag); end; function left_shift_pressed: Boolean; begin left_shift_pressed := (keyboard_flag OR 2 = keyboard_flag); end; function right_shift_pressed: Boolean; begin right_shift_pressed := (keyboard_flag OR 1 = keyboard_flag); end; function both_shifts_pressed: Boolean; begin both_shifts_pressed := (keyboard_flag OR 1 = keyboard_flag) and (keyboard_flag OR 2 = keyboard_flag); end; function alt_pressed: Boolean; begin alt_pressed := scankey(SC_ALT); end; function ctrl_pressed: Boolean; begin ctrl_pressed := scankey(SC_CTRL); end; {$ELSE} const SYMTABSIZE = $65; symtab: array[0..PRED(SYMTABSIZE*10)] of word = ( { Key Scan ASCII Shift Ctrl Alt Num Caps Sh+Caps Sh+Num SDLK_Keycode} { Esc } $01, $1B, $1B, $F000, $F000, $1B, $1B, $1B, $1B, SDLK_ESCAPE, { 1! } $02, $31, $21, $0200, $7800, $31, $31, $21, $21, SDLK_1, { 2@ } $03, $32, $40, $0300, $7900, $32, $32, $40, $40, SDLK_2, { 3# } $04, $33, $23, $0400, $7A00, $33, $33, $23, $23, SDLK_3, { 4$ } $05, $34, $24, $0500, $7B00, $34, $34, $24, $24, SDLK_4, { 5% } $06, $35, $25, $0600, $7C00, $35, $35, $25, $25, SDLK_5, { 6^ } $07, $36, $5E, $0700, $7D00, $36, $36, $5E, $5E, SDLK_6, { 7& } $08, $37, $26, $0800, $7E00, $37, $37, $26, $26, SDLK_7, { 8* } $09, $38, $2A, $0900, $7F00, $38, $38, $2A, $2A, SDLK_8, { 9( } $0A, $39, $28, $0A00, $8000, $39, $39, $28, $28, SDLK_9, { 0) } $0B, $30, $29, $0B00, $8100, $30, $30, $29, $29, SDLK_0, { -_ } $0C, $2D, $5F, $1F, $8200, $2D, $2D, $5F, $5F, SDLK_MINUS, { =+ } $0D, $3D, $2B, $F000, $8300, $3D, $3D, $2B, $2B, SDLK_EQUALS, {Bksp} $0E, $08, $08, $7F, $F000, $08, $08, $08, $08, SDLK_BACKSPACE, { Tab} $0F, $09, $0F00, $F000, $F000, $09, $09, $0F00, $0F00, SDLK_TAB, { Q } $10, $71, $51, $11, $1000, $71, $51, $71, $51, SDLK_q, { W } $11, $77, $57, $17, $1100, $77, $57, $77, $57, SDLK_w, { E } $12, $65, $45, $05, $1200, $65, $45, $65, $45, SDLK_e, { R } $13, $72, $52, $12, $1300, $72, $52, $72, $52, SDLK_r, { T } $14, $74, $54, $14, $1400, $74, $54, $74, $54, SDLK_t, { Y } $15, $79, $59, $19, $1500, $79, $59, $79, $59, SDLK_y, { U } $16, $75, $55, $15, $1600, $75, $55, $75, $55, SDLK_u, { I } $17, $69, $49, $09, $1700, $69, $49, $69, $49, SDLK_i, { O } $18, $6F, $4F, $0F, $1800, $6F, $4F, $6F, $4F, SDLK_o, { P } $19, $70, $50, $10, $1900, $70, $50, $70, $50, SDLK_p, { [ } $1A, $5B, $7B, $1B, $F000, $5B, $5B, $7B, $7B, SDLK_LEFTBRACKET, { ] } $1B, $5D, $7D, $1D, $F000, $5D, $5D, $7D, $7D, SDLK_RIGHTBRACKET, {enter} $1C, $0D, $0D, $0A, $F000, $0D, $0D, $0D, $0D, SDLK_RETURN, { A } $1E, $61, $41, $01, $1E00, $61, $41, $61, $41, SDLK_a, { S } $1F, $73, $53, $13, $1F00, $73, $53, $73, $53, SDLK_s, { D } $20, $64, $44, $04, $2000, $64, $44, $64, $44, SDLK_d, { F } $21, $66, $46, $06, $2100, $66, $46, $66, $46, SDLK_f, { G } $22, $67, $47, $07, $2200, $67, $47, $67, $47, SDLK_g, { H } $23, $68, $48, $08, $2300, $68, $48, $68, $48, SDLK_h, { J } $24, $6A, $4A, $0A, $2400, $6A, $4A, $6A, $4A, SDLK_j, { K } $25, $6B, $4B, $0B, $2500, $6B, $4B, $6B, $4B, SDLK_k, { L } $26, $6C, $4C, $0C, $2600, $6C, $4C, $6C, $4C, SDLK_l, { ;:} $27, $3B, $3A, $F000, $F000, $3B, $3B, $3A, $3A, SDLK_SEMICOLON, { '"} $28, $27, $22, $F000, $F000, $27, $27, $22, $22, SDLK_QUOTE, { `~} $29, $60, $7E, $F000, $F000, $60, $60, $7E, $7E, SDLK_BACKQUOTE, {Lshft} $2A, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_LSHIFT, { \|} $2B, $5C, $7C, $1C, $F000, $5C, $5C, $7C, $7C, SDLK_BACKSLASH, { Z } $2C, $7A, $5A, $1A, $2C00, $7A, $5A, $7A, $5A, SDLK_z, { X } $2D, $78, $58, $18, $2D00, $78, $58, $78, $58, SDLK_x, { C } $2E, $63, $43, $03, $2E00, $63, $43, $63, $43, SDLK_c, { V } $2F, $76, $56, $16, $2F00, $76, $56, $76, $56, SDLK_v, { B } $30, $62, $42, $02, $3000, $62, $42, $62, $42, SDLK_b, { Key Scan ASCII Shift Ctrl Alt Num Caps Sh+Caps Sh+Num SDLK_Keycode} { N } $31, $6E, $4E, $0E, $3100, $6E, $4E, $6E, $4E, SDLK_n, { M } $32, $6D, $4D, $0D, $3200, $6D, $4D, $6D, $4D, SDLK_m, { ,<} $33, $2C, $3C, $F000, $F000, $2C, $2C, $3C, $3C, SDLK_COMMA, { .>} $34, $2E, $3E, $F000, $F000, $2E, $2E, $3E, $3E, SDLK_PERIOD, { /?} $35, $2F, $3F, $F000, $F000, $2F, $2F, $3F, $3F, SDLK_SLASH, {Rshft} $36, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_RSHIFT, {PrtSc} $37, $2A, $F000, $F000, $F000, $2A, $2A, $F000, $F000, SDLK_PRINT, {space} $39, $20, $20, $20, $20, $20, $20, $20, $20, SDLK_SPACE, {caps} $3A, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_CAPSLOCK, { F1 } $3B, $3B00, $5400, $5E00, $6800, $3B00, $3B00, $5400, $5400, SDLK_F1, { F2 } $3C, $3C00, $5500, $5F00, $6900, $3C00, $3C00, $5500, $5500, SDLK_F2, { F3 } $3D, $3D00, $5600, $6000, $6A00, $3D00, $3D00, $5600, $5600, SDLK_F3, { F4 } $3E, $3E00, $5700, $6100, $6B00, $3E00, $3E00, $5700, $5700, SDLK_F4, { F5 } $3F, $3F00, $5800, $6200, $6C00, $3F00, $3F00, $5800, $5800, SDLK_F5, { F6 } $40, $4000, $5900, $6300, $6D00, $4000, $4000, $5900, $5900, SDLK_F6, { F7 } $41, $4100, $5A00, $6400, $6E00, $4100, $4100, $5A00, $5A00, SDLK_F7, { F8 } $42, $4200, $5B00, $6500, $6F00, $4200, $4200, $5B00, $5B00, SDLK_F8, { F9 } $43, $4300, $5C00, $6600, $7000, $4300, $4300, $5C00, $5C00, SDLK_F9, { F10} $44, $4400, $5D00, $6700, $7100, $4400, $4400, $5D00, $5D00, SDLK_F10, { num} $45, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_NUMLOCK, {scrl} $46, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_SCROLLOCK, {home} $47, $4700, $4700, $7700, $F000, $4700, $4700, $4700, $4700, SDLK_HOME, { up } $48, $0000, $4800, $F000, $F000, $4800, $4800, $4800, $4800, SDLK_UP, {pgup} $49, $4900, $4900, $8400, $F000, $4900, $4900, $4900, $4900, SDLK_PAGEUP, { np-} $4A, $2D, $2D, $F000, $F000, $2D, $2D, $2D, $2D, SDLK_KP_MINUS, {left} $4B, $4B00, $4B00, $7300, $F000, $4B00, $4B00, $4B00, $4B00, SDLK_LEFT, {centr} $4C, $4C00, $4C00, $F000, $F000, $4C00, $4C00, $4C00, $4C00, SDLK_UNKNOWN, {right} $4D, $4D00, $4D00, $7400, $F000, $4D00, $4D00, $4D00, $4D00, SDLK_RIGHT, { np+} $4E, $2B, $2B, $F000, $F000, $2B, $2B, $2B, $2B, SDLK_KP_PLUS, {end} $4F, $4F00, $4F00, $7500, $F000, $4F00, $4F00, $4F00, $4F00, SDLK_END, {down} $50, $0000, $5000, $F000, $F000, $5000, $5000, $5000, $5000, SDLK_DOWN, {pgdn} $51, $5100, $5100, $7600, $F000, $5100, $5100, $5100, $5100, SDLK_PAGEDOWN, { ins} $52, $5200, $5200, $F000, $F000, $5200, $5200, $5200, $5200, SDLK_INSERT, { del} $53, $5300, $5300, $F000, $F000, $5300, $5300, $5300, $5300, SDLK_DELETE, { F11} $57, $4500, $5E00, $6800, $F000, $4500, $4500, $5E00, $5E00, SDLK_F11, { F12} $58, $4500, $F000, $6900, $F000, $4600, $4600, $5F00, $5F00, SDLK_F12, { np0 } $52, $5200, $5200, $F000, $F000, $30, $30, $29, $30, SDLK_KP0, { np1 } $4F, $4F00, $4F00, $F000, $F000, $31, $31, $21, $31, SDLK_KP1, { np2 } $50, $5000, $5000, $F000, $F000, $32, $32, $40, $32, SDLK_KP2, { np3 } $51, $5100, $5100, $F000, $F000, $33, $33, $23, $33, SDLK_KP3, { np4 } $4B, $4B00, $4B00, $F000, $F000, $34, $34, $24, $34, SDLK_KP4, { np5 } $4C, $4C00, $4C00, $F000, $F000, $35, $35, $25, $35, SDLK_KP5, { np6 } $4D, $4D00, $4D00, $F000, $F000, $36, $36, $5E, $36, SDLK_KP6, { np7 } $47, $4700, $4700, $F000, $F000, $37, $37, $26, $37, SDLK_KP7, { np8 } $48, $4800, $4800, $F000, $F000, $38, $38, $2A, $38, SDLK_KP8, { np9 } $49, $4900, $4900, $F000, $F000, $39, $39, $28, $39, SDLK_KP9, { np. } $53, $5300, $5300, $F000, $F000, $2E, $2E, $3E, $3E, SDLK_KP_PERIOD, { np/ } $35, $2F, $2F, $F000, $F000, $2F, $2F, $2F, $2F, SDLK_KP_DIVIDE, { np* } $37, $2A, $2A, $F000, $F000, $2A, $2A, $2A, $2A, SDLK_KP_MULTIPLY, {NPent} $1C, $0D, $0D, $0A, $F000, $0D, $0D, $0A, $0A, SDLK_KP_ENTER, {LALT} $FC, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_LALT, {RALT} $FD, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_RALT, {LCTRL} $FE, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_LCTRL, {RCTRL} $FF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_RCTRL { Key Scan ASCII Shift Ctrl Alt Num Caps Sh+Caps Sh+Num SDLK_Keycode} ); procedure TranslateKeycodes; var i,j: Integer; modkeys: SDLMod; begin // translate SDL_Keycodes to scancodes For i := 0 to SDLK_LAST do For j := 0 to PRED(SYMTABSIZE) do If (i = symtab[j*10+9]) then keydown[symtab[j*10]] := keystate^[i]; // read capslock and numlock state modkeys := SDL_GetModState; _capslock := (modkeys AND KMOD_CAPS) <> 0; _numlock := (modkeys AND KMOD_NUM) <> 0; end; procedure keyboard_poll_input; begin SDL_PumpEvents; TranslateKeycodes; process_global_keys; end; function keypressed: Boolean; var event: SDL_Event; begin keypressed := FALSE; Repeat keyboard_poll_input; If (SDL_PeepEvents(event,1,SDL_PEEKEVENT,SDL_QUITMASK) > 0) then begin _force_program_quit := TRUE; keypressed := TRUE; EXIT; end; If (SDL_PeepEvents(event,1,SDL_PEEKEVENT,SDL_MOUSEEVENTMASK) > 0) then begin // skip mouse events SDL_PeepEvents(event,1,SDL_GETEVENT,SDL_MOUSEEVENTMASK); CONTINUE; end; If (SDL_PeepEvents(event,1,SDL_PEEKEVENT,SDL_KEYDOWNMASK) > 0) then If (event.key.keysym.sym >= SDLK_NUMLOCK) then begin // skip modifier key presses SDL_PeepEvents(event,1,SDL_GETEVENT,SDL_KEYDOWNMASK); CONTINUE; end else keypressed := TRUE; EXIT; until FALSE; end; function getkey: Word; function getkey_proc: Word; var event: SDL_Event; i,j: Integer; begin Repeat draw_screen; If (SDL_PollEvent(@event) <> 0) then begin If (event.eventtype = SDL_EVENTQUIT) or _force_program_quit then begin _force_program_quit := TRUE; getkey_proc := kESC; EXIT; end; // skip all other event except key presses If (event.eventtype <> SDL_KEYDOWN) then CONTINUE else begin // skip all modifier keys If (event.key.keysym.sym >= SDLK_NUMLOCK) then CONTINUE; // roll thru symtab, form correct getkey value For j := 0 to PRED(SYMTABSIZE) do begin If (event.key.keysym.sym = symtab[j*10+9]) then begin // first check with modifier keys, order: ALT, CTRL, SHIFT (as DOS does) { ALT } If (keydown[SC_LALT] = TRUE) or (keydown[SC_RALT] = TRUE) then begin // impossible combination If (symtab[j*10+4] = WORD_NULL) then CONTINUE; If (symtab[j*10+4] > BYTE_NULL) then begin getkey_proc := symtab[j*10+4]; EXIT; end; getkey_proc := (symtab[j*10] SHL 8) OR symtab[j*10+4]; EXIT; end; { CTRL } If (keydown[SC_LCTRL] = TRUE) or (keydown[SC_RCTRL] = TRUE) then begin // impossible combination If (symtab[j*10+3] = WORD_NULL) then CONTINUE; If (symtab[j*10+3] > BYTE_NULL) then begin getkey_proc := symtab[j*10+3]; EXIT; end; getkey_proc := (symtab[j*10] SHL 8) OR symtab[j*10+3]; EXIT; end; { SHIFT } If (keydown[SC_LSHIFT] = TRUE) or (keydown[SC_RSHIFT] = TRUE) then begin i := 2; // SHIFT If (_capslock = TRUE) then i := 7 // caps lock else If (_numlock = TRUE) then i := 8; // num lock // impossible combination If (symtab[j*10+i] = WORD_NULL) then CONTINUE; If (symtab[j*10+i] > BYTE_NULL) then getkey_proc := symtab[j*10+i] else getkey_proc := (symtab[j*10] SHL 8) OR symtab[j*10+i]; EXIT; end; { normal ASCII } i := 1; If (_capslock = TRUE) then i := 6 // caps lock else If (_numlock = TRUE) then i := 5; // num lock // impossible combination If (symtab[j*10+i] = WORD_NULL) then CONTINUE; If (symtab[j*10+i] > BYTE_NULL) then getkey_proc := symtab[j*10+i] else getkey_proc := (symtab[j*10] SHL 8) OR symtab[j*10+i]; // (scancode << 8) + ASCII EXIT; end; end; end; end; until FALSE; end; begin Repeat draw_screen until keypressed; // filter out CTRL+TAB combo as it is handled within timer routine If ctrl_tab_pressed then begin draw_screen; keyboard_reset_buffer; getkey := WORD_NULL; end else getkey := getkey_proc; end; function scankey(scancode: Byte): Boolean; begin TranslateKeycodes; scankey := keydown[scancode]; end; procedure keyboard_reset_buffer; var event: SDL_Event; begin // flush all unused events While (SDL_PollEvent(@event) <> 0) do ; end; procedure wait_until_F11_F12_released; begin _debug_str_ := 'ADT2KEYB.PAS:wait_until_F11_F12_released'; Repeat draw_screen; SDL_PumpEvents; TranslateKeycodes; until NOT keydown[SC_F11] and NOT keydown[SC_F12]; keyboard_reset_buffer; end; function CapsLock: Boolean; begin CapsLock := _capslock; end; function NumLock: Boolean; begin NumLock := _numlock; end; function shift_pressed: Boolean; begin shift_pressed := scankey(SC_LSHIFT) or scankey(SC_RSHIFT); end; function left_shift_pressed: Boolean; begin left_shift_pressed := scankey(SC_LSHIFT); end; function right_shift_pressed: Boolean; begin right_shift_pressed := scankey(SC_RSHIFT); end; function alt_pressed: Boolean; begin alt_pressed := scankey(SC_LALT) or scankey(SC_RALT); end; function ctrl_pressed: Boolean; begin ctrl_pressed := scankey(SC_LCTRL) or scankey(SC_RCTRL); end; procedure screen_saver; begin // relevant for DOS version only end; {$ENDIF} function ctrl_tab_pressed: Boolean; begin ctrl_tab_pressed := ctrl_pressed and scankey(SC_TAB); end; function LookUpKey(key: Word; var table; size: Byte): Boolean; var result: Boolean; begin asm mov esi,[table] xor ecx,ecx mov cl,size mov result,TRUE jecxz @@3 @@1: lodsw cmp ax,key jz @@2 loop @@1 @@2: mov result,FALSE jecxz @@3 mov result,TRUE @@3: end; LookUpKey := result; end; end. adlibtracker2-2.4.23/progicon.ico0000644000000000000000000001465613176573532015355 0ustar rootroot èF 0. ¨^ ¨  ( @€€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌDCDDDDDDDDDD³DDK0DDDDDDDDD³DDK³DDDDDDDDD³DDD»0DDDDDDDD³DDDK³DDDDDDDD³DDDD»0DDDDDDD³DDDDK³DDD@³DDDDD»0DDC333³DDDDDK³DDK»»»³DDDDDD»0DDDDD³DDDDDDK³DDDDD³DDDDDDD»0DDDD³D ³³»0³ ³³»0³³³³³³³³( @ÎØ(((ÿÿÿ00000000000 000€0Àð`ð000 000€0À00000000( @€T€Œ8(¨˜€0¨À°p @„ÔÌDL //////////////////////////////:=#/////////////////////////////- /////////////////////- /- - &&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&AAAAAAAA@@AAAAAAAA@@@@@@@A AAA6'7 HHH"3BHHHHHHHHHHHHHHHHHHH7 0) then _invoke_error_1; BlockWrite(f,_font_file_header_data,40,temp); If (temp <> 40) then _invoke_error_1; BlockWrite(f,font8x16,4096,temp); If (temp <> 4096) then _invoke_error_1; {$i-} Close(f); {$i+} If (IOresult <> 0) then _invoke_error_1; HALT(0); end; If (Upper(ParamStr(1)) = '/DATA') then begin {$i-} Assign(f,'font.com'); Reset(f,1); {$i+} If (IOresult <> 0) then _invoke_error_2; BlockRead(f,buf,SizeOf(buf),temp); If (FileSize(f) > 4096+40) or (temp < 4096+40) then _invoke_error_2; {$i-} Close(f); {$i+} If (IOresult <> 0) then _invoke_error_2; {$i-} Assign(t,'font.dat'); Rewrite(t); {$i+} If (IOresult <> 0) then _invoke_error_3; WriteLn(t,'const'); WriteLn(t,' font8x16: array[0..1023] of Dword = ('); offset := 40; For temp3 := 1 to 128 do begin Write(t,' '); For temp2 := 1 to 8 do begin temps := ''; For temp := 1 to 4 do begin temps := ExpStrL(Num2str(buf[offset],16),2,'0')+temps; Inc(offset); end; If (offset < 4096+40) then Write(t,'$'+temps+',') else Write(t,'$'+temps+');') end; WriteLn(t); end; {$i-} Close(t); {$i+} If (IOresult <> 0) then _invoke_error_3; HALT(0); end; WriteLn('Usage: DUMPFONT [/font] | [/data]'); end. adlibtracker2-2.4.23/font/FONT.DAT0000644000000000000000000002546113176573532015103 0ustar rootrootconst font8x16: array[0..1023] of Dword = ( $00000000,$00000000,$00000000,$00000000,$71300000,$313131F1,$FC313131,$00000000, $CD780000,$31190DCD,$FCCDC161,$00000000,$29CE0000,$2E292929,$C8282828,$00000000, $19080000,$FDD97939,$3C191919,$00000000,$00000000,$06361C00,$BE32180C,$00000000, $00000000,$18181F00,$9E33031E,$00000000,$00000000,$28440000,$44281010,$00000000, $E7E70000,$E7E7E7E7,$E7E7E7E7,$000000E7,$FFFF0000,$C3C7CFDF,$FFDFCFC7,$000000FF, $38100000,$1010107C,$10387C10,$00000000,$00000000,$7E7E7E3C,$00003C7E,$00000000, $991F0000,$1818385F,$70793A1C,$00000000,$191F0000,$1818181F,$70783818,$00000000, $55555500,$55555555,$55555555,$00000055,$7F7F7F00,$7F7F7F7F,$7F7F7F7F,$0000007F, $60400000,$7E7C7870,$6070787C,$00000040,$06020000,$7E3E1E0E,$060E1E3E,$00000002, $38100000,$1010107C,$10001000,$00000000,$82FE0000,$32128282,$3070FE72,$00000010, $00000000,$AA000000,$00000000,$00000000,$28140000,$50505050,$14285050,$00000000, $14280000,$0A0A0A0A,$28140A0A,$00000000,$00100000,$10100010,$10387C10,$00000000, $38100000,$1010107C,$10101010,$00000000,$10100000,$10101010,$10387C10,$00000000, $00000000,$FF0E0C08,$00080C0E,$00000000,$00000000,$FF703010,$00103070,$00000000, $00000000,$3C3C1800,$00000018,$00000000,$F3FE0000,$81FFF3F3,$FF81FF81,$00000000, $00000000,$7C383810,$00FEFE7C,$00000000,$00000000,$7C7CFEFE,$00103838,$00000000, $00000000,$00000000,$00000000,$00000000,$3C180000,$18183C3C,$18180018,$00000000, $28282800,$00002828,$00000000,$00000000,$28000000,$28287C28,$28287C28,$00000000, $D67C1010,$167CD0D2,$7CD69616,$00001010,$00000000,$08C4C200,$86462010,$00000000, $6C380000,$DC76386C,$76CCCCCC,$00000000,$10101000,$00000020,$00000000,$00000000, $10080000,$20202020,$08102020,$00000000,$08100000,$04040404,$10080404,$00000000, $00000000,$FE385410,$00105438,$00000000,$00000000,$7C101000,$00001010,$00000000, $00000000,$00000000,$10101000,$00000020,$00000000,$7C000000,$00000000,$00000000, $00000000,$00000000,$10000000,$00000000,$00000000,$08040200,$80402010,$00000000, $6C380000,$D6D6C6C6,$386CC6C6,$00000000,$38180000,$18181878,$7E181818,$00000000, $C67C0000,$30180C06,$FEC6C060,$00000000,$C67C0000,$063C0606,$7CC60606,$00000000, $1C0C0000,$FECC6C3C,$1E0C0C0C,$00000000,$C0FE0000,$06FCC0C0,$7CC60606,$00000000, $60380000,$C6FCC0C0,$7CC6C6C6,$00000000,$C6FE0000,$180C0606,$30303030,$00000000, $C67C0000,$C67CC6C6,$7CC6C6C6,$00000000,$C67C0000,$067EC6C6,$780C0606,$00000000, $00000000,$00001000,$00001000,$00000000,$00000000,$00001000,$20101000,$00000000, $04000000,$40201008,$04081020,$00000000,$00000000,$00003C00,$0000003C,$00000000, $20000000,$02040810,$20100804,$00000000,$C67C0000,$18180CC6,$18180018,$00000000, $7C000000,$DEDEC6C6,$7CC0DCDE,$00000000,$38100000,$FEC6C66C,$C6C6C6C6,$00000000, $66FC0000,$667C6666,$FC666666,$00000000,$663C0000,$C0C0C0C2,$3C66C2C0,$00000000, $6CF80000,$66666666,$F86C6666,$00000000,$66FE0000,$68786862,$FE666260,$00000000, $66FE0000,$68786862,$F0606060,$00000000,$663C0000,$DEC0C0C2,$3A66C6C6,$00000000, $C6C60000,$C6FEC6C6,$C6C6C6C6,$00000000,$183C0000,$18181818,$3C181818,$00000000, $0C1E0000,$0C0C0C0C,$78CCCCCC,$00000000,$66E60000,$78786C66,$E666666C,$00000000, $60F00000,$60606060,$FE666260,$00000000,$EEC60000,$C6D6FEFE,$C6C6C6C6,$00000000, $E6C60000,$CEDEFEF6,$C6C6C6C6,$00000000,$C67C0000,$C6C6C6C6,$7CC6C6C6,$00000000, $66FC0000,$607C6666,$F0606060,$00000000,$C67C0000,$C6C6C6C6,$7CDED6C6,$00000E0C, $66FC0000,$6C7C6666,$E6666666,$00000000,$C67C0000,$0C3860C6,$7CC6C606,$00000000, $7E7E0000,$1818185A,$3C181818,$00000000,$C6C60000,$C6C6C6C6,$7CC6C6C6,$00000000, $C6C60000,$C6C6C6C6,$10386CC6,$00000000,$C6C60000,$D6D6C6C6,$6CEEFED6,$00000000, $C6C60000,$38387C6C,$C6C66C7C,$00000000,$66660000,$183C6666,$3C181818,$00000000, $C6FE0000,$30180C86,$FEC6C260,$00000000,$20380000,$20202020,$38202020,$00000000, $00000000,$20408000,$02040810,$00000000,$041C0000,$04040404,$1C040404,$00000000, $6C381000,$000000C6,$00000000,$00000000,$00000000,$00000000,$00000000,$0000FF00, $00081010,$00000000,$00000000,$00000000,$00000000,$7C0C7800,$76CCCCCC,$00000000, $60E00000,$666C7860,$7C666666,$00000000,$00000000,$C0C67C00,$7CC6C0C0,$00000000, $0C1C0000,$CC6C3C0C,$76CCCCCC,$00000000,$00000000,$FEC67C00,$7CC6C0C0,$00000000, $6C380000,$60F06064,$F0606060,$00000000,$00000000,$CCCC7600,$7CCCCCCC,$0078CC0C, $60E00000,$66766C60,$E6666666,$00000000,$18000000,$18183800,$3C181818,$00000000, $06000000,$06060E00,$06060606,$003C6666,$60E00000,$786C6660,$E6666C78,$00000000, $18380000,$18181818,$3C181818,$00000000,$00000000,$D6FEEC00,$C6D6D6D6,$00000000, $00000000,$6666DC00,$66666666,$00000000,$00000000,$C6C67C00,$7CC6C6C6,$00000000, $00000000,$6666DC00,$7C666666,$00F06060,$00000000,$CCCC7600,$7CCCCCCC,$001E0C0C, $00000000,$6676DC00,$F0606060,$00000000,$00000000,$60C67C00,$7CC60C38,$00000000, $30100000,$3030FC30,$1C363030,$00000000,$00000000,$CCCCCC00,$76CCCCCC,$00000000, $00000000,$66666600,$183C6666,$00000000,$00000000,$D6C6C600,$6CFED6D6,$00000000, $00000000,$386CC600,$C66C3838,$00000000,$00000000,$C6C6C600,$7EC6C6C6,$00F80C06, $00000000,$18CCFE00,$FEC66030,$00000000,$100C0000,$10601010,$0C101010,$00000000, $10100000,$10001010,$10101010,$00000000,$08300000,$08060808,$30080808,$00000000, $DC760000,$00000000,$00000000,$00000000,$023E0000,$12020202,$10307E32,$00000000, $00000000,$00000000,$00000000,$FF000000,$00000000,$00000000,$00000000,$FFFF0000, $00000000,$00000000,$00000000,$FFFFFF00,$00000000,$00000000,$00000000,$FFFFFFFF, $00000000,$00000000,$FF000000,$FFFFFFFF,$00000000,$00000000,$FFFF0000,$FFFFFFFF, $00000000,$00000000,$FFFFFF00,$FFFFFFFF,$00000000,$00000000,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFF0000,$FFFFFFFF,$FFFFFFFF, $00000000,$FFFFFF00,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FF000000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFF0000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FFFFFF00,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$00FFFFFF, $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$0000FFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$000000FF, $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$00FFFFFF,$00000000, $FFFFFFFF,$FFFFFFFF,$0000FFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$000000FF,$00000000, $FFFFFFFF,$FFFFFFFF,$00000000,$00000000,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $FFFFFFFF,$0000FFFF,$00000000,$00000000,$FFFFFFFF,$000000FF,$00000000,$00000000, $FFFFFFFF,$00000000,$00000000,$00000000,$00FFFFFF,$00000000,$00000000,$00000000, $0000FFFF,$00000000,$00000000,$00000000,$000000FF,$00000000,$00000000,$00000000, $10101010,$10101010,$10101010,$7C101010,$00000000,$0A110000,$110A0404,$00000000, $AACC0000,$AACAAAAA,$CCAAAAAA,$00000000,$AA4C0000,$4A8A8AAA,$4CAA2A2A,$00000000, $44EE0000,$44444444,$44444444,$00000000,$4AE40000,$4848484A,$444A4848,$00000000, $AAAA0000,$AAEEAAAA,$AAAAAAAA,$00000000,$00000000,$FFFFFF00,$80808000,$00808080, $00000000,$FFFFFF00,$A0A0A000,$00A0A0A0,$00000000,$FFFFFF00,$A8A8A800,$00A8A8A8, $00000000,$FFFFFF00,$AAAAAA00,$00AAAAAA,$10101010,$FFFFFF10,$AAAAAA00,$00AAAAAA, $00000000,$60606000,$7E606060,$00000000,$00000000,$C6C6FC00,$C6C6CCFC,$00000000, $00100015,$1C0C0010,$0C7E6C3C,$001E0C0C,$96959566,$10006494,$10001000,$00001500, $90900000,$F7F09090,$97949291,$00000000,$00100010,$38000010,$00003838,$00000000, $44114411,$44114411,$44114411,$44114411,$AA55AA55,$AA55AA55,$AA55AA55,$AA55AA55, $77DD77DD,$77DD77DD,$77DD77DD,$77DD77DD,$10101010,$10101010,$10101010,$10101010, $10101010,$F0101010,$10101010,$10101010,$10101010,$F0F0F010,$10101010,$10101010, $3C3C3C3C,$FC3C3C3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FC000000,$3C3C3C3C,$3C3C3C3C, $00000000,$F0F0F000,$10101010,$10101010,$3C3C3C3C,$FCFCFC3C,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FCFCFC00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$FCFCFC3C,$00000000,$00000000,$3C3C3C3C,$FC3C3C3C,$00000000,$00000000, $10101010,$F0F0F010,$00000000,$00000000,$00000000,$F0000000,$10101010,$10101010, $10101010,$1F101010,$00000000,$00000000,$10101010,$FF101010,$00000000,$00000000, $00000000,$FF000000,$10101010,$10101010,$10101010,$1F101010,$10101010,$10101010, $00000000,$FF000000,$00000000,$00000000,$10101010,$FF101010,$10101010,$10101010, $10101010,$1F1F1F10,$10101010,$10101010,$3C3C3C3C,$3F3C3C3C,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3F3F3F3C,$00000000,$00000000,$00000000,$3F3F3F00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$FFFFFF3C,$00000000,$00000000,$00000000,$FFFFFF00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3F3F3F3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FFFFFF00,$00000000,$00000000, $3C3C3C3C,$FFFFFF3C,$3C3C3C3C,$3C3C3C3C,$10101010,$FFFFFF10,$00000000,$00000000, $3C3C3C3C,$FF3C3C3C,$00000000,$00000000,$00000000,$FFFFFF00,$10101010,$10101010, $00000000,$FF000000,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$3F3C3C3C,$00000000,$00000000, $10101010,$1F1F1F10,$00000000,$00000000,$00000000,$1F1F1F00,$10101010,$10101010, $00000000,$3F000000,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$FF3C3C3C,$3C3C3C3C,$3C3C3C3C, $10101010,$FFFFFF10,$10101010,$10101010,$10101010,$F0101010,$00000000,$00000000, $00000000,$1F000000,$10101010,$10101010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0, $0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $00100010,$00920010,$00100010,$00920010,$00100010,$00920010,$00100010,$FF100010, $00100010,$00920010,$00100010,$FFFF0010,$00100010,$00920010,$00100010,$FFFFFF10, $00100010,$00920010,$00100010,$FFFFFFFF,$00100010,$00920010,$FF100010,$FFFFFFFF, $00100010,$00920010,$FFFF0010,$FFFFFFFF,$00100010,$00920010,$FFFFFF10,$FFFFFFFF, $00100010,$00920010,$FFFFFFFF,$FFFFFFFF,$00100010,$FF920010,$FFFFFFFF,$FFFFFFFF, $00100010,$FFFF0010,$FFFFFFFF,$FFFFFFFF,$00100010,$FFFFFF10,$FFFFFFFF,$FFFFFFFF, $00100010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FF100010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FFFF0010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFF10,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $01010101,$01010101,$01010101,$01010101,$10000000,$10101010,$10101010,$00000000, $00000000,$FF000000,$00100010,$00920010,$00100010,$FF100010,$00000000,$00000000, $18783818,$10081C1A,$00000020,$00000000,$186C6C38,$10087C32,$00000020,$00000000, $00100010,$00100010,$00100010,$00100010,$00010001,$00010001,$00010001,$00010001, $00100015,$00100010,$00100010,$00100010,$00000000,$28281000,$00001028,$00000000, $00000000,$10000000,$00000000,$00000000,$03010000,$CC040602,$307058C8,$00000000, $3E1C0800,$FFFFFF7F,$00000000,$00000000,$00000000,$FFFFFF00,$081C3E7F,$00000000, $00000000,$7C7C7C7C,$007C7C7C,$00000000,$00000000,$00000000,$00000000,$00000000); adlibtracker2-2.4.23/iloadins.inc0000644000000000000000000014321713176573532015332 0ustar rootroot{ procedure import_standard_instrument_alt(var data); procedure import_fin_instrument_alt(var data); procedure import_hsc_instrument_alt(var data); procedure import_sat_instrument_alt(var data); procedure a2i_file_loader_alt(fname: String); procedure a2f_file_loader_alt(fname: String); procedure cif_file_loader_alt(fname: String); procedure fin_file_loader_alt(fname: String); procedure ins_file_loader_alt(fname: String); procedure sbi_file_loader_alt(fname: String); procedure sgi_file_loader_alt(fname: String); procedure import_instrument_from_data_record; procedure import_sbi_instrument_alt(var data); procedure test_instrument_alt(chan: Byte; fkey: Word; loadMacros: Boolean; bankSelector: Boolean; loadArpVib: Boolean; test_ins1,test_ins2: Byte); procedure test_instrument_alt2(chan: Byte; fkey: Word); procedure fselect_external_proc; } procedure import_standard_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_standard_instrument_alt'; {$ENDIF} With temp_instrument do begin fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[6]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[7]; fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 3; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3; fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f; end; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure import_fin_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_fin_instrument_alt'; {$ENDIF} With temp_instrument do begin fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[6]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[7]; fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 7; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 7; fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f; end; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure import_hsc_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_hsc_instrument_alt'; {$ENDIF} With temp_instrument do begin fm_data.AM_VIB_EG_carrier := pBYTE(@data)[0]; fm_data.AM_VIB_EG_modulator := pBYTE(@data)[1]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[2]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[3]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[4]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[5]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[6]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[7]; fm_data.FEEDBACK_FM := pBYTE(@data)[8] AND $0f; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3; fm_data.WAVEFORM_modulator := pBYTE(@data)[10] AND 3; end; temp_instrument.panning := 0; temp_instrument.fine_tune := pBYTE(@data)[11] SHR 4; end; procedure import_sat_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_sat_instrument_alt'; {$ENDIF} With temp_instrument do begin fm_data.FEEDBACK_FM := pBYTE(@data)[0] AND $0f; fm_data.AM_VIB_EG_modulator := pBYTE(@data)[1]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[2]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[3]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[4]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[5]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[6]; fm_data.WAVEFORM_modulator := pBYTE(@data)[7] AND 3; fm_data.WAVEFORM_carrier := pBYTE(@data)[8] AND 3; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[9]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[10]; end; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure a2i_file_loader_alt(fname: String); type tOLD_HEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Byte; end; type tHEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Word; end; const id = '_A2ins_'; var f: File; header: tOLD_HEADER; header2: tHEADER; temp,temp2: Longint; crc: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:a2i_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); EXIT; end; If NOT (header.ffver in [1..FFVER_A2I]) then begin CloseF(f); EXIT; end; If (header.ffver in [1..4]) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf2,header.b0len,crc); If (crc <> header.crc16) then begin CloseF(f); EXIT; end; Case header.ffver of 4: Move(buf2,buf3,header.b0len); 3: LZSS_decompress(buf2,buf3,header.b0len); 2: LZW_decompress(buf2,buf3); 1: SIXPACK_decompress(buf2,buf3,header.b0len); end; Move(buf3,temp_instrument,SizeOf(temp_instrument)); temp_instrument.panning := 0; end; If (header.ffver in [5..8]) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf2,header.b0len,crc); If (crc <> header.crc16) then begin CloseF(f); EXIT; end; Case header.ffver of 8: Move(buf2,buf3,header.b0len); 7: LZSS_decompress(buf2,buf3,header.b0len); 6: LZW_decompress(buf2,buf3); 5: SIXPACK_decompress(buf2,buf3,header.b0len); end; Move(buf3,temp_instrument,SizeOf(temp_instrument)); end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); EXIT; end; BlockReadF(f,buf2,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; crc := WORD_NULL; crc := Update16(header2.b0len,1,crc); crc := Update16(buf2,header2.b0len,crc); If (crc <> header2.crc16) then begin CloseF(f); EXIT; end; APACK_decompress(buf2,buf3); Move(buf3,temp_instrument,SizeOf(temp_instrument)); end; If (header.ffver = FFVER_A2I) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); EXIT; end; BlockReadF(f,buf2,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; crc := WORD_NULL; crc := Update16(header2.b0len,1,crc); crc := Update16(buf2,header2.b0len,crc); If (crc <> header2.crc16) then begin CloseF(f); EXIT; end; progress_num_steps := 0; temp := 0; temp2 := LZH_decompress(buf2,buf3,header2.b0len); Move(buf3[temp],temp_instrument,SizeOf(temp_instrument)); Inc(temp,SizeOf(temp_instrument)); // instrument data Inc(temp,SUCC(buf3[temp])); // instrument name If (temp < temp2) then // more data present => 4op instrument begin Move(temp_instrument,temp_instrument2,SizeOf(temp_instrument2)); Move(buf3[temp],temp_instrument,SizeOf(temp_instrument)); Inc(temp,SizeOf(temp_instrument)); end; end; CloseF(f); load_flag_alt := 1; end; procedure a2f_file_loader_alt(fname: String); type tHEADER = Record ident: array[1..18] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; const id = '_a2ins_w/fm-macro_'; var f: File; header: tHEADER; crc,temp,temp2: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:a2f_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); FillChar(temp_instrument_macro,SizeOf(temp_instrument_macro),0); FillChar(temp_instrument_dis_fmreg_col,SizeOf(temp_instrument_dis_fmreg_col),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); EXIT; end; If NOT (header.ffver in [1..FFVER_A2F]) then begin CloseF(f); EXIT; end; If (header.ffver = 1) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,1,crc); crc := Update32(buf2,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); EXIT; end; APACK_decompress(buf2,buf3); Move(buf3,temp_instrument,SizeOf(temp_instrument)); Move(buf3[SizeOf(songdata.instr_data[current_inst])+ buf3[SizeOf(songdata.instr_data[current_inst])]+1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(buf3[SizeOf(songdata.instr_data[current_inst])+ buf3[SizeOf(songdata.instr_data[current_inst])]+1+ SizeOf(songdata.instr_macros[current_inst])], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); end; If (header.ffver = FFVER_A2F) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,1,crc); crc := Update32(buf2,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); EXIT; end; progress_num_steps := 0; temp := 0; temp2 := LZH_decompress(buf2,buf3,header.b0len); Move(buf3[temp],temp_instrument,SizeOf(temp_instrument)); Inc(temp,SizeOf(temp_instrument)); // instrument data Inc(temp,SUCC(buf3[temp])); // instrument name Move(buf3[temp],temp_instrument_macro, SizeOf(temp_instrument_macro)); Inc(temp,SizeOf(temp_instrument_macro)); // instrument macro Move(buf3[temp],temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); Inc(temp,SizeOf(temp_instrument_dis_fmreg_col)); // disabled FM-macro columns If (temp < temp2) then // more data present => 4op instrument begin Move(temp_instrument,temp_instrument2,SizeOf(temp_instrument2)); Move(temp_instrument_macro,temp_instrument_macro2,SizeOf(temp_instrument_macro2)); Move(temp_instrument_dis_fmreg_col,temp_instrument_dis_fmreg_col2,SizeOf(temp_instrument_dis_fmreg_col2)); Move(buf3[temp],temp_instrument,SizeOf(temp_instrument)); Inc(temp,SizeOf(temp_instrument)); Inc(temp,SUCC(buf3[temp])); Move(buf3[temp],temp_instrument_macro, SizeOf(temp_instrument_macro)); Inc(temp,SizeOf(temp_instrument_macro)); Move(buf3[temp],temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); end; end; CloseF(f); load_flag_alt := 1; end; procedure cif_file_loader_alt(fname: String); const id = ''+#26; type tCIF_DATA = Record ident: array[1..20] of Char; idata: tFM_INST_DATA; resrv: Byte; iname: array[1..20] of Char; end; var f: File; buffer: tCIF_DATA; temp: Longint; const MIN_CIF_SIZE = SizeOf(buffer.ident)+ SizeOf(buffer.idata)+ SizeOf(buffer.resrv); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:cif_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If NOT ((temp >= MIN_CIF_SIZE) and (buffer.ident = id)) then begin CloseF(f); EXIT; end; import_hsc_instrument_alt(buffer.idata); temp_instrument.fine_tune := 0; CloseF(f); load_flag_alt := 1; end; type tFIN_DATA = Record dname: array[1..12] of Char; iname: array[1..27] of Char; idata: tFM_INST_DATA; end; procedure fin_file_loader_alt(fname: String); var f: File; buffer: tFIN_DATA; temp: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:fin_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If (temp <> SizeOf(buffer)) then begin CloseF(f); EXIT; end; import_fin_instrument_alt(buffer.idata); CloseF(f); load_flag_alt := 1; end; procedure ins_file_loader_alt(fname: String); type tINS_DATA = Record idata: tFM_INST_DATA; slide: Byte; _SAdT: array[0..18] of Byte; end; var f: File; buffer: tINS_DATA; temp: Longint; function correct_ins(var data): Boolean; var result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:ins_file_loader_alt:correct_ins'; {$ENDIF} result := TRUE; If NOT (tADTRACK2_INS(data).fm_data.WAVEFORM_modulator in [0..3]) then result := FALSE; If NOT (tADTRACK2_INS(data).fm_data.WAVEFORM_carrier in [0..3]) then result := FALSE; If NOT (tADTRACK2_INS(data).fm_data.FEEDBACK_FM in [0..15]) then result := FALSE; correct_ins := result; end; begin { ins_file_loader_alt } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:ins_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; If (FileSize(f) > SizeOf(buffer)) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,FileSize(f),temp); If (temp <> FileSize(f)) then begin CloseF(f); EXIT; end; Case force_ins of 0: begin If (temp = 12) then import_standard_instrument_alt(buffer.idata); If (temp = 12) and NOT correct_ins(buffer.idata) then import_hsc_instrument_alt(buffer.idata) else If (temp > 12) then import_sat_instrument_alt(buffer.idata); end; 1: import_hsc_instrument_alt(buffer.idata); 2: import_sat_instrument_alt(buffer.idata); 3: import_standard_instrument_alt(buffer.idata); end; CloseF(f); load_flag_alt := 1; end; procedure sbi_file_loader_alt(fname: String); const id = 'SBI'+#26; type tSBI_DATA = Record ident: array[1..4] of Char; iname: array[1..32] of Char; idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; var f: File; buffer: tSBI_DATA; temp: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:sbi_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If NOT ((temp = SizeOf(buffer)) and (buffer.ident = id)) then begin CloseF(f); EXIT; end; import_standard_instrument_alt(buffer.idata); CloseF(f); load_flag_alt := 1; end; procedure sgi_file_loader_alt(fname: String); type tSGI_DATA = Record { 0} attack_m, { 1} decay_m, { 2} sustain_m, { 3} release_m, { 4} waveform_m, { 5} mfmult_m, { 6} ksl_m, { 7} volume_m, { 8} ksr_m, { 9} tremolo_m, {10} vibrato_m, {11} eg_type_m, {12} attack_c, {13} decay_c, {14} sustain_c, {15} release_c, {16} waveform_c, {17} mfmult_c, {18} ksl_c, {19} volume_c, {20} ksr_c, {21} tremolo_c, {22} vibrato_c, {23} eg_type_c, {24} feedback, {25} fm: Byte; end; var f: File; buffer: tSGI_DATA; temp: Longint; procedure import_sgi_instrument(inst: Byte; var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:sgi_file_loader_alt:import_sgi_instrument'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); With temp_instrument do begin fm_data.ATTCK_DEC_modulator := (pBYTE(@data)[1] AND $0f)+ (pBYTE(@data)[0] AND $0f) SHL 4; fm_data.SUSTN_REL_modulator := (pBYTE(@data)[3] AND $0f)+ (pBYTE(@data)[2] AND $0f) SHL 4; fm_data.WAVEFORM_modulator := (pBYTE(@data)[4] AND 3); fm_data.KSL_VOLUM_modulator := (pBYTE(@data)[7] AND $3f)+ (pBYTE(@data)[6] AND 3) SHL 6; fm_data.AM_VIB_EG_modulator := (pBYTE(@data)[5] AND $0f)+ (pBYTE(@data)[8] AND 1) SHL 4+ (pBYTE(@data)[11] AND 1) SHL 5+ (pBYTE(@data)[10] AND 1) SHL 6+ (pBYTE(@data)[9] AND 1) SHL 7; fm_data.ATTCK_DEC_carrier := (pBYTE(@data)[13] AND $0f)+ (pBYTE(@data)[12] AND $0f) SHL 4; fm_data.SUSTN_REL_carrier := (pBYTE(@data)[15] AND $0f)+ (pBYTE(@data)[14] AND $0f) SHL 4; fm_data.WAVEFORM_carrier := (pBYTE(@data)[16] AND 3); fm_data.KSL_VOLUM_carrier := (pBYTE(@data)[19] AND $3f)+ (pBYTE(@data)[18] AND 3) SHL 6; fm_data.AM_VIB_EG_carrier := (pBYTE(@data)[17] AND $0f)+ (pBYTE(@data)[20] AND 1) SHL 4+ (pBYTE(@data)[23] AND 1) SHL 5+ (pBYTE(@data)[22] AND 1) SHL 6+ (pBYTE(@data)[21] AND 1) SHL 7; fm_data.FEEDBACK_FM := (pBYTE(@data)[25] AND 1)+ (pBYTE(@data)[24] AND 7) SHL 1; end; end; begin { sgi_file_loader_alt } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:sgi_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If (temp <> SizeOf(buffer)) then begin CloseF(f); EXIT; end; import_sgi_instrument(current_inst,buffer); CloseF(f); load_flag_alt := 1; end; procedure import_sbi_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_sbi_instrument_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); With temp_instrument do begin fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[6]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[7]; fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 3; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3; fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f; end; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure ibk_file_loader_alt(instr: Word); const id = 'IBK'+#26; var f: File; header: array[1..4] of Char; temp: Longint; instrument_data: Record idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:ibk_file_loader_alt'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header <> id) then begin CloseF(f); EXIT; end; SeekF(f,$004+PRED(instr)*SizeOf(instrument_data)); If (IOresult <> 0) then EXIT; BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); EXIT; end; import_sbi_instrument_alt(instrument_data); CloseF(f); load_flag_alt := 1; end; var ins__fmreg_table_backup: tREGISTER_TABLE; ins__fmreg_table_backup2: tREGISTER_TABLE; ins__dis_fmreg_col_backup: tDIS_FMREG_COL; ins__dis_fmreg_col_backup2: tDIS_FMREG_COL; arp_vib_macro_table_backup: tARP_VIB_MACRO_TABLE; chan_handle: array[1..20] of Byte; procedure test_instrument_alt(chan: Byte; fkey: Word; loadMacros: Boolean; bankSelector: Boolean; loadArpVib: Boolean; test_ins1,test_ins2: Byte); var temp,temp2,temp3,temp5: Byte; valid_key,temp4: Boolean; temps: String; channels: Byte; function output_note(chan,board_pos: Byte): Boolean; var note: Byte; freq: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:test_instrument_alt:output_note'; {$ENDIF} note := board_pos+12*(current_octave-1); If NOT (note in [0..12*8+1]) then begin output_note := FALSE; EXIT; end; chan_handle[chan] := board_scancodes[board_pos]; If (test_ins2 <> 0) then chan := _4op_main_chan[chan]; load_instrument(temp_instrument,chan); If percussion_mode and (temp_instrument.perc_voice in [4,5]) then load_instrument(temp_instrument,_perc_sim_chan[chan]); If (test_ins2 <> 0) then load_instrument(temp_instrument2,PRED(chan)); macro_speedup := songdata.macro_speedup; If (play_status = isStopped) then update_timer(songdata.tempo); freq := nFreq(note-1)+$2000+ SHORTINT(pBYTE(@Addr(temp_instrument)^)[12]); event_table[chan].note := note; freq_table[chan] := freq; freqtable2[chan] := freq; key_on(chan); change_freq(chan,freq); If (test_ins2 = 0) then init_macro_table(chan,note,test_ins1,freq) else begin init_macro_table(chan,note,test_ins1,freq); freq_table[PRED(chan)] := freq; freqtable2[PRED(chan)] := freq; init_macro_table(PRED(chan),note,test_ins2,freq); end; end; begin { test_instrument_alt } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:test_instrument_alt'; {$ENDIF} valid_key := FALSE; For temp := 1 to 29 do If NOT shift_pressed then If (board_scancodes[temp] = HI(fkey)) then begin valid_key := TRUE; BREAK; end; If scankey(SC_F7) then For temp := 1 to 20 do reset_chan_data(temp); If NOT valid_key or NOT (temp+12*(current_octave-1)-1 in [0..12*8+1]) then EXIT; If NOT percussion_mode then channels := 18 else channels := 15; FillChar(temp_instrument,SizeOf(temp_instrument),0); FillChar(temp_instrument2,SizeOf(temp_instrument2),0); temp2 := temp; If bankSelector or loadArpVib then If NOT loadArpVib then begin temps := ''; load_flag_alt := BYTE_NULL; If (test_ins2 = 0) then begin Move(temp_songdata.instr_data[test_ins1], temp_instrument, SizeOf(temp_instrument)); Move(temp_songdata.instr_macros[test_ins1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(temp_songdata.dis_fmreg_col[test_ins1], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); end else begin Move(temp_songdata.instr_data[test_ins1], temp_instrument, SizeOf(temp_instrument)); Move(temp_songdata.instr_macros[test_ins1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(temp_songdata.dis_fmreg_col[test_ins1], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); Move(temp_songdata.instr_data[test_ins2], temp_instrument2, SizeOf(temp_instrument2)); Move(temp_songdata.instr_macros[test_ins2], temp_instrument_macro2, SizeOf(temp_instrument_macro2)); Move(temp_songdata.dis_fmreg_col[test_ins2], temp_instrument_dis_fmreg_col2, SizeOf(temp_instrument_dis_fmreg_col2)); end; end else begin load_flag_alt := BYTE_NULL; If (test_ins2 = 0) then begin Move(songdata.instr_data[test_ins1], temp_instrument, SizeOf(temp_instrument)); Move(songdata.instr_macros[test_ins1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(songdata.dis_fmreg_col[test_ins1], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); end else begin Move(songdata.instr_data[test_ins1], temp_instrument, SizeOf(temp_instrument)); Move(songdata.instr_macros[test_ins1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(songdata.dis_fmreg_col[test_ins1], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); Move(songdata.instr_data[test_ins2], temp_instrument2, SizeOf(temp_instrument2)); Move(songdata.instr_macros[test_ins2], temp_instrument_macro2, SizeOf(temp_instrument_macro2)); Move(songdata.dis_fmreg_col[test_ins2], temp_instrument_dis_fmreg_col2, SizeOf(temp_instrument_dis_fmreg_col2)); end; end else begin temps := mn_environment.curr_item; load_flag_alt := BYTE_NULL; {$IFDEF GO32V2} keyboard_toggle_sleep; {$ENDIF} If (Lower(ExtOnly(temps)) = 'a2i') then a2i_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'a2f') then a2f_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'cif') then cif_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'fin') then fin_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'ins') then ins_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'sbi') then sbi_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'sgi') then sgi_file_loader_alt(temps); {$IFDEF GO32V2} keyboard_toggle_sleep; {$ENDIF} If (load_flag_alt = BYTE_NULL) then EXIT; end; If (test_ins2 <> 0) and Empty(temp_instrument2,SizeOf(temp_instrument2)) and Empty(temp_instrument_macro2,SizeOf(temp_instrument_macro2)) then test_ins2 := 0; Move(songdata.macro_table, arp_vib_macro_table_backup, SizeOf(arp_vib_macro_table_backup)); If loadArpVib then begin If arp_tab_selected then begin temp_instrument_macro.arpeggio_table := arpvib_arpeggio_table; Move(temp_songdata.macro_table[arpvib_arpeggio_table].arpeggio, songdata.macro_table[arpvib_arpeggio_table].arpeggio, SizeOf(songdata.macro_table[arpvib_arpeggio_table])); end else temp_instrument_macro.arpeggio_table := 0; If vib_tab_selected then begin temp_instrument_macro.vibrato_table := arpvib_vibrato_table; Move(temp_songdata.macro_table[arpvib_vibrato_table].vibrato, songdata.macro_table[arpvib_vibrato_table].vibrato, SizeOf(songdata.macro_table[arpvib_vibrato_table])); end else temp_instrument_macro.vibrato_table := 0; If (test_ins2 = 0) then Move(temp_instrument_macro, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])) else begin Move(temp_instrument_macro, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(temp_instrument_macro2, songdata.instr_macros[test_ins2], SizeOf(songdata.instr_macros[test_ins2])); end; end else If bankSelector and loadMacros then begin If (temp_instrument_macro.arpeggio_table <> 0) then Move(temp_songdata.macro_table[temp_instrument_macro.arpeggio_table].arpeggio, songdata.macro_table[temp_instrument_macro.arpeggio_table].arpeggio, SizeOf(songdata.macro_table[temp_instrument_macro.arpeggio_table])); If (temp_instrument_macro.vibrato_table <> 0) then Move(temp_songdata.macro_table[temp_instrument_macro.vibrato_table].vibrato, songdata.macro_table[temp_instrument_macro.vibrato_table].vibrato, SizeOf(songdata.macro_table[temp_instrument_macro.vibrato_table])); end; If (Empty(temp_instrument,SizeOf(temp_instrument)) and Empty(temp_instrument_macro,SizeOf(temp_instrument_macro))) or ((test_ins2 <> 0) and Empty(temp_instrument2,SizeOf(temp_instrument2)) and Empty(temp_instrument_macro2,SizeOf(temp_instrument_macro2))) then EXIT; ins_trailing_flag := TRUE; status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; really_no_status_refresh := TRUE; reset_player; If (Lower(ExtOnly(temps)) = 'a2f') or loadMacros or loadArpVib then If (test_ins2 = 0) then begin Move(songdata.instr_macros[test_ins1], ins__fmreg_table_backup, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins1], ins__dis_fmreg_col_backup, SizeOf(ins__dis_fmreg_col_backup)); Move(temp_instrument_macro, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(temp_instrument_dis_fmreg_col, songdata.dis_fmreg_col[test_ins1], SizeOf(songdata.dis_fmreg_col[test_ins1])); end else begin Move(songdata.instr_macros[test_ins1], ins__fmreg_table_backup, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins1], ins__dis_fmreg_col_backup, SizeOf(ins__dis_fmreg_col_backup)); Move(temp_instrument_macro, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(temp_instrument_dis_fmreg_col, songdata.dis_fmreg_col[test_ins1], SizeOf(songdata.dis_fmreg_col[test_ins1])); Move(songdata.instr_macros[test_ins2], ins__fmreg_table_backup2, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins2], ins__dis_fmreg_col_backup2, SizeOf(ins__dis_fmreg_col_backup)); Move(temp_instrument_macro2, songdata.instr_macros[test_ins2], SizeOf(songdata.instr_macros[test_ins2])); Move(temp_instrument_dis_fmreg_col2, songdata.dis_fmreg_col[test_ins2], SizeOf(songdata.dis_fmreg_col[test_ins2])); end else begin Move(songdata.instr_macros[test_ins1], ins__fmreg_table_backup, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins1], ins__dis_fmreg_col_backup, SizeOf(ins__dis_fmreg_col_backup)); FillChar(songdata.instr_macros[test_ins1],SizeOf(songdata.instr_macros[test_ins1]),0); FillChar(songdata.dis_fmreg_col[test_ins1],SizeOf(songdata.dis_fmreg_col[test_ins1]),0); If (test_ins2 <> 0) then begin Move(songdata.instr_macros[test_ins2], ins__fmreg_table_backup2, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins2], ins__dis_fmreg_col_backup2, SizeOf(ins__dis_fmreg_col_backup)); FillChar(songdata.instr_macros[test_ins2],SizeOf(songdata.instr_macros[test_ins2]),0); FillChar(songdata.dis_fmreg_col[test_ins2],SizeOf(songdata.dis_fmreg_col[test_ins2]),0); end; end; Move(channel_flag,channel_flag_backup,SizeOf(channel_flag_backup)); Move(event_table,event_table_backup,SizeOf(event_table_backup)); common_flag_backup := songdata.common_flag; volume_scaling_backup := volume_scaling; songdata.common_flag := songdata.common_flag AND NOT $80; volume_scaling := FALSE; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); Move(pan_lock,pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); flag_4op_backup := songdata.flag_4op; If NOT percussion_mode and NOT (songdata.flag_4op <> 0) then channels := 18 else If NOT (songdata.flag_4op <> 0) then channels := 15 else If (test_ins2 <> 0) then begin songdata.flag_4op := $3f; channels := 6; end else begin songdata.flag_4op := 0; If NOT percussion_mode then channels := 18 else channels := 15; end; reset_player; FillChar(chan_handle,SizeOf(chan_handle),0); Move(fmpar_table,fmpar_table_backup,SizeOf(fmpar_table_backup)); Move(volume_table,volume_table_backup,SizeOf(volume_table_backup)); Move(freq_table,freq_table_backup,SizeOf(freq_table)); Move(freqtable2,freqtable2_backup,SizeOf(freqtable2)); Move(keyoff_loop,keyoff_loop_backup,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); misc_register := current_tremolo_depth SHL 7+ current_vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; key_off(17); key_off(18); opl2out(_instr[11],misc_register); If percussion_mode and (temp_instrument.perc_voice in [1..5]) then begin output_note(temp_instrument.perc_voice+15,temp2); While scankey(board_scancodes[temp2]) do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; end else Repeat valid_key := FALSE; For temp := 1 to 29 do begin temp2 := board_scancodes[temp]; temp4 := scankey(temp2); If NOT ((songdata.flag_4op <> 0) and (test_ins2 <> 0)) then begin temp3 := get_chanpos(chan_handle,channels,temp2); temp5 := get_chanpos(chan_handle,channels,0); end else begin temp3 := get_chanpos2(chan_handle,channels,temp2); temp5 := get_chanpos2(chan_handle,channels,0); end; If temp4 then valid_key := TRUE; If temp4 and (temp3 = 0) and (temp5 <> 0) then output_note(temp5,temp); If NOT temp4 and (temp3 <> 0) then begin chan_handle[temp3] := 0; key_off(temp3); If alt_pressed then keyoff_loop[temp3] := TRUE; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; until NOT valid_key; While ctrl_pressed do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; For temp := 1 to 20 do key_off(temp); Move(ins__fmreg_table_backup, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(ins__dis_fmreg_col_backup, songdata.dis_fmreg_col[test_ins1], SizeOf(songdata.dis_fmreg_col[test_ins1])); If (test_ins2 <> 0) then begin Move(ins__fmreg_table_backup, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(ins__dis_fmreg_col_backup, songdata.dis_fmreg_col[test_ins1], SizeOf(songdata.dis_fmreg_col[test_ins1])); Move(ins__fmreg_table_backup2, songdata.instr_macros[test_ins2], SizeOf(songdata.instr_macros[test_ins2])); Move(ins__dis_fmreg_col_backup2, songdata.dis_fmreg_col[test_ins2], SizeOf(songdata.dis_fmreg_col[test_ins2])); end; Move(arp_vib_macro_table_backup, songdata.macro_table, SizeOf(songdata.macro_table)); songdata.flag_4op := flag_4op_backup; Move(fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(volume_table_backup,volume_table,SizeOf(volume_table)); Move(panning_table_backup,panning_table,SizeOf(panning_table)); songdata.common_flag := common_flag_backup; volume_scaling := volume_scaling_backup; If (status_backup.play_status = isPlaying) then reset_player; Move(channel_flag_backup,channel_flag,SizeOf(channel_flag)); Move(event_table_backup,event_table,SizeOf(event_table)); Move(pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(peak_lock_backup,peak_lock,SizeOf(volume_lock)); really_no_status_refresh := FALSE; Move(freq_table_backup,freq_table,SizeOf(freq_table)); Move(freqtable2_backup,freqtable2,SizeOf(freqtable2)); Move(keyoff_loop_backup,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; ins_trailing_flag := FALSE; keyboard_reset_buffer; end; procedure test_instrument_alt2(chan: Byte; fkey: Word); var temp,temp2,temp3,temp5: Byte; valid_key,temp4: Boolean; temps: String; channels: Byte; function output_note(chan,board_pos: Byte): Boolean; var note: Byte; freq: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:test_instrument_alt2:output_note'; {$ENDIF} note := board_pos+12*(current_octave-1); If NOT (note in [0..12*8+1]) then begin output_note := FALSE; EXIT; end; chan_handle[chan] := board_scancodes[board_pos]; load_instrument(temp_instrument,chan); If percussion_mode and (temp_instrument.perc_voice in [4,5]) then load_instrument(temp_instrument,_perc_sim_chan[chan]); freq := nFreq(note-1)+$2000+ SHORTINT(pBYTE(@Addr(temp_instrument)^)[12]); event_table[chan].note := note; freq_table[chan] := freq; freqtable2[chan] := freq; key_on(chan); change_freq(chan,freq); macro_speedup := songdata.macro_speedup; If (play_status = isStopped) then update_timer(songdata.tempo); freq_table[chan] := freq; freqtable2[chan] := freq; init_macro_table(chan,note,current_inst,freq); end; begin { test_instrument_alt2 } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:test_instrument_alt2'; {$ENDIF} valid_key := FALSE; For temp := 1 to 29 do If NOT shift_pressed then If (board_scancodes[temp] = HI(fkey)) then begin valid_key := TRUE; BREAK; end; If scankey(SC_F7) then For temp := 1 to 20 do reset_chan_data(temp); If NOT valid_key or NOT (temp+12*(current_octave-1)-1 in [0..12*8+1]) then EXIT; If NOT percussion_mode then channels := 18 else channels := 15; temp2 := temp; temps := mn_environment.curr_item; load_flag_alt := BYTE_NULL; If Empty(temp_instrument,SizeOf(temp_instrument)) then EXIT; {$IFDEF GO32V2} keyboard_toggle_sleep; {$ENDIF} If (Lower(ExtOnly(temps)) = 'bnk') then bnk_file_loader_alt(Str2num(BaseNameOnly(mn_environment.curr_item),10)) else If (Lower(ExtOnly(temps)) = 'fib') then fib_file_loader_alt(Str2num(BaseNameOnly(mn_environment.curr_item),10)) else If (Lower(ExtOnly(temps)) = 'ibk') then ibk_file_loader_alt(Str2num(BaseNameOnly(mn_environment.curr_item),10)); {$IFDEF GO32V2} keyboard_toggle_sleep; {$ENDIF} If (load_flag_alt = BYTE_NULL) then EXIT; ins_trailing_flag := TRUE; status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; really_no_status_refresh := TRUE; reset_player; Move(channel_flag,channel_flag_backup,SizeOf(channel_flag_backup)); Move(event_table,event_table_backup,SizeOf(event_table_backup)); common_flag_backup := songdata.common_flag; volume_scaling_backup := volume_scaling; songdata.common_flag := songdata.common_flag AND NOT $80; volume_scaling := FALSE; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); flag_4op_backup := songdata.flag_4op; If NOT percussion_mode and NOT (songdata.flag_4op <> 0) then channels := 18 else If NOT (songdata.flag_4op <> 0) then channels := 15 else begin songdata.flag_4op := 0; If NOT percussion_mode then channels := 18 else channels := 15; end; reset_player; FillChar(chan_handle,SizeOf(chan_handle),0); Move(pan_lock,pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); Move(fmpar_table,fmpar_table_backup,SizeOf(fmpar_table_backup)); Move(volume_table,volume_table_backup,SizeOf(volume_table_backup)); Move(freq_table,freq_table_backup,SizeOf(freq_table)); Move(freqtable2,freqtable2_backup,SizeOf(freqtable2)); Move(keyoff_loop,keyoff_loop_backup,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); misc_register := current_tremolo_depth SHL 7+ current_vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; key_off(17); key_off(18); opl2out(_instr[11],misc_register); If percussion_mode and (temp_instrument.perc_voice in [1..5]) then begin output_note(temp_instrument.perc_voice+15,temp2); While scankey(board_scancodes[temp2]) do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; end else Repeat valid_key := FALSE; For temp := 1 to 29 do begin temp2 := board_scancodes[temp]; temp3 := get_chanpos(chan_handle,channels,temp2); temp4 := scankey(temp2); temp5 := get_chanpos(chan_handle,channels,0); If temp4 then valid_key := TRUE; If temp4 and (temp3 = 0) and (temp5 <> 0) then output_note(temp5,temp); If NOT temp4 and (temp3 <> 0) then begin chan_handle[temp3] := 0; key_off(temp3); If alt_pressed then keyoff_loop[temp3] := TRUE; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; until NOT valid_key; While ctrl_pressed do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; For temp := 1 to 20 do key_off(temp); songdata.flag_4op := flag_4op_backup; Move(fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(volume_table_backup,volume_table,SizeOf(volume_table)); Move(panning_table_backup,panning_table,SizeOf(panning_table)); songdata.common_flag := common_flag_backup; volume_scaling := volume_scaling_backup; If (status_backup.play_status = isPlaying) then reset_player; Move(channel_flag_backup,channel_flag,SizeOf(channel_flag)); Move(event_table_backup,event_table,SizeOf(event_table)); Move(pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(peak_lock_backup,peak_lock,SizeOf(volume_lock)); really_no_status_refresh := FALSE; Move(freq_table_backup,freq_table,SizeOf(freq_table)); Move(freqtable2_backup,freqtable2,SizeOf(freqtable2)); Move(keyoff_loop_backup,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; ins_trailing_flag := FALSE; keyboard_reset_buffer; end; procedure fselect_external_proc; var test_ins1: Byte; test_ins2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:fselect_external_proc'; {$ENDIF} If (songdata.flag_4op <> 0) then begin If (current_inst < 255) then test_ins1 := current_inst else test_ins1 := PRED(current_inst); test_ins2 := SUCC(test_ins1); end else begin test_ins1 := current_inst; test_ins2 := 0; end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt(count_channel(pattern_hpos), mn_environment.keystroke, FALSE,FALSE,FALSE, test_ins1,test_ins2); end; adlibtracker2-2.4.23/menulib2.pas0000644000000000000000000004503113176573532015252 0ustar rootrootunit MenuLib2; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface uses DOS, AdT2unit,AdT2sys,AdT2keyb,AdT2ext2, DialogIO,TxtScrIO,StringIO,ParserIO; const MenuLib2_mn_setting: Record frame_type: String; shadow_enabled: Boolean; posbar_enabled: Boolean; title_attr, menu_attr, text_attr, text2_attr, default_attr, short_attr, short2_attr, disbld_attr, contxt_attr, contxt2_attr: Byte; center_box: Boolean; cycle_moves: Boolean; edit_contents: Boolean; reverse_use: Boolean; fixed_len: Byte; terminate_keys: array[1..50] of Word; end = (frame_type: frame_single; shadow_enabled: TRUE; posbar_enabled: TRUE; title_attr: $0f; menu_attr: $07; text_attr: $07; text2_attr: $70; default_attr: $0f; short_attr: $0f; short2_attr: $70; disbld_attr: $07; contxt_attr: $0f; contxt2_attr: $07; center_box: TRUE; cycle_moves: TRUE; edit_contents: FALSE; reverse_use: FALSE; fixed_len: 0; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); var MenuLib2_mn_environment: Record v_dest: tSCREEN_MEM_PTR; keystroke: Word; context: String; unpolite: Boolean; winshade: Boolean; edit_pos: Byte; curr_pos: Word; ext_proc: procedure; refresh: procedure; do_refresh: Boolean; preview: Boolean; descr_len: Byte; descr: Pointer; end; function MenuLib2_Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure MenuLib2_Init; implementation type tDBUFFR = array[1.. 100] of Record str: String; pos: Byte; key: Char; use: Boolean; end; type tMBUFFR = array[1..16384] of Record key: Char; use: Boolean; end; var idx,idx2,max,len2b,page, first,last,temp,temp2,opage,opos: Word; old_fr_shadow_enabled: Boolean; key: Word; solid: Boolean; qflg: Boolean; mbuf: tMBUFFR; contxt: String; var mnu_x,mnu_y,mnu_len,mnu_len2: Byte; mnu_data: Pointer; mnu_count: Word; var vscrollbar_pos: Word; function OutKey(str: String): Char; var result: Char; begin If (SYSTEM.Pos('~',str) = 0) then result := '~' else If (str[SYSTEM.Pos('~',str)+2] <> '~') then result := '~' else result := str[SYSTEM.Pos('~',str)+1]; OutKey := result; end; function pstr(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:pstr'; {$ENDIF} Move(POINTER(Ptr(0,Ofs(mnu_data^)+(item-1)*(mnu_len+1)))^,temp,mnu_len+1); If NOT solid then pstr := ExpStrR(temp,mnu_len-2,' ') else pstr := ExpStrR(temp,mnu_len,' '); end; function pdes(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:pdes'; {$ENDIF} If (mn_environment.descr <> NIL) then Move(POINTER(Ptr(0,Ofs(mn_environment.descr^)+ (item-1)*(mn_environment.descr_len+1)))^,temp,mn_environment.descr_len+1) else temp := ''; pdes := ExpStrR(temp,mn_environment.descr_len,' '); end; procedure refresh; procedure ShowCStr_clone(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); var temp,len: Byte; highlighted: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:refresh:ShowCStr_clone'; {$ENDIF} If NOT (MenuLib2_mn_setting.fixed_len <> 0) then begin ShowCStr(dest,x,y,str,atr1,atr2); EXIT; end; highlighted := FALSE; len := 0; For temp := 1 to Length(str) do If (str[temp] = '~') then highlighted := NOT highlighted else begin If (len < MenuLib2_mn_setting.fixed_len) then begin If NOT highlighted then ShowStr(dest,x+len,y,str[temp],atr1) else ShowStr(dest,x+len,y,str[temp],atr2); Inc(len); end else begin If NOT highlighted then ShowStr(dest,x+len,y,str[temp],atr3) else ShowStr(dest,x+len,y,str[temp],atr4); Inc(len); end end; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:refresh'; {$ENDIF} If (page = opage) and (idx2 = opos) and NOT MenuLib2_mn_environment.do_refresh then EXIT else begin opage := page; opos := idx2; MenuLib2_mn_environment.do_refresh := FALSE; end; For idx := page to mnu_len2+page-1 do If (idx = idx2+page-1) then ShowCStr_clone(MenuLib2_mn_environment.v_dest,mnu_x+1,mnu_y+idx2, ExpStrR(pstr(idx2+page-1)+pdes(idx2+page-1), max+(Length(pstr(idx2+page-1))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx2+page-1)+pdes(idx2+page-1))),' '), MenuLib2_mn_setting.text2_attr,MenuLib2_mn_setting.short2_attr, MenuLib2_mn_setting.text_attr,MenuLib2_mn_setting.short_attr) else If mbuf[idx].use then ShowCStr(MenuLib2_mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(pstr(idx)+pdes(idx), max+(Length(pstr(idx))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx)+pdes(idx))),' '), MenuLib2_mn_setting.text_attr,MenuLib2_mn_setting.short_attr) else ShowCStr(MenuLib2_mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(pstr(idx)+pdes(idx), max+(Length(pstr(idx))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx)+pdes(idx))),' '), MenuLib2_mn_setting.disbld_attr,MenuLib2_mn_setting.disbld_attr); vscrollbar_pos := VScrollBar(MenuLib2_mn_environment.v_dest,mnu_x+max+1,mnu_y+1,temp2,mnu_count,idx2+page-1, vscrollbar_pos,MenuLib2_mn_setting.menu_attr,MenuLib2_mn_setting.menu_attr); end; function MenuLib2_Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure SubPos(var p: Word); var temp: Word; begin temp := p; If (temp > 1) and mbuf[temp+page-2].use then Dec(temp) else If (temp > 1) then begin Dec(temp); SubPos(temp); end else If (page > first) then Dec(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 > first) then SubPos(temp); end; procedure AddPos(var p: Word); var temp: Word; begin temp := p; If (temp < len2) and (temp < last) and mbuf[temp+page].use then Inc(temp) else If (temp < len2) and (temp < last) then begin Inc(temp); AddPos(temp); end else If (page+temp <= last) then Inc(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 < last) then AddPos(temp); end; function RetKey(code: Byte): Word; var temp: Byte; begin RetKey := 0; For temp := 1 to count do If (UpCase(mbuf[temp].key) = UpCase(CHR(code))) then begin RetKey := temp; BREAK; end; end; procedure edit_contents(item: Word); var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:MenuLib2_Menu:edit_contents'; {$ENDIF} is_setting.append_enabled := TRUE; is_setting.character_set := [#32..#255]; is_environment.locate_pos := 1; If (MenuLib2_mn_environment.edit_pos > 0) and (MenuLib2_mn_environment.edit_pos < max-2) then temp := Copy(pstr(item),MenuLib2_mn_environment.edit_pos+1, Length(pstr(item))-MenuLib2_mn_environment.edit_pos+1) else temp := CutStr(pstr(item)); While (temp <> '') and (temp[Length(temp)] = ' ') do Delete(temp,Length(temp),1); temp := InputStr(temp,x+1+MenuLib2_mn_environment.edit_pos,y+idx2, max-2-MenuLib2_mn_environment.edit_pos+1, max-2-MenuLib2_mn_environment.edit_pos+1, MenuLib2_mn_setting.text2_attr,MenuLib2_mn_setting.default_attr); If (is_environment.keystroke = kENTER) then begin If (MenuLib2_mn_environment.edit_pos > 0) and (MenuLib2_mn_environment.edit_pos < max-2) then temp := Copy(pstr(item),1,MenuLib2_mn_environment.edit_pos)+temp else temp := CutStr(temp); Move(temp,POINTER(Ptr(0,Ofs(data)+(item-1)*(len+1)))^,len+1); end; ShowCStr(MenuLib2_mn_environment.v_dest,x+1,y+idx2, ExpStrR(pstr(item),max+(Length(pstr(item)))- CStrLen(pstr(item)),' '), MenuLib2_mn_setting.text2_attr,MenuLib2_mn_setting.short2_attr); end; begin { MenuLib2_Menu } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:MenuLib2_Menu'; {$ENDIF} If (count = 0) then begin MenuLib2_Menu := 0; EXIT; end; max := Length(title); mnu_data := Addr(data); mnu_count := count; mnu_len := len; If NOT MenuLib2_mn_environment.unpolite then ScreenMemCopy(MenuLib2_mn_environment.v_dest,ptr_scr_backup); If (count < 1) then EXIT; vscrollbar_pos := BYTE_NULL; If NOT MenuLib2_mn_environment.preview then HideCursor; temp := 0; For idx := 1 to count do begin mbuf[idx].key := OutKey(pstr(idx)); If NOT MenuLib2_mn_setting.reverse_use then mbuf[idx].use := mbuf[idx].key <> '~' else mbuf[idx].use := NOT (mbuf[idx].key <> '~'); If mbuf[idx].use then temp := 1; end; solid := FALSE; If (temp = 0) then begin For temp := 1 to count do mbuf[temp].use := TRUE; solid := TRUE; end; For idx := 1 to count do If (max < CStrLen(pstr(idx))+MenuLib2_mn_environment.descr_len) then max := CStrLen(pstr(idx))+MenuLib2_mn_environment.descr_len; If MenuLib2_mn_setting.center_box then begin x := (work_MaxCol-max-2) DIV 2+(work_MaxCol-max-2) MOD 2; y := (work_MaxLn-len2-1) DIV 2+(work_MaxLn-len2-1) MOD 2; end; mnu_x := x; mnu_y := y; len2b := len2; If NOT MenuLib2_mn_environment.unpolite then begin old_fr_shadow_enabled := fr_setting.shadow_enabled; fr_setting.shadow_enabled := MenuLib2_mn_setting.shadow_enabled; fr_setting.update_area := FALSE; Frame(MenuLib2_mn_environment.v_dest,x,y,x+max+1,y+len2+1,MenuLib2_mn_setting.menu_attr, title,MenuLib2_mn_setting.title_attr,MenuLib2_mn_setting.frame_type); fr_setting.update_area := TRUE; fr_setting.shadow_enabled := old_fr_shadow_enabled; contxt := DietStr(MenuLib2_mn_environment.context,max+ (Length(MenuLib2_mn_environment.context)-CStrLen(MenuLib2_mn_environment.context))); ShowCStr(MenuLib2_mn_environment.v_dest,x+max+1-CStrLen(contxt),y+len2+1, contxt,MenuLib2_mn_setting.contxt_attr,MenuLib2_mn_setting.contxt2_attr); temp2 := len2; If (len2 > count) then len2 := count; If (len2 < 1) then len2 := 1; If (spos < 1) then spos := 1; If (spos > count) then spos := count; mnu_len2 := len2; MenuLib2_mn_environment.refresh := refresh; first := 1; last := count; While NOT mbuf[first].use do Inc(first); While NOT mbuf[last].use do Dec(last); If (spos < first) or (spos > last) then spos := first; idx2 := 1; page := 1; opage := WORD_NULL; opos := WORD_NULL; While (idx2+page-1 < spos) do AddPos(idx2); end; MenuLib2_mn_environment.curr_pos := idx2+page-1; MenuLib2_mn_environment.keystroke := WORD_NULL; If (Addr(MenuLib2_mn_environment.ext_proc) <> NIL) then MenuLib2_mn_environment.ext_proc; qflg := FALSE; If MenuLib2_mn_environment.preview then begin MenuLib2_mn_environment.preview := FALSE; MenuLib2_mn_environment.unpolite := TRUE; refresh; end else Repeat key := getkey; If LookUpKey(key,MenuLib2_mn_setting.terminate_keys,50) then If NOT ((key = MenuLib2_mn_setting.terminate_keys[2]) and MenuLib2_mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx2+page-1); If NOT qflg then If (LO(key) in [$20..$0ff]) then begin idx := RetKey(LO(key)); If (idx <> 0) then begin refresh; idx2 := idx; If NOT ((key = MenuLib2_mn_setting.terminate_keys[2]) and MenuLib2_mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx); end; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then Case key of kUP: If (page+idx2-1 > first) or NOT MenuLib2_mn_setting.cycle_moves then SubPos(idx2) else begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kDOWN: If (page+idx2-1 < last) or NOT MenuLib2_mn_setting.cycle_moves then AddPos(idx2) else begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kHOME: begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kEND: begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kPgUP: For temp := 1 to len2-1 do SubPos(idx2); kPgDOWN: For temp := 1 to len2-1 do AddPos(idx2); end; MenuLib2_mn_environment.curr_pos := idx2+page-1; refresh; MenuLib2_mn_environment.keystroke := key; If (Addr(MenuLib2_mn_environment.ext_proc) <> NIL) then MenuLib2_mn_environment.ext_proc; {$IFDEF GO32V2} // draw_screen; keyboard_reset_buffer_alt; {$ELSE} draw_screen; // keyboard_reset_buffer; {$ENDIF} until qflg or _force_program_quit; If MenuLib2_mn_environment.winshade and NOT MenuLib2_mn_environment.unpolite then begin If (Addr(move_to_screen_routine) <> NIL) then begin move_to_screen_data := ptr_scr_backup; move_to_screen_area[1] := x; move_to_screen_area[2] := y; move_to_screen_area[3] := x+max+1+2; move_to_screen_area[4] := y+len2b+1+1; move_to_screen_routine; end else ScreenMemCopy(ptr_scr_backup,MenuLib2_mn_environment.v_dest); end; MenuLib2_Menu := idx2+page-1; end; procedure MenuLib2_Init; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:MenuLib2_Init'; {$ENDIF} MenuLib2_mn_setting.frame_type := frame_single; MenuLib2_mn_setting.center_box := FALSE; MenuLib2_mn_setting.shadow_enabled := FALSE; MenuLib2_mn_setting.cycle_moves := FALSE; MenuLib2_mn_setting.title_attr := dialog_background+dialog_title; MenuLib2_mn_setting.menu_attr := dialog_background+dialog_text; MenuLib2_mn_setting.text_attr := dialog_background+dialog_item; MenuLib2_mn_setting.text2_attr := dialog_sel_itm_bck+dialog_sel_itm; MenuLib2_mn_setting.default_attr := dialog_def_bckg+dialog_def; MenuLib2_mn_setting.short_attr := dialog_background+dialog_short; MenuLib2_mn_setting.short2_attr := dialog_sel_itm_bck+dialog_sel_short; MenuLib2_mn_setting.disbld_attr := dialog_background+dialog_item_dis; MenuLib2_mn_setting.contxt_attr := dialog_background+dialog_context; MenuLib2_mn_setting.contxt2_attr := dialog_background+dialog_context_dis; MenuLib2_mn_setting.terminate_keys[3] := kTAB; MenuLib2_mn_setting.terminate_keys[4] := kLEFT; MenuLib2_mn_setting.terminate_keys[5] := kRIGHT; MenuLib2_mn_setting.terminate_keys[6] := kCtrlO; MenuLib2_mn_setting.terminate_keys[7] := kF1; MenuLib2_mn_setting.terminate_keys[8] := kShTAB; MenuLib2_mn_environment.v_dest := screen_ptr; MenuLib2_mn_environment.keystroke := $0000; MenuLib2_mn_environment.context := ''; MenuLib2_mn_environment.unpolite := FALSE; MenuLib2_mn_environment.winshade := TRUE; MenuLib2_mn_environment.ext_proc := NIL; MenuLib2_mn_environment.refresh := NIL; MenuLib2_mn_environment.do_refresh := FALSE; MenuLib2_mn_environment.preview := FALSE; MenuLib2_mn_environment.descr_len := 0; MenuLib2_mn_environment.descr := NIL; end; end. adlibtracker2-2.4.23/iss_tim.pas0000644000000000000000000002106013176573532015200 0ustar rootroot { þ Inquisition's Timer Services Unit þ } { þ This file is part of the Inquisition Sound Server for the Free þ } { þ Pascal Compiler (http://www.freepascal.org) but also can be þ } { þ be distributed separately. The source code is FREE FOR ANY NON þ } { þ COMMERCIAL USAGE. þ } { þ You can modify this file, but you musn't distribute the þ } { þ modified file, only the original version. Instead, send your þ } { þ modification to us, so we can add it to the official version. þ } { þ Please note, that we can't quarantee the compatibility with þ } { þ previous versions. þ } { þ If we'll stop the development of this unit in the future, þ } { þ the source code will be freely available for any use. þ } { þ You can always download the newest version from our website, þ } { þ http://scenergy.dfmk.hu/inqcoders/ þ } { þ About Inquisition itself, see þ } { þ http://scenergy.dfmk.hu/inquisition/ þ } { þ Comments, notes, suggestions, bug reports are welcome. þ } { þ Send your mails to charlie@scenergy.dfmk.hu þ } { þ Please prefer hungarian or english languages. þ } { þ ISS_TIM - Timer Unit (GO32V2 Only!) þ } { þ Coding Starts : 10. October. 1998. þ } { þ Last Modification : 01. March. 2001. þ } { þ Note: req. FPC version 1.0.0+ for GO32V2 to compile þ } {$ASMMODE INTEL} {$MODE FPC} Unit ISS_Tim; Interface Uses GO32; Const ISS_TimerSpeed : DWord = 1193180; ISS_MaxTimers = $8; { þ Maximum Number of Timers þ } TimerIRQ = $8; { þ HW IRQ Number þ } ISS_TENoFree = $01; { þ Can't add new timer. All timers locked. þ } ISS_TENotFound = $02; { þ Can't find specified Timer, to stop. þ } Type TTimerStruc = Record TSpeed : DWord; TCount : DWord; { þ Tick Counter þ } TPrevCount : DWord; { þ Tick Counter state at prev. activity þ } TProc : Pointer; { þ Procedure To Call Offset þ } TActive : Boolean; { þ 1 If The Timer Is On þ } End; Var ISS_TimersData : Array[1..ISS_MaxTimers] Of TTimerStruc; ISS_TimerError : DWord; { þ Contains the last timer error code. þ } Function ISS_StartTimer(Var NewTProc : Pointer; NewTSpeed : DWord) : Boolean; Function ISS_StopTimer(Var TimerProc : Pointer) : Boolean; Function ISS_GetTimerNumber(TimerProc : Pointer) : DWord; Implementation Var TimerSpeed : DWord; OldTimer : TSegInfo; OldTimerCnt : DWord; NewIRQActive : Boolean; NewTimerHandler : TSegInfo; BackupDS : Word; External Name '___v2prt0_ds_alias'; Procedure UpdateUserTimers; Type Proc = Procedure; Var Counter : Word; Begin For Counter:=1 To ISS_MaxTimers Do Begin With ISS_TimersData[Counter] Do Begin If TActive Then Begin Inc(TCount,TimerSpeed); If (TCount>TSpeed) Then Begin Dec(TCount,TSpeed); TPrevCount:=TCount; Proc(TProc); { þ Calling the specified routine þ } End; End; End; End; End; Procedure UpdateUserTimers_Dummy; Begin End; Procedure SysTimerIRQ; Assembler; Asm CLI PUSH DS PUSH ES PUSH FS PUSH GS PUSHAD MOV AX,CS:[BackupDS] MOV DS,AX MOV ES,AX MOV AX,DosMemSelector MOV FS,AX CALL UpdateUserTimers MOV EAX,TimerSpeed ADD OldTimerCnt,EAX CMP OldTimerCnt,$10000 JB @NotUpdateClock SUB OldTimerCnt,$10000 INC WORD PTR FS:[1132] JNZ @Timer_2 INC WORD PTR FS:[1134] @Timer_2: MOV AX,$018 CMP FS:[1134],AX JNZ @Timer_3 MOV AX,$0B0 CMP FS:[1132],AX JNZ @Timer_3 MOV WORD PTR FS:[1134],$0 MOV WORD PTR FS:[1132],$0 MOV BYTE PTR FS:[1136],$1 @Timer_3: @NotUpdateClock: MOV DX,$20 { þ Interrupt request acknowledge þ } MOV AL,$20 OUT DX,AL POPAD POP GS POP FS POP ES POP DS IRET End; Procedure SysTimerIRQ_Dummy; Begin End; Procedure SetTimerSpeed(NewTimerSpeed : DWord); Begin If NewTimerSpeed<>TimerSpeed Then Begin Asm PUSH EAX CLI MOV AL,00110110B OUT 43H,AL MOV EAX,NEWTIMERSPEED OUT 40H,AL MOV AL,AH OUT 40H,AL STI POP EAX End; TimerSpeed:=NewTimerSpeed; End; End; Function GetTimerSpeed : DWord; Var Counter : DWord; TFastest : DWord; Begin TFastest:=$10000; For Counter:=1 To ISS_MaxTimers Do Begin If ISS_TimersData[Counter].TActive And (ISS_TimersData[Counter].TSpeed < TFastest) Then TFastest:=ISS_TimersData[Counter].TSpeed; End; GetTimerSpeed:=TFastest; End; Function ISS_StartTimer(Var NewTProc : Pointer; NewTSpeed : DWord) : Boolean; Var Counter : Word; TNumber : Word; Begin Counter:=0; TNumber:=0; Repeat Inc(Counter); If Not ISS_TimersData[Counter].TActive Then TNumber:=Counter; Until (TNumber<>0) Or (Counter=ISS_MaxTimers); If TNumber=0 Then Begin ISS_TimerError:=ISS_TENoFree; ISS_StartTimer:=False; Exit; End; If Not NewIRQActive Then Begin Lock_Data(ISS_TimersData,SizeOf(ISS_TimersData)); Lock_Data(DosMemSelector,SizeOf(DosMemSelector)); Lock_Code(@SysTimerIRQ,DWord(@SysTimerIRQ_Dummy)-DWord(@SysTimerIRQ)); Lock_Code(@UpdateUserTimers,DWord(@UpdateUserTimers_Dummy)-DWord(@UpdateUserTimers)); NewTimerHandler.Offset:=@SysTimerIRQ; NewTimerHandler.Segment:=Get_CS; Get_PM_Interrupt(TimerIRQ,OldTimer); Set_PM_Interrupt(TimerIRQ,NewTimerHandler); End; ISS_TimersData[TNumber].TSpeed:=NewTSpeed; ISS_TimersData[TNumber].TCount:=0; ISS_TimersData[TNumber].TProc:=NewTProc; ISS_TimersData[TNumber].TActive:=True; SetTimerSpeed(GetTimerSpeed); ISS_StartTimer:=True; End; Function ISS_StopTimer(Var TimerProc : Pointer) : Boolean; Var TNumber : Word; Counter : Word; LastTimer : Boolean; Begin Disable; TNumber:=0; For Counter:=1 To ISS_MaxTimers Do Begin With ISS_TimersData[Counter] Do Begin If TActive And (TProc=TimerProc) Then TNumber:=Counter; End; End; If TNumber=0 Then Begin ISS_TimerError:=ISS_TENotFound; ISS_StopTimer:=False; Enable; End Else Begin ISS_TimersData[TNumber].TActive:=False; LastTimer:=True; For Counter:=1 To ISS_MaxTimers Do Begin If ISS_TimersData[Counter].TActive=True Then LastTimer:=False; End; If LastTimer Then Begin TimerSpeed:=0; SetTimerSpeed($10000); Set_PM_Interrupt(TimerIRQ,OldTimer); Unlock_Data(DosMemSelector,SizeOf(DosMemSelector)); Unlock_Data(ISS_TimersData,SizeOf(ISS_TimersData)); UnLock_Code(@SysTimerIRQ,DWord(@SysTimerIRQ_Dummy)-DWord(@SysTimerIRQ)); UnLock_Code(@UpdateUserTimers,DWord(@UpdateUserTimers_Dummy)-DWord(@UpdateUserTimers)); End; ISS_StopTimer:=True; Enable; End; End; Function ISS_GetTimerNumber(TimerProc : Pointer) : DWord; Var Counter : DWord; Begin For Counter:=1 To ISS_MaxTimers Do Begin With ISS_TimersData[Counter] Do Begin If TActive And (TProc=TimerProc) Then Begin ISS_GetTimerNumber:=Counter; Exit; End; End; End; End; Begin FillChar(ISS_TimersData,SizeOf(ISS_TimersData),#0); NewIRQActive:=False; TimerSpeed:=0; End. { þ ISS_TIM.PAS - (C) 1998-2001 Charlie/Inquisition þ } { þ Changelog : þ } { þ 1.1.1 - Some code cleanup for less compiler hacking... þ } { þ - Webpage and email addresses fixed in the header comment. þ } { þ [01.march.2001] þ } { þ 1.1.0 - Major update, a new IRQ routine which contains less compiler þ } { þ hacking. Based on the docs of FPC 1.0.2. Not tested with þ } { þ versions below 1.0.0. GNU AS no longer required to compile. þ } { þ [03.december.2000] þ } { þ 1.0.2 - Header comment fixed. þ } { þ [18.apr.2000] þ } { þ 1.0.1 - Removed a limitation which made smartlinking impossible. þ } { þ (Reported by Surgi/Terror Opera) þ } { þ [13.apr.2000] þ } { þ 1.0.0 - First Public Version þ } { þ [08.jan.2000] þ } adlibtracker2-2.4.23/depackio.pas0000644000000000000000000005701313176573532015317 0ustar rootrootunit DepackIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface // Compression algorithm: RDC // Algorithm developed by Ed Ross function RDC_decompress(var source,dest; size: Word): Word; // Compression algorithm: LZSS // Algorithm developed by Lempel-Ziv-Storer-Szymanski function LZSS_decompress(var source,dest; size: Word): Word; // Compression algorithm: LZW // Algorithm developed by Lempel-Ziv-Welch function LZW_decompress(var source,dest): Word; // Compression algorithm: SixPack // Algorithm developed by Philip G. Gage function SIXPACK_decompress(var source,dest; size: Word): Word; // Compression algorithm: aPack // Algorithm developed by Joergen Ibsen function APACK_decompress(var source,dest): Dword; implementation const WORKMEM_SIZE = 64*1024; var work_mem: array[0..PRED(WORKMEM_SIZE)] of Byte; ibufCount,ibufSize: Word; input_size,output_size: Word; input_ptr,output_ptr,work_ptr: Pointer; var ibuf_idx,ibuf_end,obuf_idx,obuf_src: Pointer; ctrl_bits,ctrl_mask, command,count,offs: Word; procedure RDC_decode; begin asm mov ctrl_mask,0 mov eax,input_ptr mov ibuf_end,eax xor eax,eax mov ax,input_size add ibuf_end,eax mov eax,input_ptr mov ibuf_idx,eax mov eax,output_ptr mov obuf_idx,eax @@1: xor ecx,ecx mov eax,ibuf_idx cmp eax,ibuf_end jnb @@7 mov ax,ctrl_mask shr ax,1 mov ctrl_mask,ax or ax,ax jnz @@2 mov esi,ibuf_idx lodsw mov ctrl_bits,ax add ibuf_idx,2 mov ctrl_mask,8000h @@2: mov ax,ctrl_bits and ax,ctrl_mask or ax,ax jnz @@3 mov esi,ibuf_idx mov edi,obuf_idx movsb inc ibuf_idx inc obuf_idx jmp @@1 @@3: xor ah,ah mov esi,ibuf_idx lodsb shr ax,4 and ax,0fh mov command,ax xor ah,ah mov esi,ibuf_idx lodsb and ax,0fh mov count,ax inc ibuf_idx cmp command,0 jnz @@4 add count,3 mov edi,obuf_idx mov cx,count mov esi,ibuf_idx lodsb rep stosb inc ibuf_idx mov cx,count add obuf_idx,ecx jmp @@1 @@4: cmp command,1 jnz @@5 xor ah,ah mov esi,ibuf_idx lodsb shl ax,4 add count,ax inc ibuf_idx add count,19 mov edi,obuf_idx mov cx,count mov esi,ibuf_idx lodsb rep stosb inc ibuf_idx mov cx,count add obuf_idx,ecx jmp @@1 @@5: cmp command,2 jnz @@6 mov ax,count add ax,3 mov offs,ax xor ah,ah mov esi,ibuf_idx lodsb shl ax,4 add offs,ax inc ibuf_idx xor ah,ah mov esi,ibuf_idx lodsb mov count,ax inc ibuf_idx add count,16 mov eax,obuf_idx mov cx,offs sub eax,ecx mov obuf_src,eax mov esi,eax mov edi,obuf_idx mov cx,count rep movsb mov cx,count add obuf_idx,ecx jmp @@1 @@6: mov ax,count add ax,3 mov offs,ax xor ah,ah mov esi,ibuf_idx lodsb shl ax,4 add offs,ax inc ibuf_idx mov eax,obuf_idx mov cx,offs sub eax,ecx mov obuf_src,eax mov esi,eax mov edi,obuf_idx mov cx,command rep movsb mov cx,command add obuf_idx,ecx jmp @@1 @@7: mov eax,obuf_idx sub eax,output_ptr mov output_size,ax end; end; function RDC_decompress(var source,dest; size: Word): Word; begin input_ptr := @source; output_ptr := @dest; input_size := size; RDC_decode; RDC_decompress := output_size; end; const N = 4096; F = 18; T = 2; procedure GetChar; assembler; asm push ebx mov bx,ibufCount cmp bx,ibufSize jb @@1 jmp @@2 @@1: push edi mov edi,input_ptr mov al,byte ptr [edi+ebx] pop edi inc ebx mov ibufCount,bx pop ebx clc jmp @@3 @@2: pop ebx stc @@3: end; procedure PutChar; assembler; asm push ebx mov bx,output_size push edi mov edi,output_ptr mov byte ptr [edi+ebx],al pop edi inc ebx mov output_size,bx pop ebx end; procedure LZSS_decode; begin asm mov ibufCount,0 mov ax,input_size mov ibufSize,ax mov output_size,0 xor ebx,ebx xor edx,edx mov edi,N-F @@1: shr dx,1 or dh,dh jnz @@2 call GetChar jc @@5 mov dh,0ffh mov dl,al @@2: test dx,1 jz @@3 call GetChar jc @@5 push esi mov esi,work_ptr add esi,edi mov byte ptr [esi],al pop esi inc edi and edi,N-1 call PutChar jmp @@1 @@3: call GetChar jc @@5 mov ch,al call GetChar jc @@5 mov bh,al mov cl,4 shr bh,cl mov bl,ch mov cl,al and cl,0fh add cl,T inc cl @@4: and ebx,N-1 push esi mov esi,work_ptr mov al,byte ptr [esi+ebx] add esi,edi mov byte ptr [esi],al pop esi inc edi and edi,N-1 call PutChar inc ebx dec cl jnz @@4 jmp @@1 @@5: end; end; function LZSS_decompress(var source,dest; size: Word): Word; begin input_ptr := @source; output_ptr := @dest; work_ptr := @work_mem; input_size := size; FillChar(work_ptr^,WORKMEM_SIZE,0); LZSS_decode; LZSS_decompress := output_size; end; var le76,le77: Byte; le6a,le6c,le6e,le70,le72,le74,le78, le7a_0,le7a_2,le7a_4,le7a_6,le7a_8,le82a,le82b: Word; procedure NextCode; assembler; asm mov bx,le82a mov ax,le82b add bx,le78 adc ax,0 xchg bx,le82a xchg ax,le82b mov cx,bx and cx,7 shr ax,1 rcr bx,1 shr ax,1 rcr bx,1 shr ax,1 rcr bx,1 mov esi,input_ptr mov ax,[ebx+esi] mov dl,[ebx+esi+2] or cx,cx jz @@2 @@1: shr dl,1 rcr ax,1 loop @@1 @@2: mov bx,le78 sub bx,9 shl bx,1 and ax,[ebx+le7a_0] end; function LZW_decode: Word; var result: Word; begin asm xor eax,eax xor ebx,ebx xor ecx,ecx mov le72,0 mov le78,9 mov le70,102h mov le74,200h mov edi,output_ptr xor eax,eax mov le6a,ax mov le6c,ax mov le6e,ax mov le76,al mov le77,al mov le82a,ax mov le82b,ax mov le7a_0,1ffh mov le7a_2,3ffh mov le7a_4,7ffh mov le7a_6,0fffh mov le7a_8,1fffh @@1: call NextCode cmp ax,101h jnz @@2 jmp @@9 @@2: cmp ax,100h jnz @@3 mov le78,9 mov le74,200h mov le70,102h call NextCode mov le6a,ax mov le6c,ax mov le77,al mov le76,al mov al,le77 mov byte ptr [edi],al inc edi jmp @@1 @@3: mov le6a,ax mov le6e,ax cmp ax,le70 jb @@4 mov ax,le6c mov le6a,ax mov al,le76 push eax inc le72 @@4: cmp le6a,0ffh jbe @@5 mov esi,work_ptr mov bx,le6a shl bx,1 add bx,le6a mov al,[ebx+esi+2] push eax inc le72 mov ax,[ebx+esi] mov le6a,ax jmp @@4 @@5: mov ax,le6a mov le76,al mov le77,al push eax inc le72 xor ecx,ecx mov cx,le72 jecxz @@7 @@6: pop eax mov byte ptr [edi],al inc edi loop @@6 @@7: mov le72,0 push esi mov bx,le70 shl bx,1 add bx,le70 mov esi,work_ptr mov al,le77 mov [ebx+esi+2],al mov ax,le6c mov [ebx+esi],ax inc le70 pop esi mov ax,le6e mov le6c,ax mov bx,le70 cmp bx,le74 jl @@8 cmp le78,14 jz @@8 inc le78 shl le74,1 @@8: jmp @@1 @@9: mov output_size,ax mov result,ax end; LZW_decode := result; end; function LZW_decompress(var source,dest): Word; begin input_ptr := @source; output_ptr := @dest; work_ptr := @work_mem; LZW_decode; LZW_decompress := output_size; end; const MAXFREQ = 2000; MINCOPY = 3; MAXCOPY = 255; COPYRANGES = 6; TERMINATE = 256; FIRSTCODE = 257; ROOT = 1; CODESPERRANGE = MAXCOPY-MINCOPY+1; MAXCHAR = FIRSTCODE+COPYRANGES*CODESPERRANGE-1; SUCCMAX = MAXCHAR+1; TWICEMAX = 2*MAXCHAR+1; MAXBUF = PRED(64*1024); MAXDISTANCE = 21389; MAXSIZE = 21389+MAXCOPY; const BitValue: array[1..14] of Word = (1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192); CopyBits: array[0..PRED(COPYRANGES)] of Word = (4,6,8,10,12,14); CopyMin: array[0..PRED(COPYRANGES)] of Word = (0,16,80,336,1360,5456); var leftC,rghtC: array[0..MAXCHAR] of Word; dad,frq: array[0..TWICEMAX] of Word; index,ibitCount,ibitBuffer,obufCount: Word; procedure InitTree; begin asm xor edi,edi mov di,2 mov bx,2 mov cx,1 @@1: xor dx,dx mov ax,di div bx push edi shl di,1 mov word ptr dad[edi],ax mov word ptr frq[edi],cx pop edi inc di cmp di,TWICEMAX jbe @@1 mov di,1 @@2: xor dx,dx mov ax,di mul bx push edi shl di,1 mov word ptr leftC[edi],ax inc ax mov word ptr rghtC[edi],ax pop edi inc di cmp di,MAXCHAR jbe @@2 end; end; procedure UpdateFreq(a,b: Word); begin asm xor ecx,ecx xor edi,edi @@1: mov di,a shl di,1 mov bx,word ptr frq[edi] mov di,b shl di,1 add bx,word ptr frq[edi] mov di,a shl di,1 mov dx,word ptr dad[edi] mov di,dx shl di,1 mov word ptr frq[edi],bx mov a,dx cmp a,ROOT jz @@3 mov di,a shl di,1 mov di,word ptr dad[edi] mov ax,di shl di,1 mov bx,word ptr leftC[edi] cmp a,bx jnz @@2 mov di,ax shl di,1 mov bx,word ptr rghtC[edi] mov b,bx jmp @@3 @@2: mov di,ax shl di,1 mov bx,word ptr leftC[edi] mov b,bx @@3: cmp a,ROOT jnz @@1 mov bx,MAXFREQ mov di,ROOT shl di,1 cmp word ptr frq[edi],bx jnz @@5 lea esi,[frq] lea edi,[frq] mov cx,TWICEMAX movsw @@4: lodsw shr ax,1 stosw loop @@4 @@5: end; end; procedure UpdateModel(code: Word); begin asm xor ecx,ecx xor edi,edi mov bx,code add bx,SUCCMAX mov di,bx shl di,1 mov ax,di mov cx,word ptr frq[edi] inc cx mov word ptr frq[edi],cx mov di,ax mov cx,ROOT cmp word ptr dad[edi],cx jz @@10 mov dx,word ptr dad[edi] push edi lea edi,[leftC] mov cx,dx shl cx,1 add edi,ecx mov si,word ptr [edi] pop edi cmp si,bx jnz @@1 mov di,dx shl di,1 mov si,word ptr rghtC[edi] @@1: push ebx push edx push ebx push esi call UpdateFreq pop edx pop ebx @@2: xor edi,edi mov di,dx shl di,1 mov ax,word ptr dad[edi] mov di,ax shl di,1 mov cx,di cmp word ptr leftC[edi],dx jnz @@3 mov di,cx mov si,word ptr rghtC[edi] jmp @@4 @@3: mov si,word ptr leftC[edi] @@4: xor edi,edi mov di,bx shl di,1 push eax mov ax,word ptr frq[edi] mov di,si shl di,1 mov cx,ax pop eax cmp cx,word ptr frq[edi] jbe @@9 mov di,ax shl di,1 mov cx,di cmp word ptr leftC[edi],dx jnz @@5 mov di,cx mov word ptr rghtC[edi],bx jmp @@6 @@5: xor edi,edi mov di,cx mov word ptr leftC[edi],bx @@6: lea edi,[leftC] xor ecx,ecx mov cx,dx shl cx,1 add edi,ecx cmp word ptr [edi],bx jnz @@7 mov word ptr [edi],si xor edi,edi mov di,cx mov cx,word ptr rghtC[edi] jmp @@8 @@7: xor edi,edi mov di,cx mov word ptr rghtC[edi],si mov cx,word ptr leftC[edi] @@8: xor edi,edi mov di,si shl di,1 mov word ptr dad[edi],dx mov di,bx shl di,1 mov word ptr dad[edi],ax push esi push esi push ecx call UpdateFreq pop ebx @@9: xor edi,edi mov di,bx shl di,1 mov bx,word ptr dad[edi] mov di,bx shl di,1 mov dx,word ptr dad[edi] cmp dx,ROOT jnz @@2 @@10: end; end; function InputCode(bits: Word): Word; var result: Word; begin asm xor bx,bx xor ecx,ecx mov cx,1 @@1: cmp ibitCount,0 jnz @@3 cmp ibufCount,MAXBUF jnz @@2 mov ax,input_size mov ibufCount,0 @@2: mov edi,input_ptr xor edx,edx mov dx,ibufCount shl dx,1 add edi,edx mov ax,[edi] mov ibitBuffer,ax inc ibufCount mov ibitCount,15 jmp @@4 @@3: dec ibitCount @@4: cmp ibitBuffer,7fffh jbe @@5 xor edi,edi mov di,cx dec di shl di,1 mov ax,word ptr BitValue[edi] or bx,ax @@5: shl ibitBuffer,1 inc cx cmp cx,bits jbe @@1 mov ax,bx mov result,ax end; InputCode := result; end; function Uncompress: Word; var result: Word; begin asm xor eax,eax xor ebx,ebx mov bx,1 mov dx,ibitCount mov cx,ibitBuffer mov ax,ibufCount @@1: or dx,dx jnz @@3 cmp ax,MAXBUF jnz @@2 mov ax,input_size xor ax,ax @@2: shl ax,1 mov edi,input_ptr add edi,eax shr ax,1 mov cx,[edi] inc ax mov dx,15 jmp @@4 @@3: dec dx @@4: cmp cx,7fffh jbe @@5 mov edi,ebx shl edi,1 mov bx,word ptr rghtC[edi] jmp @@6 @@5: mov edi,ebx shl edi,1 mov bx,word ptr leftC[edi] @@6: shl cx,1 cmp bx,MAXCHAR jle @@1 sub bx,SUCCMAX mov ibitCount,dx mov ibitBuffer,cx mov ibufCount,ax push ebx push ebx call UpdateModel pop eax mov result,ax end; Uncompress := result; end; procedure SIXPACK_decode; begin asm mov ibitCount,0 mov ibitBuffer,0 mov obufCount,0 mov ibufCount,0 xor ebx,ebx xor ecx,ecx mov count,0 call InitTree call Uncompress @@1: cmp ax,TERMINATE jz @@10 cmp ax,256 jae @@3 mov edi,output_ptr push ebx mov bx,obufCount add edi,ebx pop ebx stosb inc obufCount mov bx,MAXBUF cmp obufCount,bx jnz @@2 mov output_size,bx mov obufCount,0 @@2: mov edi,work_ptr push ebx mov bx,count add edi,ebx pop ebx stosb inc count cmp count,MAXSIZE jnz @@9 mov count,0 jmp @@9 @@3: sub ax,FIRSTCODE mov cx,ax xor dx,dx mov bx,CODESPERRANGE div bx mov index,ax xor dx,dx mul bx mov bx,cx add bx,MINCOPY sub bx,ax mov si,bx xor edi,edi mov di,index shl di,1 mov bx,word ptr CopyBits[edi] push ebx call InputCode add ax,si xor edi,edi mov di,index shl di,1 add ax,word ptr CopyMin[edi] mov bx,count mov dx,bx sub dx,ax mov cx,dx cmp count,ax jae @@4 add cx,MAXSIZE @@4: xor dx,dx @@5: mov edi,work_ptr add edi,ecx mov al,byte ptr [edi] mov edi,output_ptr push ebx mov bx,obufCount add edi,ebx pop ebx mov byte ptr [edi],al inc obufCount mov ax,MAXBUF cmp obufCount,ax jnz @@6 mov output_size,ax mov obufCount,0 @@6: mov edi,work_ptr push edi add edi,ecx mov al,byte ptr [edi] pop edi add edi,ebx mov byte ptr [edi],al inc bx cmp bx,MAXSIZE jnz @@7 xor bx,bx @@7: inc cx cmp cx,MAXSIZE jnz @@8 xor cx,cx @@8: inc dx cmp dx,si jb @@5 mov ax,si add count,ax cmp count,MAXSIZE jb @@9 sub count,MAXSIZE @@9: call Uncompress jmp @@1 @@10: mov bx,obufCount mov output_size,bx end; end; function SIXPACK_decompress(var source,dest; size: Word): Word; begin input_ptr := @source; output_ptr := @dest; work_ptr := @work_mem; input_size := size; SIXPACK_decode; SIXPACK_decompress := output_size; end; function APACK_decompress(var source,dest): Dword; var temp,result: Dword; begin asm mov esi,[source] mov edi,[dest] cld mov dl,80h @@1: movsb @@2: add dl,dl jnz @@3 mov dl,[esi] inc esi adc dl,dl @@3: jnc @@1 xor ecx,ecx add dl,dl jnz @@4 mov dl,[esi] inc esi adc dl,dl @@4: jnc @@8 xor eax,eax add dl,dl jnz @@5 mov dl,[esi] inc esi adc dl,dl @@5: jnc @@15 inc ecx mov al,10h @@6: add dl,dl jnz @@7 mov dl,[esi] inc esi adc dl,dl @@7: adc al,al jnc @@6 jnz @@24 stosb jmp @@2 @@8: inc ecx @@9: add dl,dl jnz @@10 mov dl,[esi] inc esi adc dl,dl @@10: adc ecx,ecx add dl,dl jnz @@11 mov dl,[esi] inc esi adc dl,dl @@11: jc @@9 dec ecx loop @@16 xor ecx,ecx inc ecx @@12: add dl,dl jnz @@13 mov dl,[esi] inc esi adc dl,dl @@13: adc ecx,ecx add dl,dl jnz @@14 mov dl,[esi] inc esi adc dl,dl @@14: jc @@12 jmp @@23 @@15: lodsb shr eax,1 jz @@25 adc ecx,ecx jmp @@20 @@16: xchg eax,ecx dec eax shl eax,8 lodsb xor ecx,ecx inc ecx @@17: add dl,dl jnz @@18 mov dl,[esi] inc esi adc dl,dl @@18: adc ecx,ecx add dl,dl jnz @@19 mov dl,[esi] inc esi adc dl,dl @@19: jc @@17 cmp eax,32000 jae @@20 cmp ah,5 jae @@21 cmp eax,7fh ja @@22 @@20: inc ecx @@21: inc ecx @@22: xchg eax,temp @@23: mov eax,temp @@24: push esi mov esi,edi sub esi,eax rep movsb pop esi jmp @@2 @@25: sub edi,[dest] mov result,edi end; APACK_decompress := result; end; end. adlibtracker2-2.4.23/adt2ext5.pas0000644000000000000000000051321013176573532015174 0ustar rootrootunit AdT2ext5; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const arp_tab_selected: Boolean = FALSE; vib_tab_selected: Boolean = FALSE; var ptr_arpeggio_table: Byte; ptr_vibrato_table: Byte; procedure bnk_file_loader; procedure fib_file_loader; procedure ibk_file_loader; procedure bnk_file_loader_alt(instr: Word); procedure fib_file_loader_alt(instr: Word); procedure ibk_file_loader_alt(instr: Word); procedure a2b_file_loader(bankSelector: Boolean; loadBankPossible: Boolean); procedure a2w_file_loader(loadFromFile: Boolean; loadMacros: Boolean; bankSelector: Boolean; loadBankPossible: Boolean; updateCurInstr: Boolean); implementation uses {$IFNDEF UNIX} CRT, {$ENDIF} {$IFDEF GO32V2} GO32, {$ELSE} SDL_Timer, {$ENDIF} DOS, AdT2opl3,AdT2sys,AdT2keyb,AdT2unit,AdT2extn,AdT2ext2,AdT2ext3,AdT2ext4,AdT2text,AdT2pack, StringIO,DialogIO,ParserIO,TxtScrIO,DepackIO; procedure a2b_lister_external_proc; forward; procedure a2w_lister_external_proc_callback; forward; procedure a2w_macro_lister_external_proc_callback; forward; procedure bnk_lister_external_proc; forward; procedure fib_lister_external_proc; forward; procedure ibk_lister_external_proc; forward; var xstart,ystart: Byte; window_xsize,window_ysize: Byte; context_str,context_str2,context_str3: String; var temp_marks: array[1..255] of Char; a2b_queue: array[1..255+3] of String[74]; a2b_queue_more: array[1..255+3] of String[104]; a2w_queue: array[1..255+3] of String[72]; a2w_queue_more: array[1..255+3] of String[102]; a2w_queue_more2: array[1..255+3] of String[121]; a2w_queue_m: array[1..255+5] of String[72]; a2w_institle_pos: Byte; update_current_inst: Boolean; var xstart_arp,ystart_arp,xstart_vib,ystart_vib: Byte; scrollbar_xstart,scrollbar_ystart,scrollbar_size: Byte; macro_table_size: Byte; arpeggio_table_idx,vibrato_table_idx: Byte; arpeggio_table_pos,vibrato_table_pos: Byte; procedure import_old_instruments(old_songdata: pOLD_FIXED_SONGDATA; new_songdata: pFIXED_SONGDATA; instr,count: Byte); var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:import_old_instruments'; {$ENDIF} For temp := instr to instr+PRED(count) do begin new_songdata^.instr_names[temp] := Copy(new_songdata^.instr_names[temp],1,9)+ Copy(old_songdata^.instr_names[temp],10,22); new_songdata^.instr_data[temp].fm_data := old_songdata^.instr_data[temp].fm_data; new_songdata^.instr_data[temp].panning := old_songdata^.instr_data[temp].panning; new_songdata^.instr_data[temp].fine_tune := old_songdata^.instr_data[temp].fine_tune; new_songdata^.instr_data[temp].perc_voice := 0; end; end; function count_instruments: Byte; var result: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:count_instruments'; {$ENDIF} result := 255; While (result > 0) and Empty(temp_songdata.instr_data[result],INSTRUMENT_SIZE) and (CutStr(Copy(temp_songdata.instr_names[result],10,32)) = '') do Dec(result); count_instruments := result; end; function count_macros: Byte; var result: Byte; begin result := 255; While (result > 0) and Empty(temp_songdata.macro_table[result].arpeggio, SizeOf(tARPEGGIO_TABLE)) and Empty(temp_songdata.macro_table[result].vibrato, SizeOf(tVIBRATO_TABLE)) do Dec(result); count_macros := result; end; function get_free_arpeggio_table_idx(data: tARPEGGIO_TABLE): Byte; var result: Byte; free_flag: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:get_free_arpeggio_table_idx'; {$ENDIF} result := 0; free_flag := FALSE; // first try to find empty space or same macro for overwriting Repeat Inc(result); If Empty(songdata.macro_table[result].arpeggio, SizeOf(tARPEGGIO_TABLE)) or Compare(songdata.macro_table[result].arpeggio,data, SizeOf(tARPEGGIO_TABLE)) then free_flag := TRUE; until free_flag or (result = 255); // next to find dummy macro (length=0) for overwriting If NOT free_flag then Repeat If (temp_songdata.macro_table[result].arpeggio.length = 0) then free_flag := TRUE else Dec(result); until free_flag or (result = 0); get_free_arpeggio_table_idx := result; end; function get_free_vibrato_table_idx(data: tVIBRATO_TABLE): Byte; var result: Byte; free_flag: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:get_free_vibrato_table_idx'; {$ENDIF} result := 0; free_flag := FALSE; // first try to find empty space or same macro for overwriting Repeat Inc(result); If Empty(songdata.macro_table[result].vibrato, SizeOf(tViBRATO_TABLE)) or Compare(songdata.macro_table[result].vibrato,data, SizeOf(tVIBRATO_TABLE)) then free_flag := TRUE; until free_flag or (result = 255); // next to find dummy macro (length=0) for overwriting If NOT free_flag then Repeat If (temp_songdata.macro_table[result].vibrato.length = 0) then free_flag := TRUE else Dec(result); until free_flag or (result = 0); get_free_vibrato_table_idx := result; end; function _gfx_bar_str(value: Byte; neg: Boolean): String; var result: String; begin result := ''; If NOT neg then Repeat If (value > 15) then begin result := result+#219; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := result+CHR(127+value) until (value <= 15) else Repeat If (value > 15) then begin result := #219+result; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := CHR(158-value)+result; until (value <= 15); _gfx_bar_str := flipstr(result); end; const _4op_flag_chr_beg = #172; _4op_flag_chr_end = #173; _4op_flag_chars: Set of Char = [_4op_flag_chr_beg,_4op_flag_chr_end]; _4op_flag_column: array[1..255] of Char = ''; _a2b_lister_count: Byte = 0; _a2w_lister_count: Byte = 0; var _4op_idx11,_4op_idx12, _4op_idx21,_4op_idx22: Byte; _4op_ins_flag: Boolean; function check_4op_flag_temp(ins: Byte): Boolean; var result: Boolean; idx: Byte; begin result := FALSE; For idx := 1 to temp_songdata.ins_4op_flags.num_4op do If (temp_songdata.ins_4op_flags.idx_4op[idx] = ins) then begin result := TRUE; BREAK; end; check_4op_flag_temp := result; end; function get_4op_to_test_temp: Word; var result: Word; curr_inst: Byte; begin result := 0; curr_inst := mn_environment.curr_pos; If (curr_inst in [1..255]) and (songdata.flag_4op <> 0) then If (_4op_flag_column[curr_inst] = _4op_flag_chr_beg) then result := SUCC(curr_inst)+curr_inst SHL 8 else If (curr_inst > 1) and (_4op_flag_column[curr_inst] = _4op_flag_chr_end) then result := curr_inst+PRED(curr_inst) SHL 8; get_4op_to_test_temp := result; end; procedure a2b_lister_external_proc_callback; forward; procedure a2b_lister_external_proc; var temp: Byte; attr: Byte; begin For temp := 1 to _a2b_lister_count do begin If (mn_environment.curr_pos = mn_environment.curr_page+temp-1) then attr := mn_setting.text2_attr else attr := mn_setting.text_attr; ShowStr(mn_environment.v_dest,mn_environment.xpos+1,mn_environment.ypos+3+temp, _4op_flag_column[mn_environment.curr_page+temp-1], attr); end; a2b_lister_external_proc_callback; end; procedure a2b_file_loader(bankSelector: Boolean; loadBankPossible: Boolean); type tOLD_HEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; type tHEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; const id = '_A2insbank_'; var f: File; header: tOLD_HEADER; header2: tHEADER; crc,temp: Longint; old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; idx,index,nm_valid: Byte; temp_str: String; ysize: Byte; const new_keys: array[1..3] of Word = (kESC,kENTER,kCtENTR); var old_keys: array[1..3] of Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2b_file_loader'; {$ENDIF} progress_num_steps := 0; progress_step := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; temp_songdata := songdata; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2B]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; init_old_songdata; If (header.ffver in [1..4]) then begin FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,2,crc); crc := Update32(buf1,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; Case header.ffver of 4: Move(buf1,old_songdata.instr_names,header.b0len); 3: LZSS_decompress(buf1,old_songdata.instr_names,header.b0len); 2: LZW_decompress(buf1,old_songdata.instr_names); 1: SIXPACK_decompress(buf1,old_songdata.instr_names,header.b0len); end; For temp := 1 to 250 do old_songdata.instr_data[temp].panning := 0; import_old_instruments(Addr(old_songdata),Addr(temp_songdata),1,250); end; If (header.ffver in [5..8]) then begin FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,2,crc); crc := Update32(buf1,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; Case header.ffver of 8: Move(buf1,old_songdata.instr_names,header.b0len); 7: LZSS_decompress(buf1,old_songdata.instr_names,header.b0len); 6: LZW_decompress(buf1,old_songdata.instr_names); 5: SIXPACK_decompress(buf1,old_songdata.instr_names,header.b0len); end; import_old_instruments(Addr(old_songdata),Addr(temp_songdata),1,250); end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header2.b0len,2,crc); crc := Update32(buf1,header2.b0len,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; APACK_decompress(buf1,temp_songdata.instr_names); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); end; If (header.ffver = FFVER_A2B) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header2.b0len,2,crc); crc := Update32(buf1,header2.b0len,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; progress_num_steps := 0; LZH_decompress(buf1,buf2,header2.b0len); Move(buf2,temp_songdata.instr_names,SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)); Move(buf2[SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)],temp_songdata.ins_4op_flags, SizeOf(songdata.ins_4op_flags)); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); end; FillChar(temp_songdata.dis_fmreg_col,SizeOf(temp_songdata.dis_fmreg_col),FALSE); CloseF(f); If NOT bankSelector then begin songdata.instr_names := temp_songdata.instr_names; songdata.instr_data := temp_songdata.instr_data; load_flag := 1; EXIT; end; // init 4OP flags FillChar(_4op_flag_column,SizeOf(_4op_flag_column),0); For temp := 1 to PRED(255) do If check_4op_flag_temp(temp) then begin If NOT (_4op_flag_column[temp] in _4op_flag_chars) then _4op_flag_column[temp] := _4op_flag_chr_beg; If NOT (_4op_flag_column[SUCC(temp)] in _4op_flag_chars) then _4op_flag_column[SUCC(temp)] := _4op_flag_chr_end; end; a2b_queue[1] := a2b_header_str[1]; a2b_queue[2] := a2b_header_str[2]; a2b_queue[3] := a2b_header_str[3]; a2b_queue_more[1] := a2b_header_hires_str[1]; a2b_queue_more[2] := a2b_header_hires_str[2]; a2b_queue_more[3] := a2b_header_hires_str[3]; nm_valid := count_instruments; If (nm_valid = 0) then nm_valid := 1; For idx := 1 to nm_valid do begin a2b_queue[3+idx] := '~'+ExpStrR(Copy(temp_songdata.instr_names[idx],1,9)+'~'+ Copy(temp_songdata.instr_names[idx],10,32),45,' '); a2b_queue_more[3+idx] := a2b_queue[3+idx]; With temp_songdata.instr_data[idx].fm_data do begin a2b_queue_more[3+idx] := a2b_queue_more[3+idx]+ byte2hex(AM_VIB_EG_carrier)+ byte2hex(AM_VIB_EG_modulator)+' '+ byte2hex(KSL_VOLUM_carrier)+ byte2hex(KSL_VOLUM_modulator)+' '+ byte2hex(ATTCK_DEC_carrier)+ byte2hex(ATTCK_DEC_modulator)+' '+ byte2hex(SUSTN_REL_carrier)+ byte2hex(SUSTN_REL_modulator)+' '+ byte2hex(WAVEFORM_carrier)+ byte2hex(WAVEFORM_modulator)+' '+ byte2hex(FEEDBACK_FM)+' '; end; Case temp_songdata.instr_data[idx].panning of 0..2: temp_str := ins_pan_str2[temp_songdata.instr_data[idx].panning]; else temp_str := ExpStrL('',7,#250); end; a2b_queue[3+idx] := a2b_queue[3+idx]+temp_str+' '; a2b_queue_more[3+idx] := a2b_queue_more[3+idx]+temp_str+' '; If (temp_songdata.instr_data[idx].fine_tune > 0) then temp_str := '+'+ExpStrR(Num2str(temp_songdata.instr_data[idx].fine_tune,16),5,' ') else If (temp_songdata.instr_data[idx].fine_tune < 0) then temp_str := '-'+ExpStrR(Num2str(0-temp_songdata.instr_data[idx].fine_tune,16),5,' ') else temp_str := ExpStrR('',6,' '); a2b_queue[3+idx] := a2b_queue[3+idx]+temp_str+' '; a2b_queue_more[3+idx] := a2b_queue_more[3+idx]+temp_str+' '; Case temp_songdata.instr_data[idx].perc_voice of 0..5: temp_str := perc_voice_str[temp_songdata.instr_data[idx].perc_voice]; else temp_str := ExpStrL('',7,' '); end; a2b_queue[3+idx] := a2b_queue[3+idx]+temp_str; a2b_queue_more[3+idx] := a2b_queue_more[3+idx]+temp_str; end; Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); mn_environment.ext_proc := a2b_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; If loadBankPossible then mn_environment.context := ' ~[~'+Num2str(nm_valid,10)+'~/255]~ ^ENTER '#196#16' LOAD COMPLETE BANK ' else mn_environment.context := '~[~'+Num2str(nm_valid,10)+'~/255]~'; keyboard_reset_buffer; If is_default_screen_mode then ysize := 20 else ysize := 30; _a2b_lister_count := ysize-3; If NOT _force_program_quit then If (program_screen_mode in [0,3,4,5]) then index := Menu(a2b_queue,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 74,ysize,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' ') else index := Menu(a2b_queue_more,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 104,30,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' '); add_bank_position(instdata_source,nm_valid,index+3); Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; If (mn_environment.keystroke = kENTER) or (loadBankPossible and (mn_environment.keystroke = kCtENTR)) then begin If (mn_environment.keystroke = kENTER) then begin If shift_pressed then begin // put 4op instrument (alternate) _4op_ins_flag := FALSE; If (_4op_flag_column[index] = _4op_flag_chr_beg) then If check_4op_flag(current_inst) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else If check_4op_flag(PRED(current_inst)) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else else If (_4op_flag_column[index] = _4op_flag_chr_end) then If check_4op_flag(current_inst) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := PRED(index); _4op_idx22 := index; end else If check_4op_flag(PRED(current_inst)) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := PRED(index); _4op_idx22 := index; end; If _4op_ins_flag then begin songdata.instr_data[_4op_idx11] := temp_songdata.instr_data[_4op_idx21]; songdata.instr_names[_4op_idx11] := Copy(songdata.instr_names[_4op_idx11],1,9)+ Copy(temp_songdata.instr_names[_4op_idx21],10,32); songdata.instr_data[_4op_idx12] := temp_songdata.instr_data[_4op_idx22]; songdata.instr_names[_4op_idx12] := Copy(songdata.instr_names[_4op_idx12],1,9)+ Copy(temp_songdata.instr_names[_4op_idx22],10,32); end; end else begin // put 4op instrument (force) _4op_ins_flag := FALSE; If (_4op_flag_column[index] = _4op_flag_chr_beg) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else If (_4op_flag_column[index] = _4op_flag_chr_end) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := PRED(index); _4op_idx22 := index; end; If _4op_ins_flag then begin songdata.instr_data[_4op_idx11] := temp_songdata.instr_data[_4op_idx21]; songdata.instr_names[_4op_idx11] := Copy(songdata.instr_names[_4op_idx11],1,9)+ Copy(temp_songdata.instr_names[_4op_idx21],10,32); songdata.instr_data[_4op_idx12] := temp_songdata.instr_data[_4op_idx22]; songdata.instr_names[_4op_idx12] := Copy(songdata.instr_names[_4op_idx12],1,9)+ Copy(temp_songdata.instr_names[_4op_idx22],10,32); set_4op_flag(_4op_idx11); end; end; // put 2op instrument If NOT _4op_ins_flag then begin songdata.instr_data[current_inst] := temp_songdata.instr_data[index]; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(temp_songdata.instr_names[index],10,32); end; end else begin songdata.instr_data := temp_songdata.instr_data; songdata.ins_4op_flags := temp_songdata.ins_4op_flags; For idx := 1 to 255 do songdata.instr_names[idx] := Copy(songdata.instr_names[idx],1,9)+ Copy(temp_songdata.instr_names[idx],10,32); end; load_flag := 1; load_flag_alt := BYTE_NULL; end; keyboard_reset_buffer; end; procedure _macro_preview_refresh; var temp,max_value: Integer; d_factor: Real; function arpeggio_def_attr(page: Byte): Word; var attr, attr2: Byte; begin If (page <= temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.length) then If (page >= temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_begin) and (page <= temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_begin+ PRED(temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_length)) and (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_begin > 0) and (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.keyoff_pos) and (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; arpeggio_def_attr := attr+attr2 SHL 8; end; function vibrato_def_attr(page: Byte): Word; var attr, attr2: Byte; begin If (page <= temp_songdata.macro_table[vibrato_table_idx]. vibrato.length) then If (page >= temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_begin) and (page <= temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_begin+ PRED(temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_length)) and (temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_begin > 0) and (temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= temp_songdata.macro_table[vibrato_table_idx]. vibrato.keyoff_pos) and (temp_songdata.macro_table[vibrato_table_idx]. vibrato.keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; vibrato_def_attr := attr+attr2 SHL 8; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_macro_preview_refresh'; {$ENDIF} // arpeggio preview ShowStr(centered_frame_vdest,xstart_arp+15,ystart_arp, #253, macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart_arp+15,ystart_arp+7, #252, macro_background+macro_topic2); ShowVStr(centered_frame_vdest,xstart_arp,ystart_arp+1, #179#179#179#179#179#158, macro_background+macro_text); ShowVStr(centered_frame_vdest,xstart_arp+30,ystart_arp+1, #179#179#179#179#179#158, macro_background+macro_text); max_value := 0; For temp := 1 to 255 do If (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[temp] > max_value) then If (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[temp] < $80) then max_value := Abs(temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[temp]); ShowStr(centered_frame_vdest,xstart_arp+31,ystart_arp+1, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart_arp+31,ystart_arp+2, '+', macro_background+macro_topic); d_factor := 90/min(max_value,1); For temp := -14 to 14 do If (arpeggio_table_pos+temp >= 1) and (arpeggio_table_pos+temp <= 255) then If (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[arpeggio_table_pos+temp] < $80) then ShowVStr(centered_frame_vdest,xstart_arp+15+temp,ystart_arp+1, ExpStrL(_gfx_bar_str(Round(temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[arpeggio_table_pos+temp]*d_factor),FALSE),6,' '), LO(arpeggio_def_attr(arpeggio_table_pos+temp))) else ShowVStr(centered_frame_vdest,xstart_arp+15+temp,ystart_arp+1, ExpStrL(FilterStr(note_layout[temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[arpeggio_table_pos+temp]-$80],'-',#241),6,' '), LO(arpeggio_def_attr(arpeggio_table_pos+temp))) else ShowVStr(centered_frame_vdest,xstart_arp+15+temp,ystart_arp+1, ExpStrL('',6,' '), macro_background+macro_text); // vibrato preview ShowStr(centered_frame_vdest,xstart_vib+15,ystart_vib, #253, macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart_vib+15,ystart_vib+7, #252, macro_background+macro_topic2); ShowVStr(centered_frame_vdest,xstart_vib,ystart_vib+1, #179#179#158#179#179#179, macro_background+macro_text); ShowVStr(centered_frame_vdest,xstart_vib+30,ystart_vib+1, #179#179#158#179#179#179, macro_background+macro_text); max_value := 0; For temp := 1 to 255 do If (Abs(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[temp]) > max_value) then max_value := Abs(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[temp]); ShowStr(centered_frame_vdest,xstart_vib+31,ystart_vib+1, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart_vib+31,ystart_vib+2, '+', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart_vib+31,ystart_vib+5, '-', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart_vib+31,ystart_vib+6, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_topic); d_factor := 45/min(max_value,1); For temp := -14 to 14 do If (vibrato_table_pos+temp >= 1) and (vibrato_table_pos+temp <= 255) then If (Round(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[vibrato_table_pos+temp]*d_factor) >= 0) then ShowVStr(centered_frame_vdest,xstart_vib+15+temp,ystart_vib+1, ExpStrR(ExpStrL(_gfx_bar_str(Round(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[vibrato_table_pos+temp]*d_factor),FALSE),3,' '),6,' '), LO(vibrato_def_attr(vibrato_table_pos+temp))) else ShowVStr(centered_frame_vdest,xstart_vib+15+temp,ystart_vib+1, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[vibrato_table_pos+temp])*d_factor),TRUE),3,' '),6,' '), LO(vibrato_def_attr(vibrato_table_pos+temp))) else ShowVStr(centered_frame_vdest,xstart_vib+15+temp,ystart_vib+1, ExpStrR('',6,' '), macro_background+macro_text); end; procedure a2w_macro_lister_external_proc; const _check_chr: array[BOOLEAN] of Char = (#251,' '); var temp,idx: Byte; attr,attr2,attr3: Byte; temps: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_macro_lister_external_proc'; {$ENDIF} temps := Copy(mn_environment.curr_item,2,2); idx := Str2num(temps,16); If (idx = 0) then idx := 1; VScrollBar(centered_frame_vdest,scrollbar_xstart,scrollbar_ystart, scrollbar_size,macro_table_size,idx,WORD_NULL, macro_background+macro_border, macro_background+macro_border); arpeggio_table_idx := idx; vibrato_table_idx := idx; Case mn_environment.keystroke of kSPACE: begin If shift_pressed then begin arp_tab_selected := NOT arp_tab_selected; If alt_pressed then begin temp_songdata.instr_macros[current_inst].arpeggio_table := 0; arp_tab_selected := FALSE; end; If arp_tab_selected then temp_songdata.instr_macros[current_inst].arpeggio_table := arpeggio_table_idx else If NOT alt_pressed then temp_songdata.instr_macros[current_inst].arpeggio_table := songdata.instr_macros[current_inst].arpeggio_table; end; If ctrl_pressed then begin vib_tab_selected := NOT vib_tab_selected; If alt_pressed then begin temp_songdata.instr_macros[current_inst].vibrato_table := 0; vib_tab_selected := FALSE; end; If vib_tab_selected then temp_songdata.instr_macros[current_inst].vibrato_table := vibrato_table_idx else If NOT alt_pressed then temp_songdata.instr_macros[current_inst].vibrato_table := songdata.instr_macros[current_inst].vibrato_table; end; end; kESC: begin temp_songdata.instr_macros[current_inst].arpeggio_table := songdata.instr_macros[current_inst].arpeggio_table; temp_songdata.instr_macros[current_inst].vibrato_table := songdata.instr_macros[current_inst].vibrato_table; EXIT; end; kENTER: begin If NOT arp_tab_selected and (temp_songdata.instr_macros[current_inst].arpeggio_table = 0) then songdata.instr_macros[current_inst].arpeggio_table := 0; If NOT vib_tab_selected and (temp_songdata.instr_macros[current_inst].vibrato_table = 0) then songdata.instr_macros[current_inst].vibrato_table := 0; EXIT; end; kLEFT, kShLEFT: If shift_pressed then If (arpeggio_table_pos > 1) then Dec(arpeggio_table_pos); kCtLEFT: begin If shift_pressed then If (arpeggio_table_pos > 1) then Dec(arpeggio_table_pos); If (vibrato_table_pos > 1) then Dec(vibrato_table_pos); end; kRIGHT, kShRGHT: If shift_pressed then If (arpeggio_table_pos < 255) then Inc(arpeggio_table_pos); kCtRGHT: begin If shift_pressed then If (arpeggio_table_pos < 255) then Inc(arpeggio_table_pos); If (vibrato_table_pos < 255) then Inc(vibrato_table_pos); end; kPgUP: If shift_pressed then If (arpeggio_table_pos-18 > 1) then Dec(arpeggio_table_pos,18) else arpeggio_table_pos := 1; kCtPgUP: begin If shift_pressed then If (arpeggio_table_pos-18 > 1) then Dec(arpeggio_table_pos,18) else arpeggio_table_pos := 1; If (vibrato_table_pos-18 > 1) then Dec(vibrato_table_pos,18) else vibrato_table_pos := 1; end; kPgDOWN: If shift_pressed then If (arpeggio_table_pos+18 < 255) then Inc(arpeggio_table_pos,18) else arpeggio_table_pos := 255; kCtPgDN: begin If shift_pressed then If (arpeggio_table_pos+18 < 255) then Inc(arpeggio_table_pos,18) else arpeggio_table_pos := 255; If (vibrato_table_pos+18 < 255) then Inc(vibrato_table_pos,18) else vibrato_table_pos := 255; end; kHOME: If shift_pressed then If (arpeggio_table_pos > temp_songdata.macro_table[idx].arpeggio.length) then arpeggio_table_pos := min(1,temp_songdata.macro_table[idx].arpeggio.length) else arpeggio_table_pos := 1; kCtHOME: If (vibrato_table_pos > temp_songdata.macro_table[idx].vibrato.length) then vibrato_table_pos := min(1,temp_songdata.macro_table[idx].vibrato.length) else vibrato_table_pos := 1; kEND: If shift_pressed then If (arpeggio_table_pos < temp_songdata.macro_table[idx].arpeggio.length) then arpeggio_table_pos := temp_songdata.macro_table[idx].arpeggio.length else arpeggio_table_pos := 255; kCtEND: If (vibrato_table_pos < temp_songdata.macro_table[idx].vibrato.length) then vibrato_table_pos := temp_songdata.macro_table[idx].vibrato.length else vibrato_table_pos := 255; kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If update_current_inst and (current_inst > 1) then begin Dec(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; STATUS_LINE_refresh; keyboard_reset_buffer; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If update_current_inst and (current_inst < 255) then begin Inc(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; STATUS_LINE_refresh; keyboard_reset_buffer; end; end; If arp_tab_selected then begin attr := macro_hi_text SHL 4+macro_background SHR 4; attr2 := macro_background+macro_hi_text; attr3 := macro_hi_text SHL 4+macro_background SHR 4; temp := arpeggio_table_idx; end else begin attr := macro_background+macro_hi_text; If (temp_songdata.instr_macros[current_inst].arpeggio_table <> 0) then attr2 := macro_background+macro_hi_text else attr2 := macro_background+macro_text_dis; attr3 := macro_background+macro_text; temp := temp_songdata.instr_macros[current_inst].arpeggio_table; end; ShowC3Str(centered_frame_vdest,xstart_arp-1,ystart_arp+8, '`[`'+_check_chr[NOT arp_tab_selected and (temp_songdata.instr_macros[current_inst].arpeggio_table = 0)]+ '`]`~ '+byte2hex(temp)+'~', attr,attr2,attr3); If vib_tab_selected then begin attr := macro_hi_text SHL 4+macro_background SHR 4; attr2 := macro_background+macro_hi_text; attr3 := macro_hi_text SHL 4+macro_background SHR 4; temp := vibrato_table_idx; end else begin attr := macro_background+macro_hi_text; If (temp_songdata.instr_macros[current_inst].vibrato_table <> 0) then attr2 := macro_background+macro_hi_text else attr2 := macro_background+macro_text_dis; attr3 := macro_background+macro_text; temp := temp_songdata.instr_macros[current_inst].vibrato_table; end; ShowC3Str(centered_frame_vdest,xstart_vib-1,ystart_vib+8, '`[`'+_check_chr[NOT vib_tab_selected and (temp_songdata.instr_macros[current_inst].vibrato_table = 0)]+ '`]`~ '+byte2hex(temp)+'~', attr,attr2,attr3); If (arpeggio_table_pos > 15) then ShowStr(centered_frame_vdest,xstart_arp+6,ystart_arp+8,#17, macro_background+macro_text) else ShowStr(centered_frame_vdest,xstart_arp+6,ystart_arp+8,#17, macro_background+macro_text_dis); If (arpeggio_table_pos < temp_songdata.macro_table[idx].arpeggio.length-15+1) then ShowStr(centered_frame_vdest,xstart_arp+25,ystart_arp+8,#16, macro_background+macro_text) else ShowStr(centered_frame_vdest,xstart_arp+25,ystart_arp+8,#16, macro_background+macro_text_dis); If (vibrato_table_pos > 15) then ShowStr(centered_frame_vdest,xstart_vib+6,ystart_vib+8,#17, macro_background+macro_text) else ShowStr(centered_frame_vdest,xstart_vib+6,ystart_vib+8,#17, macro_background+macro_text_dis); If (vibrato_table_pos < temp_songdata.macro_table[idx].vibrato.length-15+1) then ShowStr(centered_frame_vdest,xstart_vib+24,ystart_vib+8,#16, macro_background+macro_text) else ShowStr(centered_frame_vdest,xstart_vib+24,ystart_vib+8,#16, macro_background+macro_text_dis); ShowCStr(centered_frame_vdest,xstart_arp+10,ystart_vib+8, 'ARPEGGiO (~'+byte2hex(arpeggio_table_pos)+'~)', macro_background+macro_text, macro_background+macro_hi_text); ShowCStr(centered_frame_vdest,xstart_vib+10,ystart_vib+8, 'ViBRATO (~'+byte2hex(vibrato_table_pos)+'~)', macro_background+macro_text, macro_background+macro_hi_text); context_str3 := ''; If update_current_inst and (get_4op_to_test <> 0) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then If (LO(get_4op_to_test) = HI(get_4op_to_test)) then context_str3 := ' ~[~'#244+byte2hex(HI(get_4op_to_test))+'~,~'#245+byte2hex(HI(get_4op_to_test))+'~]~' else If (current_inst = HI(get_4op_to_test)) then context_str3 := ' ~[~'#244+byte2hex(HI(get_4op_to_test))+'~,'#245+byte2hex(LO(get_4op_to_test))+']~' else context_str3 := ' ~['#244+byte2hex(HI(get_4op_to_test))+',~'#245+byte2hex(LO(get_4op_to_test))+'~]~'; temps := '`'+ExpStrL('`'+context_str3+context_str2+context_str+' `[`SPEED:'+Num2str(tempo*songdata.macro_speedup,10)+#174+'`]` ',52,#205); ShowC3Str(centered_frame_vdest,xstart+window_xsize-C3StrLen(temps),ystart+window_ysize, temps, macro_background+macro_context, macro_background+macro_context_dis, macro_background+macro_border); If (a2w_institle_pos <> 0) then ShowStr(centered_frame_vdest,mn_environment.xpos+a2w_institle_pos,mn_environment.ypos, byte2hex(current_inst), macro_background+macro_title); arpvib_arpeggio_table := arpeggio_table_idx; arpvib_vibrato_table := vibrato_table_idx; _macro_preview_refresh; a2w_macro_lister_external_proc_callback; end; const _panning: array[0..2] of Char = #241'<>'; _hex: array[0..15] of Char = '0123456789ABCDEF'; _fmreg_add_prev_size: Byte = 0; var fmreg_cursor_pos: Byte; fmreg_left_margin: Byte; fmreg_hpos: Byte; fmreg_vpos: Byte; fmreg_instr: Byte; fmreg_page: Byte; fmreg_str: String; fmreg_scrlbar_size: Byte; fmreg_scrlbar_items: Byte; function min0(number: Integer; flag: Integer): Integer; begin If (number > 0) then min0 := number else min0 := flag; end; function fmreg_def_attr(page: Byte): Word; var attr, attr2: Byte; begin If (page <= temp_songdata.instr_macros[fmreg_instr].length) then If (page >= temp_songdata.instr_macros[fmreg_instr].loop_begin) and (page <= temp_songdata.instr_macros[fmreg_instr].loop_begin+ PRED(temp_songdata.instr_macros[fmreg_instr].loop_length)) and (temp_songdata.instr_macros[fmreg_instr].loop_begin > 0) and (temp_songdata.instr_macros[fmreg_instr].loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= temp_songdata.instr_macros[fmreg_instr].keyoff_pos) and (temp_songdata.instr_macros[fmreg_instr].keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; fmreg_def_attr := attr+attr2 SHL 8; end; function _fmreg_str(page: Byte): String; var fmreg_str: String; begin With temp_songdata.instr_macros[fmreg_instr].data[page].fm_data do begin fmreg_str := _hex[ATTCK_DEC_modulator SHR 4]+' '+ _hex[ATTCK_DEC_modulator AND $0f]+' '+ _hex[SUSTN_REL_modulator SHR 4]+' '+ _hex[SUSTN_REL_modulator AND $0f]+' '+ _hex[WAVEFORM_modulator AND 7]+' '+ byte2hex(KSL_VOLUM_modulator AND $3f)+' '+ _hex[KSL_VOLUM_modulator SHR 6]+' '+ _hex[AM_VIB_EG_modulator AND $0f]+' '; If (AM_VIB_EG_modulator SHR 7 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'T'; If (AM_VIB_EG_modulator SHR 6 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'V'; If (AM_VIB_EG_modulator SHR 4 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'K'; If (AM_VIB_EG_modulator SHR 5 AND 1 = 0) then fmreg_str := fmreg_str+#250' ' else fmreg_str := fmreg_str+'S '; fmreg_str := fmreg_str+ _hex[ATTCK_DEC_carrier SHR 4]+' '+ _hex[ATTCK_DEC_carrier AND $0f]+' '+ _hex[SUSTN_REL_carrier SHR 4]+' '+ _hex[SUSTN_REL_carrier AND $0f]+' '+ _hex[WAVEFORM_carrier AND 7]+' '+ byte2hex(KSL_VOLUM_carrier AND $3f)+' '+ _hex[KSL_VOLUM_carrier SHR 6]+' '+ _hex[AM_VIB_EG_carrier AND $0f]+' '; If (AM_VIB_EG_carrier SHR 7 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'T'; If (AM_VIB_EG_carrier SHR 6 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'V'; If (AM_VIB_EG_carrier SHR 4 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'K'; If (AM_VIB_EG_carrier SHR 5 AND 1 = 0) then fmreg_str := fmreg_str+#250' ' else fmreg_str := fmreg_str+'S '; fmreg_str := fmreg_str+_hex[FEEDBACK_FM AND 1]+' '; fmreg_str := fmreg_str+_hex[FEEDBACK_FM SHR 1 AND 7]+' '; end; With temp_songdata.instr_macros[fmreg_instr].data[page] do begin If (freq_slide < 0) then fmreg_str := fmreg_str+'-'+ExpStrL(Num2str(Abs(freq_slide),16),3,'0')+' ' else fmreg_str := fmreg_str+'+'+ExpStrL(Num2str(Abs(freq_slide),16),3,'0')+' '; fmreg_str := fmreg_str+ _panning[panning]+' '+ byte2hex(duration); end; _fmreg_str := fmreg_str; end; function _dis_fmreg_col(fmreg_col: Byte): Boolean; var result: Boolean; begin result := FALSE; Case fmreg_col of 1,2,3,4, 5: If temp_songdata.dis_fmreg_col[fmreg_instr][fmreg_col-1] then result := TRUE; 6, 7: If temp_songdata.dis_fmreg_col[fmreg_instr][5] then result := TRUE; 8,9,10,11,12,13, 14,15,16,17, 18: If temp_songdata.dis_fmreg_col[fmreg_instr][fmreg_col-2] then result := TRUE; 19, 20: If temp_songdata.dis_fmreg_col[fmreg_instr][17] then result := TRUE; 21,22,23,24, 25,26,27, 28: If temp_songdata.dis_fmreg_col[fmreg_instr][fmreg_col-3] then result := TRUE; 29,30,31, 32: If temp_songdata.dis_fmreg_col[fmreg_instr][26] then result := TRUE; 33: If temp_songdata.dis_fmreg_col[fmreg_instr][27] then result := TRUE; end; If (fmreg_col in [14..28]) and (temp_songdata.instr_data[current_inst].perc_voice in [2..5]) then result := TRUE; _dis_fmreg_col := result; end; function _str1(def_chr: Char): String; const _on_off: array[BOOLEAN] of Char = (#205,#254); var temp: Byte; temp_str: String; begin temp_str := ''; _on_off[FALSE] := def_chr; For temp := 0 to 4 do temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][temp]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][5]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][5]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][6]]+ def_chr+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][7]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][8]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][9]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][10]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][11]]+def_chr; For temp := 12 to 16 do temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][temp]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][17]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][17]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][18]]+def_chr+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][19]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][20]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][21]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][22]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][23]]+def_chr; For temp := 24 to 25 do temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][temp]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][26]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][26]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][26]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][26]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][27]]; _str1 := temp_str; end; function _str2(str: String; len: Byte): String; begin asm lea esi,[str] mov edi,@RESULT movzx ebx,len xor edx,edx push edi lodsb inc edi xor ecx,ecx mov ecx,ebx jecxz @@3 movzx ecx,al jecxz @@3 @@1: cmp edx,ebx jae @@3 lodsb stosb cmp al,'`' jz @@2 inc edx @@2: loop @@1 @@3: pop edi mov eax,esi lea esi,[str] sub eax,esi dec eax stosb end; end; procedure fmreg_page_refresh(xpos,ypos: Byte; page: Word); var attr: Byte; temps,fmreg_str2: String; fmreg_col,index, index2: Byte; dummy_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fmreg_page_refresh'; {$ENDIF} attr := LO(fmreg_def_attr(page AND $0fff)); fmreg_str := _fmreg_str(page AND $0fff); fmreg_str2 := fmreg_str; index := 0; index2 := 0; For fmreg_col := 1 to 35-1 do If _dis_fmreg_col(fmreg_col) then begin Insert('`',fmreg_str2,pos5[fmreg_col]+index); Insert('`',fmreg_str2,pos5[fmreg_col]+index+2); If (pos5[fmreg_col] < fmreg_left_margin) then Inc(index2,2); Inc(index,2); end; temps := Copy(fmreg_str2,fmreg_left_margin+index2, Length(fmreg_str2)-fmreg_left_margin-index2+1); dummy_str := macro_retrig_str[temp_songdata.instr_macros[fmreg_instr].data[page AND $0ff].fm_data. FEEDBACK_FM SHR 5]; ShowC3Str(centered_frame_vdest,xpos+3,ypos, #179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_xsize-82-_fmreg_add_prev_size)+'~', macro_background+macro_text, attr, macro_background+macro_text_dis) end; procedure _scroll_cur_left; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_scroll_cur_left'; {$ENDIF} Repeat If (fmreg_cursor_pos > 1) then Dec(fmreg_cursor_pos) else Dec(fmreg_left_margin); until (fmreg_str[PRED(fmreg_left_margin+fmreg_cursor_pos-1)] = ' ') or (fmreg_left_margin+fmreg_cursor_pos-1 = 1); fmreg_cursor_pos := pos5[fmreg_hpos]-fmreg_left_margin+1; end; procedure _scroll_cur_right; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_scroll_cur_right'; {$ENDIF} Repeat If (fmreg_cursor_pos < 31+window_xsize-82-_fmreg_add_prev_size) then Inc(fmreg_cursor_pos) else Inc(fmreg_left_margin); until (fmreg_str[SUCC(fmreg_left_margin+fmreg_cursor_pos-1)] = ' ') or (fmreg_left_margin+fmreg_cursor_pos-1 = 57); fmreg_cursor_pos := pos5[fmreg_hpos]-fmreg_left_margin+1; end; procedure _dec_fmreg_hpos; var old_hpos_idx: Byte; new_hpos_idx: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_dec_fmreg_hpos'; {$ENDIF} old_hpos_idx := pos5vw[fmreg_hpos]; Repeat Dec(fmreg_hpos); new_hpos_idx := pos5vw[fmreg_hpos]; _scroll_cur_left; until (fmreg_hpos = 1) or (old_hpos_idx <> new_hpos_idx); If (fmreg_hpos > 1) then While (pos5vw[PRED(fmreg_hpos)] = pos5vw[fmreg_hpos]) do begin Dec(fmreg_hpos); _scroll_cur_left; end; end; procedure _inc_fmreg_hpos; var old_hpos_idx: Byte; new_hpos_idx: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_inc_fmreg_hpos'; {$ENDIF} old_hpos_idx := pos5vw[fmreg_hpos]; Repeat Inc(fmreg_hpos); new_hpos_idx := pos5vw[fmreg_hpos]; _scroll_cur_right; until (fmreg_hpos = 35-1) or (old_hpos_idx <> new_hpos_idx); end; function _fmreg_param(page,fmreg_hpos: Byte): Integer; var result: Integer; fmreg_str: String; begin fmreg_str := _fmreg_str(page); Case fmreg_hpos of {%n} 1,2,3,4,5,8,9,14,15,16,17, 18,21,22,27,28: result := Str2num(fmreg_str[pos5[fmreg_hpos]],16); {%nn} 6,7: result := Str2num(Copy(fmreg_str,pos5[6],2),16); 19,20: result := Str2num(Copy(fmreg_str,pos5[19],2),16); 34,35: result := Str2num(Copy(fmreg_str,pos5[34],2),16); {sw} 10,11,12,13,23,24, 25,26: If (fmreg_str[pos5[fmreg_hpos]] = #251) then result := 1 else result := 0; {fsl} 29,30,31,32: begin result := Str2num(Copy(fmreg_str,pos5[30],3),16); If (fmreg_str[pos5[29]] = '-') then result := -result; end; {pan} 33: Case SYSTEM.Pos(fmreg_str[pos5[33]],_panning) of 1: result := 0; 2: result := -1; 3: result := 1; end; end; _fmreg_param := result; end; procedure _fmreg_macro_preview_refresh(xstart,ystart: Byte; page: Byte); var temp,max_value: Integer; d_factor: Real; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_fmreg_macro_preview_refresh'; {$ENDIF} ShowStr(centered_frame_vdest,xstart+10+(_fmreg_add_prev_size DIV 2),ystart, #253, macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart+10+(_fmreg_add_prev_size DIV 2),ystart+7, #252, macro_background+macro_topic2); If NOT (fmreg_hpos in [29..33]) then begin ShowVStr(centered_frame_vdest,xstart,ystart+1, #179#179#179#179#179#158, macro_background+macro_text); ShowVStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size,ystart+1, #179#179#179#179#179#158, macro_background+macro_text); end else begin ShowVStr(centered_frame_vdest,xstart,ystart+1, #179#179#158#179#179#179, macro_background+macro_text); ShowVStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size,ystart+1, #179#179#158#179#179#179, macro_background+macro_text); end; max_value := 0; For temp := 1 to 255 do If (Abs(_fmreg_param(temp,fmreg_hpos)) > max_value) then max_value := Abs(_fmreg_param(temp,fmreg_hpos)); If NOT (fmreg_hpos in [29..33]) then begin ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+1, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+2, '+', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+5, ' ', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+6, ExpStrR('',3,' '), macro_background+macro_topic); end else begin ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+1, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+2, '+', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+5, '-', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+6, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); end; If NOT (fmreg_hpos in [29..33]) then d_factor := 90/min(max_value,1) else d_factor := 45/min(max_value,1); If NOT (fmreg_hpos in [29..33]) then For temp := -9-(_fmreg_add_prev_size DIV 2) to 9+(_fmreg_add_prev_size DIV 2) do If (page+temp >= 1) and (page+temp <= 255) then If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL(_gfx_bar_str(Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor),FALSE),6,' '), LO(fmreg_def_attr(page+temp))) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL(_gfx_bar_str(Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor),FALSE),6,' '), macro_background+macro_text_dis) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL('',6,' '), macro_background+macro_text) else For temp := -9-(_fmreg_add_prev_size DIV 2) to 9+(_fmreg_add_prev_size DIV 2) do If (page+temp >= 1) and (page+temp <= 255) then If (Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor) >= 0) then If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrR(ExpStrL(_gfx_bar_str(Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor),FALSE),3,' '),6,' '), LO(fmreg_def_attr(page+temp))) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrR(ExpStrL(_gfx_bar_str(Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor),FALSE),3,' '),6,' '), macro_background+macro_text_dis) else If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(_fmreg_param(page+temp,fmreg_hpos))*d_factor),TRUE),3,' '),6,' '), LO(fmreg_def_attr(page+temp))) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(_fmreg_param(page+temp,fmreg_hpos))*d_factor),TRUE),3,' '),6,' '), macro_background+macro_text_dis) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL('',6,' '), macro_background+macro_text); end; procedure a2w_lister_external_proc; var idx,temp: Byte; temps: String; songdata_ptr: Pointer; attr: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_lister_external_proc'; {$ENDIF} Case mn_environment.keystroke of kUP: If shift_pressed then If (fmreg_vpos > 1) then Dec(fmreg_vpos) else If (fmreg_page > 1) then Dec(fmreg_page); kDOWN: If shift_pressed then If (fmreg_vpos < 6) then Inc(fmreg_vpos) else If (fmreg_page < 255-6+1) then Inc(fmreg_page); kPgUP: If shift_pressed then If (fmreg_page > 6) then Dec(fmreg_page,6) else If (fmreg_page > 1) then fmreg_page := 1 else fmreg_vpos := 1; kPgDOWN: If shift_pressed then If (fmreg_page+6 < 255-6+1) then Inc(fmreg_page,6) else If (fmreg_page < 255-6+1) then fmreg_page := 255-6+1 else fmreg_vpos := 6; kHOME: If shift_pressed then begin fmreg_page := 1; fmreg_vpos := 1; end; kEND: If shift_pressed then begin fmreg_page := 255-6+1; fmreg_vpos := 6; end; kCtHOME: begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kCtEND: begin fmreg_hpos := 35-1; fmreg_cursor_pos := max(pos5[fmreg_hpos],31+window_xsize-82-_fmreg_add_prev_size); fmreg_left_margin := min(pos5[35]-(31+window_xsize-82-_fmreg_add_prev_size),1); _dec_fmreg_hpos; _inc_fmreg_hpos; end; kLEFT: If shift_pressed then If (fmreg_hpos > 1) then _dec_fmreg_hpos else If cycle_pattern then begin fmreg_hpos := 35-1; fmreg_cursor_pos := max(pos5[fmreg_hpos],31+window_xsize-82-_fmreg_add_prev_size); fmreg_left_margin := min(pos5[35]-(31+window_xsize-82-_fmreg_add_prev_size),1); _dec_fmreg_hpos; _inc_fmreg_hpos; end; kRIGHT: If shift_pressed then If (fmreg_hpos < 35-1) then _inc_fmreg_hpos else If cycle_pattern then begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end; end; For temp := 1 to _a2w_lister_count do begin If (mn_environment.curr_pos = mn_environment.curr_page+temp-1) then attr := mn_setting.text2_attr else attr := mn_setting.text_attr; ShowStr(mn_environment.v_dest,mn_environment.xpos+1,mn_environment.ypos+3+temp, _4op_flag_column[mn_environment.curr_page+temp-1], attr); end; fmreg_instr := Str2num(Copy(mn_environment.curr_item,7,2),16); songdata_ptr := Addr(temp_songdata); If update_current_inst then begin current_inst := fmreg_instr; instrum_page := fmreg_instr; STATUS_LINE_refresh; songdata_ptr := Addr(songdata); end; If (a2w_institle_pos <> 0) then ShowStr(centered_frame_vdest,mn_environment.xpos+a2w_institle_pos,mn_environment.ypos, byte2hex(current_inst), macro_background+macro_title); context_str3 := ''; If update_current_inst and (get_4op_to_test <> 0) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then If (LO(get_4op_to_test) = HI(get_4op_to_test)) then context_str3 := ' ~[~'#244+byte2hex(HI(get_4op_to_test))+'~,~'#245+byte2hex(HI(get_4op_to_test))+'~]~' else If (current_inst = HI(get_4op_to_test)) then context_str3 := ' ~[~'#244+byte2hex(HI(get_4op_to_test))+'~,'#245+byte2hex(LO(get_4op_to_test))+']~' else context_str3 := ' ~['#244+byte2hex(HI(get_4op_to_test))+',~'#245+byte2hex(LO(get_4op_to_test))+'~]~'; temps := '`'+ExpStrL('`'+context_str3+context_str2+context_str+' `[`SPEED:'+Num2str(tempo*songdata.macro_speedup,10)+#174+'`]` ',52,#205); ShowC3Str(centered_frame_vdest,xstart+window_xsize-C3StrLen(temps),ystart+window_ysize, temps, macro_background+macro_context, macro_background+macro_context_dis, macro_background+macro_border); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+2, 'LENGTH: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].length)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+3, 'LOOP BEG.: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].loop_begin)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+4, 'LOOP LEN.: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].loop_length)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+5, 'KEY-OFF: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].keyoff_pos)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+6, 'ARP.TABLE: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].arpeggio_table)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+7, 'ViB.TABLE: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].vibrato_table)+' ~', macro_background+macro_topic, macro_background+macro_text); VScrollBar(centered_frame_vdest,xstart+window_xsize,ystart+3, fmreg_scrlbar_size,fmreg_scrlbar_items,mn_environment.curr_pos,WORD_NULL, macro_background+macro_border, macro_background+macro_border); VScrollBar(centered_frame_vdest,xstart+window_xsize,ystart+window_ysize-10+1, 8,255-6,fmreg_page,WORD_NULL, macro_background+macro_border, macro_background+macro_border); _fmreg_macro_preview_refresh(xstart+17,ystart+window_ysize-10+1,fmreg_page+fmreg_vpos-1); ShowCStr(centered_frame_vdest,xstart+49+_fmreg_add_prev_size,ystart+window_ysize-10+1, ExpStrL('',fmreg_cursor_pos,#205)+'~'+#31+'~'+ ExpStrL('',window_xsize-49-_fmreg_add_prev_size-fmreg_cursor_pos-1,#205), macro_background+macro_topic2, macro_background+macro_hi_text); ShowCStr(centered_frame_vdest,xstart+49+_fmreg_add_prev_size,ystart+window_ysize-2, ExpStrL('',fmreg_cursor_pos,#205)+'~'+#30+'~'+ ExpStrL('',window_xsize-49-_fmreg_add_prev_size-fmreg_cursor_pos-1,#205), macro_background+macro_topic2, macro_background+macro_hi_text); ShowStr(centered_frame_vdest,xstart+2,ystart+window_ysize-1, ExpStrR(macro_table_hint_str[20+fmreg_hpos],window_xsize-2,' '), macro_background+macro_hint); For idx := 1 to 6 do begin If (idx = fmreg_vpos) then ShowStr(centered_frame_vdest,xstart+43+_fmreg_add_prev_size,ystart+window_ysize-10+1+idx, #16+byte2hex(fmreg_page+idx-1)+#17, macro_background+macro_hi_text) else ShowStr(centered_frame_vdest,xstart+43+_fmreg_add_prev_size,ystart+window_ysize-10+1+idx, ' '+byte2hex(fmreg_page+idx-1)+' ', macro_background+macro_topic); fmreg_page_refresh(xstart+44+_fmreg_add_prev_size,ystart+window_ysize-10+1+idx,fmreg_page+idx-1); end; a2w_lister_external_proc_callback; end; procedure a2w_file_loader(loadFromFile: Boolean; loadMacros: Boolean; bankSelector: Boolean; loadBankPossible: Boolean; updateCurInstr: Boolean); type tOLD_HEADER = Record ident: array[1..20] of Char; crc32: Longint; ffver: Byte; b0len: Longint; b1len: Longint; end; type tHEADER = Record ident: array[1..20] of Char; crc32: Longint; ffver: Byte; b0len: Longint; b1len: Longint; b2len: Longint; end; const id = '_A2insbank_w/macros_'; var f: File; a2w_instdata_source: String; header: tHEADER; header2: tOLD_HEADER; crc,temp: Longint; idx,index,nm_valid: Byte; idx1,idx2: Integer; temp_str: String; arpvib_arpeggio_table_bak: Byte; arpvib_vibrato_table_bak: Byte; browser_flag: Boolean; ysize: Byte; // backup of Menu settings / variables old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; old_topic_mask_chr: Set of Char; old_frame_enabled: Boolean; old_shadow_enabled: Boolean; old_winshade: Boolean; old_center_box: Boolean; old_show_scrollbar: Boolean; old_text_attr, old_text2_attr, old_short_attr, old_short2_attr, old_disbld_attr, old_contxt_attr, old_contxt2_attr, old_topic_attr, old_hi_topic_attr: Byte; const new_keys: array[1..5] of Word = (kESC,kENTER,kF1,kTAB,kCtENTR); var old_keys: array[1..50] of Word; procedure _put_2op_instrument; begin songdata.instr_data[current_inst] := temp_songdata.instr_data[index]; songdata.instr_macros[current_inst] := temp_songdata.instr_macros[index]; songdata.dis_fmreg_col[current_inst] := temp_songdata.dis_fmreg_col[index]; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(temp_songdata.instr_names[index],10,32); idx1 := -1; idx2 := -1; If (songdata.instr_macros[current_inst].arpeggio_table <> 0) then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[ songdata.instr_macros[current_inst].arpeggio_table].arpeggio); If (songdata.instr_macros[current_inst].vibrato_table <> 0) then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[ songdata.instr_macros[current_inst].vibrato_table].vibrato); temp_str := ''; If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If NOT (temp_str <> '') then begin If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[songdata.instr_macros[current_inst].arpeggio_table].arpeggio; songdata.instr_macros[current_inst].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[songdata.instr_macros[current_inst].vibrato_table].vibrato; songdata.instr_macros[current_inst].vibrato_table := idx2; end end else Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); end; procedure _put_4op_instrument; begin songdata.instr_data[_4op_idx11] := temp_songdata.instr_data[_4op_idx21]; songdata.instr_macros[_4op_idx11] := temp_songdata.instr_macros[_4op_idx21]; songdata.dis_fmreg_col[_4op_idx11] := temp_songdata.dis_fmreg_col[_4op_idx21]; songdata.instr_names[_4op_idx11] := Copy(songdata.instr_names[_4op_idx11],1,9)+ Copy(temp_songdata.instr_names[_4op_idx21],10,32); idx1 := -1; idx2 := -1; If (songdata.instr_macros[_4op_idx11].arpeggio_table <> 0) then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[ songdata.instr_macros[_4op_idx11].arpeggio_table].arpeggio); If (songdata.instr_macros[_4op_idx11].vibrato_table <> 0) then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[ songdata.instr_macros[_4op_idx11].vibrato_table].vibrato); temp_str := ''; If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If NOT (temp_str <> '') then begin If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[songdata.instr_macros[_4op_idx11].arpeggio_table].arpeggio; songdata.instr_macros[_4op_idx11].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[songdata.instr_macros[_4op_idx11].vibrato_table].vibrato; songdata.instr_macros[_4op_idx11].vibrato_table := idx2; end end else Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); songdata.instr_data[_4op_idx12] := temp_songdata.instr_data[_4op_idx22]; songdata.instr_macros[_4op_idx12] := temp_songdata.instr_macros[_4op_idx22]; songdata.dis_fmreg_col[_4op_idx12] := temp_songdata.dis_fmreg_col[_4op_idx22]; songdata.instr_names[_4op_idx12] := Copy(songdata.instr_names[_4op_idx12],1,9)+ Copy(temp_songdata.instr_names[_4op_idx22],10,32); idx1 := -1; idx2 := -1; If (songdata.instr_macros[_4op_idx12].arpeggio_table <> 0) then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[ songdata.instr_macros[_4op_idx12].arpeggio_table].arpeggio); If (songdata.instr_macros[_4op_idx12].vibrato_table <> 0) then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[ songdata.instr_macros[_4op_idx12].vibrato_table].vibrato); temp_str := ''; If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If NOT (temp_str <> '') then begin If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[songdata.instr_macros[_4op_idx12].arpeggio_table].arpeggio; songdata.instr_macros[_4op_idx12].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[songdata.instr_macros[_4op_idx12].vibrato_table].vibrato; songdata.instr_macros[_4op_idx12].vibrato_table := idx2; end end else Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); end; label _jmp1,_jmp1e,_jmp2,_jmp2e,_end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_file_loader'; {$ENDIF} arpvib_arpeggio_table_bak := arpvib_arpeggio_table; arpvib_vibrato_table_bak := arpvib_vibrato_table; songdata_bak := songdata; temp_songdata := songdata_bak; update_current_inst := updateCurInstr; browser_flag := FALSE; progress_num_steps := 0; progress_step := 0; If NOT loadFromFile and bankSelector and NOT loadBankPossible then begin a2w_instdata_source := ''; If loadMacros then begin arp_tab_selected := _macro_editor__pos[_arp_vib_mode] in [8..13]; vib_tab_selected := _macro_editor__pos[_arp_vib_mode] in [14..20]; end else begin arp_tab_selected := songdata.instr_macros[current_inst].arpeggio_table <> 0; vib_tab_selected := songdata.instr_macros[current_inst].vibrato_table <> 0; end; // init 4OP flags (no file bank) temp_songdata.ins_4op_flags := songdata.ins_4op_flags; FillChar(_4op_flag_column,SizeOf(_4op_flag_column),0); For temp := 1 to PRED(255) do If check_4op_flag_temp(temp) then begin If NOT (_4op_flag_column[temp] in _4op_flag_chars) then _4op_flag_column[temp] := _4op_flag_chr_beg; If NOT (_4op_flag_column[SUCC(temp)] in _4op_flag_chars) then _4op_flag_column[SUCC(temp)] := _4op_flag_chr_end; end; If loadMacros then GOTO _jmp1 // Arpeggio/Vibrato Macro Browser else GOTO _jmp2; // Instrument Macro Browser end else a2w_instdata_source := instdata_source; {$i-} Assign(f,a2w_instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2W]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; If (header.ffver = 1) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header2.b0len,2,crc); crc := Update32(header2.b1len,2,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; SeekF(f,SizeOf(header2)); If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; APACK_decompress(buf1,temp_songdata.instr_names); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; APACK_decompress(buf1,temp_songdata.macro_table); FillChar(temp_songdata.dis_fmreg_col,SizeOf(temp_songdata.dis_fmreg_col),FALSE); end; If (header.ffver = 2) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header.b0len,2,crc); crc := Update32(header.b1len,2,crc); crc := Update32(header.b2len,2,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; APACK_decompress(buf1,temp_songdata.instr_names); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; APACK_decompress(buf1,temp_songdata.macro_table); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; APACK_decompress(buf1,temp_songdata.dis_fmreg_col); end; If (header.ffver = FFVER_A2W) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header.b0len,2,crc); crc := Update32(header.b1len,2,crc); crc := Update32(header.b2len,2,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; progress_num_steps := 0; LZH_decompress(buf1,buf2,header.b0len); Move(buf2,temp_songdata.instr_names,SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)+ SizeOf(songdata.instr_macros)); Move(buf2[SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)+ SizeOf(songdata.instr_macros)],temp_songdata.ins_4op_flags, SizeOf(songdata.ins_4op_flags)); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; LZH_decompress(buf1,temp_songdata.macro_table,header.b1len); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; LZH_decompress(buf1,temp_songdata.dis_fmreg_col,header.b2len); end; CloseF(f); // init 4OP flags (file bank) FillChar(_4op_flag_column,SizeOf(_4op_flag_column),0); For temp := 1 to PRED(255) do If check_4op_flag_temp(temp) then begin If NOT (_4op_flag_column[temp] in _4op_flag_chars) then _4op_flag_column[temp] := _4op_flag_chr_beg; If NOT (_4op_flag_column[SUCC(temp)] in _4op_flag_chars) then _4op_flag_column[SUCC(temp)] := _4op_flag_chr_end; end; If loadMacros then begin _jmp1: ScreenMemCopy(screen_ptr,ptr_screen_backup); nm_valid := count_macros; If (nm_valid = 0) then nm_valid := 1; If NOT bankSelector then begin mn_environment.keystroke := kCtENTR; arp_tab_selected := TRUE; vib_tab_selected := TRUE; GOTO _jmp1e; end; window_xsize := 73; If is_default_screen_mode then window_ysize := max(nm_valid+5,15)+10 else window_ysize := max(nm_valid+5,20)+10; If (a2w_instdata_source <> '') theN temp_str := ' '+iCASE(NameOnly(a2w_instdata_source))+' '#16' A/V MACROS ' else temp_str := ' ARPEGGiO/ViBRATO MACRO BROWSER '; If update_current_inst then temp_str := temp_str + '(iNS_ ) ' else temp_str := temp_str + '[iNS_ ] '; a2w_institle_pos := (window_xsize DIV 2)+(Length(temp_str) DIV 2)-3; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,window_xsize,window_ysize, temp_str, macro_background+macro_border, macro_background+macro_title, frame_double); ShowStr(centered_frame_vdest,xstart+1,ystart+window_ysize-10+1, av_browser_str[6], macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart+1,ystart+window_ysize-2, ExpStrR('',72,#205), macro_background+macro_topic2); context_str := ' ~[~'+Num2str(nm_valid,10)+'~/255]~'; xstart_arp := xstart+3; ystart_arp := ystart+window_ysize-10+1; xstart_vib := xstart+38; ystart_vib := ystart+window_ysize-10+1; scrollbar_xstart := xstart+window_xsize; scrollbar_ystart := ystart+1; scrollbar_size := window_ysize-10+1; macro_table_size := nm_valid; If (a2w_instdata_source <> '') then temp_str := a2w_instdata_source else temp_str := '?internal_instrument_data'; arpeggio_table_pos := min(1,get_bank_position(temp_str+'?macro_av?arp_pos',nm_valid)); vibrato_table_pos := min(1,get_bank_position(temp_str+'?macro_av?vib_pos',nm_valid)); a2w_queue_m[1] := av_browser_str[1]; a2w_queue_m[2] := av_browser_str[2]; a2w_queue_m[3] := av_browser_str[3]; a2w_queue_m[4] := av_browser_str[4]; a2w_queue_m[5] := av_browser_str[5]; For idx := 1 to nm_valid do begin a2w_queue_m[5+idx] := ' ~'+byte2hex(idx)+'~ '#186; If Empty(temp_songdata.macro_table[idx].arpeggio,SizeOf(tARPEGGIO_TABLE)) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#186 else With temp_songdata.macro_table[idx].arpeggio do begin If (length > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(length)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (speed > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(speed)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (loop_begin > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(loop_begin)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (loop_length > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(loop_length)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (keyoff_pos > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(keyoff_pos)+' '#186 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#186; end; If Empty(temp_songdata.macro_table[idx].vibrato,SizeOf(tViBRATO_TABLE)) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250 else With temp_songdata.macro_table[idx].vibrato do begin If (length > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(length)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (speed > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(speed)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (delay > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(delay)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (loop_begin > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(loop_begin)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (loop_length > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(loop_length)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (keyoff_pos > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(keyoff_pos)+' '#186 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249; end; end; Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; old_topic_mask_chr := mn_setting.topic_mask_chr; old_frame_enabled := mn_setting.frame_enabled; old_shadow_enabled := mn_setting.shadow_enabled; old_winshade := mn_environment.winshade; old_center_box := mn_setting.center_box; old_show_scrollbar := mn_setting.show_scrollbar; old_text_attr := mn_setting.text_attr; old_text2_attr := mn_setting.text2_attr; old_short_attr := mn_setting.short_attr; old_short2_attr := mn_setting.short2_attr; old_disbld_attr := mn_setting.disbld_attr; old_contxt_attr := mn_setting.contxt_attr; old_contxt2_attr := mn_setting.contxt2_attr; old_topic_attr := mn_setting.topic_attr; old_hi_topic_attr := mn_setting.hi_topic_attr; Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); mn_setting.terminate_keys[4] := 0; // TAB possible only in FM-Register bank browser If NOT loadBankPossible then mn_setting.terminate_keys[5] := 0; // ^ENTER possible only in Arpeggio/Vibrato Macro Editor mn_environment.ext_proc := a2w_macro_lister_external_proc; mn_setting.topic_len := 5; mn_setting.cycle_moves := FALSE; mn_setting.topic_mask_chr := [#179,#186]; mn_setting.frame_enabled := FALSE; mn_setting.shadow_enabled := FALSE; mn_environment.winshade := FALSE; mn_setting.center_box := FALSE; mn_setting.show_scrollbar := FALSE; mn_environment.unpolite := FALSE; mn_environment.preview := TRUE; mn_environment.v_dest := ptr_temp_screen; mn_setting.text_attr := macro_background+macro_item; mn_setting.text2_attr := macro_sel_itm_bck+macro_sel_itm; mn_setting.short_attr := macro_background+macro_short; mn_setting.short2_attr := macro_sel_itm_bck+macro_sel_short; mn_setting.disbld_attr := macro_background+macro_item_dis; mn_setting.contxt_attr := macro_background+macro_context; mn_setting.contxt2_attr := macro_background+macro_context_dis; mn_setting.topic_attr := macro_background+macro_topic2; mn_setting.hi_topic_attr := macro_background+macro_hi_topic; If (a2w_instdata_source <> '') then temp_str := a2w_instdata_source else temp_str := '?internal_instrument_data'; If is_default_screen_mode then ysize := 15 else ysize := 20; If (program_screen_mode in [0,3,4,5]) then Menu(a2w_queue_m,xstart,ystart, min(1,get_bank_position(temp_str+'?macro_av?pos',nm_valid)), 72,max(nm_valid+5,ysize),nm_valid+5,'') else Menu(a2w_queue_m,xstart,ystart, min(1,get_bank_position(temp_str+'?macro_av?pos',nm_valid)), 72,max(nm_valid+5,20),nm_valid+5,''); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+window_xsize+2+1; move_to_screen_area[4] := ystart+window_ysize+1; move2screen_alt; mn_environment.unpolite := FALSE; mn_environment.preview := FALSE; mn_environment.v_dest := screen_ptr; centered_frame_vdest := mn_environment.v_dest; If is_default_screen_mode then ysize := 15 else ysize := 20; keyboard_reset_buffer; If NOT _force_program_quit then If (program_screen_mode in [0,3,4,5]) then index := Menu(a2w_queue_m,xstart,ystart, min(1,get_bank_position(temp_str+'?macro_av?pos',nm_valid)), 72,max(nm_valid+5,ysize),nm_valid+5,'') else index := Menu(a2w_queue_m,xstart,ystart, min(1,get_bank_position(temp_str+'?macro_av?pos',nm_valid)), 72,max(nm_valid+5,20),nm_valid+5,''); add_bank_position(temp_str+'?macro_av?pos',nm_valid,index+5); add_bank_position(temp_str+'?macro_av?arp_pos',nm_valid,arpeggio_table_pos); add_bank_position(temp_str+'?macro_av?vib_pos',nm_valid,vibrato_table_pos); Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; mn_setting.topic_mask_chr := old_topic_mask_chr; mn_setting.frame_enabled := old_frame_enabled; mn_setting.shadow_enabled := old_shadow_enabled; mn_environment.winshade := old_winshade; mn_setting.center_box := old_center_box; mn_setting.show_scrollbar := old_show_scrollbar; mn_setting.text_attr := old_text_attr; mn_setting.text2_attr := old_text2_attr; mn_setting.short_attr := old_short_attr; mn_setting.short2_attr := old_short2_attr; mn_setting.disbld_attr := old_disbld_attr; mn_setting.contxt_attr := old_contxt_attr; mn_setting.contxt2_attr := old_contxt2_attr; mn_setting.topic_attr := old_topic_attr; mn_setting.hi_topic_attr := old_hi_topic_attr; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+window_xsize+2+1; move_to_screen_area[4] := ystart+window_ysize+1; move2screen; If (mn_environment.keystroke = kF1) then begin HELP('macro_browser_av'); If NOT _force_program_quit then GOTO _jmp1; end; If NOT update_current_inst and (mn_environment.keystroke = kENTER) then begin songdata := songdata_bak; temp_songdata := songdata_bak; mn_environment.keystroke := kESC; end; If NOT loadMacros and (mn_environment.keystroke = kESC) then begin load_flag := BYTE_NULL; load_flag_alt := BYTE_NULL; GOTO _jmp2; end; _jmp1e: If (mn_environment.keystroke = kENTER) or (loadBankPossible and (mn_environment.keystroke = kCtENTR)) then begin If (mn_environment.keystroke = kENTER) then begin If loadMacros or _arp_vib_loader then begin arpvib_arpeggio_table := arpvib_arpeggio_table_bak; arpvib_vibrato_table := arpvib_vibrato_table_bak; If arp_tab_selected then songdata.macro_table[arpvib_arpeggio_table].arpeggio := temp_songdata.macro_table[index].arpeggio; If vib_tab_selected then songdata.macro_table[arpvib_vibrato_table].vibrato := temp_songdata.macro_table[index].vibrato; end else begin idx1 := -1; idx2 := -1; If arp_tab_selected then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[index].arpeggio); If vib_tab_selected then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[index].vibrato); temp_str := ''; If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If NOT (temp_str <> '') then begin If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[index].arpeggio; songdata.instr_macros[current_inst].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[index].vibrato; songdata.instr_macros[current_inst].vibrato_table := idx2; end; end else begin Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); GOTO _end; end; end; load_flag := 1; load_flag_alt := BYTE_NULL; end else begin temp_str := ''; If arp_tab_selected then temp_str := 'ARPEGGiO'; If vib_tab_selected then If (temp_str <> '') then temp_str := temp_str+'/ViBRATO' else temp_str := 'ViBRATO'; If NOT (NOT arp_tab_selected and NOT vib_tab_selected) or (nm_valid < 2) then begin If bankSelector then index := Dialog('ALL UNSAVED '+temp_str+' MACRO DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2W LOADER ',1) else begin index := 1; dl_environment.keystroke := kENTER; end; If (dl_environment.keystroke <> kESC) and (index = 1) then begin For idx := 1 to 255 do If NOT (idx > nm_valid) then begin If arp_tab_selected then songdata.macro_table[idx].arpeggio := temp_songdata.macro_table[idx].arpeggio; If vib_tab_selected then songdata.macro_table[idx].vibrato := temp_songdata.macro_table[idx].vibrato; end else begin FillChar(songdata.macro_table[idx].arpeggio,SizeOf(songdata.macro_table[idx].arpeggio),0); FillChar(songdata.macro_table[idx].vibrato,SizeOf(songdata.macro_table[idx].vibrato),0); end; load_flag := 1; load_flag_alt := BYTE_NULL; end; end; end; end; end else begin _jmp2: browser_flag := FALSE; ScreenMemCopy(screen_ptr,ptr_screen_backup); a2w_queue[1] := a2w_header_str[1]; a2w_queue[2] := a2w_header_str[2]; a2w_queue[3] := a2w_header_str[3]; a2w_queue_more[1] := a2w_header_hires1_str[1]; a2w_queue_more[2] := a2w_header_hires1_str[2]; a2w_queue_more[3] := a2w_header_hires1_str[3]; a2w_queue_more2[1] := a2w_header_hires2_str[1]; a2w_queue_more2[2] := a2w_header_hires2_str[2]; a2w_queue_more2[3] := a2w_header_hires2_str[3]; nm_valid := count_instruments; If (nm_valid = 0) then nm_valid := 1; If NOT bankSelector then begin mn_environment.keystroke := kCtENTR; GOTO _jmp2e; end; context_str := ''; context_str2 := ''; If (a2w_instdata_source = '') then nm_valid := 255 else begin context_str := ' ~[~'+Num2str(nm_valid,10)+'~/255]~'; If NOT loadBankPossible then context_str2 := ' ~[BANK]~' else context_str2 := ' [BANK]'; end; For idx := 1 to nm_valid do begin a2w_queue[3+idx] := '~ '+ExpStrR(Copy(temp_songdata.instr_names[idx],2,8)+'~'+ Copy(temp_songdata.instr_names[idx],10,32),44,' '); a2w_queue_more[3+idx] := a2w_queue[3+idx]; With temp_songdata.instr_data[idx].fm_data do begin a2w_queue_more[3+idx] := a2w_queue_more[3+idx]+ byte2hex(AM_VIB_EG_carrier)+ byte2hex(AM_VIB_EG_modulator)+' '+ byte2hex(KSL_VOLUM_carrier)+ byte2hex(KSL_VOLUM_modulator)+' '+ byte2hex(ATTCK_DEC_carrier)+ byte2hex(ATTCK_DEC_modulator)+' '+ byte2hex(SUSTN_REL_carrier)+ byte2hex(SUSTN_REL_modulator)+' '+ byte2hex(WAVEFORM_carrier)+ byte2hex(WAVEFORM_modulator)+' '+ byte2hex(FEEDBACK_FM)+' '; end; Case temp_songdata.instr_data[idx].panning of 0..2: temp_str := ins_pan_str2[temp_songdata.instr_data[idx].panning]; else temp_str := ExpStrL('',7,#250); end; a2w_queue_more2[3+idx] := a2w_queue_more[3+idx]+temp_str+' '; If (temp_songdata.instr_data[idx].fine_tune > 0) then temp_str := '+'+ExpStrR(Num2str(temp_songdata.instr_data[idx].fine_tune,16),5,' ') else If (temp_songdata.instr_data[idx].fine_tune < 0) then temp_str := '-'+ExpStrR(Num2str(0-temp_songdata.instr_data[idx].fine_tune,16),5,' ') else temp_str := ExpStrR('',6,' '); a2w_queue_more2[3+idx] := a2w_queue_more2[3+idx]+temp_str+' '; Case temp_songdata.instr_data[idx].perc_voice of 0..5: temp_str := perc_voice_str[temp_songdata.instr_data[idx].perc_voice]; else temp_str := ExpStrL('',7,' '); end; a2w_queue[3+idx] := a2w_queue[3+idx]+temp_str; a2w_queue_more[3+idx] := a2w_queue_more[3+idx]+temp_str; a2w_queue_more2[3+idx] := a2w_queue_more2[3+idx]+temp_str; If (temp_songdata.instr_macros[idx].length <> 0) then temp_str := ' MACRO:FM' else temp_str := ' '; With temp_songdata.macro_table[ temp_songdata.instr_macros[idx].arpeggio_table].arpeggio do If (temp_songdata.instr_macros[idx].arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'MACRO:ARP'; With temp_songdata.macro_table[ temp_songdata.instr_macros[idx].vibrato_table].vibrato do If (temp_songdata.instr_macros[idx].vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'MACRO:ViB'; a2w_queue[3+idx] := a2w_queue[3+idx]+' '+ExpStrR(temp_str,18,' '); a2w_queue_more[3+idx] := a2w_queue_more[3+idx]+' '+ExpStrR(temp_str,18,' '); a2w_queue_more2[3+idx] := a2w_queue_more2[3+idx]+' '+ExpStrR(temp_str,18,' '); end; If (a2w_instdata_source <> '') then temp_str := a2w_instdata_source else temp_str := '?internal_instrument_data'; idx := min(1,get_bank_position(temp_str+'?macro?pos',nm_valid)); fmreg_page := min(1,get_bank_position(temp_str+'?macro?fmreg_page',nm_valid)); fmreg_hpos := min(1,get_bank_position(temp_str+'?macro?fmreg_hpos',nm_valid)); fmreg_vpos := min(1,get_bank_position(temp_str+'?macro?fmreg_vpos',nm_valid)); fmreg_left_margin := min(1,get_bank_position(temp_str+'?macro?fmreg_left_margin',nm_valid)); fmreg_cursor_pos := min(1,get_bank_position(temp_str+'?macro?fmreg_cursor_pos',nm_valid)); If (a2w_instdata_source <> '') then temp_str := ' '+iCASE(NameOnly(a2w_instdata_source))+' ' else begin If updateCurInstr then add_bank_position('?internal_instrument_data?pos',255,current_inst); temp_str := ' iNSTRUMENT MACRO BROWSER '; end; Case program_screen_mode of 0, 3: begin window_xsize := 73; If is_default_screen_mode then window_ysize := max(nm_valid+3,15)+10 else window_ysize := max(nm_valid+3,20)+10; end; 4, 5: begin window_xsize := 73; window_ysize := max(nm_valid+3,20)+10; end; 1: begin window_xsize := 103; window_ysize := max(nm_valid+3,20)+10; end; 2: begin window_xsize := 122; window_ysize := max(nm_valid+3,20)+10; end; end; xstart := ((work_MaxCol-window_xsize) DIV 2); ystart := ((work_MaxLn-window_ysize) DIV 2)+1; fmreg_scrlbar_items := nm_valid; fmreg_scrlbar_size := window_ysize-10-2; If NOT (program_screen_mode in [0,3,4,5]) then _fmreg_add_prev_size := 10 else _fmreg_add_prev_size := 0; If update_current_inst then begin temp_str := temp_str + '(iNS_ ) '; idx := current_inst; end else temp_str := temp_str + '[iNS_ ] '; a2w_institle_pos := (window_xsize DIV 2)+(Length(temp_str) DIV 2)-3; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,window_xsize,window_ysize, temp_str, macro_background+macro_border, macro_background+macro_title, frame_double); ShowStr(centered_frame_vdest,xstart+1,ystart+window_ysize-10+1, ExpStrR('',window_xsize-1,#205), macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart+1,ystart+window_ysize-2, ExpStrR('',window_xsize-1,#205), macro_background+macro_topic2); ShowVStr(centered_frame_vdest,xstart+42+_fmreg_add_prev_size,ystart+window_ysize-10+1, #203#186#186#186#186#186#186#202, macro_background+macro_topic2); Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; old_topic_mask_chr := mn_setting.topic_mask_chr; old_frame_enabled := mn_setting.frame_enabled; old_shadow_enabled := mn_setting.shadow_enabled; old_winshade := mn_environment.winshade; old_center_box := mn_setting.center_box; old_show_scrollbar := mn_setting.show_scrollbar; old_text_attr := mn_setting.text_attr; old_text2_attr := mn_setting.text2_attr; old_short_attr := mn_setting.short_attr; old_short2_attr := mn_setting.short2_attr; old_disbld_attr := mn_setting.disbld_attr; old_contxt_attr := mn_setting.contxt_attr; old_contxt2_attr := mn_setting.contxt2_attr; old_topic_attr := mn_setting.topic_attr; old_hi_topic_attr := mn_setting.hi_topic_attr; Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); If NOT update_current_inst then mn_setting.terminate_keys[4] := 0; // TAB not possible when called from Macro Browser If NOT loadBankPossible then mn_setting.terminate_keys[5] := 0; // ^ENTER possible only in Instrument Control mn_environment.ext_proc := a2w_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; mn_setting.frame_enabled := FALSE; mn_setting.shadow_enabled := FALSE; mn_environment.winshade := FALSE; mn_setting.center_box := FALSE; mn_setting.show_scrollbar := FALSE; mn_environment.unpolite := FALSE; mn_environment.preview := TRUE; mn_environment.v_dest := ptr_temp_screen; mn_setting.text_attr := macro_background+macro_item; mn_setting.text2_attr := macro_sel_itm_bck+macro_sel_itm; mn_setting.short_attr := macro_background+macro_short; mn_setting.short2_attr := macro_sel_itm_bck+macro_sel_short; mn_setting.disbld_attr := macro_background+macro_item_dis; mn_setting.contxt_attr := macro_background+macro_context; mn_setting.contxt2_attr := macro_background+macro_context_dis; mn_setting.topic_attr := macro_background+macro_topic2; mn_setting.hi_topic_attr := macro_background+macro_hi_topic; If is_default_screen_mode then ysize := 15 else ysize := 20; _a2w_lister_count := max(nm_valid+3,ysize)-3; If NOT _force_program_quit then If (program_screen_mode in [0,3,4,5]) then index := Menu(a2w_queue,xstart,ystart,idx+3,72,max(nm_valid+3,ysize),nm_valid+3,temp_str) else If (program_screen_mode = 1) then index := Menu(a2w_queue_more,xstart,ystart,idx+3,102,max(nm_valid+3,20),nm_valid+3,temp_str) else index := Menu(a2w_queue_more2,xstart,ystart,idx+3,121,max(nm_valid+3,20),nm_valid+3,temp_str); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+window_xsize+2+1; move_to_screen_area[4] := ystart+window_ysize+1; move2screen_alt; mn_environment.unpolite := FALSE; mn_environment.preview := FALSE; mn_environment.v_dest := screen_ptr; centered_frame_vdest := mn_environment.v_dest; keyboard_reset_buffer; If NOT _force_program_quit then If (program_screen_mode in [0,3,4,5]) then index := Menu(a2w_queue,xstart,ystart,idx+3,72,max(nm_valid+3,ysize),nm_valid+3,temp_str) else If (program_screen_mode = 1) then index := Menu(a2w_queue_more,xstart,ystart,idx+3,102,max(nm_valid+3,20),nm_valid+3,temp_str) else index := Menu(a2w_queue_more2,xstart,ystart,idx+3,121,max(nm_valid+3,20),nm_valid+3,temp_str); If (a2w_instdata_source <> '') then temp_str := a2w_instdata_source else temp_str := '?internal_instrument_data'; add_bank_position(temp_str+'?macro?pos',nm_valid,index); add_bank_position(temp_str+'?macro?fmreg_page',nm_valid,fmreg_page); add_bank_position(temp_str+'?macro?fmreg_hpos',nm_valid,fmreg_hpos); add_bank_position(temp_str+'?macro?fmreg_vpos',nm_valid,fmreg_vpos); add_bank_position(temp_str+'?macro?fmreg_left_margin',nm_valid,fmreg_left_margin); add_bank_position(temp_str+'?macro?fmreg_cursor_pos',nm_valid,fmreg_cursor_pos); Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; mn_setting.topic_mask_chr := old_topic_mask_chr; mn_setting.frame_enabled := old_frame_enabled; mn_setting.shadow_enabled := old_shadow_enabled; mn_environment.winshade := old_winshade; mn_setting.center_box := old_center_box; mn_setting.show_scrollbar := old_show_scrollbar; mn_setting.text_attr := old_text_attr; mn_setting.text2_attr := old_text2_attr; mn_setting.short_attr := old_short_attr; mn_setting.short2_attr := old_short2_attr; mn_setting.disbld_attr := old_disbld_attr; mn_setting.contxt_attr := old_contxt_attr; mn_setting.contxt2_attr := old_contxt2_attr; mn_setting.topic_attr := old_topic_attr; mn_setting.hi_topic_attr := old_hi_topic_attr; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+window_xsize+2+1; move_to_screen_area[4] := ystart+window_ysize+1; move2screen; centered_frame_vdest := screen_ptr; If (mn_environment.keystroke = kESC) then GOTO _end; If (mn_environment.keystroke = kTAB) then begin arp_tab_selected := songdata.instr_macros[current_inst].arpeggio_table <> 0; vib_tab_selected := songdata.instr_macros[current_inst].vibrato_table <> 0; loadMacros := FALSE; browser_flag := TRUE; GOTO _jmp1; end; If (mn_environment.keystroke = kF1) then begin HELP('macro_browser'); If NOT _force_program_quit then GOTO _jmp2; end; _jmp2e: If (mn_environment.keystroke = kENTER) or (loadBankPossible and (mn_environment.keystroke = kCtENTR)) then begin If (mn_environment.keystroke = kENTER) then begin If shift_pressed then begin // put 4op instrument (alternate) _4op_ins_flag := FALSE; If (_4op_flag_column[index] = _4op_flag_chr_beg) then If check_4op_flag(current_inst) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else If check_4op_flag(PRED(current_inst)) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else else If (_4op_flag_column[index] = _4op_flag_chr_end) then If check_4op_flag(current_inst) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := PRED(index); _4op_idx22 := index; end else If check_4op_flag(PRED(current_inst)) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := PRED(index); _4op_idx22 := index; end; If _4op_ins_flag then _put_4op_instrument; end else begin // put 4op instrument (force) _4op_ins_flag := FALSE; If (_4op_flag_column[index] = _4op_flag_chr_beg) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else If (_4op_flag_column[index] = _4op_flag_chr_end) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := PRED(index); _4op_idx22 := index; end; If _4op_ins_flag then begin _put_4op_instrument; set_4op_flag(_4op_idx11); end; end; // put 2op instrument If NOT _4op_ins_flag then _put_2op_instrument; load_flag := 1; load_flag_alt := BYTE_NULL; end else begin If bankSelector then index := Dialog('ALL UNSAVED iNSTRUMENT AND MACRO DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2W LOADER ',1) else begin index := 1; dl_environment.keystroke := kENTER; end; If (dl_environment.keystroke <> kESC) and (index = 1) then begin temp_str := ''; For idx := 1 to 255 do If NOT (idx > nm_valid) then begin songdata.instr_data[idx] := temp_songdata.instr_data[idx]; songdata.instr_macros[idx] := temp_songdata.instr_macros[idx]; songdata.dis_fmreg_col[idx] := temp_songdata.dis_fmreg_col[idx]; songdata.instr_names[idx] := Copy(songdata.instr_names[idx],1,9)+ Copy(temp_songdata.instr_names[idx],10,32); idx1 := -1; idx2 := -1; If (songdata.instr_macros[idx].arpeggio_table <> 0) then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[ songdata.instr_macros[idx].arpeggio_table].arpeggio); If (songdata.instr_macros[idx].vibrato_table <> 0) then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[ songdata.instr_macros[idx].vibrato_table].vibrato); If (temp_str = '') then If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[songdata.instr_macros[idx].arpeggio_table].arpeggio; songdata.instr_macros[idx].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[songdata.instr_macros[idx].vibrato_table].vibrato; songdata.instr_macros[idx].vibrato_table := idx2; end; end else begin FillChar(songdata.instr_data[idx],SizeOf(songdata.instr_data[idx]),0); FillChar(songdata.instr_macros[idx],SizeOf(songdata.instr_macros[idx]),0); FillChar(songdata.dis_fmreg_col[idx],SizeOf(songdata.dis_fmreg_col[idx]),0); songdata.instr_names[idx] := Copy(songdata.instr_names[idx],1,9); end; songdata.ins_4op_flags := temp_songdata.ins_4op_flags; If (temp_str <> '') then Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); load_flag := 1; load_flag_alt := BYTE_NULL; end; end; end; end; _end: If browser_flag then GOTO _jmp2; arpvib_arpeggio_table := arpvib_arpeggio_table_bak; arpvib_vibrato_table := arpvib_vibrato_table_bak; {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; type tBNK_HEADER = Record fver_major : Byte; fver_minor : Byte; signature : array[1..6] of Char; entries_used : Word; total_entries : Word; name_offset : Longint; data_offset : Longint; filler : array[1..8] of Byte; end; type tBNK_NAME_RECORD = Record data_index : Word; usage_flag : Boolean; ins_name : array[1..9] of Char; end; type tBNK_OPERATOR = Record ksl, freq_mult, feedback, attack, sust_level, sustain, decay, release, output, am, vib, ksr, fm: Byte; end; type tBNK_DATA_RECORD = Record mode : Byte; voice_num : Byte; modulator : tBNK_OPERATOR; carrier : tBNK_OPERATOR; wform_mod : Byte; wform_car : Byte; end; const bnk_id = 'ADLIB-'; MAX_TIMBRES = 4096; var bnk_queue: array[1..MAX_TIMBRES+3] of String[72]; bnk_skip: Byte; name_record: tBNK_NAME_RECORD; data_record: tBNK_DATA_RECORD; procedure import_instrument_from_data_record; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:import_instrument_from_data_record'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); With temp_instrument.fm_data do begin AM_VIB_EG_modulator := data_record.modulator.freq_mult AND $0f+ data_record.modulator.ksr AND 1 SHL 4+ data_record.modulator.sustain AND 1 SHL 5+ data_record.modulator.vib AND 1 SHL 6+ data_record.modulator.am AND 1 SHL 7; AM_VIB_EG_carrier := data_record.carrier.freq_mult AND $0f+ data_record.carrier.ksr AND 1 SHL 4+ data_record.carrier.sustain AND 1 SHL 5+ data_record.carrier.vib AND 1 SHL 6+ data_record.carrier.am AND 1 SHL 7; KSL_VOLUM_modulator := data_record.modulator.output AND $3f+ data_record.modulator.ksl AND 3 SHL 6; KSL_VOLUM_carrier := data_record.carrier.output AND $3f+ data_record.carrier.ksl AND 3 SHL 6; ATTCK_DEC_modulator := data_record.modulator.decay AND $0f+ data_record.modulator.attack AND $0f SHL 4; ATTCK_DEC_carrier := data_record.carrier.decay AND $0f+ data_record.carrier.attack AND $0f SHL 4; SUSTN_REL_modulator := data_record.modulator.release AND $0f+ data_record.modulator.sust_level AND $0f SHL 4; SUSTN_REL_carrier := data_record.carrier.release AND $0f+ data_record.carrier.sust_level AND $0f SHL 4; WAVEFORM_modulator := data_record.wform_mod AND 7; WAVEFORM_carrier := data_record.wform_car AND 7; FEEDBACK_FM := data_record.modulator.fm XOR 1 AND 1+ data_record.modulator.feedback AND 7 SHL 1; end; If (data_record.voice_num in [6..10]) then temp_instrument.perc_voice := data_record.voice_num-5; end; procedure bnk_file_loader_alt(instr: Word); var f: File; header: tBNK_HEADER; temp: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:bnk_file_loader_alt'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) then begin CloseF(f); EXIT; end; If NOT ((header.fver_major = 1) and (header.fver_minor = 0)) then begin CloseF(f); EXIT; end; If (instr > max(header.total_entries,MAX_TIMBRES)) or (header.signature <> bnk_id) or (header.total_entries < header.entries_used) then begin CloseF(f); EXIT; end; SeekF(f,header.name_offset+PRED(instr)*SizeOf(name_record)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,name_record,SizeOf(name_record),temp); If (temp <> SizeOf(name_record)) then begin CloseF(f); EXIT; end; SeekF(f,header.data_offset+name_record.data_index*SizeOf(data_record)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,data_record,SizeOf(data_record),temp); If (temp <> SizeOf(data_record)) then begin CloseF(f); EXIT; end; import_instrument_from_data_record; CloseF(f); load_flag_alt := 1; end; type tFIB_HEADER = Record ident: array[1..4] of Char; nmins: Word; end; type tFIN_DATA = Record dname: array[1..12] of Char; iname: array[1..27] of Char; idata: tFM_INST_DATA; end; procedure fib_file_loader_alt(instr: Word); const id = 'FIB'+#244; var f: File; ident: array[1..4] of Char; header: tFIB_HEADER; temp: Longint; instrument_data: tFIN_DATA; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fib_file_loader_alt'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header.ident <> id) then begin CloseF(f); EXIT; end; SeekF(f,SizeOf(header)+header.nmins*SizeOf(instrument_data)); If (IOresult <> 0) then EXIT; BlockReadF(f,ident,SizeOf(ident),temp); If (temp <> SizeOf(ident)) or (ident <> id) then begin CloseF(f); EXIT; end; SeekF(f,SizeOf(header)+PRED(instr)*SizeOf(instrument_data)); If (IOresult <> 0) then EXIT; BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); EXIT; end; import_standard_instrument_alt(instrument_data.idata); CloseF(f); load_flag_alt := 1; end; var ibk_queue: array[1..128+3] of String[45]; ibk_skip: Byte; procedure import_sbi_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:import_sbi_instrument_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); With temp_instrument do begin fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[6]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[7]; fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 3; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3; fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f; end; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure ibk_file_loader_alt(instr: Word); const id = 'IBK'+#26; var f: File; header: array[1..4] of Char; temp: Longint; instrument_data: Record idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:ibk_file_loader_alt'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header <> id) then begin CloseF(f); EXIT; end; SeekF(f,$004+PRED(instr)*SizeOf(instrument_data)); If (IOresult <> 0) then EXIT; BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); EXIT; end; import_sbi_instrument_alt(instrument_data); CloseF(f); load_flag_alt := 1; end; procedure bnk_file_loader; const _perc_voice: array[1..5] of String[2] = ('BD','SD','TT','TC','HH'); var f: File; header: tBNK_HEADER; temp: Longint; index: Word; old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; xstart,ystart: Byte; nm_valid: Word; ysize: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:bnk_file_loader:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; end; begin { bnk_file_loader } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:bnk_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; If NOT ((header.fver_major = 1) and (header.fver_minor = 0)) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; If (header.signature <> bnk_id) or (header.total_entries < header.entries_used) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' '+iCASE(NameOnly(instdata_source))+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; bnk_queue[1] := bnk_header_str[1]; bnk_queue[2] := bnk_header_str[2]; bnk_queue[3] := bnk_header_str[3]; progress_num_steps := 1; progress_step := 1; progress_value := max(header.total_entries,MAX_TIMBRES); progress_old_value := BYTE_NULL; progress_xstart := xstart+2; progress_ystart := ystart+2; ShowCStr(screen_ptr,xstart+2,ystart+1, 'LOADiNG DATA FROM BANK FiLE...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(0); nm_valid := 0; bnk_skip := 0; For index := 1 to max(header.total_entries,MAX_TIMBRES) do begin If (ticklooper = 0) then If keypressed and (index > 1) then begin fkey := getkey; If (fkey = kESC) then begin Dec(index); BREAK; end; end; If (ticklooper = 0) then show_progress(index); SeekF(f,header.name_offset+PRED(index)*SizeOf(name_record)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; BlockReadF(f,name_record,SizeOf(name_record),temp); If (temp <> SizeOf(name_record)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; SeekF(f,header.data_offset+name_record.data_index*SizeOf(data_record)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; BlockReadF(f,data_record,SizeOf(data_record),temp); If (temp <> SizeOf(data_record)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; import_instrument_from_data_record; If name_record.usage_flag then begin bnk_queue[3+index-bnk_skip] := '~ ~~'; Inc(nm_valid); end else begin If (nm_valid = 0) then begin Inc(bnk_skip); CONTINUE; end; bnk_queue[3+index-bnk_skip] := ' '; end; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+ ExpStrR(CutStr(asciiz_string(name_record.ins_name)),11,' ')+'~ '; With temp_instrument.fm_data do begin bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(AM_VIB_EG_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(AM_VIB_EG_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(KSL_VOLUM_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(KSL_VOLUM_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(ATTCK_DEC_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(ATTCK_DEC_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(SUSTN_REL_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(SUSTN_REL_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(WAVEFORM_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(WAVEFORM_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(FEEDBACK_FM)+' '; end; Case data_record.mode of 0: bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+'MELODiC'; 1: Case data_record.voice_num of 6..10: bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+'PERCUSSiON ('+ _perc_voice[data_record.voice_num-5]+')'; else bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+'PERCUSSiON (??)'; end; else bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+'???'; end; end; CloseF(f); show_progress(index); // delay for awhile to show progress bar {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; If (nm_valid = 0) then EXIT; If (index = header.total_entries) and (bnk_skip = 0) then mn_environment.context := '~[~'+Num2str(nm_valid,10)+'~/'+ Num2str(index,10)+']~' else mn_environment.context := '['+Num2str(nm_valid,10)+']~['+ Num2str(index,10)+'/'+ Num2str(header.total_entries,10)+']~'; old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; mn_environment.ext_proc := bnk_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; If is_default_screen_mode then ysize := 20 else ysize := 30; keyboard_reset_buffer; If NOT _force_program_quit then index := Menu(bnk_queue,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 72,ysize,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' '); add_bank_position(instdata_source,nm_valid,index+3); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; If (mn_environment.keystroke = kENTER) then begin load_flag := 1; load_flag_alt := BYTE_NULL; bnk_file_loader_alt(bnk_skip+index); If (load_flag_alt <> BYTE_NULL) then begin songdata.instr_data[current_inst] := temp_instrument; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(bnk_queue[3+index],5,8); end; end; end; procedure fib_file_loader; const id = 'FIB'#244; var f: File; ident: array[1..4] of Char; header: tFIB_HEADER; temp: Longint; index: Word; old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; xstart,ystart: Byte; instrument_data: tFIN_DATA; nm_valid: Word; ysize: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fib_file_loader:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; end; begin { fib_file_loader } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fib_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header.ident <> id) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' '+iCASE(NameOnly(instdata_source))+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; bnk_queue[1] := fib_header_str[1]; bnk_queue[2] := fib_header_str[2]; bnk_queue[3] := fib_header_str[3]; progress_num_steps := 1; progress_step := 1; progress_value := max(header.nmins,MAX_TIMBRES); progress_old_value := BYTE_NULL; progress_xstart := xstart+2; progress_ystart := ystart+2; ShowCStr(screen_ptr,xstart+2,ystart+1, 'LOADiNG DATA FROM BANK FiLE...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(0); nm_valid := 0; bnk_skip := 0; For index := 1 to max(header.nmins,MAX_TIMBRES) do begin If (ticklooper = 0) then If keypressed and (index > 1) then begin fkey := getkey; If (fkey = kESC) then begin Dec(index); BREAK; end; end; If (ticklooper = 0) then show_progress(index); BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; import_standard_instrument_alt(instrument_data.idata); If NOT Empty(instrument_data.idata,SizeOf(instrument_data.idata)) then begin bnk_queue[3+index-bnk_skip] := '~ ~~'; Inc(nm_valid); end else begin If (nm_valid = 0) then begin Inc(bnk_skip); CONTINUE; end; bnk_queue[3+index-bnk_skip] := ' '; end; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+ ExpStrR(Upper(CutStr(BaseNameOnly(instrument_data.dname))),8,' ')+'~ '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+ ExpStrR(CutStr(instrument_data.iname),27,' ')+' '; With temp_instrument.fm_data do begin bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(AM_VIB_EG_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(AM_VIB_EG_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(KSL_VOLUM_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(KSL_VOLUM_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(ATTCK_DEC_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(ATTCK_DEC_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(SUSTN_REL_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(SUSTN_REL_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(WAVEFORM_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(WAVEFORM_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(FEEDBACK_FM)+' '; end; end; SeekF(f,SizeOf(header)+header.nmins*SizeOf(instrument_data)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; BlockReadF(f,ident,SizeOf(ident),temp); If (temp <> SizeOf(ident)) or (ident <> id) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; CloseF(f); show_progress(index); // delay for awhile to show progress bar {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; If (nm_valid = 0) then EXIT; If (index = header.nmins) and (bnk_skip = 0) then mn_environment.context := '~[~'+Num2str(nm_valid,10)+'~/'+ Num2str(index,10)+']~' else mn_environment.context := '['+Num2str(nm_valid,10)+']~['+ Num2str(index,10)+'/'+ Num2str(128,10)+']~'; old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; mn_environment.ext_proc := fib_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; If is_default_screen_mode then ysize := 20 else ysize := 30; keyboard_reset_buffer; If NOT _force_program_quit then index := Menu(bnk_queue,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 72,ysize,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' '); add_bank_position(instdata_source,nm_valid,index+3); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; If (mn_environment.keystroke = kENTER) then begin load_flag := 1; load_flag_alt := BYTE_NULL; fib_file_loader_alt(index+bnk_skip); If (load_flag_alt <> BYTE_NULL) then begin songdata.instr_data[current_inst] := temp_instrument; If (CutStr(Copy(bnk_queue[3+index],16,27)) <> '') then songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(bnk_queue[3+index],16,27) else songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(bnk_queue[3+index],5,8) end; end; end; procedure ibk_file_loader; const id = 'IBK'#26; var f: File; header: array[1..4] of Char; temp: Longint; index: Word; old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; xstart,ystart: Byte; nm_valid: Word; ysize: Byte; instrument_name: array[1..9] of Char; instrument_data: Record idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:ibk_file_loader:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; end; begin { ibk_file_loader } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:ibk_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header <> id) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' '+iCASE(NameOnly(instdata_source))+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; ibk_queue[1] := ibk_header_str[1]; ibk_queue[2] := ibk_header_str[2]; ibk_queue[3] := ibk_header_str[3]; progress_num_steps := 1; progress_step := 1; progress_value := 128; progress_old_value := BYTE_NULL; progress_xstart := xstart+2; progress_ystart := ystart+2; ShowCStr(screen_ptr,xstart+2,ystart+1, 'LOADiNG DATA FROM BANK FiLE...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(0); nm_valid := 0; ibk_skip := 0; For index := 1 to 128 do begin If (ticklooper = 0) then If keypressed and (index > 1) then begin fkey := getkey; If (fkey = kESC) then begin Dec(index); BREAK; end; end; If (ticklooper = 0) then show_progress(index); SeekF(f,$004+PRED(index)*SizeOf(instrument_data)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; SeekF(f,$804+PRED(index)*SizeOf(instrument_name)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; BlockReadF(f,instrument_name,SizeOf(instrument_name),temp); If (temp <> SizeOf(instrument_name)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; import_sbi_instrument_alt(instrument_data); If NOT Empty(instrument_data,SizeOf(instrument_data)) then begin ibk_queue[3+index-ibk_skip] := '~ ~~'; Inc(nm_valid); end else begin If (nm_valid = 0) then begin Inc(ibk_skip); CONTINUE; end; ibk_queue[3+index-ibk_skip] := ' '; end; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+ ExpStrR(CutStr(asciiz_string(instrument_name)),11,' ')+'~ '; With temp_instrument.fm_data do begin ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(AM_VIB_EG_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(AM_VIB_EG_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(KSL_VOLUM_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(KSL_VOLUM_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(ATTCK_DEC_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(ATTCK_DEC_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(SUSTN_REL_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(SUSTN_REL_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(WAVEFORM_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(WAVEFORM_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(FEEDBACK_FM)+' '; end; end; CloseF(f); show_progress(index); // delay for awhile to show progress bar {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; If (nm_valid = 0) then EXIT; If (index = 128) and (ibk_skip = 0) then mn_environment.context := '~[~'+Num2str(nm_valid,10)+'~/'+ Num2str(index,10)+']~' else mn_environment.context := '['+Num2str(nm_valid,10)+']~['+ Num2str(index,10)+'/'+ Num2str(128,10)+']~'; old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; mn_environment.ext_proc := ibk_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; If is_default_screen_mode then ysize := 20 else ysize := 30; keyboard_reset_buffer; If NOT _force_program_quit then index := Menu(ibk_queue,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 45,ysize,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' '); add_bank_position(instdata_source,nm_valid,index+3); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; If (mn_environment.keystroke = kENTER) then begin load_flag := 1; load_flag_alt := BYTE_NULL; ibk_file_loader_alt(index+ibk_skip); If (load_flag_alt <> BYTE_NULL) then begin songdata.instr_data[current_inst] := temp_instrument; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(ibk_queue[3+index],5,8); end; end; end; procedure a2b_lister_external_proc_callback; var test_ins1: Byte; test_ins2: Byte; curr_inst: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2b_lister_external_proc_callback'; {$ENDIF} If (get_4op_to_test_temp <> 0) then begin test_ins1 := LO(get_4op_to_test_temp); test_ins2 := HI(get_4op_to_test_temp); end else begin curr_inst := mn_environment.curr_pos; If NOT (curr_inst in [1..255]) then EXIT; test_ins1 := curr_inst; test_ins2 := 0; end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt(count_channel(pattern_hpos), mn_environment.keystroke, FALSE,TRUE,FALSE, // test instrument from bank, without any macros test_ins1,test_ins2); end; procedure a2w_lister_external_proc_callback; var test_ins1: Byte; test_ins2: Byte; curr_inst: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_lister_external_proc'; {$ENDIF} If (get_4op_to_test_temp <> 0) then begin test_ins1 := LO(get_4op_to_test_temp); test_ins2 := HI(get_4op_to_test_temp); end else begin curr_inst := mn_environment.curr_pos; If NOT (curr_inst in [1..255]) then EXIT; test_ins1 := curr_inst; test_ins2 := 0; end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt(count_channel(pattern_hpos), mn_environment.keystroke, TRUE,TRUE,FALSE, // test instrument from bank, with chosen FM-data and macro test_ins1,test_ins2); // and current Arp./Vib. macro tables end; procedure a2w_macro_lister_external_proc_callback; var test_ins1: Byte; test_ins2: Byte; curr_inst: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_macro_lister_external_proc_callback'; {$ENDIF} If (get_4op_to_test_temp <> 0) then begin test_ins1 := LO(get_4op_to_test_temp); test_ins2 := HI(get_4op_to_test_temp); end else begin curr_inst := mn_environment.curr_pos; If NOT (curr_inst in [1..255]) then EXIT; test_ins1 := curr_inst; test_ins2 := 0; end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt(count_channel(pattern_hpos), mn_environment.keystroke, FALSE,FALSE,TRUE, // test current instr, with current FM-data and macro test_ins1,test_ins2); // and chosen Arp./Vib. macro tables from bank end; procedure bnk_lister_external_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:bnk_lister_external_proc'; {$ENDIF} mn_environment.curr_item := Num2str(mn_environment.curr_pos+bnk_skip,10)+'.bnk'; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt2(count_channel(pattern_hpos), mn_environment.keystroke); end; procedure fib_lister_external_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fib_lister_external_proc'; {$ENDIF} mn_environment.curr_item := Num2str(mn_environment.curr_pos+bnk_skip,10)+'.fib'; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt2(count_channel(pattern_hpos), mn_environment.keystroke); end; procedure ibk_lister_external_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:ibk_lister_external_proc'; {$ENDIF} mn_environment.curr_item := Num2str(mn_environment.curr_pos+ibk_skip,10)+'.ibk'; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt2(count_channel(pattern_hpos), mn_environment.keystroke); end; end. adlibtracker2-2.4.23/adt2ext3.pas0000644000000000000000000006636613176573532015211 0ustar rootrootunit AdT2ext3; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface procedure a2m_file_loader; procedure a2t_file_loader; procedure a2p_file_loader; procedure a2i_file_loader; procedure a2f_file_loader; procedure amd_file_loader; procedure cff_file_loader; procedure dfm_file_loader; procedure fmk_file_loader; procedure hsc_file_loader; procedure mtk_file_loader; procedure rad_file_loader; procedure s3m_file_loader; procedure sat_file_loader; procedure sa2_file_loader; procedure cif_file_loader; procedure fin_file_loader; procedure ins_file_loader; procedure sbi_file_loader; procedure sgi_file_loader; procedure fselect_external_proc; procedure import_standard_instrument_alt(var data); procedure test_instrument_alt(chan: Byte; fkey: Word; loadMacros: Boolean; bankSelector: Boolean; loadArpVib: Boolean; test_ins1,test_ins2: Byte); procedure test_instrument_alt2(chan: Byte; fkey: Word); implementation uses DOS, AdT2opl3,AdT2sys,AdT2keyb,AdT2unit,AdT2extn,AdT2ext2,AdT2ext4,AdT2ext5,AdT2text,AdT2pack, StringIO,DialogIO,ParserIO,TxtScrIO,DepackIO; {$i iloadins.inc} {$i iloaders.inc} procedure a2i_file_loader; type tOLD_HEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Byte; end; type tHEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Word; end; const id = '_A2ins_'; var f: File; header: tOLD_HEADER; header2: tHEADER; temp,temp2: Longint; ins_4op: Word; crc: Word; temp_ins,temp_ins2: tADTRACK2_INS; temp_str,temp_str2: String; _4op_ins_flag: Boolean; _4op_ins_idx: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:a2i_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2I]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; init_old_songdata; If (header.ffver in [1..4]) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf2,header.b0len,crc); If (crc <> header.crc16) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; Case header.ffver of 4: Move(buf2,buf3,header.b0len); 3: LZSS_decompress(buf2,buf3,header.b0len); 2: LZW_decompress(buf2,buf3); 1: SIXPACK_decompress(buf2,buf3,header.b0len); end; Move(buf3, old_songdata.instr_data[1], SizeOf(old_songdata.instr_data[1])); Move(buf3[SizeOf(old_songdata.instr_data[1])], temp_str, buf3[SizeOf(old_songdata.instr_data[1])]+1); old_songdata.instr_data[1].panning := 0; If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); old_songdata.instr_names[1] := Copy(old_songdata.instr_names[1],1,9)+truncate_string(temp_str); import_single_old_instrument(Addr(old_songdata),current_inst,1); end; If (header.ffver in [5..8]) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf2,header.b0len,crc); If (crc <> header.crc16) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; Case header.ffver of 8: Move(buf2,buf3,header.b0len); 7: LZSS_decompress(buf2,buf3,header.b0len); 6: LZW_decompress(buf2,buf3); 5: SIXPACK_decompress(buf2,buf3,header.b0len); end; Move(buf3, old_songdata.instr_data[1], SizeOf(old_songdata.instr_data[1])); Move(buf3[SizeOf(old_songdata.instr_data[1])], temp_str, buf3[SizeOf(old_songdata.instr_data[1])]+1); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); old_songdata.instr_names[1] := Copy(old_songdata.instr_names[1],1,9)+truncate_string(temp_str); import_single_old_instrument(Addr(old_songdata),current_inst,1); end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; BlockReadF(f,buf2,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; crc := WORD_NULL; crc := Update16(header2.b0len,1,crc); crc := Update16(buf2,header2.b0len,crc); If (crc <> header2.crc16) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; APACK_decompress(buf2,buf3); Move(buf3, songdata.instr_data[current_inst], SizeOf(songdata.instr_data[current_inst])); Move(buf3[SizeOf(songdata.instr_data[current_inst])], temp_str, buf3[SizeOf(songdata.instr_data[current_inst])]+1); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+truncate_string(temp_str); end; If (header.ffver = FFVER_A2I) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; BlockReadF(f,buf2,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; crc := WORD_NULL; crc := Update16(header2.b0len,1,crc); crc := Update16(buf2,header2.b0len,crc); If (crc <> header2.crc16) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; _4op_ins_flag := FALSE; progress_num_steps := 0; temp := 0; temp2 := LZH_decompress(buf2,buf3,header2.b0len); Move(buf3[temp],temp_ins,SizeOf(temp_ins)); Inc(temp,SizeOf(temp_ins)); // instrument data Move(buf3[temp],temp_str,SUCC(buf3[temp])); Inc(temp,SUCC(buf3[temp])); // instrument name If (temp < temp2) then // more data present => 4op instrument begin _4op_ins_flag := TRUE; Move(buf3[temp],temp_ins2,SizeOf(temp_ins2)); Inc(temp,SizeOf(temp_ins2)); Move(buf3[temp],temp_str2,SUCC(buf3[temp])); Inc(temp,SUCC(buf3[temp])); end; If NOT _4op_ins_flag then begin ins_4op := check_4op_to_test; If (ins_4op <> 0) then begin reset_4op_flag(HI(ins_4op)); update_4op_flag_marks; end; Move(temp_ins,songdata.instr_data[current_inst],SizeOf(temp_ins)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+truncate_string(temp_str); end else begin _4op_ins_idx := current_inst; set_4op_flag(current_inst); update_4op_flag_marks; If (_4op_ins_idx = 255) then Dec(_4op_ins_idx); // 4OP 1/2 Move(temp_ins,songdata.instr_data[_4op_ins_idx],SizeOf(temp_ins)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source))+' [4OP 1/2]'; songdata.instr_names[_4op_ins_idx] := Copy(songdata.instr_names[_4op_ins_idx],1,9)+truncate_string(temp_str); // 4OP 2/2 Move(temp_ins2,songdata.instr_data[SUCC(_4op_ins_idx)],SizeOf(temp_ins2)); If (temp_str2 = '') then temp_str2 := Lower(NameOnly(instdata_source))+' [4OP 2/2]'; songdata.instr_names[SUCC(_4op_ins_idx)] := Copy(songdata.instr_names[SUCC(_4op_ins_idx)],1,9)+truncate_string(temp_str2); end; end; CloseF(f); load_flag := 1; end; procedure a2f_file_loader; type tHEADER = Record ident: array[1..18] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; const id = '_a2ins_w/fm-macro_'; var f: File; header: tHEADER; crc,temp,temp2: Longint; ins_4op: Word; temp_ins,temp_ins2: tADTRACK2_INS; temp_str,temp_str2: String; temp_macro: tREGISTER_TABLE; temp_macro2: tREGISTER_TABLE; temp_dis_fmreg_col: tDIS_FMREG_COL; temp_dis_fmreg_col2: tDIS_FMREG_COL; _4op_ins_flag: Boolean; _4op_ins_idx: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:a2f_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2F]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; If (header.ffver = 1) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,1,crc); crc := Update32(buf2,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; APACK_decompress(buf2,buf3); Move(buf3, songdata.instr_data[current_inst], SizeOf(songdata.instr_data[current_inst])); Move(buf3[SizeOf(songdata.instr_data[current_inst])], temp_str, buf3[SizeOf(songdata.instr_data[current_inst])]+1); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+truncate_string(temp_str); Move(buf3[SizeOf(songdata.instr_data[current_inst])+ buf3[SizeOf(songdata.instr_data[current_inst])]+1], songdata.instr_macros[current_inst], SizeOf(songdata.instr_macros[current_inst])); Move(buf3[SizeOf(songdata.instr_data[current_inst])+ buf3[SizeOf(songdata.instr_data[current_inst])]+1+ SizeOf(songdata.instr_macros[current_inst])], songdata.dis_fmreg_col[current_inst], SizeOf(songdata.dis_fmreg_col[current_inst])); end; If (header.ffver = FFVER_A2F) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,1,crc); crc := Update32(buf2,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; _4op_ins_flag := FALSE; progress_num_steps := 0; temp := 0; temp2 := LZH_decompress(buf2,buf3,header.b0len); Move(buf3[temp],temp_ins,SizeOf(temp_ins)); Inc(temp,SizeOf(temp_ins)); // instrument data Move(buf3[temp],temp_str,SUCC(buf3[temp])); Inc(temp,SUCC(buf3[temp])); // instrument name Move(buf3[temp],temp_macro,SizeOf(temp_macro)); Inc(temp,SizeOf(temp_macro)); // FM-macro data Move(buf3[temp],temp_dis_fmreg_col,SizeOf(temp_dis_fmreg_col)); Inc(temp,SizeOf(temp_dis_fmreg_col)); // disabled FM-macro column data If (temp < temp2) then // more data present => 4op instrument begin _4op_ins_flag := TRUE; Move(buf3[temp],temp_ins2,SizeOf(temp_ins2)); Inc(temp,SizeOf(temp_ins2)); Move(buf3[temp],temp_str2,SUCC(buf3[temp])); Inc(temp,SUCC(buf3[temp])); Move(buf3[temp],temp_macro2,SizeOf(temp_macro2)); Inc(temp,SizeOf(temp_macro2)); Move(buf3[temp],temp_dis_fmreg_col2,SizeOf(temp_dis_fmreg_col2)); end; If NOT _4op_ins_flag then begin ins_4op := check_4op_to_test; If (ins_4op <> 0) then begin reset_4op_flag(HI(ins_4op)); update_4op_flag_marks; end; Move(temp_ins,songdata.instr_data[current_inst],SizeOf(temp_ins)); Move(temp_macro,songdata.instr_macros[current_inst],SizeOf(temp_macro)); Move(temp_dis_fmreg_col,songdata.dis_fmreg_col[current_inst],SizeOf(temp_dis_fmreg_col)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+truncate_string(temp_str); end else begin _4op_ins_idx := current_inst; set_4op_flag(current_inst); update_4op_flag_marks; If (_4op_ins_idx = 255) then Dec(_4op_ins_idx); // 4OP 1/2 Move(temp_ins,songdata.instr_data[_4op_ins_idx],SizeOf(temp_ins)); Move(temp_macro,songdata.instr_macros[_4op_ins_idx],SizeOf(temp_macro)); Move(temp_dis_fmreg_col,songdata.dis_fmreg_col[_4op_ins_idx],SizeOf(temp_dis_fmreg_col)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source))+' [4OP 1/2]'; songdata.instr_names[_4op_ins_idx] := Copy(songdata.instr_names[_4op_ins_idx],1,9)+truncate_string(temp_str); // 4OP 2/2 Move(temp_ins2,songdata.instr_data[SUCC(_4op_ins_idx)],SizeOf(temp_ins2)); Move(temp_macro2,songdata.instr_macros[SUCC(_4op_ins_idx)],SizeOf(temp_macro2)); Move(temp_dis_fmreg_col2,songdata.dis_fmreg_col[SUCC(_4op_ins_idx)],SizeOf(temp_dis_fmreg_col2)); If (temp_str2 = '') then temp_str2 := Lower(NameOnly(instdata_source))+' [4OP 2/2]'; songdata.instr_names[SUCC(_4op_ins_idx)] := Copy(songdata.instr_names[SUCC(_4op_ins_idx)],1,9)+truncate_string(temp_str2); end; end; CloseF(f); load_flag := 1; end; procedure cif_file_loader; const id = ''+#26; type tCIF_DATA = Record ident: array[1..20] of Char; idata: tFM_INST_DATA; resrv: Byte; iname: array[1..20] of Char; end; var f: File; buffer: tCIF_DATA; temp: Longint; temp_str: String; const MIN_CIF_SIZE = SizeOf(buffer.ident)+ SizeOf(buffer.idata)+ SizeOf(buffer.resrv); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:cif_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CiF LOADER ',1); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If NOT ((temp >= MIN_CIF_SIZE) and (buffer.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CiF LOADER ',1); EXIT; end; import_hsc_instrument(current_inst,buffer.idata); songdata.instr_data[current_inst].fine_tune := 0; temp_str := truncate_string(buffer.iname); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+temp_str; CloseF(f); load_flag := 1; end; procedure fin_file_loader; var f: File; buffer: tFIN_DATA; temp: Longint; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:fin_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiN LOADER ',1); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If (temp <> SizeOf(buffer)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiN LOADER ',1); EXIT; end; import_fin_instrument(current_inst,buffer.idata); If (Length(truncate_string(buffer.iname)) <= 32) then temp_str := truncate_string(buffer.iname) else temp_str := Lower(truncate_string(buffer.dname)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+Copy(temp_str,1,32); CloseF(f); load_flag := 1; end; procedure ins_file_loader; type tINS_DATA = Record idata: tFM_INST_DATA; slide: Byte; _SAdT: array[0..18] of Byte; end; var f: File; buffer: tINS_DATA; temp: Longint; function correct_ins(var data): Boolean; var result: Boolean; begin result := TRUE; If NOT (tADTRACK2_INS(data).fm_data.WAVEFORM_modulator in [0..3]) then result := FALSE; If NOT (tADTRACK2_INS(data).fm_data.WAVEFORM_carrier in [0..3]) then result := FALSE; If NOT (tADTRACK2_INS(data).fm_data.FEEDBACK_FM in [0..15]) then result := FALSE; correct_ins := result; end; begin { ins_file_loader } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:ins_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iNS LOADER ',1); EXIT; end; If (FileSize(f) > SizeOf(buffer)) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT TYPE$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iNS LOADER ',1); EXIT; end; BlockReadF(f,buffer,FileSize(f),temp); If (temp <> FileSize(f)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iNS LOADER ',1); EXIT; end; Case force_ins of 0: begin If (temp = 12) then import_standard_instrument(current_inst,buffer.idata); If (temp = 12) and NOT correct_ins(buffer.idata) then import_hsc_instrument(current_inst,buffer.idata) else If (temp > 12) then import_sat_instrument(current_inst,buffer.idata); end; 1: import_hsc_instrument(current_inst,buffer.idata); 2: import_sat_instrument(current_inst,buffer.idata); 3: import_standard_instrument(current_inst,buffer.idata); end; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Lower(NameOnly(instdata_source)); CloseF(f); load_flag := 1; end; procedure sbi_file_loader; const id = 'SBI'+#26; type tSBI_DATA = Record ident: array[1..4] of Char; iname: array[1..32] of Char; idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; var f: File; buffer: tSBI_DATA; temp: Longint; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:sbi_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SBi LOADER ',1); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If NOT ((temp = SizeOf(buffer)) and (buffer.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SBi LOADER ',1); EXIT; end; import_standard_instrument(current_inst,buffer.idata); temp_str := truncate_string(buffer.iname); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+Copy(temp_str,1,32); CloseF(f); load_flag := 1; end; procedure import_sgi_instrument(inst: Byte; var data); begin FillChar(songdata.instr_data[inst], SizeOf(songdata.instr_data[inst]),0); With songdata.instr_data[inst] do begin fm_data.ATTCK_DEC_modulator := (pBYTE(@data)[1] AND $0f)+ (pBYTE(@data)[0] AND $0f) SHL 4; fm_data.SUSTN_REL_modulator := (pBYTE(@data)[3] AND $0f)+ (pBYTE(@data)[2] AND $0f) SHL 4; fm_data.WAVEFORM_modulator := (pBYTE(@data)[4] AND 3); fm_data.KSL_VOLUM_modulator := (pBYTE(@data)[7] AND $3f)+ (pBYTE(@data)[6] AND 3) SHL 6; fm_data.AM_VIB_EG_modulator := (pBYTE(@data)[5] AND $0f)+ (pBYTE(@data)[8] AND 1) SHL 4+ (pBYTE(@data)[11] AND 1) SHL 5+ (pBYTE(@data)[10] AND 1) SHL 6+ (pBYTE(@data)[9] AND 1) SHL 7; fm_data.ATTCK_DEC_carrier := (pBYTE(@data)[13] AND $0f)+ (pBYTE(@data)[12] AND $0f) SHL 4; fm_data.SUSTN_REL_carrier := (pBYTE(@data)[15] AND $0f)+ (pBYTE(@data)[14] AND $0f) SHL 4; fm_data.WAVEFORM_carrier := (pBYTE(@data)[16] AND 3); fm_data.KSL_VOLUM_carrier := (pBYTE(@data)[19] AND $3f)+ (pBYTE(@data)[18] AND 3) SHL 6; fm_data.AM_VIB_EG_carrier := (pBYTE(@data)[17] AND $0f)+ (pBYTE(@data)[20] AND 1) SHL 4+ (pBYTE(@data)[23] AND 1) SHL 5+ (pBYTE(@data)[22] AND 1) SHL 6+ (pBYTE(@data)[21] AND 1) SHL 7; fm_data.FEEDBACK_FM := (pBYTE(@data)[25] AND 1)+ (pBYTE(@data)[24] AND 7) SHL 1; end; end; procedure sgi_file_loader; type tSGI_DATA = Record { 0} attack_m, { 1} decay_m, { 2} sustain_m, { 3} release_m, { 4} waveform_m, { 5} mfmult_m, { 6} ksl_m, { 7} volume_m, { 8} ksr_m, { 9} tremolo_m, {10} vibrato_m, {11} eg_type_m, {12} attack_c, {13} decay_c, {14} sustain_c, {15} release_c, {16} waveform_c, {17} mfmult_c, {18} ksl_c, {19} volume_c, {20} ksr_c, {21} tremolo_c, {22} vibrato_c, {23} eg_type_c, {24} feedback, {25} fm: Byte; end; var f: File; buffer: tSGI_DATA; temp: Longint; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:sgi_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SGi LOADER ',1); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If (temp <> SizeOf(buffer)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SGi LOADER ',1); EXIT; end; import_sgi_instrument(current_inst,buffer); temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+Copy(temp_str,1,32); CloseF(f); load_flag := 1; end; end. adlibtracker2-2.4.23/adt2vesa.pas0000644000000000000000000002572013176573532015251 0ustar rootrootunit Adt2VESA; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const VESA_640x480 = $101; VESA_800x600 = $103; VESA_1024x768 = $105; const VESA_GraphicsSysInited: Boolean = FALSE; type tModeInfo = Record ModeNumber: Word; XResolution: Word; YResolution: Word; BufferAddress: Pointer; end; var VESA_NumberOfModes: Byte; (* Total LFB videomodes supported *) VESA_FrameBuffer: Pointer; (* LFB address for current mode *) VESA_ModeList: array[0..255] of tModeInfo; VESA_Version: Word; (* VESA version *) VESA_OEM_String: String; (* VESA OEM string *) VESA_Capabilities: Dword; (* Hardware capabilities *) VESA_VideoMemory: Word; (* Videomemory amount in Kb *) VESA_OEM_SoftwareRevision: Word; (* VESA implementation revision *) VESA_OEM_VendorName: String; (* VESA vendor name *) VESA_OEM_ProductName: String; (* VESA OEM product name *) VESA_OEM_ProductRevision: String; (* VESA OEM product revision *) VESA_Mode: Word; (* Current videomode *) VESA_ModeIndex: Byte; (* Current mode index in VESA_ModeList *) VESA_XResolution, (* Current X resolution *) VESA_YResolution: Word; (* Current Y resolution *) type tPaletteArray = array[0..767] of Byte; var VESA_SegLFB: Word; StepWorkPalette: tPaletteArray; StepRealPal,StepDelta: array[0..767] of Single; FadeSteps: Word; procedure VESA_Init; function VESA_SetMode(Mode: Word): Integer; procedure VESA_GetPalette(var Palette); procedure VESA_SetPalette(var Palette); procedure VESA_InitStepFade(var StartPalette,EndPalette; Speed: Single); procedure VESA_StepFade; procedure VESA_SwitchBank(Bank: Byte); implementation uses GO32; type tModeInfoBlock = Record ModeAttributes: Word; WinAAttributes: Byte; WinBAttributes: Byte; WinGranularity: Word; WinSize: Word; WinASegment: Word; WinBSegment: Word; WinFuncPtr: Pointer; BytesPerScanLine: Word; // VESA 1.2+ specific XResolution: Word; YResolution: Word; XCharSize: Byte; YCharSize: Byte; NumberOfPlanes: Byte; BitsPerPixel: Byte; NumberOfBanks: Byte; MemoryModel: Byte; BankSize: Byte; NumberOfImagePages: Byte; Reserved1: Byte; // direct color data RedMaskSize: Byte; RedFieldPosition: Byte; GreenMaskSize: Byte; GreenFieldPosition: Byte; BlueMaskSize: Byte; BlueFieldPosition: Byte; RsvdMaskSize: Byte; RsvdFieldPosition: Byte; DirectColorModeInfo: Byte; // VESA 2.0+ specific PhysBasePtr: Pointer; OffScreenMemOffset: Dword; OffScreenMemSize: Word; Reserved2: array[0..205] of Byte; end; type tModeList = array[0..127] of Word; tVESA_Info = Record Signature: array[0..3] of Char; Version: Word; OEM_StringPtr: Dword; Capabilities: Dword; ModeListPtr: Dword; VideoMemory: Word; OEM_SoftwareRevision: Word; OEM_VendorNamePtr: Dword; OEM_ProductNamePtr: Dword; OEM_ProductRevisionPtr: Dword; Reserved: array[0..221] of Byte; OEM_Data: array[0..255] of Byte; end; var ModeList: tModeList; VESA_Info: tVESA_Info; ModeInfoBlock: tModeInfoBlock; procedure VESA_Init; var idx,idx2: Byte; regs: tRealRegs; dos_sel,dos_seg: Word; dos_mem_adr: Dword; function GetVESAInfoStr(dpmiStrPtr: Dword): String; begin GetVESAInfoStr := StrPas(PCHAR(POINTER(Ofs(VESA_Info)+WORD(dpmiStrPtr)))); end; begin If VESA_GraphicsSysInited then EXIT; With VESA_ModeList[0] do begin ModeNumber := $13; XResolution := 320; YResolution := 200; BufferAddress := POINTER($A0000); end; dos_mem_adr := global_dos_alloc(SizeOf(tVESA_Info)); dos_sel := WORD(dos_mem_adr); dos_seg := WORD(dos_mem_adr SHR 16); FillChar(VESA_Info,SizeOf(tVESA_Info),0); VESA_Info.Signature := 'VBE2'; dosmemput(dos_seg,0,VESA_Info,4); regs.ax := $4f00; regs.ds := dos_seg; regs.es := dos_seg; regs.di := 0; RealIntr($10,regs); dosmemget(dos_seg,0,VESA_Info,SizeOf(tVESA_Info)); global_dos_free(dos_sel); If (VESA_Info.Signature <> 'VESA') then EXIT; // ERROR: VESA BIOS extensions not found! VESA_Version := VESA_Info.Version; If (HI(VESA_Version) < 2) then EXIT; // ERROR: VESA 2.0 required! VESA_OEM_String := GetVESAInfoStr(VESA_Info.OEM_StringPtr); VESA_Capabilities := VESA_Info.Capabilities; VESA_VideoMemory := VESA_Info.VideoMemory SHL 6; VESA_OEM_SoftwareRevision := VESA_Info.OEM_SoftwareRevision; VESA_OEM_VendorName := GetVESAInfoStr(VESA_Info.OEM_VendorNamePtr); VESA_OEM_ProductName := GetVESAInfoStr(VESA_Info.OEM_ProductNamePtr); VESA_OEM_ProductRevision := GetVESAInfoStr(VESA_Info.OEM_ProductRevisionPtr); dpmi_dosmemget(WORD(VESA_Info.ModeListPtr SHR 16), WORD(VESA_Info.ModeListPtr), ModeList, SizeOf(tModeList)); dos_mem_adr := global_dos_alloc(SizeOf(tModeInfoBlock)); dos_sel := WORD(dos_mem_adr); dos_seg := WORD(dos_mem_adr SHR 16); idx := 0; idx2 := 1; Repeat regs.ax := $4f01; regs.cx := ModeList[idx]; regs.ds := dos_seg; regs.es := dos_seg; regs.di := 0; RealIntr($10,regs); dosmemget(dos_seg,0,ModeInfoBlock,SizeOf(tModeInfoBlock)); Inc(idx); until ((ModeInfoBlock.ModeAttributes AND $0091 = $0091) and (ModeInfoBlock.NumberOfPlanes = 1) and (ModeInfoBlock.BitsPerPixel = 8)) or (ModeList[idx-1] = $FFFF); If (ModeList[idx-1] <> $FFFF) then begin Inc(idx2); With VESA_ModeList[1] do begin ModeNumber := ModeList[idx-1]; XResolution := ModeInfoBlock.XResolution; YResolution := ModeInfoBlock.YResolution; BufferAddress := ModeInfoBlock.PhysBasePtr; end; While (idx <= 127) and (ModeList[idx] <> $FFFF) do begin regs.ax := $4f01; regs.cx := ModeList[idx]; regs.ds := dos_seg; regs.es := dos_seg; regs.di := 0; RealIntr($10,regs); dosmemget(dos_seg,0,ModeInfoBlock,SizeOf(tModeInfoBlock)); If (ModeInfoBlock.ModeAttributes AND $0091 = $0091) and (ModeInfoBlock.NumberOfPlanes = 1) and (ModeInfoBlock.BitsPerPixel = 8) then begin With VESA_ModeList[idx2] do begin ModeNumber := ModeList[idx]; XResolution := ModeInfoBlock.XResolution; YResolution := ModeInfoBlock.YResolution; end; Inc(idx2); end; Inc(idx); end; end; global_dos_free(dos_sel); VESA_NumberOfModes := idx2-1; If (VESA_NumberOfModes >= 1) then begin VESA_ModeList[1].BufferAddress := POINTER(DWORD(Get_Linear_Addr(DWORD(VESA_ModeList[1].BufferAddress),4096*1024))); If (VESA_ModeList[1].BufferAddress = NIL) then EXIT; // ERROR: Cannot remap LFB to linear address space! For idx := 2 to VESA_NumberOfModes do VESA_ModeList[idx].BufferAddress := VESA_ModeList[1].BufferAddress; end; VESA_Mode := 0; VESA_GraphicsSysInited := TRUE; end; function VESA_SetMode(Mode: Word): Integer; var idx: Byte; result: Integer; begin If NOT VESA_GraphicsSysInited then begin VESA_SetMode := -1; EXIT; end; VESA_ModeIndex := VESA_NumberOfModes+1; For idx := 0 to VESA_NumberOfModes do If (VESA_ModeList[idx].ModeNumber = Mode) then begin Write(VESA_ModeList[idx].ModeNumber,','); VESA_ModeIndex := idx; BREAK; end; If (VESA_ModeIndex = VESA_NumberOfModes+1) then begin VESA_SetMode := -1; EXIT; end; If (Mode <> 19) then Mode := Mode OR $4000; asm mov ax,4f02h mov bx,Mode int 10h mov result,0 cmp ax,4fh je @@1 mov result,-1 @@1: end; VESA_SetMode := result; If (result <> 0) then EXIT; VESA_Mode := Mode; VESA_XResolution := VESA_ModeList[VESA_ModeIndex].XResolution; VESA_YResolution := VESA_ModeList[VESA_ModeIndex].YResolution; VESA_Framebuffer := VESA_ModeList[VESA_ModeIndex].BufferAddress; end; procedure VESA_GetPalette(var Palette); assembler; asm mov dx,3c7h xor al,al out dx,al mov edi,Palette inc dx inc dx mov ecx,768 rep insb end; procedure VESA_SetPalette(var Palette); assembler; asm mov dx,3dah @@1: in al,dx test al,8 jz @@1 mov dx,3c8h xor al,al out dx,al mov esi,Palette inc dx mov ecx,768 rep outsb end; procedure VESA_InitStepFade(var StartPalette,EndPalette; Speed: Single); var EndRealPal: array[0..767] of Single; idx: Word; begin For idx := 0 to 767 do begin StepRealPal[idx] := tPaletteArray(StartPalette)[idx]; StepWorkPalette[idx] := tPaletteArray(StartPalette)[idx]; EndRealPal[idx] := tPaletteArray(EndPalette)[idx]; StepDelta[idx] := (EndRealPal[idx]-StepRealPal[idx])/Speed; end; VESA_SetPalette(StartPalette); FadeSteps := TRUNC(Speed); end; procedure VESA_StepFade; var idx: Word; begin For idx := 0 to 767 do begin StepRealPal[idx] := StepRealPal[idx]+StepDelta[idx]; StepWorkPalette[idx] := ROUND(StepRealPal[idx]); end; VESA_SetPalette(StepWorkPalette); end; procedure VESA_SwitchBank(Bank: Byte); var regs: tRealRegs; granularity: Byte; begin regs.ax := $4f05; regs.bx := 0; Case ModeInfoBlock.WinGranularity of 32: granularity := 5; 16: granularity := 4; 8: granularity := 3; 4: granularity := 2; 2: granularity := 1; 1: granularity := 0; end; regs.dx := bank SHL granularity; RealIntr($10,regs); end; end. adlibtracker2-2.4.23/package/0000755000000000000000000000000013176573533014421 5ustar rootrootadlibtracker2-2.4.23/package/instr/0000755000000000000000000000000013176573533015560 5ustar rootrootadlibtracker2-2.4.23/package/instr/synmllet.sgi0000644000000000000000000000003213176573532020125 0ustar rootroot adlibtracker2-2.4.23/package/instr/elguitar.sbi0000644000000000000000000000006413176573532020072 0ustar rootrootSBIelguitar.sbi2‡€¡}3adlibtracker2-2.4.23/package/instr/eguitar3.sgi0000644000000000000000000000003213176573532020001 0ustar rootrootadlibtracker2-2.4.23/package/instr/trumpet3.sbi0000644000000000000000000000006413176573532020041 0ustar rootrootSBItrumpet3.sbi1¡€A’;adlibtracker2-2.4.23/package/instr/strom2.sgi0000644000000000000000000000003213176573532017504 0ustar rootrootadlibtracker2-2.4.23/package/instr/minebass.sgi0000644000000000000000000000003213176573532020057 0ustar rootrootadlibtracker2-2.4.23/package/instr/kuorsaus.sbi0000644000000000000000000000006413176573532020132 0ustar rootrootSBIkuorsaus.sbipÖÄ€¤EBadlibtracker2-2.4.23/package/instr/easybass.cif0000644000000000000000000000006413176573532020054 0ustar rootrootMôó|Veasybass.cifadlibtracker2-2.4.23/package/instr/syn6.sbi0000644000000000000000000000006413176573532017155 0ustar rootrootSBIsyn6.sbi$!Añ~^ adlibtracker2-2.4.23/package/instr/vibra2.sbi0000644000000000000000000000006413176573532017443 0ustar rootrootSBIvibra2.sbiAsöòT³adlibtracker2-2.4.23/package/instr/cviolin.sbi0000644000000000000000000000006413176573532017721 0ustar rootrootSBIcviolin.sbirbQRadlibtracker2-2.4.23/package/instr/snare1.fin0000644000000000000000000000006213176573532017444 0ustar rootrootSNARE1.FIN Snare 1 òö%õ adlibtracker2-2.4.23/package/instr/asbass.fin0000644000000000000000000000006213176573532017527 0ustar rootrootASBASS.FIN AsBass @¤¤¡adlibtracker2-2.4.23/package/instr/funnybas.sbi0000644000000000000000000000006413176573532020103 0ustar rootrootSBIfunnybas.sbi K{Åradlibtracker2-2.4.23/package/instr/harpsi3.sbi0000644000000000000000000000006413176573532017627 0ustar rootrootSBIharpsi3.sbi5„€¨}3adlibtracker2-2.4.23/package/instr/vibra1.sbi0000644000000000000000000000006413176573532017442 0ustar rootrootSBIvibra1.sbiD`S€õý3%adlibtracker2-2.4.23/package/instr/drum1.ins0000644000000000000000000000003313176573532017316 0ustar rootroot éê(*drum1.insadlibtracker2-2.4.23/package/instr/synth.ins0000644000000000000000000000001413176573532017432 0ustar rootrootAÂCòÿÿadlibtracker2-2.4.23/package/instr/vlnpizz1.sbi0000644000000000000000000000006413176573532020053 0ustar rootrootSBIvlnpizz1.sbi11œ€ñ÷ùæadlibtracker2-2.4.23/package/instr/gun.sgi0000644000000000000000000000003213176573532017047 0ustar rootrootadlibtracker2-2.4.23/package/instr/clavecin.sbi0000644000000000000000000000006413176573532020042 0ustar rootrootSBIclavecin.sbi òò± adlibtracker2-2.4.23/package/instr/icerain.sgi0000644000000000000000000000003213176573532017670 0ustar rootroot  adlibtracker2-2.4.23/package/instr/piano.sgi0000644000000000000000000000003213176573532017364 0ustar rootrootadlibtracker2-2.4.23/package/instr/fupp.cif0000644000000000000000000000006413176573532017214 0ustar rootrootr7HYÿÿfupp.cifadlibtracker2-2.4.23/package/instr/bagpipe2.sbi0000644000000000000000000000006413176573532017747 0ustar rootrootSBIbagpipe2.sbi0cÿe  adlibtracker2-2.4.23/package/instr/claves.sbi0000644000000000000000000000006413176573532017533 0ustar rootrootSBIclaves.sbi€ûèÿÿ adlibtracker2-2.4.23/package/instr/basemax.sgi0000644000000000000000000000003213176573532017676 0ustar rootroot adlibtracker2-2.4.23/package/instr/tom2.cif0000644000000000000000000000006413176573532017123 0ustar rootroot2Dõøÿtom2.cifadlibtracker2-2.4.23/package/instr/fstrp2.sbi0000644000000000000000000000006413176573532017476 0ustar rootrootSBIfstrp2.sbi°à€U‡/ adlibtracker2-2.4.23/package/instr/galaxi.sgi0000644000000000000000000000003213176573532017523 0ustar rootrootadlibtracker2-2.4.23/package/instr/fantpan2.sbi0000644000000000000000000000006413176573532017767 0ustar rootrootSBIfantpan2.sbitÖ‡€¤EBadlibtracker2-2.4.23/package/instr/bstacc.sbi0000644000000000000000000000006413176573532017515 0ustar rootrootSBIbstacc.sbiMóôV|adlibtracker2-2.4.23/package/instr/hack.cif0000644000000000000000000000006413176573532017150 0ustar rootrootòâõ¯öòhack.cifadlibtracker2-2.4.23/package/instr/sax1.sbi0000644000000000000000000000006413176573532017132 0ustar rootrootSBIsax1.sbiOqRS| adlibtracker2-2.4.23/package/instr/eguhigh.sgi0000644000000000000000000000003213176573532017676 0ustar rootroot adlibtracker2-2.4.23/package/instr/sunrise.sgi0000644000000000000000000000003213176573532017746 0ustar rootrootadlibtracker2-2.4.23/package/instr/tuba2.sbi0000644000000000000000000000006413176573532017273 0ustar rootrootSBItuba2.sbibsduadlibtracker2-2.4.23/package/instr/tromb2.sbi0000644000000000000000000000006413176573532017463 0ustar rootrootSBItromb2.sbi!¡€SR; adlibtracker2-2.4.23/package/instr/bass2.cif0000644000000000000000000000006413176573532017254 0ustar rootrootAŽc1tbass2.cifadlibtracker2-2.4.23/package/instr/belpiano.sbi0000644000000000000000000000006413176573532020047 0ustar rootrootSBIbelpiano.sbiOñòRGadlibtracker2-2.4.23/package/instr/hihat2.cif0000644000000000000000000000006413176573532017421 0ustar rootrootÇvñôôhihat2.cifadlibtracker2-2.4.23/package/instr/bsynth.sbi0000644000000000000000000000006413176573532017565 0ustar rootrootSBIbsynth.sbiŠ@ññ³adlibtracker2-2.4.23/package/instr/elguit4.sbi0000644000000000000000000000006413176573532017633 0ustar rootrootSBIelguit4.sbi€Úù adlibtracker2-2.4.23/package/instr/rlog.sbi0000644000000000000000000000006413176573532017221 0ustar rootrootSBIrlog.sbi2Døõÿadlibtracker2-2.4.23/package/instr/floete.sgi0000644000000000000000000000003213176573532017534 0ustar rootroot  adlibtracker2-2.4.23/package/instr/wave.sbi0000644000000000000000000000006413176573532017220 0ustar rootrootSBIwave.sbi€ð¢adlibtracker2-2.4.23/package/instr/softtrom.cif0000644000000000000000000000006413176573532020117 0ustar rootroot(A‘ûsofttrom.cifadlibtracker2-2.4.23/package/instr/basemed.sgi0000644000000000000000000000003213176573532017656 0ustar rootrootadlibtracker2-2.4.23/package/instr/briss4.sgi0000644000000000000000000000003213176573532017464 0ustar rootroot adlibtracker2-2.4.23/package/instr/shrtviol.cif0000644000000000000000000000006413176573532020114 0ustar rootrootâÈ fuö÷shrtviol.cifadlibtracker2-2.4.23/package/instr/piano3.sbi0000644000000000000000000000006413176573532017447 0ustar rootrootSBIpiano3.sbiOñÒP|adlibtracker2-2.4.23/package/instr/mdrnphon.sbi0000644000000000000000000000006413176573532020103 0ustar rootrootSBImdrnphon.sbi0nÀþñadlibtracker2-2.4.23/package/instr/tom.cif0000644000000000000000000000006413176573532017041 0ustar rootroot2Dõøÿtom.cifadlibtracker2-2.4.23/package/instr/deadbass.cif0000644000000000000000000000006413176573532020010 0ustar rootrootÒÀóøõdeadbass.cifadlibtracker2-2.4.23/package/instr/$mt32.ibk0000644000000000000000000000620413176573532017101 0ustar rootrootIBKPñÒPvPñÒPvKñÒPvPñÒPv2’‹ÿÿ 4’ ÿÿ 4’ ÿÿ SQN ñÒ†(!Ï øÀåÿâáÊ øÀå,¡Ô ùÀÿÿ+!Ê øÀåÿ)!Í ðà‘†$!Ð ðà†#!È ðà†daÉ °ð†3…‹¡r#1…‹¡s31‹¡Â0tŠ‹ðô{{Š€ðô{{#Š€òô{{2€‹r32€‹s31! s€Žž0! s€~ž1!”3 s—1!” Ó s—12E ñòS' òò¶ òò¶ þò½áM úñññ@ º$1aá§‹rPŽáM 2Qã1À‹A1!‹õóU3áM úñññC 1øäL‚ð—ò@ ÑQSqñ! wñá 2ñsqH ññSqaKqr×ÒO òña² ððÿø 1a‹ A"1a‹ ÿD! 1a‹ A2q! ýçÖq! QTgq! QTq! TSIqaV QTq! QT)‹õòuó)‹ðôu3I ññSt‰ ññSt‰ ññSt€ ññSt@KññSS!!‹ÓÃ,, !‹ÔÄòŠ N ðô{ÈD ðó««S ôñÈ»S òòÈÅ!! ´”L¬ !! ”d¬ !¡‹w`*!¡‹w`¿*¡â‹Ö`¯*¢â‹•`$*2aš‹Q`9 ¤â‹ô`0*!! cc 1! cc !! cc ! cc 2a‹‚` 2á‹Qb6 1"à ‡‹q"ÃŽ‹p" nk$1O òR1a dÐg1a aÒ6 1a 1P6 1a A 6 !!š‹S V!!š‹S Va! S X a! s W !! q¡¦–…¡‘ õðDEaQ õð3%Œ€ÿÿ!8±Œ@óõ 3‡"‘ õðUT³J ¶Ñ21ÂþöðµN€Úð @ ÷S”°×Ä‹¤@Bàaìne*055 õðð›õöš€ `Ç¥ S…?_ â[€P %€ðÐØØ––  ôö FŠKññ³@ ÑòSV2Døõÿ@ ÷S”€€__ P òòpr@ öS”‘R ¨ÖLO  å][ú1‡€¡}E0ôôI3 $1TUPý-ACOUPNO1ACOUPNO2ACOUPNO3ELECPNO1ELECPNO2ELECPNO3ELECPNO4HONKTONKELECORG1ELECORG2ELECORG3ELECORG4PIPEORG1PIPEORG2PIPEORG3ACCORDN HARPSI1 HARPSI2 HARPSI3 CLAVI1P CLAVI2P CLAVI3P CELESTA1CELESTA2SYNBRSS1SYNBRSS2SYNBRSS3SYNBRSS4SYNBASS1SYNBASS2SYNBASS3SYNBASS4FANTASY HARMOPANCHORALE GLASSES SOUNDTRKATMOSPHRWARMBELLFUNNYVOXECHOBELLICERAIN OBOE2001ECHOPAN DOCSOLO SCHLDAZEBELLSINGSQWAVEP STRSECT1STRSECT2STRSECT3PIZZICTOVIOLIN1 VIOLIN2 CELLO1P CELLO2P CONTRABSHARP1 P HARP2 P GUITAR1 GUITAR2 ELECGTR1ELECGTR2SITAR P ACOUBS1 ACOUBS2 ELECBS1 ELECBS2 SLAPBS1 SLAPBS2 FRETLS1 FRETLS2 FLUTE1P FLUTE2P PICCOLO1PICCOLO2RECORDERPANPIPESSAX1P P SAX2P P SAX3P P SAX4P P CLARINT1CLARINT2OBOEP P ENGHORN BASSOON HARMONCATRUMPET1TRUMPET2TROMBON1TROMBON2FRHORN1 FRHORN2 TUBAP P BRSSECT1BRSSECT2VIBES1P VIBES2P SYNMALLTWINDBELLGLOCK P TUBEBELLXYLOPHONMARIMBA KOTOP P SHO P P SHAKUHCHWHISTLE1WHISTLE2BOTTLBLOBREATHPPTIMPANI MELODTOMDEEPSNAROBERHEIMNOISE P TAIKO P TAIKORIMREVCYMB JAWHARP TRIANGLEORCHEHITBASSDRM BIRDTWT BANJO P MOOGSYN JUNGLTUNadlibtracker2-2.4.23/package/instr/synbal1.sbi0000644000000000000000000000006413176573532017627 0ustar rootrootSBIsynbal1.sbi&àÿð1adlibtracker2-2.4.23/package/instr/bellong.sbi0000644000000000000000000000006413176573532017700 0ustar rootrootSBIbellong.sbi¤>ÛÀÿóbadlibtracker2-2.4.23/package/instr/key2.sgi0000644000000000000000000000003213176573532017130 0ustar rootrootadlibtracker2-2.4.23/package/instr/btgo.sbi0000644000000000000000000000006413176573532017211 0ustar rootrootSBIbtgo.sbiN@tdS|adlibtracker2-2.4.23/package/instr/bells.sbi0000644000000000000000000000006413176573532017357 0ustar rootrootSBIbells.sbiOòò`radlibtracker2-2.4.23/package/instr/snare.sbi0000644000000000000000000000006413176573532017366 0ustar rootrootSBIsnare.sbi. ÿöJadlibtracker2-2.4.23/package/instr/jazzbas2.sbi0000644000000000000000000000006413176573532020004 0ustar rootrootSBIjazzbas2.sbi !@{ur adlibtracker2-2.4.23/package/instr/scratch4.sbi0000644000000000000000000000006413176573532017771 0ustar rootrootSBIscratch4ð\ðÜadlibtracker2-2.4.23/package/instr/mltrdrum.sbi0000644000000000000000000000006413176573532020124 0ustar rootrootSBImltrdrum.sbi åÈ;¶Úadlibtracker2-2.4.23/package/instr/elecfl.sbi0000644000000000000000000000006413176573532017510 0ustar rootrootSBIelecfl.sbià¡mWg}adlibtracker2-2.4.23/package/instr/celguit.sbi0000644000000000000000000000006413176573532017712 0ustar rootrootSBIcelguit.sbi–ˆÿÿ! adlibtracker2-2.4.23/package/instr/hardsynt.cif0000644000000000000000000000006413176573532020076 0ustar rootroot@@ññSShardsynt.cifadlibtracker2-2.4.23/package/instr/flapbas.sbi0000644000000000000000000000006413176573532017666 0ustar rootrootSBIflapbas.sbi´Ãrsadlibtracker2-2.4.23/package/instr/harp2.sbi0000644000000000000000000000006413176573532017272 0ustar rootrootSBIharp2.sbi™€õöUSadlibtracker2-2.4.23/package/instr/alien.sbi0000644000000000000000000000006413176573532017346 0ustar rootrootSBIalien.sbiõÓOòó@Badlibtracker2-2.4.23/package/instr/st1.sbi0000644000000000000000000000006413176573532016765 0ustar rootrootSBIst1.sbi´Ùadlibtracker2-2.4.23/package/instr/powersn.sgi0000644000000000000000000000003213176573532017753 0ustar rootrootadlibtracker2-2.4.23/package/instr/modacid.sgi0000644000000000000000000000003213176573532017656 0ustar rootrootadlibtracker2-2.4.23/package/instr/synsnr2.sbi0000644000000000000000000000006413176573532017674 0ustar rootrootSBIsynsnr2.sbiðöð´adlibtracker2-2.4.23/package/instr/troll.sgi0000644000000000000000000000003213176573532017412 0ustar rootrootadlibtracker2-2.4.23/package/instr/deepstri.cif0000644000000000000000000000006413176573532020061 0ustar rootrootâðÀdeepstri.cifadlibtracker2-2.4.23/package/instr/violin1.sbi0000644000000000000000000000006413176573532017637 0ustar rootrootSBIviolin1.sbi1¡€QTgadlibtracker2-2.4.23/package/instr/horror2.sgi0000644000000000000000000000003213176573532017653 0ustar rootroot adlibtracker2-2.4.23/package/instr/bass295.fin0000644000000000000000000000006213176573532017443 0ustar rootrootBASS295.FIN Bass 295 ÐÈ„£òadlibtracker2-2.4.23/package/instr/pianobel.sbi0000644000000000000000000000006413176573532020047 0ustar rootrootSBIpianobel.sbiOñòStadlibtracker2-2.4.23/package/instr/cromorne.sbi0000644000000000000000000000006413176573532020102 0ustar rootrootSBIcromorne.sbi€ððÿÿadlibtracker2-2.4.23/package/instr/belshort.sbi0000644000000000000000000000006413176573532020100 0ustar rootrootSBIbelshort.sbiàpc€ø÷óóadlibtracker2-2.4.23/package/instr/synbass4.sbi0000644000000000000000000000006413176573532020024 0ustar rootrootSBIsynbass4.sbiA‘ƒe2t adlibtracker2-2.4.23/package/instr/snare7.sbi0000644000000000000000000000006413176573532017455 0ustar rootrootSBIsnare7.sbi$@µÕT…adlibtracker2-2.4.23/package/instr/roehr.cif0000644000000000000000000000006413176573532017361 0ustar rootrootåà—(óroehr.cifadlibtracker2-2.4.23/package/instr/moogsynt.sbi0000644000000000000000000000006413176573532020135 0ustar rootrootSBImoogsynt.sbi õôž[ adlibtracker2-2.4.23/package/instr/drum4.ins0000644000000000000000000000003313176573532017321 0ustar rootroot éödrum4.insadlibtracker2-2.4.23/package/instr/logdrum1.sbi0000644000000000000000000000006413176573532020010 0ustar rootrootSBIlogdrum1.sbi2Døõÿadlibtracker2-2.4.23/package/instr/beep.cif0000644000000000000000000000006413176573532017155 0ustar rootroot3ÿbeep.cifadlibtracker2-2.4.23/package/instr/epiano.sbi0000644000000000000000000000006413176573532017531 0ustar rootrootSBIepiano.sbiA£¢"adlibtracker2-2.4.23/package/instr/jet.cif0000644000000000000000000000006413176573532017024 0ustar rootroot $jet.cifadlibtracker2-2.4.23/package/instr/ultra2.sgi0000644000000000000000000000003213176573532017467 0ustar rootroot  adlibtracker2-2.4.23/package/instr/topcbl2.sgi0000644000000000000000000000003213176573532017623 0ustar rootroot   adlibtracker2-2.4.23/package/instr/vibra3.sbi0000644000000000000000000000006413176573532017444 0ustar rootrootSBIvibra3.sbiSQ—€ª¬!adlibtracker2-2.4.23/package/instr/syn1.sbi0000644000000000000000000000006413176573532017150 0ustar rootrootSBIsyn1.sbi•—€*Bóadlibtracker2-2.4.23/package/instr/tromb1.sbi0000644000000000000000000000006413176573532017462 0ustar rootrootSBItromb1.sbiq¡€A’;adlibtracker2-2.4.23/package/instr/bass5.fin0000644000000000000000000000006213176573532017270 0ustar rootrootBASS5.FIN Bass ÿÿadlibtracker2-2.4.23/package/instr/contra2.sbi0000644000000000000000000000006413176573532017626 0ustar rootrootSBIcontra2.sbi”ƒ¶&adlibtracker2-2.4.23/package/instr/brush2.sbi0000644000000000000000000000006413176573532017463 0ustar rootrootSBIbrush2.sbiÞ~€Á‡‘çadlibtracker2-2.4.23/package/instr/cool.sgi0000644000000000000000000000003213176573532017212 0ustar rootrootadlibtracker2-2.4.23/package/instr/gun2.sgi0000644000000000000000000000003213176573532017131 0ustar rootrootadlibtracker2-2.4.23/package/instr/trombone.sbi0000644000000000000000000000006413176573532020103 0ustar rootrootSBItrombone.sbi!¡€SR; adlibtracker2-2.4.23/package/instr/guit2.fin0000644000000000000000000000006213176573532017305 0ustar rootrootGUIT2.FIN Guitarko AQõóÿ adlibtracker2-2.4.23/package/instr/v42.sgi0000644000000000000000000000003213176573532016671 0ustar rootroot  adlibtracker2-2.4.23/package/instr/claps1.sbi0000644000000000000000000000006413176573532017441 0ustar rootrootSBIclaps1.sbiñrçÿÿadlibtracker2-2.4.23/package/instr/tuba3.sbi0000644000000000000000000000006413176573532017274 0ustar rootrootSBItuba3.sbiRsevadlibtracker2-2.4.23/package/instr/sitar2.sbi0000644000000000000000000000006413176573532017462 0ustar rootrootSBIsitar2.sbi@@ññSSadlibtracker2-2.4.23/package/instr/eguitar4.sgi0000644000000000000000000000003213176573532020002 0ustar rootroot  adlibtracker2-2.4.23/package/instr/leen4.cif0000644000000000000000000000006413176573532017251 0ustar rootrootbrRQleen4.cifadlibtracker2-2.4.23/package/instr/trumpet4.sbi0000644000000000000000000000006413176573532020042 0ustar rootrootSBItrumpet4.sbi1¡€A’ ; adlibtracker2-2.4.23/package/instr/epicbell.cif0000644000000000000000000000006413176573532020021 0ustar rootroot%€ˆôû"epicbell.cifadlibtracker2-2.4.23/package/instr/dune.sgi0000644000000000000000000000003213176573532017211 0ustar rootroot  adlibtracker2-2.4.23/package/instr/dan.sgi0000644000000000000000000000003213176573532017020 0ustar rootroot adlibtracker2-2.4.23/package/instr/syntom.cif0000644000000000000000000000006413176573532017573 0ustar rootrootäâ÷öösyntom.cifadlibtracker2-2.4.23/package/instr/dot.sgi0000644000000000000000000000003213176573532017044 0ustar rootroot adlibtracker2-2.4.23/package/instr/tom2.sbi0000644000000000000000000000006413176573532017137 0ustar rootrootSBItom2.sbi0Èà—@adlibtracker2-2.4.23/package/instr/elorgan1.sbi0000644000000000000000000000006413176573532017766 0ustar rootrootSBIelorgan1.sbirqÍ€‘‘**adlibtracker2-2.4.23/package/instr/deepdapb.cif0000644000000000000000000000006413176573532020006 0ustar rootrootÄÂööÿÿdeepdapb.cifadlibtracker2-2.4.23/package/instr/tech2.sgi0000644000000000000000000000003213176573532017263 0ustar rootroot adlibtracker2-2.4.23/package/instr/phone2.sbi0000644000000000000000000000006413176573532017451 0ustar rootrootSBIphone2.sbiO òña´adlibtracker2-2.4.23/package/instr/xylofone.sbi0000644000000000000000000000006413176573532020121 0ustar rootrootSBIxylofone.sbi1-Èõ/õ adlibtracker2-2.4.23/package/instr/synsnr1.sbi0000644000000000000000000000006413176573532017673 0ustar rootrootSBIsynsnr1.sbiðøð¶adlibtracker2-2.4.23/package/instr/bass4.cif0000644000000000000000000000006413176573532017256 0ustar rootroot@ETñSSbass4.cifadlibtracker2-2.4.23/package/instr/strings2.sgi0000644000000000000000000000003213176573532020031 0ustar rootroot  adlibtracker2-2.4.23/package/instr/violin3.sbi0000644000000000000000000000006413176573532017641 0ustar rootrootSBIviolin3.sbiá"ˆƒdS),adlibtracker2-2.4.23/package/instr/string2.cif0000644000000000000000000000006413176573532017632 0ustar rootrootæÂDf÷%string2.cifadlibtracker2-2.4.23/package/instr/bassharp.sbi0000644000000000000000000000006413176573532020061 0ustar rootrootSBIbassharp.sbiÀmùòsadlibtracker2-2.4.23/package/instr/blob.sgi0000644000000000000000000000003213176573532017174 0ustar rootrootadlibtracker2-2.4.23/package/instr/flute1.sbi0000644000000000000000000000006413176573532017456 0ustar rootrootSBIflute1.sbiaa'€te*adlibtracker2-2.4.23/package/instr/ebass.sgi0000644000000000000000000000003213176573532017353 0ustar rootroot    adlibtracker2-2.4.23/package/instr/acidbass.sgi0000644000000000000000000000003213176573532020027 0ustar rootrootadlibtracker2-2.4.23/package/instr/laser.sgi0000644000000000000000000000003213176573532017364 0ustar rootroot adlibtracker2-2.4.23/package/instr/solovln.sbi0000644000000000000000000000006413176573532017752 0ustar rootrootSBIsolovln.sbi° QTgadlibtracker2-2.4.23/package/instr/flute.cif0000644000000000000000000000006413176573532017361 0ustar rootrootâÄ V6ö÷flute.cifadlibtracker2-2.4.23/package/instr/fight.sgi0000644000000000000000000000003213176573532017357 0ustar rootrootadlibtracker2-2.4.23/package/instr/bpiano.sbi0000644000000000000000000000006413176573532017526 0ustar rootrootSBIbpiano.sbiLóÔ |adlibtracker2-2.4.23/package/instr/fifths.fin0000644000000000000000000000006213176573532017536 0ustar rootrootFIFTHS.FIN Fifths echo õô¢adlibtracker2-2.4.23/package/instr/synbass1.sbi0000644000000000000000000000006413176573532020021 0ustar rootrootSBIsynbass1.sbi0±ˆ€Õa adlibtracker2-2.4.23/package/instr/base3.cif0000644000000000000000000000006413176573532017237 0ustar rootroot2Dõøÿbase3.cifadlibtracker2-2.4.23/package/instr/lostinsp.sgi0000644000000000000000000000003213176573532020131 0ustar rootroot  adlibtracker2-2.4.23/package/instr/celpiano.sbi0000644000000000000000000000006413176573532020050 0ustar rootrootSBIcelpiano.sbi"òõCadlibtracker2-2.4.23/package/instr/syn4.cif0000644000000000000000000000006413176573532017137 0ustar rootroot(T‘syn4.cifadlibtracker2-2.4.23/package/instr/sunrise2.sgi0000644000000000000000000000003213176573532020030 0ustar rootroot adlibtracker2-2.4.23/package/instr/syn3.sbi0000644000000000000000000000006413176573532017152 0ustar rootrootSBIsyn3.sbiŠ@ññ³adlibtracker2-2.4.23/package/instr/bdrum2.sbi0000644000000000000000000000006413176573532017451 0ustar rootrootSBIbdrum2.sbi Èðïßadlibtracker2-2.4.23/package/instr/organ1.sbi0000644000000000000000000000006413176573532017445 0ustar rootrootSBIorgan1.sbi¥±Ò€ñadlibtracker2-2.4.23/package/instr/basedrum.sgi0000644000000000000000000000003213176573532020060 0ustar rootrootadlibtracker2-2.4.23/package/instr/cbanjo.sbi0000644000000000000000000000006413176573532017512 0ustar rootrootSBIcbanjo.sbi1‡…¡}Cadlibtracker2-2.4.23/package/instr/harp3.sbi0000644000000000000000000000006413176573532017273 0ustar rootrootSBIharp3.sbiW€õöVTadlibtracker2-2.4.23/package/instr/bguit.sbi0000644000000000000000000000006413176573532017370 0ustar rootrootSBIbguit.sbi!£ÄT2 adlibtracker2-2.4.23/package/instr/sdrum2.sbi0000644000000000000000000000006413176573532017472 0ustar rootrootSBIsdrum2.sbiðöð´adlibtracker2-2.4.23/package/instr/knock.cif0000644000000000000000000000006413176573532017347 0ustar rootrootÚú¿¿knock.cifadlibtracker2-2.4.23/package/instr/tensax3.sbi0000644000000000000000000000006413176573532017643 0ustar rootrootSBItensax3.sbiP‘RqRf‹adlibtracker2-2.4.23/package/instr/harpsi2.sbi0000644000000000000000000000006413176573532017626 0ustar rootrootSBIharpsi2.sbi3‡€¡}Cadlibtracker2-2.4.23/package/instr/dipp2.cif0000644000000000000000000000006413176573532017260 0ustar rootrootââXöòõô dipp2.cifadlibtracker2-2.4.23/package/instr/blast.sbi0000644000000000000000000000006413176573532017363 0ustar rootrootSBIblast.sbiÿÿadlibtracker2-2.4.23/package/instr/brass.sgi0000644000000000000000000000003213176573532017370 0ustar rootrootadlibtracker2-2.4.23/package/instr/belguit2.sbi0000644000000000000000000000006413176573532017773 0ustar rootrootSBIbelguit2.sbi”€ÿÿ! adlibtracker2-2.4.23/package/instr/syn3.cif0000644000000000000000000000006413176573532017136 0ustar rootrootSs+7Isyn3.cifadlibtracker2-2.4.23/package/instr/keybrd2.sbi0000644000000000000000000000006413176573532017620 0ustar rootrootSBIkeybrd2.sbi€ò‚½½adlibtracker2-2.4.23/package/instr/fifth.fin0000644000000000000000000000006213176573532017353 0ustar rootrootFIFTH.FIN Fifths õô£adlibtracker2-2.4.23/package/instr/shaker.cif0000644000000000000000000000006413176573532017517 0ustar rootrootÍÌYðlðshaker.cifadlibtracker2-2.4.23/package/instr/galaxy3.sgi0000644000000000000000000000003213176573532017626 0ustar rootroot  adlibtracker2-2.4.23/package/instr/scratch.sbi0000644000000000000000000000006413176573532017705 0ustar rootrootSBIscratch.sbið\ðÜadlibtracker2-2.4.23/package/instr/cello2.sbi0000644000000000000000000000006413176573532017436 0ustar rootrootSBIcello2.sbippÅ„R1þadlibtracker2-2.4.23/package/instr/sftfl2.sbi0000644000000000000000000000006413176573532017456 0ustar rootrootSBIsftfl2.sbiæã'p`Ÿ adlibtracker2-2.4.23/package/instr/violin.sbi0000644000000000000000000000006413176573532017556 0ustar rootrootSBIviolin.sbirbQRadlibtracker2-2.4.23/package/instr/accordn.sbi0000644000000000000000000000006413176573532017667 0ustar rootrootSBIaccordn.sbi$1OòR adlibtracker2-2.4.23/package/instr/bdrum.sbi0000644000000000000000000000006413176573532017367 0ustar rootrootSBIbdrum ¨ÖLOadlibtracker2-2.4.23/package/instr/luola.sbi0000644000000000000000000000006413176573532017372 0ustar rootrootSBIluola.sbiÊÌ„ðYðb adlibtracker2-2.4.23/package/instr/bell.ins0000644000000000000000000000001413176573532017203 0ustar rootrootaâõõòô adlibtracker2-2.4.23/package/instr/jazzbass.sbi0000644000000000000000000000006413176573532020105 0ustar rootrootSBIjazzbass.sbi !@{õr adlibtracker2-2.4.23/package/instr/cymbal.sbi0000644000000000000000000000006413176573532017525 0ustar rootrootSBIcymbal.sbid@²—¢Ôadlibtracker2-2.4.23/package/instr/tom1.sbi0000644000000000000000000000006413176573532017136 0ustar rootrootSBItom1.sbi÷ÖµOadlibtracker2-2.4.23/package/instr/fuzguit2.sbi0000644000000000000000000000006413176573532020035 0ustar rootrootSBIfuzguit2.sbi12HñòS'adlibtracker2-2.4.23/package/instr/$mlfbank.bnk0000644000000000000000000017603413176573532017744 0ustar rootrootADLIB-ñH9AAHSAALTOABRSS1ACCDN001ACCORDNßACGPIANOACGUIT1ACGUIT1AACGUIT2¯ACOUBASSKACOUBS1LACOUBS2"ACOUPNO1#ACOUPNO2$ACOUPNO3íACOUSTAACOUSTIàACPIANOADLIB*AGOGO@AGUITARALIEN1 ALIEN1AÿALTOSAX ALTOVIO2 ALTOVIOL APPLAUSE ART1 ART2ART3ART4ART5’ATMOSPHRB1B10B11B12B13B2B3B4B5B6B7B8B9'BAGPIPEBAGPIPE1BAGPIPE2 BAMBA#BANJO!BANJO1"BANKMNGBARISAXåBARORGAN#BASBNC01$BASELC01%BASELC02&BASFLP01'BASFLUT2(BASFLUT3)BASFLUT4*BASFNY01+BASJAZ01,BASJAZ02-BASLON01.BASNOR01/BASNOR020BASNOR031BASNOR042BASPOP013BASPOP024BASREED25BASS6BASS-POP7BASS0018BASS0029BASS003:BASS004;BASS005<BASS006=BASS1>BASS1A?BASS2@BASS3ABASS4BBASS5CBASSBEL2DBASSBELLkBASSDRM¾BASSDRM1¿BASSDRM2ÀBASSDRM3ÔBASSDRM6ÕBASSDRM7EBASSDRN1FBASSDRN2GBASSDRN3HBASSDRN4IBASSFLUT×BASSFUNJBASSGTRKBASSGTR2LBASSGUITMBASSHARPBASSOONNBASSOON1‚BASSOON2OBASSREEDPBASSSYN1QBASSTRLGRBASSVIOLSBASSVLN2TBASYKA01UBBELL2VBCKWRD1WBDRUMXBDRUM0YBDRUM1ZBDRUM1A[BDRUM2\BDRUM2A]BDRUM3^BDRUM4_BDRUM5`BDRUM8aBELLONGéBELLORGbBELLScBELLS1dBELLS2eBELLS3ABELLSINGßBELLYfBELSHORTÃBIGBOTTM·BIGHORNlBIRDTWTgBITEME1hBLIPP1iBLIPP1AjBLIPP2kBLIPP3lBLIPP3AmBLURB1nBLURB1AoBLURB2pBLURB3qBLURB4rBNCEBASSsBOING‘BONGtBOOMDRUMbBOTTLBLOBOTTLEuBOTTLE1vBOTTLE1A‹BOWGLASSwBRASS01xBRASS02yBRASS03zBRASS1{BRASS2|BRASS4}BRASS5µBRASSECT·BRASSOFTÔBRASSYžBRDTWEET1BREATHcBREATHPP“BRIGHTˆBRSS&LD~BRSS1A[BRSSECT1\BRSSECT2¶BRTGUITRBRUSH01€BRUSH02BRUSH03‚BRUSH04ƒBRUSH1„BRUSH2…BRUSHES†BRUSHES2‡BSSN-KˆBSYSGNL‰CACOPH1ŠCACOPH1AƒCALLIOPE‹CASTANETŒCBASSOONCBBSN-KŽCELESTA3CELESTA1CELESTA2CELLO‘CELLO#1’CELLO#2GCELLO1“CELLO2…CHARANG0CHICKEN”CHICKEN1•CHICKEN2„CHIFF–CHIFF1—CHIFF2˜CHIFF2A™CHIFF2BšCHIFF2C›CHIFF3œCHIFF3ACHIFF4žCHIFF5ŸCHIFF6 CHIFF6A¡CHIFF6B¢CHIFF6C£CHIFF7¤CHIFF7AÎCHIFFER¥CHIME¦CHINA1§CHINA1A¨CHIRP©CHIRPY1tCHOIRŠCHOIRPAD8CHORALE_CHORSPNOüCHORUS’CJC“CJCIIªCKNX1«CKNX2¬CKNX3­CKNX4®CKNX5¯CLAPPING°CLAR003±CLAR1²CLAR1A³CLAR2´CLARINETVCLARINT1WCLARINT2ƒCLARINT3„CLARINT4…CLARINT5µCLARION†CLARSUSTµCLAVECIN0CLAVI11CLAVI22CLAVI3äCLAVICHDaCLAVINET¶CLICKâCLOOP·CLRNOR01¸CLRNOR02¹CLRNOR03ºCLRNOR04»CLRNT-K¼CLVELC01½CLVELC02¾CLVELC03¿CLVNOR01ÀCOMPUT1öCONTRAîCONTRA1ÁCONTRA2ÂCONTRABHCONTRABSÃCOOLPHN1ÄCRAZY2ÅCRAZYSNDÆCROMORNE4CROWDÇCRUNCHY1ÈCRUNCHY2ÉCRUNCHY3‘CRYSTAL”CUNÊCYMB10LËCYMB10MÌCYMB10SÍCYMB10SSÎCYMBALÏCYMBAL0ÐCYMBAL1ÑCYMBAL10ÒCYMBAL1AÓCYMBAL2ÔCYMBAL3ÕCYMBAL4ÖCYMBAL5×CYMBAL6ØCYMBAL7ÙCYMBAL8ÚCYMBAL9ÛCYMBALAXÜCYMBL2ÝCYMCRASHÞCYMCRSH1ßCYMRIDE8DBLBASS‡DBLREEDˆDBLREED1àDBLREED2‰DBLREED3ŠDBLREED4‹DBLREED5dDEEPSNARáDEMO•DIR¹DIRTYmDISTGTR¾DISTGTR1¿DISTGTR2–DISTORS1—DM1˜DM2BDOCGUIT1CDOCGUIT2DDOCGUIT3EDOCGUTFZFDOCGUTL1GDOCGUTL2HDOCGUTL3sDOCORG1tDOCORG2uDOCORG3vDOCORG4?DOCSOLOØDOCSYN3ÙDOCSYNMÚDOCSYNM2âDOCTOR1ãDOCTOR1AäDOCTOR1BåDOCTOR2æDOCTOR2AçDOCTOR2BèDOCTOR2CéDOG1êDOG1AëDOG1CìDOG1DíDOLPHIN1îDOLPHIN2ïDOLPHIN3æDPNOSST±DRAGFLYðDRIPñDRMELC01òDRMELC02óDRMLOG01ôDRMMLT01õDRMPWR01öDRONE1÷DRONE1AøDRONE2ùDRONE3úDRONE4óDTGUITARdDULCIMERûECHIMESüECHOBASS<ECHOBELL•ECHOESÙECHOFAIRýECHOGUIT>ECHOPANþEG1ÿEG2EG3EG4EG5EG6IEGUITAR0JEGUITAR1KEGUITAR2LEGUITAR3MEGUITAR4NEGUITAR5OEGUITAR6PEGUITAR7QEGUITAR8REGUITAR9ELBANJO1ELBASS1ELBASS2ELBASS8wELCFLUT1xELCFLUT2ELCLAV1 ELCLAV2 ELCLAV3 ELDRUM1 ELDRUM2°ELECBASSMELECBS1NELECBS2 ELECFLELECFL2jELECGTRIELECGTR1JELECGTR2)ELECORG1*ELECORG2+ELECORG3,ELECORG4%ELECPNO1&ELECPNO2'ELECPNO3(ELECPNO4ELECVIBEðELGMUTEáELGPIANOSELGT1LSELGUITELGUIT1ELGUIT10ELGUIT11ELGUIT1AELGUIT1BELGUIT1CELGUIT2ELGUIT3ELGUIT4ELGUIT5ELGUIT6ELGUIT7ELGUIT9ïELGUITARELORGAN1ELORGAN2\ELPIANO ELPIANO1!ELPIANO2"ELPIANO3XENGHORN#ENGHRN-KENGLHORN$ENGLHRN1%ENGLHRN2&EPIANO1A'EPIANO1B(ETHEREAL)ETHNIC)EXCELSTR*EXP1+EXP2,EXP3™EXPLODE1-FANTAPAN6FANTASY.FANTPAN2/FHORN(FIDDLE‡FIFTHS0FIFTHTN1FISH#12FISH#1A3FLAPBAS4FLTELC015FLTELC026FLTNOR017FLTNOR028FLTNOR039FLTNOR04:FLTNOR05ÍFLUBBER;FLUTE<FLUTE001=FLUTE002>FLUTE009?FLUTE1@FLUTE1AAFLUTE2BFLUTE3yFLUTE3AzFLUTE4{FLUTE5|FLUTE6}FLUTE7~FLUTE8CFLUTE9FLUTELDFLUTESAXoFNGRBASSEFRED1FFRED1A²FRETLESSQFRETLS1RFRETLS2zFRHORNGFRHORN1HFRHORN2IFRHRN-KJFSTRP1KFSTRP1ALFSTRP2MFUNKORGNNFUNKYOFUNNYBAS;FUNNYVOXPFUZ13LQFUZ13MRFUZ13SSFUZGUI12TFUZGUIT1UFUZGUIT2VFUZZBAS2WFUZZBAS3XFUZZBASSÝFUZZYBFX1FX2FX3FX4?FX4_ATMSFX5FX6 FX7!FX8YFZZBAZZ1šGANSEI9GLASSES¸GLOCKbGLOCKNSP”GOBLINSZGONG[GRANDPNO[GRATE1\GRATE2]GTRELC01^GTRELC02_GTRELC03`GTRELC04aGTRELC05bGTRELC06cGTRELC07dGTRELC08eGTRELC09fGTRELC10gGTRELC11hGTRELC12iGTRELC13jGTRELC14GTRFRETkGTRFUZ01lGTRFUZ02nGTRHARMmGTRHVY01nGTRHVY02oGTRHVY03pGTRHVY04qGTRJAZ02rGTRJAZZ0sGTRNOR01tGTRNOR02uGTRNOR03vGTRNOR04wGTRNOR05xGTRNOR06yGTRPIZ01zGTRPIZZ1{GTRSTL01|GTRSTL02}GTRSTL03~GTRSTL04GTRSUS01€GTVOLGUIT-SUS‚GUITARƒGUITAR1„GUITAR2…GUITAR3†GUITAR4‡GUITAR5ˆGUITAR6TGUITAR7UGUITARACVGUITDIS6GUITHARM‰GUITHIGHWGUITHVXGUITNOSEŠGUN1¡GUNSHOTHALOPADeHAMMOND‹HAND1ŒHANDBELLêHARMNICAHARMON1gHARMONCA7HARMOPANŽHARPHARP1HARP2‘HARP3’HARPE1ãHARPSCHD`HARPSI“HARPSI1”HARPSI1A•HARPSI1B–HARPSI2—HARPSI3˜HARPSI4™HARPSI5šHARTBEATèHEADYÚHEARTSTR›HELICOœHELICO1HELICO2žHELICO3ŸHELICPTR HELILOWÌHENHOUSE¡HHWAVE#1¢HHWAVE#2£HIHAT1¤HIHAT11¥HIHAT2¦HIHAT3§HIHAT4ÂHIHAT6ÃHIHAT7¨HONKTNK©HONKTNK2âHONKTONK]HONKYTNKªHORN1«HORN2¬HOTCYMB1­HRMCA-K®HRNENG01¯HRNENG02°HRNFR01±HRNFR02²HRNNOR01³HRNNOR02´HRPBAS01µHRPNOR01¶HRPNOR02·HRPNOR03¸HRPNOR04¹HRPNOR05ºHUMAN1»HUMAN2¼HUMAN3½HUMAN4¾HUMAN5¿HUMAN6òHVYMETALÀHVYMETL1ÁHVYMETL2ÂHVYMETL3ÃHVYMETL4ÄHVYMETL5YHVYMETL6ICERAINÅINSECTSÆINSTRMÇJAVAIC2ÈJAVAIC3ÉJAVAIC4ÊJAVAICA2ËJAVAICA3ÌJAVAICA4ÍJAVAICANiJAWHARPÎJAZGIT10ZJAZGUIT1ÏJAZGUIT2ÐJAZZBAS2ÑJAZZBASSîJAZZGTRÒJAZZGUITÓJAZZORGÔJET1ÕJET11AÖJET11B×JEWSHARPØJORGANnJUNGLTUN&KALIMBAÙKETTLE1ÚKEYBRD1ÛKEYBRD2ÜKEYBRD3ÝKEYBRD8ÞKEYBRD9ßKJM%KOTOàKOTO1áKUORSAU2âKUORSAUSãLASERäLASER1åLASER2 LEAD1 LEAD2 LEAD3 LEAD4LEAD5LEAD6LEAD7LEAD8æLEADGTRçLNGCYMBLèLNGSNAREéLOGDRUM1êLONGBASSëLOOSPRNGìLOVE30íLOVE31îLOVE32ïLOWðLOW001ñLOWSYN1òLOWSYN2óLOWSYN3ôLOWSYN4õLOWSYN5öLOWSYN6÷LOWSYN7øLOWSYN8ùLOWSYN9úLUOLAûMARIMB1A»MARIMBAüMARIMBA1ýMARIMBA2þMATTINSÿMDRNPHON.MELDRUM›MELODTOM¼MELOFLUTMEOWMEOW1MEOW1AMEOW2MEOW2AMEOW2BMERIMETAL1ŒMETALLICÆMETALSYNàMETLINGMGUN1 MGUN2 MGUN3 MIXTRE MLTRDRUM MNSYN1'MNSYN16'MNSYN2'MNSYN4'MNSYN8'ëMOHORNmMOOGSYN›MOOGSYN2œMOOGSYN3MOOGSYN4MOOGSYNTMOONMOTOR1MSUS01MSUS02yMTRUMPET¹MUSICBOXkMUTEDGTRMYINSMYSOUND1ÖNAVARROžNEW=NEWAGE¸NITESONGfNOISENOISE1NOISE1ANOISE2NOISE3NOISESYNNOTBIGìNYLONäNYLOONeOBERHEIMOBOEOBOE-K OBOE1!OBOE2=OBOE2001"OBOEV€OCARINA#OINKEE1$OINKEE23OINKEY%OLDPIA1&OLDSNAR:OOHSÖORCHjORCHEHITýORCHHIT'ORG10(ORG9ÄORGAN-B)ORGAN1*ORGAN101+ORGAN102,ORGAN103-ORGAN13.ORGAN2/ORGAN2A0ORGAN31ORGAN3A2ORGAN3B3ORGAN44ORGAN4A5ORGAN56ORGAN67ORGAN7oORGAN88ORGANASpORGANFDqORGANFD19ORGANKrORGANVL:ORGELC01;ORGNOR01<ORGNOR02=ORGNOR03>ORGNOR04?ORGNOR05@ORGNOR06AORGNOR07BORGNPERCCORGPEC01DORGPEDALñOVERDRIVlOVRDRGTRPAD1PAD2PAD3PAD4PAD5PAD6PAD7PAD8~PANFLUTE;PANPIPESÀPARLORGNfPERCORGNÜPHLASOREPHONE1FPHONE2GPHONE3ŸPHONE3A PHONE3B¡PHONE5HPHSHF1IPIAN1AJPIAN1BKPIAN1CLPIANOMPIANO1NPIANO10OPIANO11PPIANO1AQPIANO2RPIANO3SPIANO4ìPIANO64TPIANOBELUPIANOFVPIANOSUSWPICCOLOSPICCOLO1TPICCOLO2ÞPICKB±PICKBASSXPIG1YPINBEL01ZPINELC01[PINELC02\PINELC03]PINELC04^PINELC05_PINNOR01`PINNOR02aPINNOR03bPINNOR04cPINNOR05dPINNOR06ePINNOR07fPINNOR08gPINNOR09hPINNOR10iPINOLD01-PIPEORG1.PIPEORG2/PIPEORG3èPIPEORGNPIPESjPIPES1PIPES2÷PIZZsPIZZCATOFPIZZICTOkPLANE1lPLANE2mPLANE3nPLBASS1oPLIPH1‰POLYSNTHpPOPBASS1qPOPBASS2rPOPBASS3sPOPCORN1tPOWRDRUMæPRCORGANãPRCWOODuQBERT1vQBERT1AwQBERT1BxQBERT1CyQBERT1DzQBERT2{QWERTY1|QWERTY2áRAINY€RC1RECORDERéREEDORGN}REVCY#2~REVCYMBREVHHAT1€REVSNAR1REVVER1‚REVVER2^RHODESƒRIBIT„RIMSHOT…RKSNARE1çROCKORGN²RUDEBRSSçRUUBER¢S_SPI000£S_SPI001¤S_SPI002¥S_SPI003¦S_SPI004§S_SPI005¨S_SPI006©S_SPI007ªS_SPI008«S_SPI009¬S_SPI010­S_SPI011®S_SPI012¯S_SPI013°S_SPI014±S_SPI015²S_SPI016³S_SPI017´S_SPI018µS_SPI019¶S_SPI020·S_SPI021¸S_SPI022¹S_SPI023ºS_SPI024»S_SPI025¼S_SPI026½S_SPI027¾S_SPI028¿S_SPI029ÀS_SPI030ÁS_SPI031ÂS_SPI032ÃS_SPI033ÄS_SPI034ÅS_SPI035ÆS_SPI036ÇS_SPI037ÈS_SPI038ÉS_SPI039ÊS_SPI040ËS_SPI041ÌS_SPI042ÍS_SPI043ÎS_SPI044ÏS_SPI045ÐS_SPI046ÑS_SPI047ÒS_SPI048ÓS_SPI049ÔS_SPI050ÕS_SPI051ÖS_SPI052×S_SPI053ØS_SPI054ÙS_SPI055ÚS_SPI056ÛS_SPI057ÜS_SPI058ÝS_SPI059ÞS_SPI060ßS_SPI061àS_SPI062áS_SPI063âS_SPI064ãS_SPI065äS_SPI066åS_SPI067æS_SPI068çS_SPI069èS_SPI070éS_SPI071êS_SPI072ëS_SPI073ìS_SPI074íS_SPI075îS_SPI076ïS_SPI077ðS_SPI078ñS_SPI079òS_SPI080óS_SPI081ôS_SPI082õS_SPI083öS_SPI084÷S_SPI085øS_SPI086ùS_SPI087úS_SPI088ûS_SPI089üS_SPI090ýS_SPI091þS_SPI092ÿS_SPI093S_SPI094S_SPI095S_SPI096S_SPI097S_SPI098S_SPI099S_SPI100S_SPI101S_SPI102 S_SPI103 S_SPI104 S_SPI105 S_SPI106 S_SPI107S_SPI108S_SPI109S_SPI110S_SPI111S_SPI112S_SPI113S_SPI114S_SPI115S_SPI116S_SPI117S_SPI118S_SPI119S_SPI120S_SPI121S_SPI122S_SPI123S_SPI124S_SPI125 S_SPI126!S_SPI127‚SAWTOOTH†SAX1‡SAX11ˆSAX2‰SAX3USAX4ŠSAXNOR01‹SAXNOR02ŒSAXNOR03SAXNOR04ŽSAXTEN01SAXTEN02SAXTEN03‘SAXTEN04’SAXUNDERÅSAXXY“SBSYNTH°SBTIMBRE@SCHLDAZE–SCIFI”SCRATCH•SCRATCH4–SDROLD01—SDRRCK01˜SDRSUS01™SDRSYN01šSDRSYN02›SDRUM22SEASHOREœSEAWAVE1SEAWAVE2žSFTBRSS1ŸSFTFL2 SFTSTRNGŒSGLREEDSGLREED1ŽSGLREED2SGLREED3SGLREED4SHAKA<SHAKAHUSHAKUHCH$SHAMISEN—SHANAI¡SHIMMER1aSHO¢SHOCK1£SHOCK2¤SHOCK3¥SHOCK4¢SHORT£SHORT1¤SHORT2¥SHORT3¦SHORT4§SHORT5¨SHORT6ÂSHORTSYN5SHOT¦SHOT1§SHOT2¨SHPPIZZ©SHRTVIBEªSHUHP«SINEWV1¬SIREN1­SIREN2A®SIREN2B"SITAR¯SITAR1°SITAR2»SIXTIES7SLAP2pSLAPBAS1qSLAPBAS2³SLAPBASSOSLAPBS1PSLAPBS2êSLOCELLO©SMOOTH±SNAKEFL²SNARE1³SNARE10´SNARE2µSNARE3ÉSNARE4ÊSNARE5ÍSNARE6ÎSNARE7ÒSNARE8ÓSNARE9¶SNDRUM1·SNRSUST¸SOCE1ÐSOFTPAD¹SOFTPIZZ´SOFTRUMPºSOFTSAX»SOLOVLNþSOPRANO¼SOUNDA½SOUNDBSOUNDTRKÁSOUTHWNDíSPACBASS¾SPACE1¿SPACE1AÀSPACE1BÁSPACE1CÉSPACEBARÊSPACEFXÂSPASM1ÃSPBELLS1åSPCTDIST}SPRNOSAXSQUAREBSQWAVEÄSTANDARDÅSTEELD+STEELDRMÆSTEELGÇSTEELGT1ÈSTEELGT2ÉSTEELGT6ÊSTEELGT7iSTEELGTRËSTRBAS01ÌSTRING1ÍSTRING2ÎSTRING3ÏSTRING4ÐSTRING5ÑSTRING6ÒSTRING7ÓSTRINGS1ÔSTRINGS2ÕSTRINGYÖSTRLON01×STRLON02ºSTRLONGØSTRNG-KÙSTRNLON2ÚSTRNLONGÛSTRNOR01ÜSTRNOR02ÝSTRNOR03ùSTRSECTCSTRSECT1DSTRSECT2ESTRSECT3ÞSUDSY1ßSUDSY1AàSUDSY1BáSUDSY1CâSUDSY2ãSUDSY2AäSUDSY3åSURFŽSWEEPæSWINTH1çSWINTH2èSWINTH3éSWINTH4ØSWPIPORGêSYN1ëSYN10ìSYN12LíSYN12MîSYN12SïSYN12SSðSYN13ªSYN15ñSYN2òSYN3«SYN3AóSYN3SôSYN4õSYN5öSYN6÷SYN6AøSYN7ùSYN9úSYNBAL1ûSYNBAL2ÇSYNBARüSYNBAS01ýSYNBAS02þSYNBAS03ÿSYNBAS04SYNBAS05SYNBAS06SYNBAS07SYNBAS08SYNBASS1SYNBASS2SYNBASS3SYNBASS4SYNBASS5 SYNBASS6 SYNBASS8¶SYNBRASS{SYNBRSS1|SYNBRSS24SYNBRSS35SYNBRSS4_SYNMALLT SYNMOG01 SYNNOR01 SYNNOR02SYNNOR03SYNNOR04SYNNOR05SYNNOR06SYNNOR07SYNNOR08SYNNOR09SYNNOR10ÑSYNORCH½SYNPUNCH/SYNSNARSYNSNR1SYNSNR2úSYNSTR1ûSYNSTR2SYNT1SYNTH1SYNTH2¬SYNTH3­SYNTH4œSYNTHDRMvSYNVOICEÒSYNWHIZZ®T-PUPPY1¯T-PUPPY2T0-TAIDRUMgTAIKOšTAIKODRMhTAIKORIMëTANGOhTANGOACCTCA1TCD1ŸTELEPHONTENORSAXTENSAXTENSAX2 TENSAX3!TENSAX4"TEST1#TESTACC$TESTINSÈTHICKPADðTIMPøTIMPANI%TINCAN1&TING˜TINKLBEL'TLKBASS1(TLKBASS2)TMA1*TMD1+TOM1,TOM10-TOM11.TOM2/TOM30TOM41TOMTOM1ÇTOMTOM10ÈTOMTOM11ËTOMTOM12ÌTOMTOM13ÏTOMTOM14ÐTOMTOM15ÑTOMTOM16ÁTOMTOM6ÄTOMTOM7ÅTOMTOM8ÆTOMTOM9ÛTORTURE2TRAIN13TRAIN24TRAINBELrTREMOLO5TRIANGLE6TROFF17TROFF28TROMB19TROMB2:TROMB3YTROMBON1ZTROMBON2wTROMBONE;TROMBV<TRON1=TRON1A>TRON1B?TRPCUP1@TRUMPETATRUMPET1BTRUMPET2CTRUMPET3DTRUMPET4ETRUMPET5FTRUMPET6xTUBAGTUBA1HTUBA2ITUBA3½TUBEBELLJUFO1KUFO2ºVIBES]VIBES1^VIBES2³VIBPHONELVIBRA1MVIBRA2NVIBRA3cVIBRAPHNOVIBRELLSõVIOLAôVIOLINPVIOLIN1×VIOLIN1AQVIOLIN2RVIOLIN3ïVIOLIN4SVIOLIN8TVIOLIN9UVLN-KVVLNALT01WVLNALT02XVLNNOR01YVLNNOR02ZVLNNOR03[VLNNOR04\VLNNOR05]VLNPIZ01^VLNPIZZ1uVOICE†VOXLEAD_VOXSYNTH´WAABRASS:WARMBELL>WARMPAD`WASHMEaWASHME2bWASHME2AcWAVEdWAVE2eWEATHERfWEIRD1gWEIRD1AhWEIRD1BiWEIRD2jWHISTLEÛWHISTLE1kWHISTLE2ÜWHISTLE3lWHIZZO1mWHIZZO1AnWHIZZO1BoWHIZZO1CpWHIZZO1DqWHIZZO2rWHIZZO2AsWHIZZO2BtWHIZZO2CuWHIZZO2DvWHIZZO3wWIERD3xWIERD4`WINDBELLÏWINDBITEyWLKNGBSS WOODzWOOD1™WOODBLCK,WOODBLOCÕWOODYËWOOF{WOOFY1|WOOFY1A}WOOFY1B~WRDBASSWUZZLE1€WUZZLE1AWUZZLE1B‚WUZZLE1CƒWUZZLE1D„WUZZLE1E…WUZZLE1F†WUZZLE1G‡WUZZLE1HˆWUZZLE1I‰WUZZLE1JŠWUZZLE1K‹WUZZLE1LŒWUZZLE1MWUZZLE1NŽWUZZLE1OWUZZLE2WUZZLE2A‘WUZZLE2B’WUZZLE2C“WUZZLE2D”WUZZLE3•WUZZLE3A–WUZZLE3B—WUZZLE3C˜WUZZLE3D™WUZZLE3EšWUZZLE3F›WUZZLE3GœWUZZLE3HWUZZLE3IžWUZZLE3JÓWUZZYÝXYLOŸXYLO1 XYLO2¡XYLO3¼XYLOPHON¢YKABASS1ÞYKABASS2£YS1¤ZOINKS1¥ZOINKS1A¦ZOINKS1B§ZOINKS2¨ZOINKS2A©ZORF1ªZORF1A«ZORF1B¬ZORF1C­ZORF1D®ZORF1Eñòóôõö÷øùúûüýþÿ  8   (          4y                         #  #        *                         -                                                                    ?        ?        '                    .                                         ?    ?      ?   ?   <    ? <   <)   <A<   ?   ?     ?  ?       ?                                     2   ?         #  #  #             -                           ?        "    #  # #                      -  ' , '   '  , '                                                                                    !    ))                       ?    <   '     <  <   <          ? #  #            -'))                                                                                !   !      2        !         5                                          #  &                " #    #  &                   ?        ?     ?                            !  8  '           ?      <    < 5   #                        !                                                                                              ??????                ????    ? ?                   ,                      3                                                                  -                               "         )  *  ; =     <   <  C J  9  I  D  *  *<  < @  4  0  5   H  !  C  !  ?(N   <>A'                                             %                      - ,                                           !                                       #  3  $      '  '                                          & , +          !       %  +                !                                                                                     '                                   ) )                                                                                                      5                                                                                   '                                                                                                             1   #    *  # 8                #            #                              #)                               ,                     '                                       % adlibtracker2-2.4.23/package/instr/triangle.sgi0000644000000000000000000000003213176573532020063 0ustar rootroot   adlibtracker2-2.4.23/package/instr/basesyn.cif0000644000000000000000000000006413176573532017706 0ustar rootroot$@Õµ…Tbasesyn.cifadlibtracker2-2.4.23/package/instr/synbass2.sbi0000644000000000000000000000006413176573532020022 0ustar rootrootSBIsynbass2.sbiA†e2t adlibtracker2-2.4.23/package/instr/epiano1b.sbi0000644000000000000000000000006413176573532017754 0ustar rootrootSBIepiano1b.sbiWõõúúadlibtracker2-2.4.23/package/instr/banjo.sbi0000644000000000000000000000006413176573532017347 0ustar rootrootSBIbanjo.sbi1‡€¡}Cadlibtracker2-2.4.23/package/instr/bass5.cif0000644000000000000000000000006413176573532017257 0ustar rootroot££bass5.cifadlibtracker2-2.4.23/package/instr/oboe1.sbi0000644000000000000000000000006413176573532017263 0ustar rootrootSBIoboe1.sbiq"Ån‹adlibtracker2-2.4.23/package/instr/bassoon.sbi0000644000000000000000000000006413176573532017722 0ustar rootrootSBIbassoon.sbi0±Í€Õa adlibtracker2-2.4.23/package/instr/pianof.sbi0000644000000000000000000000006413176573532017532 0ustar rootrootSBIpianof.sbiÏñòSƒadlibtracker2-2.4.23/package/instr/strings1.sbi0000644000000000000000000000006413176573532020030 0ustar rootrootSBIstrings1.sbiq¡‹@qBadlibtracker2-2.4.23/package/instr/upswing.sgi0000644000000000000000000000003213176573532017752 0ustar rootrootadlibtracker2-2.4.23/package/instr/bagpipe1.sbi0000644000000000000000000000006413176573532017746 0ustar rootrootSBIbagpipe1.sbi1"Cn‹ adlibtracker2-2.4.23/package/instr/beverly.sgi0000644000000000000000000000003213176573532017726 0ustar rootrootadlibtracker2-2.4.23/package/instr/bim.cif0000644000000000000000000000006413176573532017011 0ustar rootroot!*õòˆ bim.cifadlibtracker2-2.4.23/package/instr/terzm.sgi0000644000000000000000000000003213176573532017417 0ustar rootrootadlibtracker2-2.4.23/package/instr/shppizz.sbi0000644000000000000000000000006413176573532017765 0ustar rootrootSBIshppizz.sbiâpF€ø÷óóadlibtracker2-2.4.23/package/instr/cbassoon.sbi0000644000000000000000000000006413176573532020065 0ustar rootrootSBIcbassoon.sbi01Å€R1.adlibtracker2-2.4.23/package/instr/piccolo.sbi0000644000000000000000000000006413176573532017706 0ustar rootrootSBIpiccolo.sbiääp`Ÿ adlibtracker2-2.4.23/package/instr/base.cif0000644000000000000000000000006413176573532017154 0ustar rootrootÀàö¨øXbase.cifadlibtracker2-2.4.23/package/instr/harmonca.sbi0000644000000000000000000000006413176573532020046 0ustar rootrootSBIharmonca.sbi"ò@Aaadlibtracker2-2.4.23/package/instr/galaxy3v.sgi0000644000000000000000000000003213176573532020014 0ustar rootroot  adlibtracker2-2.4.23/package/instr/moon.sbi0000644000000000000000000000006413176573532017226 0ustar rootrootSBImoon.sbi†€ò ½›adlibtracker2-2.4.23/package/instr/celpno2.sbi0000644000000000000000000000006413176573532017620 0ustar rootrootSBIcelpno2.sbi" òõ$Dadlibtracker2-2.4.23/package/instr/harpsi4.sbi0000644000000000000000000000006413176573532017630 0ustar rootrootSBIharpsi4.sbi òò± adlibtracker2-2.4.23/package/instr/dragbass.sgi0000644000000000000000000000003213176573532020044 0ustar rootrootadlibtracker2-2.4.23/package/instr/loop.cif0000644000000000000000000000006413176573532017213 0ustar rootroot!!qž®loop.cifadlibtracker2-2.4.23/package/instr/geige.sgi0000644000000000000000000000003213176573532017336 0ustar rootrootadlibtracker2-2.4.23/package/instr/tuba2.sgi0000644000000000000000000000003213176573532017273 0ustar rootrootadlibtracker2-2.4.23/package/instr/pzzicato.sgi0000644000000000000000000000003213176573532020121 0ustar rootroot adlibtracker2-2.4.23/package/instr/syn5.sbi0000644000000000000000000000006413176573532017154 0ustar rootrootSBIsyn5.sbiOqRS|adlibtracker2-2.4.23/package/instr/bdrum.ins0000644000000000000000000000001413176573532017376 0ustar rootrootàÀ¨öXøadlibtracker2-2.4.23/package/instr/ebass-l.sgi0000644000000000000000000000003213176573532017604 0ustar rootroot  adlibtracker2-2.4.23/package/instr/future.sgi0000644000000000000000000000003213176573532017570 0ustar rootrootadlibtracker2-2.4.23/package/instr/briss5.sgi0000644000000000000000000000003213176573532017465 0ustar rootroot adlibtracker2-2.4.23/package/instr/tom.sbi0000644000000000000000000000006413176573532017055 0ustar rootrootSBItom.sbiúÚ¿¿adlibtracker2-2.4.23/package/instr/harpe1.sbi0000644000000000000000000000006413176573532017436 0ustar rootrootSBIharpe1.sbi)õòuóadlibtracker2-2.4.23/package/instr/gpb.sgi0000644000000000000000000000003213176573532017026 0ustar rootroot  adlibtracker2-2.4.23/package/instr/snakefl.sbi0000644000000000000000000000006413176573532017701 0ustar rootrootSBIsnakefl.sbi¡± €a adlibtracker2-2.4.23/package/instr/notbig.sbi0000644000000000000000000000006413176573532017540 0ustar rootrootSBInotbig.sbi°µ5Žû ð›adlibtracker2-2.4.23/package/instr/3klang2.sgi0000644000000000000000000000003213176573532017517 0ustar rootrootadlibtracker2-2.4.23/package/instr/seashore.sbi0000644000000000000000000000006413176573532020067 0ustar rootrootSBIseashore.sbi bTog>ÿÿadlibtracker2-2.4.23/package/instr/blip.cif0000644000000000000000000000006413176573532017170 0ustar rootrootÄÈ÷–a blip.cifadlibtracker2-2.4.23/package/instr/reverb2.sbi0000644000000000000000000000006413176573532017625 0ustar rootrootSBIreverb2.sbi ¯?adlibtracker2-2.4.23/package/instr/marimba1.sbi0000644000000000000000000000006413176573532017747 0ustar rootrootSBImarimba1.sbiNÚù% adlibtracker2-2.4.23/package/instr/string1.cif0000644000000000000000000000006413176573532017631 0ustar rootrootB@=string1.cifadlibtracker2-2.4.23/package/instr/bell.sgi0000644000000000000000000000003213176573532017174 0ustar rootroot adlibtracker2-2.4.23/package/instr/englhrn1.sbi0000644000000000000000000000006413176573532017774 0ustar rootrootSBIenglhrn1.sbiáä#q‚®ž adlibtracker2-2.4.23/package/instr/sweep.sbi0000644000000000000000000000006413176573532017401 0ustar rootrootSBIsweep.sbi¡! a÷o÷=ÿÿadlibtracker2-2.4.23/package/instr/slapbs1.sbi0000644000000000000000000000006413176573532017623 0ustar rootrootSBIslapbs1.sbióñöùo÷=ÿÿadlibtracker2-2.4.23/package/instr/technol.sgi0000644000000000000000000000003213176573532017712 0ustar rootrootadlibtracker2-2.4.23/package/instr/bassdrum.sgi0000644000000000000000000000003213176573532020076 0ustar rootroot adlibtracker2-2.4.23/package/instr/shrtvibe.sbi0000644000000000000000000000006413176573532020104 0ustar rootrootSBIshrtvibe.sbiäÀÿó?adlibtracker2-2.4.23/package/instr/synbal2.sbi0000644000000000000000000000006413176573532017630 0ustar rootrootSBIsynbal2.sbi(àèðadlibtracker2-2.4.23/package/instr/organ3a.sbi0000644000000000000000000000006413176573532017610 0ustar rootrootSBIorgan3a.sbi[ðð adlibtracker2-2.4.23/package/instr/piano4.sbi0000644000000000000000000000006413176573532017450 0ustar rootrootSBIpiano4.sbiMñÒ`{adlibtracker2-2.4.23/package/instr/keybrd3.sbi0000644000000000000000000000006413176573532017621 0ustar rootrootSBIkeybrd3.sbiäðóð6adlibtracker2-2.4.23/package/instr/basstrlg.sbi0000644000000000000000000000006413176573532020077 0ustar rootrootSBIbasstrlg.sbiÁàO±Stadlibtracker2-2.4.23/package/instr/funny.sgi0000644000000000000000000000003213176573532017415 0ustar rootrootadlibtracker2-2.4.23/package/instr/xylo1.sbi0000644000000000000000000000006413176573532017332 0ustar rootrootSBIxylo11-Èõ/õ adlibtracker2-2.4.23/package/instr/bassoon1.sbi0000644000000000000000000000006413176573532020003 0ustar rootrootSBIbassoon1.sbi0±È€Õa adlibtracker2-2.4.23/package/instr/bellsngr.sgi0000644000000000000000000000003213176573532020066 0ustar rootroot  adlibtracker2-2.4.23/package/instr/frhorn1.sbi0000644000000000000000000000006413176573532017635 0ustar rootrootSBIfrhorn1.sbi!!Ÿ€SªZ adlibtracker2-2.4.23/package/instr/harpsi5.sbi0000644000000000000000000000006413176573532017631 0ustar rootrootSBIharpsi5.sbi6‡€Š3adlibtracker2-2.4.23/package/instr/bass.ins0000644000000000000000000000001413176573532017215 0ustar rootroot` ót85 adlibtracker2-2.4.23/package/instr/leed2.cif0000644000000000000000000000006413176573532017235 0ustar rootrootbC²Åleed2.cifadlibtracker2-2.4.23/package/instr/dapbass.cif0000644000000000000000000000006413176573532017657 0ustar rootrootââö¦öödapbass.cifadlibtracker2-2.4.23/package/instr/celesta.sbi0000644000000000000000000000006413176573532017676 0ustar rootrootSBIcelesta.sbi“¶sbadlibtracker2-2.4.23/package/instr/woodbloc.fin0000644000000000000000000000006213176573532020063 0ustar rootrootWOODBLOC.FINWoodblock :QÎø†öadlibtracker2-2.4.23/package/instr/church.sgi0000644000000000000000000000003213176573532017532 0ustar rootrootadlibtracker2-2.4.23/package/instr/chirp.sbi0000644000000000000000000000006413176573532017363 0ustar rootrootSBIchirp.sbi .ð_ððadlibtracker2-2.4.23/package/instr/orgnperc.sbi0000644000000000000000000000006413176573532020075 0ustar rootrootSBIorgnperc.sbi øÖµOadlibtracker2-2.4.23/package/instr/snare2.cif0000644000000000000000000000006413176573532017434 0ustar rootrootdA—²Ô¢snare2.cifadlibtracker2-2.4.23/package/instr/alien2.sbi0000644000000000000000000000006413176573532017430 0ustar rootrootSBIalien2õÓOòó@Badlibtracker2-2.4.23/package/instr/tech.sgi0000644000000000000000000000003213176573532017201 0ustar rootroot adlibtracker2-2.4.23/package/instr/horn.cif0000644000000000000000000000006413176573532017210 0ustar rootroota1€’A; horn.cifadlibtracker2-2.4.23/package/instr/csynth.sbi0000644000000000000000000000006413176573532017566 0ustar rootrootSBIcsynth.sbiŠHññ³adlibtracker2-2.4.23/package/instr/jazzguit.sbi0000644000000000000000000000006413176573532020125 0ustar rootrootSBIjazzguit.sbi^…ÒQqadlibtracker2-2.4.23/package/instr/snare.ins0000644000000000000000000000001413176573532017375 0ustar rootrootÏàÅðö„øadlibtracker2-2.4.23/package/instr/elorgan4.sgi0000644000000000000000000000003213176573532017771 0ustar rootroot    adlibtracker2-2.4.23/package/instr/pian1b.sbi0000644000000000000000000000006413176573532017430 0ustar rootrootSBIpian1b.sbi&õõúúadlibtracker2-2.4.23/package/instr/mhihat.fin0000644000000000000000000000006213176573532017525 0ustar rootrootMHIHAT.FIN MetalHihat ·¥ adlibtracker2-2.4.23/package/instr/kupfer.cif0000644000000000000000000000006413176573532017536 0ustar rootrootäÄu„÷÷kupfer.cifadlibtracker2-2.4.23/package/instr/syntbell.cif0000644000000000000000000000006413176573532020076 0ustar rootroot$‘¿Bsyntbell.cifadlibtracker2-2.4.23/package/instr/organ3b.sbi0000644000000000000000000000006413176573532017611 0ustar rootrootSBIorgan3b.sbi[’ðð adlibtracker2-2.4.23/package/instr/hihathi.sgi0000644000000000000000000000003213176573532017674 0ustar rootroot  adlibtracker2-2.4.23/package/instr/bass2.sbi0000644000000000000000000000006413176573532017270 0ustar rootrootSBIbass2.sbiòõïx adlibtracker2-2.4.23/package/instr/meri.sbi0000644000000000000000000000006413176573532017212 0ustar rootrootSBImeri.sbit@Áöadlibtracker2-2.4.23/package/instr/whistle.cif0000644000000000000000000000006413176573532017721 0ustar rootroot ‰ whistle.cifadlibtracker2-2.4.23/package/instr/fuzguit1.sbi0000644000000000000000000000006413176573532020034 0ustar rootrootSBIfuzguit1.sbiñ% —ñ adlibtracker2-2.4.23/package/instr/organ4.sbi0000644000000000000000000000006413176573532017450 0ustar rootrootSBIorgan4.sbi>±)€û ð›adlibtracker2-2.4.23/package/instr/synbass.sbi0000644000000000000000000000006413176573532017740 0ustar rootrootSBIsynbass.sbiA‘ƒe2t adlibtracker2-2.4.23/package/instr/pian1a.sbi0000644000000000000000000000006413176573532017427 0ustar rootrootSBIpian1a.sbiAc€óòXXadlibtracker2-2.4.23/package/instr/dungeon.sgi0000644000000000000000000000003213176573532017715 0ustar rootrootadlibtracker2-2.4.23/package/instr/pling.cif0000644000000000000000000000006413176573532017353 0ustar rootroot€èûÿÿ pling.cifadlibtracker2-2.4.23/package/instr/synbuz.sbi0000644000000000000000000000006413176573532017610 0ustar rootrootSBIsynbuz.sbióô9 adlibtracker2-2.4.23/package/instr/cello.sbi0000644000000000000000000000006413176573532017354 0ustar rootrootSBIcello.sbipqÅ€R1þadlibtracker2-2.4.23/package/instr/steelgt2.sbi0000644000000000000000000000006413176573532020007 0ustar rootrootSBIsteelgt2.sbi¡Gñ‘ƒ†adlibtracker2-2.4.23/package/instr/frhorn2.sbi0000644000000000000000000000006413176573532017636 0ustar rootrootSBIfrhorn2.sbi !Ž¥6=adlibtracker2-2.4.23/package/instr/ykabass1.sbi0000644000000000000000000000006413176573532017774 0ustar rootrootSBIykabass1.sbi@•ÿˆadlibtracker2-2.4.23/package/instr/marimba2.sbi0000644000000000000000000000006413176573532017750 0ustar rootrootSBImarimba2.sbiEAN€Úù adlibtracker2-2.4.23/package/instr/koto.sgi0000644000000000000000000000003213176573532017232 0ustar rootroot  adlibtracker2-2.4.23/package/instr/topcbl.sgi0000644000000000000000000000003213176573532017541 0ustar rootroot  adlibtracker2-2.4.23/package/instr/phone1.sbi0000644000000000000000000000006413176573532017450 0ustar rootrootSBIphone1.sbiOòña²adlibtracker2-2.4.23/package/instr/elguit2.sbi0000644000000000000000000000006413176573532017631 0ustar rootrootSBIelguit2.sbi–€ÿÿ! adlibtracker2-2.4.23/package/instr/cymbal1.sbi0000644000000000000000000000006413176573532017606 0ustar rootrootSBIcymbal1.sbiõÖµOadlibtracker2-2.4.23/package/instr/organ2.sbi0000644000000000000000000000006413176573532017446 0ustar rootrootSBIorgan2.sbi$!€€ÿÿadlibtracker2-2.4.23/package/instr/xylo2.sbi0000644000000000000000000000006413176573532017333 0ustar rootrootSBIxylo3.sbiÄÿøðµadlibtracker2-2.4.23/package/instr/trible.sgi0000644000000000000000000000003213176573532017537 0ustar rootrootadlibtracker2-2.4.23/package/instr/drum2.ins0000644000000000000000000000003313176573532017317 0ustar rootroot éêdrum2.insadlibtracker2-2.4.23/package/instr/cymbal2.sbi0000644000000000000000000000006413176573532017607 0ustar rootrootSBIcymbal2.sbi$@µÕT…adlibtracker2-2.4.23/package/instr/koto1.sbi0000644000000000000000000000006413176573532017313 0ustar rootrootSBIkoto1.sbi@ ÷S”adlibtracker2-2.4.23/package/instr/violin.ins0000644000000000000000000000001413176573532017565 0ustar rootrootBâdA^ÿadlibtracker2-2.4.23/package/instr/drum3.ins0000644000000000000000000000003313176573532017320 0ustar rootroot éödrum3.insadlibtracker2-2.4.23/package/instr/piffclap.sgi0000644000000000000000000000003213176573532020042 0ustar rootrootadlibtracker2-2.4.23/package/instr/cstacc.sbi0000644000000000000000000000006413176573532017516 0ustar rootrootSBIcstacc.sbi"òöu˜adlibtracker2-2.4.23/package/instr/piano2.sbi0000644000000000000000000000006413176573532017446 0ustar rootrootSBIpiano2.sbiòòQñadlibtracker2-2.4.23/package/instr/v42-2.sgi0000644000000000000000000000003213176573532017030 0ustar rootroot   adlibtracker2-2.4.23/package/instr/hihat2.sgi0000644000000000000000000000003213176573532017435 0ustar rootroot  adlibtracker2-2.4.23/package/instr/jungdrum.sgi0000644000000000000000000000003213176573532020111 0ustar rootrootadlibtracker2-2.4.23/package/instr/bcymbal.sbi0000644000000000000000000000006413176573532017667 0ustar rootrootSBIbcymbal.sbid@²—‚Ôadlibtracker2-2.4.23/package/instr/dot2.sgi0000644000000000000000000000003213176573532017126 0ustar rootroot adlibtracker2-2.4.23/package/instr/mars.sbi0000644000000000000000000000006413176573532017220 0ustar rootrootSBImars.sbiÅÙO1BSradlibtracker2-2.4.23/package/instr/organ3.sbi0000644000000000000000000000006413176573532017447 0ustar rootrootSBIorgan3.sbi[€ðð adlibtracker2-2.4.23/package/instr/chord.ins0000644000000000000000000000003313176573532017365 0ustar rootroot` ct85chord.insadlibtracker2-2.4.23/package/instr/bdrum3.sbi0000644000000000000000000000006413176573532017452 0ustar rootrootSBIbdrum3.sbi è¥ïÿadlibtracker2-2.4.23/package/instr/broguit.fin0000644000000000000000000000006213176573532017726 0ustar rootrootBROGUIT.FIN BrokGuitar Cŧò#adlibtracker2-2.4.23/package/instr/melody.cif0000644000000000000000000000006413176573532017533 0ustar rootroota²óú‹melody.cifadlibtracker2-2.4.23/package/instr/trumpet1.sbi0000644000000000000000000000006413176573532020037 0ustar rootrootSBItrumpet1.sbi1¡€A’ ;adlibtracker2-2.4.23/package/instr/string6.cif0000644000000000000000000000006413176573532017636 0ustar rootroot(A‘ústring6.cifadlibtracker2-2.4.23/package/instr/horror3.sgi0000644000000000000000000000003213176573532017654 0ustar rootroot adlibtracker2-2.4.23/package/instr/jewsharp.sbi0000644000000000000000000000006413176573532020101 0ustar rootrootSBIjewsharp.sbiPòòpradlibtracker2-2.4.23/package/instr/pipes.sbi0000644000000000000000000000006413176573532017376 0ustar rootrootSBIpipes.sbi¥±Ò€ñadlibtracker2-2.4.23/package/instr/tensax2.sbi0000644000000000000000000000006413176573532017642 0ustar rootrootSBItensax2.sbi‘OqR[{adlibtracker2-2.4.23/package/instr/hihat.ins0000644000000000000000000000001413176573532017362 0ustar rootroot vððadlibtracker2-2.4.23/package/instr/bass3.cif0000644000000000000000000000006413176573532017255 0ustar rootrootÁáõ¡õõbass3.cifadlibtracker2-2.4.23/package/instr/altovio2.sbi0000644000000000000000000000006413176573532020015 0ustar rootrootSBIaltovio2ðñЀR1þadlibtracker2-2.4.23/package/instr/clarinet.sbi0000644000000000000000000000006413176573532020057 0ustar rootrootSBIclarinet.sbi2¡€Q‚E adlibtracker2-2.4.23/package/instr/base.sgi0000644000000000000000000000003213176573533017171 0ustar rootrootadlibtracker2-2.4.23/package/instr/tamb_g.cif0000644000000000000000000000006413176573533017474 0ustar rootrootÇvñôôtamb_g.cifadlibtracker2-2.4.23/package/instr/syn2.cif0000644000000000000000000000006413176573533017136 0ustar rootrootÄá‘ÿósyn2.cifadlibtracker2-2.4.23/package/instr/laser.sbi0000644000000000000000000000006413176573533017365 0ustar rootrootSBIlaser.sbiæ0%ðµ@adlibtracker2-2.4.23/package/instr/coolbass.sgi0000644000000000000000000000003213176573533020064 0ustar rootrootadlibtracker2-2.4.23/package/instr/sitar.sbi0000644000000000000000000000006413176573533017401 0ustar rootrootSBIsitar.sbi@òòTEadlibtracker2-2.4.23/package/instr/clar2.sbi0000644000000000000000000000006413176573533017262 0ustar rootrootSBIclar2.sbi1 €AB; adlibtracker2-2.4.23/package/instr/tone.cif0000644000000000000000000000006413176573533017210 0ustar rootrootOÒñtStone.cifadlibtracker2-2.4.23/package/instr/synth1.sbi0000644000000000000000000000006413176573533017505 0ustar rootrootSBIsynth1.sbiŠ@ññ³adlibtracker2-2.4.23/package/instr/atari.sgi0000644000000000000000000000003213176573533017357 0ustar rootrootadlibtracker2-2.4.23/package/instr/harp1.sbi0000644000000000000000000000006413176573533017272 0ustar rootrootSBIharp1.sbi)ƒõòuóadlibtracker2-2.4.23/package/instr/bbass.sbi0000644000000000000000000000006413176573533017351 0ustar rootrootSBIbbass.sbi‘€ÿÿ! adlibtracker2-2.4.23/package/instr/crystal.sbi0000644000000000000000000000006413176573533017740 0ustar rootrootSBIcrystal.sbi×ÑMAóóÅäo?ÿÿadlibtracker2-2.4.23/package/instr/base3.sgi0000644000000000000000000000003213176573533017254 0ustar rootrootadlibtracker2-2.4.23/package/instr/hihat.cif0000644000000000000000000000006413176573533017340 0ustar rootrootàÏÀ—ðô„hihat.cifadlibtracker2-2.4.23/package/instr/eklavie.cif0000644000000000000000000000006413176573533017663 0ustar rootrootèâõ¤öö eklavie.cifadlibtracker2-2.4.23/package/instr/bells.cif0000644000000000000000000000006413176573533017344 0ustar rootroot‘ÿ€!ÿbells.cifadlibtracker2-2.4.23/package/instr/rksnare1.sbi0000644000000000000000000000006413176573533020005 0ustar rootrootSBIrksnare1.sbi ÐÇp´adlibtracker2-2.4.23/package/instr/eguitar.sgi0000644000000000000000000000003213176573533017717 0ustar rootrootadlibtracker2-2.4.23/package/instr/string3.cif0000644000000000000000000000006413176573533017634 0ustar rootroot(A‘üstring3.cifadlibtracker2-2.4.23/package/instr/start.fin0000644000000000000000000000006213176573533017411 0ustar rootrootSTART.FIN Startsound Iòòôö adlibtracker2-2.4.23/package/instr/noise1.sbi0000644000000000000000000000006413176573533017455 0ustar rootrootSBInoise1.sbi@ÑòSadlibtracker2-2.4.23/package/instr/space.cif0000644000000000000000000000006413176573533017336 0ustar rootroot#!‘#[xÈ2space.cifadlibtracker2-2.4.23/package/instr/eguitarl.sgi0000644000000000000000000000003213176573533020073 0ustar rootrootadlibtracker2-2.4.23/package/instr/bass1.sbi0000644000000000000000000000006413176573533017270 0ustar rootrootSBIbass1.sbi!€%e/l adlibtracker2-2.4.23/package/instr/xylo.cif0000644000000000000000000000006413176573533017236 0ustar rootrootNùÚ% xylo.cifadlibtracker2-2.4.23/package/instr/drumdown.sgi0000644000000000000000000000003213176573533020116 0ustar rootroot adlibtracker2-2.4.23/package/instr/string5.cif0000644000000000000000000000006413176573533017636 0ustar rootroot(A‘üstring5.cifadlibtracker2-2.4.23/package/instr/tomtom.sgi0000644000000000000000000000003213176573533017576 0ustar rootrootadlibtracker2-2.4.23/package/instr/basdr3.sbi0000644000000000000000000000006413176573533017435 0ustar rootrootSBIbasdr3.sbiA@ªú' adlibtracker2-2.4.23/package/instr/snare2.sbi0000644000000000000000000000006413176573533017451 0ustar rootrootSBIsnare2.sbi@@ Ìöadlibtracker2-2.4.23/package/instr/snare1.sbi0000644000000000000000000000006413176573533017450 0ustar rootrootSBIsnare1.sbi øÖµOadlibtracker2-2.4.23/package/instr/elpiano1.sbi0000644000000000000000000000006413176573533017767 0ustar rootrootSBIelpiano1.sbiOñÒP|adlibtracker2-2.4.23/package/instr/knarbass.cif0000644000000000000000000000006413176573533020047 0ustar rootrootââ òñöòknarbass.cifadlibtracker2-2.4.23/package/instr/deep.sgi0000644000000000000000000000003213176573533017174 0ustar rootrootadlibtracker2-2.4.23/package/instr/horror1.sgi0000644000000000000000000000003213176573533017653 0ustar rootroot adlibtracker2-2.4.23/package/instr/master.sgi0000644000000000000000000000003213176573533017552 0ustar rootrootadlibtracker2-2.4.23/package/instr/kupfer2.cif0000644000000000000000000000006413176573533017621 0ustar rootrootâäöô÷÷kupfer2.cifadlibtracker2-2.4.23/package/instr/strloop.fin0000644000000000000000000000006213176573533017756 0ustar rootrootSTRLOOP.FIN Strongloop a Só/"adlibtracker2-2.4.23/package/instr/trompet.cif0000644000000000000000000000006413176573533017735 0ustar rootroot1¡A€ ’;trompet.cifadlibtracker2-2.4.23/package/instr/fstrp1.sbi0000644000000000000000000000006413176573533017476 0ustar rootrootSBIfstrp1.sbiðà€U‡ïadlibtracker2-2.4.23/package/instr/kuorsau2.sbi0000644000000000000000000000006413176573533020032 0ustar rootrootSBIkuorsau2.sbipÖÄ€¤EBadlibtracker2-2.4.23/package/instr/zong.cif0000644000000000000000000000006413176573533017220 0ustar rootrootG@ÿÿzong.cifadlibtracker2-2.4.23/package/instr/brass2.sbi0000644000000000000000000000006413176573533017453 0ustar rootrootSBIbrass2.sbia`q®.adlibtracker2-2.4.23/package/instr/vlnpizz.sbi0000644000000000000000000000006413176573533017773 0ustar rootrootSBIvlnpizz.sbiòá@€õý¨­adlibtracker2-2.4.23/package/instr/trainbel.sbi0000644000000000000000000000006413176573533020057 0ustar rootrootSBItrainbel.sbiOòòatadlibtracker2-2.4.23/package/instr/trumpet.sbi0000644000000000000000000000006413176573533017757 0ustar rootrootSBItrumpet1¡€A’ ;adlibtracker2-2.4.23/package/instr/muteclav.sgi0000644000000000000000000000003213176573533020077 0ustar rootroot adlibtracker2-2.4.23/package/instr/eguittar.cif0000644000000000000000000000006413176573533020067 0ustar rootroot @EññSSeguittar.cifadlibtracker2-2.4.23/package/instr/wamm.cif0000644000000000000000000000006413176573533017204 0ustar rootrootâ ññö÷ wamm.cifadlibtracker2-2.4.23/package/instr/bell#2.ins0000644000000000000000000000001413176573533017331 0ustar rootrootaâõõòô adlibtracker2-2.4.23/package/instr/piano.sbi0000644000000000000000000000006413176573533017365 0ustar rootrootSBIpiano.sbi!Lñòcradlibtracker2-2.4.23/package/instr/alien.cif0000644000000000000000000000006413176573533017333 0ustar rootroot, þ##alien.cifadlibtracker2-2.4.23/package/instr/syn2.sbi0000644000000000000000000000006413176573533017152 0ustar rootrootSBIsyn2.sbi—€š›adlibtracker2-2.4.23/package/instr/briss6.sgi0000644000000000000000000000003213176573533017467 0ustar rootroot adlibtracker2-2.4.23/package/instr/cool.cif0000644000000000000000000000006413176573533017177 0ustar rootrootââô¤ööcool.cifadlibtracker2-2.4.23/package/instr/vol.sgi0000644000000000000000000000003213176573533017057 0ustar rootroot  adlibtracker2-2.4.23/package/instr/shrtbass.cif0000644000000000000000000000006413176573533020074 0ustar rootrootäâ÷¤ööshrtbass.cifadlibtracker2-2.4.23/package/instr/warp.sgi0000644000000000000000000000003213176573533017230 0ustar rootroot  adlibtracker2-2.4.23/package/instr/snrsust.sbi0000644000000000000000000000006413176573533020000 0ustar rootrootSBIsnrsust.sbiÄðÄð4adlibtracker2-2.4.23/package/instr/popcorn.sbi0000644000000000000000000000006413176573533017737 0ustar rootrootSBIpopcorn.sbi¹zL~o?ÿÿadlibtracker2-2.4.23/package/instr/hihat.sgi0000644000000000000000000000003213176573533017354 0ustar rootroot  adlibtracker2-2.4.23/package/instr/powerbas.sgi0000644000000000000000000000003213176573533020101 0ustar rootrootadlibtracker2-2.4.23/package/instr/violin2.sbi0000644000000000000000000000006413176573533017641 0ustar rootrootSBIviolin2.sbiá"ˆ€bS), adlibtracker2-2.4.23/package/instr/ultra.sgi0000644000000000000000000000003213176573533017406 0ustar rootroot  adlibtracker2-2.4.23/package/instr/drum5.ins0000644000000000000000000000003313176573533017323 0ustar rootrootéödrum5.insadlibtracker2-2.4.23/package/instr/leed.cif0000644000000000000000000000006413176573533017154 0ustar rootrootò"@aAleed.cifadlibtracker2-2.4.23/package/instr/dot3.sgi0000644000000000000000000000003213176573533017130 0ustar rootroot adlibtracker2-2.4.23/package/instr/elclav2.sbi0000644000000000000000000000006413176573533017607 0ustar rootrootSBIelclav2.sbiIññStadlibtracker2-2.4.23/package/instr/elclav1.sbi0000644000000000000000000000006413176573533017606 0ustar rootrootSBIelclav1.sbiŠ€ðô{{adlibtracker2-2.4.23/package/instr/englhrn2.sbi0000644000000000000000000000006413176573533017776 0ustar rootrootSBIenglhrn2.sbiàä#q€®ž adlibtracker2-2.4.23/package/instr/fantapan.sbi0000644000000000000000000000006413176573533020047 0ustar rootrootSBIfantapan.sbitׇ€¤EBadlibtracker2-2.4.23/package/instr/elpiano2.sbi0000644000000000000000000000006413176573533017770 0ustar rootrootSBIelpiano2.sbi"òõCadlibtracker2-2.4.23/package/instr/bass6.cif0000644000000000000000000000006413176573533017261 0ustar rootrootäâ÷¤ööbass6.cifadlibtracker2-2.4.23/package/instr/orgel.cif0000644000000000000000000000006413176573533017353 0ustar rootrootä ÿorgel.cifadlibtracker2-2.4.23/package/instr/altoviol.sbi0000644000000000000000000000006413176573533020110 0ustar rootrootSBIaltoviol.sbipqЀR1þadlibtracker2-2.4.23/package/instr/aalto.sbi0000644000000000000000000000006413176573533017357 0ustar rootrootSBIaaltoð€ ¢¤adlibtracker2-2.4.23/package/instr/bassdrm1.sgi0000644000000000000000000000003213176573533017773 0ustar rootroot  adlibtracker2-2.4.23/package/instr/sitar1.sbi0000644000000000000000000000006413176573533017462 0ustar rootrootSBIsitar1.sbi@@ññSSadlibtracker2-2.4.23/package/instr/acid.cif0000644000000000000000000000006413176573533017143 0ustar rootrootZP‘¹ F6_acid.cifadlibtracker2-2.4.23/package/instr/spring.cif0000644000000000000000000000006413176573533017545 0ustar rootrootö ô„ spring.cifadlibtracker2-2.4.23/package/instr/trpcup1.sbi0000644000000000000000000000006413176573533017655 0ustar rootrootSBItrpcup1.sbiàã,q€®žadlibtracker2-2.4.23/package/instr/battle.sgi0000644000000000000000000000003213176573533017532 0ustar rootroot adlibtracker2-2.4.23/package/instr/highlow.sgi0000644000000000000000000000003213176573533017720 0ustar rootrootadlibtracker2-2.4.23/package/instr/pan.cif0000644000000000000000000000006413176573533017021 0ustar rootrootâfi÷÷pan.cifadlibtracker2-2.4.23/package/instr/shaker.sbi0000644000000000000000000000006413176573533017534 0ustar rootrootSBIshaker.sbi€ûèÿÿ adlibtracker2-2.4.23/package/instr/bncebass.sbi0000644000000000000000000000006413176573533020037 0ustar rootrootSBIbncebass.sbi !K{õradlibtracker2-2.4.23/package/instr/strnlong.sbi0000644000000000000000000000006413176573533020125 0ustar rootrootSBIstrnlong.sbiá!O±Ótadlibtracker2-2.4.23/package/instr/viol.sgi0000644000000000000000000000003213176573533017230 0ustar rootroot adlibtracker2-2.4.23/package/instr/nice2.sgi0000644000000000000000000000003213176573533017257 0ustar rootrootadlibtracker2-2.4.23/package/instr/elecvibe.sbi0000644000000000000000000000006413176573533020035 0ustar rootrootSBIelecvibe.sbiQ—€š›adlibtracker2-2.4.23/package/instr/verplant.cif0000644000000000000000000000006413176573533020076 0ustar rootroot$@Õµ…Tverplant.cifadlibtracker2-2.4.23/package/instr/logdrum.sgi0000644000000000000000000000003213176573533017730 0ustar rootrootadlibtracker2-2.4.23/package/instr/terz.sgi0000644000000000000000000000003213176573533017243 0ustar rootrootadlibtracker2-2.4.23/package/instr/jump2.sgi0000644000000000000000000000003213176573533017314 0ustar rootrootadlibtracker2-2.4.23/package/instr/syncrsh.cif0000644000000000000000000000006413176573533017734 0ustar rootrootDFBLsyncrsh.cifadlibtracker2-2.4.23/package/instr/contrab.sbi0000644000000000000000000000006413176573533017707 0ustar rootrootSBIcontrab.sbi”ƒ¶&adlibtracker2-2.4.23/package/instr/keybrd1.sbi0000644000000000000000000000006413176573533017620 0ustar rootrootSBIkeybrd1.sbi€ðòúúadlibtracker2-2.4.23/package/instr/harpsi1.sbi0000644000000000000000000000006413176573533017626 0ustar rootrootSBIharpsi1.sbi2‡€¡}3adlibtracker2-2.4.23/package/instr/softsax.sbi0000644000000000000000000000006413176573533017746 0ustar rootrootSBIsoftsax.sbiPRqRf‹adlibtracker2-2.4.23/package/instr/tuba.cif0000644000000000000000000000006413176573533017176 0ustar rootroot¡!RS; tuba.cifadlibtracker2-2.4.23/package/instr/trumpet2.sbi0000644000000000000000000000006413176573533020041 0ustar rootrootSBItrumpet2.sbi1¡€#R; adlibtracker2-2.4.23/package/instr/bassnew.fin0000644000000000000000000000006213176573533017716 0ustar rootrootBASSNEW.FIN Bass new Áóó÷adlibtracker2-2.4.23/package/instr/jump.sgi0000644000000000000000000000003213176573533017232 0ustar rootroot   adlibtracker2-2.4.23/package/instr/banjo1.sbi0000644000000000000000000000006413176573533017431 0ustar rootrootSBIbanjo11‡¡}Cadlibtracker2-2.4.23/package/instr/acidbas4.sgi0000644000000000000000000000003213176573533017731 0ustar rootroot adlibtracker2-2.4.23/package/instr/elguit3.sbi0000644000000000000000000000006413176573533017633 0ustar rootrootSBIelguit3.sbi€‚‚}} adlibtracker2-2.4.23/package/instr/panic.sgi0000644000000000000000000000003213176573533017351 0ustar rootroot adlibtracker2-2.4.23/package/instr/bass.fin0000644000000000000000000000006213176573533017204 0ustar rootrootBASS.FIN Bass Ñ^¥“2adlibtracker2-2.4.23/package/instr/syn9.sbi0000644000000000000000000000006413176573533017161 0ustar rootrootSBIsyn9.sbi‡€ððadlibtracker2-2.4.23/package/instr/tensax.sbi0000644000000000000000000000006413176573533017561 0ustar rootrootSBItensax.sbiQKqRX| adlibtracker2-2.4.23/package/instr/sunrise4.sgi0000644000000000000000000000003213176573533020033 0ustar rootrootadlibtracker2-2.4.23/package/instr/pian1c.sbi0000644000000000000000000000006413176573533017432 0ustar rootrootSBIpian1c.sbiWõõúúadlibtracker2-2.4.23/package/instr/3klang1.sgi0000644000000000000000000000003213176573533017517 0ustar rootrootadlibtracker2-2.4.23/package/instr/epiano1a.sbi0000644000000000000000000000006413176573533017754 0ustar rootrootSBIepiano1a.sbiAc€óòXXadlibtracker2-2.4.23/package/instr/silly.sgi0000644000000000000000000000003213176573533017413 0ustar rootroot  adlibtracker2-2.4.23/package/instr/wave1.sbi0000644000000000000000000000006413176573533017302 0ustar rootrootSBIwave1.sbiyÀ@Radlibtracker2-2.4.23/package/instr/$gmopl.ibk0000644000000000000000000000620413176573533017433 0ustar rootrootIBKòòô÷8Kòòô÷8Iòòôö8Aòò÷÷6Wñò÷÷0“ñò÷÷0€¡òòõ8’ÂÂøø: \öóôõ0—€óòòñ2!Tôôô2˜bóòöö0#öçö÷0‘öööö4EY€Ó£óó<I€uµõõ4q1’öñ2r0ÇÇX2p±DªŠ4#±“—U#4a±€—U0$±H˜F*<a!‘a:!¡‰qa6Aœ€óó”È<Tóñšç<#!_ñò:ø0!‡€öó"ø6!GùöT:0#!J‘„A8#!J•”8 „¡€ ÑOø8!¢”æ211ññ(:11ññèx:12[Qq(H<!‹@¡òšß8!!‹¢¡ß811‹ôñèx:11ññ(:1!ÝV&81!Ýf8q1IÑa 8!#M€qr2ñá@ño!2€õ…u50€õóuô0AõòÃ2!¢›±r%>¡!˜?0¡a“ÁO:!aÁO"<1r[ƒôŠ0¡atq9g0qrWTz<AT¥cE8!!’… <!!”u <!a”v‚7<1!Cžb,2!!›aj 2a"Šut8¡!†ƒrqU0!!MT¦<81a“r 81aŽ“r 81a‘“‚ :1aŽ“r:!!Kª 81!~‹ 612ua02!›r!4áá…e_0ááFˆe_0¡!œuu 21!‹„eX0á¡LfeV&0b¡ËvUF60b¡™WV;b¡“wv;"!Yÿÿ0!!ÿÿ0"!F€†dU0!¡Ef– 0!"‹’‘**0¢až@ßo2 `ï0!!€ñô) :w¡¥S ”2a±€¨%:aa‘U4<qr]Tj0!¢—!BC58¡!¡1wG0!a‰B3%:¡!ÏG0:QÎø†ö2!!!A#0[t¥•r0"a’ƒ±ò&<ABMñòQõ0a£”€Q6a¡Œ€16¤aLós#4…ÒòSö0 €£¢å0öòAæ4“‘‘Ôë28OúÂV<!"I|o 61!…ÝV3: !Ú 6j€ñÃåå6ìø&:gß58–úø(å:†¨ú6AøóG4Žñó>Àÿ>€ˆøV$„>Ðø4>Àö>ÕÚ•@7V£705\²ôa:ÐöOõ>&äÿ>óöðÉ>ACGPIANOACPIANO"ELGPIANOHONKTONKELPIANO1ELPIANO2HARPSCHDCLAVICHDCELESTAGLOCKMUSICBOXVIBES P MARIMBAXYLOPHONTUBEBELLPIANOBELBARORGANPRCORGANROCKORGNPIPEORGNREEDORGNACCORDNHARMNICATANGONYLONACOUSTJAZZGTRELGUITARELGMUTEOVERDRIVHVYMETALGUITHARMACOUBASSELECBASSPICKBASSFRETLESSSLAPBASSWRDBASSSYNBASS1SYNBASS2VIOLINVIOLACELLODBLBASS©STRINGS1PIZZHARPVTIMPANIEXCELSTRSTRSECT©SYNSTR1èSYNSTR2©AAHSÒOOHSÒVOXSYNTHORCHHITSTRUMPET1TROMB1TUBA3SOFTRUMPFRHORN1BRASSECTSYNBRASSBRASSOFTSOPRANO©ALTOSAXTENORSAXBARISAXOBOEENGLHORNBASSOONCLARINETPICCOLOFLUTERECORDERPANPIPESBOTTLE ´SHAKAHU©WHISTLEWOODLEAD1LEAD2LEAD3LEAD4LEAD5WUZZLE1ELEAD7SYNBASS1NEWAGE"WARMPADÒPAD3PAD4PAD5PAD6PAD7PAD8FX1/FX2FX3FX4FX5FX6FX7FX8SITARBANJOSHAMISENKOTOKALIMBABAGPIPEFIDDLEETHNICHANDBELLAGOGOSTEELDRMWOODBLOCTAIDRUMMELDRUMSYNSNARREVCYMBCHICKENBREATHSEASHOREINSECTSOINKEYHELICPTRCROWDSHOTadlibtracker2-2.4.23/package/instr/water.sgi0000644000000000000000000000003213176573533017401 0ustar rootroot adlibtracker2-2.4.23/package/instr/piano.ins0000644000000000000000000000001413176573533017374 0ustar rootroot¡¢¥¥õôadlibtracker2-2.4.23/package/instr/astring.sbi0000644000000000000000000000006413176573533017726 0ustar rootrootSBIastring.sbi"!öû'adlibtracker2-2.4.23/package/instr/saxafone.sbi0000644000000000000000000000006413176573533020063 0ustar rootrootSBIsaxafone.sbiQRS| adlibtracker2-2.4.23/package/instr/helicptr.sbi0000644000000000000000000000006413176573533020071 0ustar rootrootSBIhelicptr.sbiðâÀadlibtracker2-2.4.23/package/instr/flute2.sbi0000644000000000000000000000006413176573533017460 0ustar rootrootSBIflute2.sbià¡ìne*adlibtracker2-2.4.23/package/instr/syn4.sbi0000644000000000000000000000006413176573533017154 0ustar rootrootSBIsyn4.sbi!" €ée:l adlibtracker2-2.4.23/package/instr/eguitar5.sgi0000644000000000000000000000003213176573533020004 0ustar rootroot   adlibtracker2-2.4.23/package/instr/flute.sbi0000644000000000000000000000006413176573533017376 0ustar rootrootSBIflute.sbiáa'€SSŠWadlibtracker2-2.4.23/package/instr/ghost.sgi0000644000000000000000000000003213176573533017403 0ustar rootroot adlibtracker2-2.4.23/package/instr/triangle.sbi0000644000000000000000000000006413176573533020064 0ustar rootrootSBItriangle.sbi&àÿð1adlibtracker2-2.4.23/package/instr/sftbrss1.sbi0000644000000000000000000000006413176573533020026 0ustar rootrootSBIsftbrss1.sbiááq®ž adlibtracker2-2.4.23/package/instr/xylo3.sbi0000644000000000000000000000006413176573533017335 0ustar rootrootSBIxylo3Äÿøðµadlibtracker2-2.4.23/package/instr/deepbell.cif0000644000000000000000000000006413176573533020017 0ustar rootroot.‘¿Bdeepbell.cifadlibtracker2-2.4.23/package/instr/drum2.sgi0000644000000000000000000000003213176573533017310 0ustar rootrootadlibtracker2-2.4.23/package/instr/$at2demo.a2w0000644000000000000000000001366213176573533017602 0ustar rootroot_A2insbank_w/macros_ØlÀâR­ŽQ!P&¸u¤ÿïwwwtî“¥’I'Kd“Ý%)*´mFŠ[:X/²VÈZŽ/I:IØI:Ó­mй#d´ 8 ¦ŠÜ@¢éŽb¡ à€®8è¸c˜†¡E]G¤—§u ûÿ¿ÿ÷»§»ª\A¤²tî’@3ÔÐuÝè‚éº$~SDt߀'Yøø…;{Ý[r6å]³ëì—ï¯AÝm¾ý^\ÛÀxúÿâ!|ðzìlàsiH/æÁ qúÖˆ„ªÅS³¦*ì6îû ‰eJ³ÒÍì¾u‚p ² Ý¡²öŠ‘X¨%kùÈ´=ýÁàÐÊJ׬•t¶+t²Wf²W8ª–JUþõì ˜‡æaR2ʧ,CNÁ‚5îk+å•#íW¬•¯Y*éd«¥’»5’»5’½JÉ^§E+©óm›üİ.ÃMÅ´2 ƒ,`À{|þ÷×m©[}¼´Ä¢¬íÝ?¸í=ŒX©V~­5ݘ4-ÄÍ,U}0ª~ÅàwläÅ]L¹Ì™VƒÑÈJß=àpô_Å*X$®^€ôÁ+«ýÚ\öâñþ¼Äü=´­ì †2®G^L\’7×*d˜!¿mônx%Dûmôâ$ª^/Ÿ“Šììó\,©é =«yX¬ïsÊÐë¯q++à{دÝJí®’{ðoÃF=Ïÿ4«7V§•*ÏjõJ‘ÿ4Î;¼êÝ=‚÷B\V¥ÄµÛ]…~¾d,Í€,Rx{(³cËH‰sà˜OU±ØÞpÛ:ø®Ý~ú±½RªõŠ,U³éh %‹×¶ß]B½¸'Æ,»»%>‚"¦ÎÉ «Ä [ÕLÚÓ#¢U=i€öÿ®}xó–·ØK¢ï`>A"ä/ _ÐNQ$U¹{ròöi_E*(:}rGTC­ØXhPÊ‘R:ESû[„Ú¶¾ã>× %H¬Tï:Ô^jV½d«¥’®¦égõÕyíã×ÂÓtç íb©p´mg üU)o “’TŒÚc•hPË–U/Ïḉ(/7Óms’Uïè å­ëÁ5‘wF•­êhT&ÂÔCIï±j#M奥•ŽâÑÞB}pŽöÃî\ºíb¤òUÂEÄØ’U-*×r^–î’ ¦°#KKwïtø2£•"±WüJϨ•A[Y:I]M­lR¡/­ô » ©­Åtµ¸³":)1"ðV†÷¨ƒnøïöUÑ»ËýU'X¨çj°êëÅbÃôHK½»%Cãd5Â…"VéÀ%]Â}pó¬;àû¢ö=ÔJÐZïïðErÖ©×Ñšá>¡VdngŸ¯Å'£hÞ^•f\9¥H¬Uî¥EÉÄ”adWì÷¶Ùö+ÿ½Hަ€ô~Skæô.ªT¿ÇMÿÒ¿õ+EÎàuv±R>½˜bþ‹âsìéU(©V}Á¶ž'UíÄÞ*HåS:ÆaïEmX‚n Þ:eJ‘Ïî¸zN ±_ˆIÜçGƒšU™f›QÛ×÷zuJ&U£û± "`Ïø…Ûûœþ¥é%YÚÚÉø¨GÙŒT‚©·Nu£ˆxrS>ƒ¥tâ…Z=¸ õ*›4Z½R¬ö¯Þ ¡½.˜MjùSZ¿Þ·ÃS’ ¼ÊÐ4ù•™»~Np8X:tžB†Ði9&q)z…YdÖÈšYÖŠ°É‰®`‘Q:Ê_¬7>É•J½[“ô ÷ƒC(©°¿wÓÊJŽX¡§I¼Oî˜áí¥Yn\éBÅB¤ÍÚ“ ÔÚÖ rèû5nF%$¬t£©R>ý¸¿Û`„ÃII†÷~npi{$©Š¿šV~Ú¸ØD¨¾g½––æ•f¥¨%fÞMêf%ÛˆðB$ I«²S‡/@d•KÐCW niVn€·ë·â@c¢ÏOÉ*Gûñgê%[«òB¨N7g¡L”‚©”Ÿ4Kš³Ùå)L«K•ÿv"zúÿM*™WÀ•¨7w:]ÜC—^Ë`4ȆÖ6Hg7¡yx£øйÃ(‘6ÑWy=lWVʉeyµH] †™Y[hÃÅ!{ª‰•e1k©Ž‰ËÛrÌ,Ôƒxª ó޶m“å„%4vNB^¦»’.Œó 8ÂõYbé*/²§TXÃ*‹µ¢*Ló ¥0¶Dõræ› áwÃÕº^µŒé®`r1™à ÕâIâH¼º©>ºÉDI²*M’I?žå£O¥¾†àÛ*=A´;¸t¦õ&5iÝd©—Ï 8¡Î+Î á_ĆIöígj°q¡Ñ2 º¢z¶ªºñaúCÕ¡}[_/T…‘'IÊQ&?4gdd'úƒ ŸL¿Ãüѽ3išóÙÓý¿»Ë±…nP-ÃUEÎÉOªT\þ®@²+éñò}exå=c?çáy÷LÙϤ…xÚƒoÕѶDOè±ÊéÓ‰ ŠÜ=LXÅô§x €»âþ†®@³È·€f¾)â.Ú¡ œ¦LÊnpvZN»º`‘¹J5&ÑÃØÐ†XK†Ð§!ÿu¬Jïã ŽÞd>cCk]w9÷<нøØŠvGý6<>ò–()IΚ/샱ò„vÊÓÉ kÄT[‰"è7Ê‹¨,b\÷[Þ¸._+éÐPV/ÇȉØ.®™ÕxÕÈÙFõÙVêλ…DÌÑ#ñ«[VÝohºseð,%sÔ³T\÷L¨½c~y¸ÁzÂnlHÆ‘m]%GÃå—^O®JNiá–¬þ¿MãäQYZ7 Ü{N@r öñωÚÒ…xf³Ûm\W·UÀ‘©Mèð·Ð)ú³ äu¿"ÕÀÚ„ä’¨²F*«C¨ã:>·ðQñ"ħå¦,¡ÉµR éR–ôçõŒÉ½&%Îûd¾¦š.-Si™ u™0TI^ª.'¬.ÇÊü}ê^¥’¹ÿî2bÉA#}Ìf†åŽ$±½?44*bõÄ7ØÇvO]¢‚Ï#®FûÞO’quw“ÉëØvÏ~c„åþr«%×bÑÃŒFK+k®­$"d$îUIÊùs‘ ®ÅË„ÊmÚNcÝ$nœ™xRdÊÎD™]y¾ž+¶QűT_"P±Fo²zƒæñÄ’`»b`û_¾"µ‘‹ ‚û΀ºœ+¬I)>‰4µç!ì:e5ä‚þL>œÂÃ7Q±üœ»-Ó%ßuÁªbäVÃ35“ˆFKfŸ«ZBz§íÃ?]?’>Šcp.¡¤„Iœl{SΤnfI8ÏR’”¨f‘‘"ÒÏ‘1=4ž²ª.2”£¤C àœÈ2J üqÁŸ<-NñqŒã ¦­‡wÈ`°M+@wáH#¿Î•'PÚ!i¶Ee4^b nm9!» 9„/Ëù^$bz–nuÃ3åCüL“ŠÚ Ð&%dÉ6=ðI„M,ˆD‰Uг‘*¹R¹$hºÁ45áÿ\7‹J•H‰ ® i`œhW„á‘K©îCè¶¶,“hQm(dFN'¯p3ÞA¦ÃCCêJ,ýsù‚ÆûóŹòèø©@Ô+ùÐ5ý¯ŠFK»Q™È¯oÏIí{W âþ›HÔ'ˆ|ÞˆR‘ÑÍSaüczÌ«NÇ’EíÔ:C/K¯;Å5ä1èŒLL“‹nž¶p‹†f×a©aa¨/ά´íñòÛâzñ«8Éú¤…üúîǸ˯ìø|r b `5:`’4ÿ™þæfï]Ñ`ÒŒ½ÍyD^ÀC•IêXôKo[A‚ƒàƒ%|ÈíEîè)¿çùÝÛ¹þŠ0,¾'|ľd+–Kà€>ËíºÇ°í»Yw­nô]‘è£õ~\<ý%ãíÿ¯£ÛÿLzâö´K.Î\¿³V^ätShçåíì?_“°ürãùËäËø=Ÿk/wèÛ·ÙÒý9ñüûnì{Uüwû?v+û¾ÝÏÏ–´&.ǽÉâÛëß—ÜÂþ—oæ· %ÚcÙ_Üë|¼;.üåîmõz½¸õ‰ãþ2å¯Â:r:Ÿú‚#ß&^ôŸSÊjÂzgÕofn*ðš}qXÚ"ÝÞ•1[÷îCÁ“ ¼3›>9ñ–a7pC\Ôì™óèæ~×{sNî~iÝíýóa\ó_(‹½¹)ÞÞM1Ýuªïl¦ðÎmW{nã,ÂmW{e6«»Û&ýt·‘€ÝÞÚç53›îöÁw´ÿÛQ»Ûµ…ÞÝ»WLÙü¹º®öèÝéMÞœÓô[yþ2S“©Ãï÷}~.LݨB›pýXÍïûM½¹„ÝŸo ¾MޜݜÞì¾}þU]ã^]ýý\|p³=²Âº¶ð›æ³_¦\þ›WÿŸKåõ]÷hî»Ûè_-qóÕ4nïSëkš«;1›ô曯tÝÛåúïmR»KŒ ÖݱªsS³6æ„0™w´ô2d–êŒônïpÅE–Q£Lw]x*é›?—7¿‹ ¸!„ÝéÌùôú»ÛŽøåË¿¿mØ8ÿQê[.**£–j.›z{8ÈO6™æË›ã£Šþn›¹¾)M,Ø>}<ÊîñËVin«¢ýÑ´Ëw·GT·]kš𛦳š`ó±× tÛ»ÚWh¸xy®Âsnö»v\9÷{rÍ &Ú‡Å)TE ­¨ÿ?ù%·(é¼/p)tVèÛ u\oPì“ÿˆ ”71@t%Ðd@Ò»tÀ݇­s·„,¿â§ËÐeÞK¹wµý¸ù·´}íí½€«{SÊÞÐ[Øü·µÖö†vö‚ÞÀÚÊã+Laoj1·µ8[Ú{Q-©Ën~^²9óaŸ7wþ£~6ö—»ß†Ú¥Þ8<Û6t[ÛÝáÂzÿ:rÚã dŒ¼aE¿®þ;·h–ЖßÜ6Û.`ÕóF»¼uÕm»¯]Ž©[ž«­ï.n‰ÜNœöŽ[YÞWTm¢+£k½F7^†šéÇ»Ýww³öö†Þ7éé·VÉËo.o^{_óKn~¿nÏŠõØ`%Œ²Dÿï{K)ZG¥i PÒ5 àÈ/€´ŽSb_V”‚~R¸%ྜÃ7­Ü5öæf÷;wÀÒ2Q#ED”pK~q.à(€|Kþ{žæ>þŸ7–ˆÃÕl%î·v {-÷Ûz7[Áâè³Ñ€í,>£Ÿ“ÓfxbñÝøã*xõûgj:z·Û«ðùÞ)>½£™¶U^ÉQwnxú'j}uu¹ìñøÛÛ—v»vÑ ;sﶉíîè°}{{JXónªÛ#ŠþÜü²žÞÝ5qNͽ ç·´ûoÓ–ÚíªˆßÛÚëh®Í¼,ñ÷ÛÛ“6ÆÞÐý·¶SÛ½ºí½°Ãol³á·¶ÞÀ÷om ½ ÿom ½ ó·¶,tÏ··6Øb¾³·jŸ%Ömí?]½©ëÛvÞÞ–¬;{NÞööæágˆÀ>{{aOo\ööOomööï]fÞÐ>)aó,™¶Um‘Å«}cË;S¦®)Ú‹ìñöííS—uvÕD/íÏ;gË¢»6ð³Ä` 3Ž SÿßW¾L´’LÜ™$©“2Ö÷¥ÑqI$¯RK‚I$“37vfàÌn Í›fI%T—ÁRI)*¤’g›y™™¾ù<Æã߀w.ü]¿(‰U@?éïçκT¯Ý qÔ0Á˜ “e7éCÉduV+x'Zgç­=¬ç[†+OÇo ëlEiÚLëhEh\ —ÐOÃAס¢£¤¥¦ìö»}Îí=EMUem}…{¿eg&ÒÖÚÞâæêîò]þ&.6>FNW‹Çäòù¼þO«×í÷|>9y™¹Ùú:zšºÚû;[{›»Ü|¼Üý?)Ÿ9¿_·ßñúÚêãÍîÿ¿±ìâ•Õ=(ó,÷ƒ ÿ«NæB a83€@©š‹€Ç°GP)üÄ hä@v¬€ÿÿêÝ› @nÐÐÑ !Œ”€ êår: € |qIØÎ&¥]<î×YtÇhj­BÈÎë6Ëë%wàŸHJ=QA?é¬»Çøy]ßúpâ;dGz«³¤kšÅ ÄŽÞ:aï¼<¥ÿ…ÞþûzeÛþ°>“œ¸ì|å adlibtracker2-2.4.23/package/instr/long-hi.sgi0000644000000000000000000000003213176573533017614 0ustar rootroot  adlibtracker2-2.4.23/package/instr/dshrtbas.cif0000644000000000000000000000006413176573533020055 0ustar rootrootäâ÷¤öödshrtbas.cifadlibtracker2-2.4.23/package/instr/tensax4.sbi0000644000000000000000000000006413176573533017645 0ustar rootrootSBItensax4.sbiP‘’qRf‹adlibtracker2-2.4.23/package/instr/piano1.sbi0000644000000000000000000000006413176573533017446 0ustar rootrootSBIpiano1.sbiOñÒStadlibtracker2-2.4.23/package/instr/strings3.sgi0000644000000000000000000000003213176573533020033 0ustar rootroot  adlibtracker2-2.4.23/package/instr/lullbass.sbi0000644000000000000000000000006413176573533020100 0ustar rootrootSBIlullbass.sbiAŽc1tadlibtracker2-2.4.23/package/instr/bass2.ins0000644000000000000000000000001413176573533017300 0ustar rootroot`pãïT adlibtracker2-2.4.23/package/instr/base2.cif0000644000000000000000000000006413176573533017237 0ustar rootroot Ö¨OLbase2.cifadlibtracker2-2.4.23/package/instr/harp.sbi0000644000000000000000000000006413176573533017211 0ustar rootrootSBIharp.sbi!£ÄC" adlibtracker2-2.4.23/package/instr/shrttne2.sbi0000644000000000000000000000006413176573533020030 0ustar rootrootSBIshrttne2.sbiÛ©6adlibtracker2-2.4.23/package/instr/sachso2.sgi0000644000000000000000000000003213176573533017621 0ustar rootrootadlibtracker2-2.4.23/package/instr/softpizz.sbi0000644000000000000000000000006413176573533020147 0ustar rootrootSBIsoftpizz.sbiàpc€ø÷óóadlibtracker2-2.4.23/package/instr/bdrum1.sbi0000644000000000000000000000006413176573533017451 0ustar rootrootSBIbdrum1.sbi ¨ÖLOadlibtracker2-2.4.23/package/instr/hammer.sgi0000644000000000000000000000003213176573533017530 0ustar rootroot  adlibtracker2-2.4.23/package/instr/bassdrum.fin0000644000000000000000000000006213176573533020074 0ustar rootrootBASSDRUM.FINBassdrum ¨¨Kadlibtracker2-2.4.23/package/instr/brass1.sbi0000644000000000000000000000006413176573533017452 0ustar rootrootSBIbrass1.sbi!!q®žadlibtracker2-2.4.23/package/instr/nicebass.sgi0000644000000000000000000000003213176573533020046 0ustar rootrootadlibtracker2-2.4.23/package/instr/oboe.sbi0000644000000000000000000000006413176573533017203 0ustar rootrootSBIoboe.sbiqbÅn‹adlibtracker2-2.4.23/package/instr/klarinet.cif0000644000000000000000000000006413176573533020054 0ustar rootrootò"@aAklarinet.cifadlibtracker2-2.4.23/package/instr/long2.sgi0000644000000000000000000000003213176573533017300 0ustar rootroot   adlibtracker2-2.4.23/package/instr/string0.cif0000644000000000000000000000006413176573533017631 0ustar rootrootòò 2ó#string0.cifadlibtracker2-2.4.23/package/instr/elguit1.sbi0000644000000000000000000000006413176573533017631 0ustar rootrootSBIelguit1.sbiñ! —ñadlibtracker2-2.4.23/package/instr/tuba1.sbi0000644000000000000000000000006413176573533017273 0ustar rootrootSBItuba1.sbi!!€C…Œ/ adlibtracker2-2.4.23/package/instr/techno.sgi0000644000000000000000000000003213176573533017537 0ustar rootrootadlibtracker2-2.4.23/package/instr/marimba.sgi0000644000000000000000000000003213176573533017667 0ustar rootroot adlibtracker2-2.4.23/package/instr/ligtbell.cif0000644000000000000000000000006413176573533020041 0ustar rootroot…€NùÚ ligtbell.cifadlibtracker2-2.4.23/package/instr/javaican.sbi0000644000000000000000000000006413176573533020033 0ustar rootrootSBIjavaican.sbiJVM€x…BT adlibtracker2-2.4.23/package/instr/strom.sgi0000644000000000000000000000003213176573533017423 0ustar rootroot  adlibtracker2-2.4.23/package/instr/marimba.sbi0000644000000000000000000000006413176573533017667 0ustar rootrootSBImarimba.sbiNÚù% adlibtracker2-2.4.23/package/instr/steelgt1.sbi0000644000000000000000000000006413176573533020007 0ustar rootrootSBIsteelgt1.sbi¡Fñ1ƒ†adlibtracker2-2.4.23/package/instr/string4.cif0000644000000000000000000000006413176573533017635 0ustar rootrootÅà—!óstring4.cifadlibtracker2-2.4.23/package/instr/sax.ins0000644000000000000000000000001413176573533017061 0ustar rootroot¡"ÿððadlibtracker2-2.4.23/package/instr/popbass1.sbi0000644000000000000000000000006413176573533020007 0ustar rootrootSBIpopbass1.sbiuõ“‚adlibtracker2-2.4.23/package/instr/jungle.sgi0000644000000000000000000000003213176573533017543 0ustar rootroot  adlibtracker2-2.4.23/package/instr/guitar1.sbi0000644000000000000000000000006413176573533017633 0ustar rootrootSBIguitar1.sbiòõˆ adlibtracker2-2.4.23/package/instr/clar1.sbi0000644000000000000000000000006413176573533017261 0ustar rootrootSBIclar1.sbi2!€su$Wadlibtracker2-2.4.23/package/instr/chorn.sbi0000644000000000000000000000006413176573533017370 0ustar rootrootSBIchorn.sbi!¡‹cc2 adlibtracker2-2.4.23/package/instr/leed3.cif0000644000000000000000000000006413176573533017237 0ustar rootrootHŠññ³leed3.cifadlibtracker2-2.4.23/package/instr/tincan1.sbi0000644000000000000000000000006413176573533017614 0ustar rootrootSBItincan1.sbiOï˜ñadlibtracker2-2.4.23/package/ver/0000755000000000000000000000000013176573533015215 5ustar rootrootadlibtracker2-2.4.23/package/ver/sdl/0000755000000000000000000000000013176573533015777 5ustar rootrootadlibtracker2-2.4.23/package/ver/sdl/adtrack2.mht0000644000000000000000000761225013176573533020221 0ustar rootrootMIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_NextPart_01D1E5D7.64999090" Tento dokument je jednosúborová webová stránka, nazývaná tiež webový archív. Ak sa zobrazuje toto hlásenie, váš preh¾adávaè alebo editor nepodporuje súbory webových archívov. Prevezmite preh¾adávaè, ktorý podporuje webové archívy, napríklad program Windows® Internet Explorer®. ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.htm Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="windows-1250"

 

 ┌^= 72;──────────&#= 9472;∙·          &n= bsp;            = ;            &n= bsp;             ·∙─────────^= 88;

 ∙      &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;     │

 ·       &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;    │

        &n= bsp;            = ;        subz3ro's   &nb= sp;            =             &nb= sp;         │

                        &nb= sp;        ─┬─  &nbs= p;    ──         &nb= sp;            =          │

        &n= bsp;            = ;       /┤DLiB&= #9474;R/┤CK3R ││ SDL&n= bsp;            = ;              │

        &n= bsp;            = ;        │    &nb= sp;  │     ──    &= nbsp;           &nbs= p;              │

        &n= bsp;            = ;            &n= bsp;            = ;            &n= bsp;            = ;     │

        &n= bsp;                                                                   

        &n= bsp;            = ;            &n= bsp;            = ;            &n= bsp;            = ;     │

 = CONTENTS          = ;                 &nb= sp;            =             &nb= sp;            =   ∙

        &n= bsp;            = ;               &nb= sp;                       &nb= sp;            =    ·

I= V. iNSTRUMENTS

&= nbsp;   V. EFFECTS

&= nbsp;  VI. SONG VARiABLES

&= nbsp; VII. GETTiNG STARTED

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I. PROLOGUE           &= nbsp;   

∙       &= nbsp; ·∙─────────^= 72;───────┘

 

 

 AdLib tracker is= a 9-channel FM tracker for the OPL2-compatible

 chips found on most sound cards.<= /span>

 A few years ago, there was a huge variety of= AdLib trackers.

 The most common were:

 

 Zwerg Zwack/Chicken's HSC-Tracker,

 Jens-Christian Huus' EdLib,

 Shayde's Reality= AdLib Tracker,

 Erik Pojar's Sur= prise! AdLib Tracker,

 and the latest piece of cake - Conqueror's <= span class=3DSpellE>Amusic.

 

 This new way of AdLib tracking was just that missing part in scene,

 splitting the two different worlds: a world = of ugly CMF shit,

 as Chicken used to say, and a world of sample based trackers, such as

 FastTracker or I= mpulse Tracker.

 

 The above trackers became pretty popular and were used to produce

 very nice FM music, short on size but high on quality. Such tunes were

 included in many BBS intros and demos. Unfortunately, the things

 went wrong, and AdLib tracking has come to fruition.

 

 Nowadays, at the end of second Millennium, <= span class=3DSpellE>i decided to revive this part

 of tracking history. Ladies and gentlemen, subz3ro is proud to present

 you a brandnew <= span class=3DSpellE>AdLib tool - /┤DLiB= TR/┤CK3R ][.

 

 You may probably ask WHY? Let me use the wor= ds of Jens-Christian Huus,

 one of the most common people in C64 and AdLib programming, the author

 of EdLib:

 

 "People begun to actually hate FM sound= s. The arrival of GUS and AWE32

  made wavetable techniques very popular and indeed it sounds very good,

  but there are some things in the old FM standard that is unique.

  You can't fiddle with samples in the same w= ay as you can with FM.

  I personally never quite liked sampling, i find it downright boring.

  With a FM chip it is like on a C64; you hav= e a few parameters and

  everything you do has to be done within the= se parameters.

  These boundaries makes it funny to make mus= ic, to see how far you can

  actually push AdLib. To do sounds on FM requires expertice but<= /o:p>

  if you're good at it, almost any instrument= can be reproduced properly,

  except perhaps drums."

 

 

 ──────&#= 9472;───

 

 ■ features best available software OPL3 playback to this date

 

 ■ supports 4-op instruments, melodic a= nd percussion instruments

 

 ■ supports up to 255 instruments, 128 patterns, 128 order list entries,

   89 effect commands, and 21 extended commands

 

 ■ features 2 effect columns and instru= ment macro-definitions

 

 ■ loads following song formats:

     A2M (AdT2)

     A2P (AdT2) [pattern]=

     A2T (AdT2) [tiny module]<= o:p>

 N1/ AMD (Amusic)=

     CFF (BoomTracker 4.0)

     D= FM (Digital-FM)

 N2/ FMK (FM-Kingtracker)

          MTK (MPU-401 trÆkkεr)

     RAD (Reality AdLib Tracker)

 N3/ S3M (Scream Tracker 3.x)

 N4/ SAT (Surprise! AdLi= b Tracker)     {ver.1,5,6}

 N4/ SA2 (Surprise! AdLi= b Tracker 2.0) {ver.8,9}

 N1/ XMS (XMS-Tracker)

 

 Because of bug in Amusi= c's (and its crack XMS-Tracker's) replay routine,

 the Arpeggio effect used to generate buggy sounds. Since /┤DLiB TR/┤CK3R ][

 ain't got a supp= ort for such buggy things, the Arpeggio effect may differ.

 

 After conversion, the Tremolo and Vibrato effects may sound different,

 because FM-Kingtracker<= /span> uses slow speed table (not 100% emulated in AT2)

 and optional waveform definitions that are currently not supported.

 Also the Retrig = Note effect is slightly different (if i should be ho= nest,

 i really couldn'= t get any sense of Sami's frame counting; all i could=

 do to make this effect sound way "authentic" was the frame correction during

 conversion phase--and this ain't perfect, though :)

 The OPL3 setting is ignored, Stereo setting = is accepted, Rhythm mode is

 not supported, because it was incorrectly implemented in earlier

 versions of the tracker, and the author hims= elf stopped supporting it.

 Also the pattern order list will be truncate= d to 128 if exceeds.

 

 Conversion of these (primarily sample based) modules may not be 100% exact.

 Therefore Slide Up/Down, Vibrato, and Tone <= span class=3DSpellE>Portamento effects may be

 inaccurate after importing to /┤DLiB TR/┤CK3R ][.

 Anyway, some experimental methods are used to fix up the fine-tuning

 and frequency slide based Scream Tracker's effects during

 conversion phase (experimental understand as "non-perfect" :)

 Note that the optional vibrato/tremolo wavef= orms are not supported.

 Also the pattern order list will be truncate= d to 128 if exceeds.

 

 Since Surprise! AdLib Tracker uses non-standard Volume Slide procedure

 in replay routine, Volume Slide based effects may differ after importing

 to /┤DLiB = TR/┤CK3R ][. Anyway, an experimental method to fix up

 this difference is used during conversion ph= ase (blabla, same as above :)

 The special arpeggio is also currently not supported (anyway, there are

 no SA2 modules using that feature, afaik :)

 

 ■ loads following instrument formats:<= o:p>

     A2i (AdT2)

     A2F (AdT2) [w/fm-register macro]

     CiF<= /span> (BoomTracker 4.0)

     FiN<= /span> (FM-Kingtracker)

     iNS<= /span> (HSC-Tracker/RAD-Tracker, SAdT, Amusic/AdLib instrument)

     SBi<= /span> (Creative Labs FM instrument)

     SGi<= /span> (Sound Generator 3.0)

 

 Note that the type of "ins" file c= an be set up in configuration file

 if neccessary (s= ee option "force_ins").

 

 ■ loads following bank formats:

     A2B (AdT2)

     A2W (AdT2) [w/macros]

     BNK (AdLib instrument bank) {ver.1.0}

     FiB<= /span> (FM-Kingtracker)

     iBK<= /span> (Creative Labs FM instrument bank)

 

 ■ The tracker supports block operation= s, and has an instrument editor.

   In addition, it features Tracing, Debugging, and a MidiBoard.

 

 ■ The tracker reads many of its settin= gs from a configuration file.

   It has strong support geared for row = by row tracing, pausing,

   and playing from any line in a patter= n.

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I= I. SCREEN LAYOUT          = 729;

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 The main window of the tracker is roughly composed of 5 parts:

 

   A. The upper left hand window shows t= he Status of the song

      (paused, playing, etc.), row number and order/pattern position,

      current speed/tempo, time playing and file information.

 

   B. The upper right hand window is the Pattern Order.

      There the user can build the order by which the patterns are played.

 

   C. The main window is the Pattern Edi= tor with total count of 18/20 tracks,

      5 tracks visible at= a time, where the user can compose the song,

      enter the notes, commands, number of instrument, and effects.

 

   D. The Status Line at the bottom where the user can keep track

      of the different mo= des and the active mode which is

      highlighted (MBoard, Trace, Debug, Track, Synth!), active octave,<= o:p>

      active instrument, = behavior mode, a.o. The user should experiment

      to gain familiarity with different modes that can be activated.

 

   E. The bottom window under Pattern Ed= itor shows the Volume Analyzer.

      User have to scroll= up the rest of main screen to see it.

      You can get all the volume information (carrier and modulator

      output level, overa= ll volume and global song volume,

      approximate intensi= ty in dB) there.

 

 

 ──────&#= 9472;──────────= ───

 

 [A]=           means the 'a' key on your keyboard

 [^A= ]         means the 'a' key + [Ctrl]

 [Sh= ift] A    means the 'a' key + [Shift]

 [Al= t] A      means the 'a' key + [Alt]

 [Sh= ift] ^A   means the 'a' key + [Ctrl] + [Shift]

 [Al= t] ^A     means the 'a' key + [Ctrl] + [Alt]

 

 In case of composite sh= ortkeys, it is recommended to use following

 order of pressing the keys:

 

 1st: [Ctrl] (if any)

 2nd: [Alt] or [Shift] or [Tab] (if any)

 3rd: "ordinary" key (if any :)

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I= II. KEY REFERENCE         ∙

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;

 

 F1<= /b>            =            Help

 F2 = (^S)           &= nbsp;      Save file

 F3 = (^L)           &= nbsp;      Load file

 F4 = (^A)           &= nbsp;      Toggle Nuke'm dialog

 F5<= /b>            =            Play

 F6<= /b>            =            Pause

 F7<= /b>            =            Stop

 F8<= /b>            =            Play song from current pattern or order

 F9<= /b>            =            Play current pattern or order only

 [Ct= rl] F8           = ;     @F8 from current line

 [Ct= rl] F9           = ;     @F9 from current line (Pattern Editor)

 [Al= t] F6           =       Single-play pattern   (Shift toggles trace)

 [Al= t] F5           =       @F5

 [Al= t] F8                 @F8 ├ = without synchronization

 [Al= t] F9           =       @F9

 [Shift] F2               Quick Save

 [Shift] F3               Quick Load

 [Sh= ift] F5           &nb= sp;   F5 with Trace

 [Sh= ift] F6           &nb= sp;   Toggle Debug mode from position at cursor

 [Sh= ift] F8           &nb= sp;   F8 with Trace

 [Sh= ift] F9           &nb= sp;   F9 with Trace

 [Sh= ift] Space            Toggle MidiBoard mode ON/OFF<= /p>

 ^Space                   Toggle Note Recorder m= ode ON/OFF (if possible)

 [Ct= rl] Home,End       = ;   Skip to previous/next pattern while Tracing

 +,-=             = ;          Same as above; play pattern from start

 

 ┌───= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;───┐

 γ= 4; WHEN iN NOTE RECORDER MODE                                            γ= 4;

 ζ= 0;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┤<= /span>

 γ= 4; ^Left,^Right<= /span>     Select group of tracks for recording=                 

 γ= 4; Enter            Start recording from current position (*)           

 γ= 4; Space            Toggle using custom instrumen= t for all tracks       γ= 4;

 γ= 4; [Alt] Space      Toggle using present instruments in tracks    ref. γ= 4;

 γ= 4; MBoard keys      Write notes to corresponding tracks=            (*) 

 γ= 4; F8,F9            Toggle pattern repeat OFF/ON<= span style=3D'mso-spacerun:yes'>                       

 γ= 4; Backspace        Clear note/instrument sequence in tracks             

 Backspace       Clear complete note/instrument columns               γ= 4;

 γ= 4; Up,Down          Rewind/Fast-Forward while recording                  γ= 4;

 γ= 4; [Shift] Up,Do= wn  Increase/Decrease row correction for wr= iting notes  

 γ= 4; [Shift] F6       Continue in Debug mode from positi= on at cursor      

 γ= 4; F7               Stop recording and reset starting position;          γ= 4;

 γ= 4;                  current group of tracks= can be modified              γ= 4;

 γ= 4; [Alt] 1..9,0     Toggle track channel ON/OFF (Shift toggles 1X)       γ= 4;

 γ= 4; [Alt] R          Reset flags on all tracks                            γ= 4;

 γ= 4; *=                 Reverse ON/OFF = on all tracks                         γ= 4;

 ζ= 0;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┤<= /span>

 γ= 4; In case you need non-continuos track selection,= you can choose        <= /o:p>

 γ= 4; from already selected group a subset of tracks where notes will be   

 γ= 4; written by manipulating track ON/OFF flags.                           γ= 4;

 ε= 2;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┘<= /span>

 

 ┌───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────┐

  iF SONG iS PLAYED WiTH TRACE, iT CAN BE REMOVED WHiLE..= .        &nb= sp; γ= 4;

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────┤

  Enter        Playback is paused and cursor stays on position     

  Esc          Cursor jumps to last position and playba= ck continues

 γ= 4; [Shift] Esc  Cursor stays on position and playback continues     

 └───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────┘

 

 Note that playing with Trace and playing wit= hout synchronization can be

 set up in configuration file (see options &q= uot;trace_by_default"

 and "nosync_by_def= ault")

 

 

 ^En= ter           &n= bsp;       Play next pattern according to order

 ^Le= ft  (Up)           &= nbsp;  Rewind current pattern (with Trace)

 ^Ri= ght (Down)            Fast-Forward (with Trace)

 [Ctrl][Alt] <hold down>  Temporarily show Debug Info window=

 ^B                       Toggle Message Boa= rd window

 ^D                       Toggle Debug Info = window

 ^Q                       Toggle Instrument = Macro Editor window

 ^G<= /b>            =            Toggle Arpeggio/Vibrato Macro Editor window

 ^M                       Toggle Macro Brows= er window

 ^F<= /b>            =            Toggle Song Variables window

 ^H<= /b>            =            Toggle Replace window

 ^I<= /b>            =            Toggle Instrument Control panel

 ^E<= /b>            =            Toggle Instrument Editor window

 ^O<= /b>            =            Toggle Octave Control panel

 ^P<= /b>            =            Toggle Pattern List window

 ^R<= /b>            =            Toggle Remap Instrument window

 ^T<= /b>            =            Toggle Transpose window

 ^X<= /b>            =            Toggle Rearrange Tracks window

 ^1.= .^8           &n= bsp;       Quick-set octave

 [Al= t] +,- (Up,Down)    &= nbsp; Adjust volume level of sound output

 [Al= t] C             &nb= sp;    Copy object to clipboard (with selection)

 [Al= t] P           &= nbsp;      Paste object from clipboard

 [Al= t] M           &= nbsp;      Toggle marking lines ON/OFF

 [Al= t] L           &= nbsp;      Toggle Line Marking Setup window

 [Al= t] 1..9,0           = ;  Toggle track channel ON/OFF (Shift= toggles 1X)<= /p>

 [Al= t] S           &= nbsp;      Set all OFF except current track (solo)

 [Al= t] R           &= nbsp;      Reset flags on all tracks

 *            &= nbsp;           Reverse ON/OFF on all tracks=

 F10                      Quit program

 F11                      Toggle typing mode = in Pattern Editor (AT-►FT-►ST)<= /span>

 F12                      Toggle line feed in Pattern Editor<= /o:p>

 [Shift] F12              Toggle jump to marked line in Pattern Editor

 [Ctrl][Tab] [...] (*)    Scroll Volume Analyzer section (if necessary)

 

 (*) Up,Down,PgUp= ,PgDown

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 [Alt|Ctrl= ]{Shift} F11    Toggle WAV recording ON<= o:p>

 [Alt|Ctrl= ]{Shift} F12    Toggle WAV recording OFF=

 

 ┌───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────┐

  FUNCTiONALiTY O= F ALTERNATiVE KEYS                   

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────┤

  Alt    Toggle normal recording mode                 

  Ctrl   Toggle 'per track' recording mode            

  Shift  Toggle Fade in / Fade out sound processing   

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────┤

  POSSiBLE COMBiNATiONS: Alt,Ctrl,Alt+S= hift,Ctrl+Shift

 └───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────┘

 

 If 'per t= rack' recording mode is activated and song playback is stopped<= /p>

 you can exclude/include corresponing tracks from/to bei= ng recorded

 with ordi= nary track selection procedure:

 

 [Alt] 1..9,0             Toggle track channel ON/OFF = (Shift toggles 1X)

 [Alt] S                  Set all OFF except curr= ent track (solo)

 [Alt] R                  Reset flags on all trac= ks

 

 

 III= /3. PATTERN ORDER KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 Up,Down,Left,Right       Cursor navigation

 PgUp,PgDn        = ;        Move up/down 32 patterns

 Home,End        =          Move to the top/end of pattern order

 Tab= ,[Shift] Tab          Move to next/previous entry

 Ins= ert           &n= bsp;       Insert new entry

 Del= ete           &n= bsp;       Delete entry

 Bac= kspace           = ;     Clear entry

 ^Sp= ace           &n= bsp;       Enter skip mark

 ^C<= /b>            =            Copy entry to clipboard

 ^V<= /b>            =            Paste entry from clipboard

 +,-=             = ;          Adjust entry

 ^F2=             = ;          Save module in tiny format

 Ent= er           &nb= sp;        Switch to Pattern Editor

 

 Note that 80-FF pattern number range causes a jump in pattern order.

 syntax: order_number[hex](+80h); e.g. "9A" jumps to order 1A

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 Up,Down,Left,Right       Cursor navigation

 PgUp,PgDn        = ;        Move up/down 16 lines

 Home,End        =          Move to the top/end of current pattern

 Tab= ,[Shift] Tab          Move to next/previous track

 [Sh= ift] PgDn,PgUp (+,-)  Move to next/previous patte= rn

 [Sh= ift] Home,End       = ;  Move fwd./bckwd. to the first/last pattern=

 ^Home,^End      &nbs= p;        Move to the end/top of previous/next pattern

 Spa= ce           &nb= sp;        Advance to next row

 ^PgUp,^PgDn  = ;            Transpose note (block) halftone up/down

 Bac= kspace           = ;     Remove note or clear attributes

 Ins= ert           &n= bsp;       Insert new line (within track only)<= /span>

 Del= ete           &n= bsp;       Delete line (within track only)

 [Sh= ift] Insert           Insert new line

 [Sh= ift] Delete           Delete line

 [Sh= ift] Enter            Toggle fixed and regular note

 ^K<= /b>            =            Insert Key-Off

 ^C<= /b>            =            Copy object at cursor to clipboard

 ^V<= /b>            =            Paste object from clipboard

 [Alt][Shift] P           Paste object from clipboard to= more patterns

 ^Z                       Undo last operatio= n (if possible)

 {Ct= rl} "[","]"       &n= bsp;   Change current instrument

 [Al= t] F2           =       Save current pattern to file

 ^F2=             = ;          Save module in tiny format

 [Shift] F3               Quick load recent pattern = data

 Ent= er           &nb= sp;        Switch to Pattern Order

 

 NOTE SYSTEM: C,C#,D,D#,E,F,F#,G,G#,A,A#,B(H)

 VALiD NOTE ENTRiES: C,C-,C#,C1,C-1,C#1...<= /p>

 

 ┌───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┐

  BLOCK OPERATiONS iN PATTE= RN EDiTOR       =             = ;           

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┤

  Starting to mark a block: [Shift] Up,Down,Left,Right   &nbs= p;        

  When at least one row in one track is marked, you can continue  

  marking also with PgUp,PgDn,Home,End (Shift is still held down!)

  Quick mark: [Alt] Q (1x-2x-3x) track ─> pattern ─> discard      

  Toggle last marked block: [Alt] B    &n= bsp;            = ;            &n= bsp; 

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┤

  ^B  Blank block  (Insert blank block to pattern)           &= nbsp;    

  ^C  Copy block   (Copy block to clipboard)           = ;           

  ^D  Delete block (Remove block from pattern)           &= nbsp;        

  ^N  Nuke block   (Clear block contents)           =             &nb= sp; 

  ^V  Paste block  (Paste block from cli= pboard to pattern) (*)  &nb= sp; 

  ^X  Cut block    (Combine bo= th Copy and Delete operation)       

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┤

  (*) PASTE BLOCK OPERATiON VARi= ANTS                               γ= 4;

  ¯¯¯¯¯¯¯¯&m= acr;¯¯¯¯¯¯¯¯¯¯¯¯= ;¯¯¯¯¯¯¯¯¯¯¯¯&m= acr;                               

  "Paste block" operation has th= ree other functional variants      γ= 4;

  with different key shortcuts for activation:                     γ= 4;

  1) [Alt] V toggles "Mix block" operation, when block data       

     from clipboard is applied without overwriting existing data; 

  2) [Shift] ^V toggles "Selective paste block" operation,        

     when only block data from clipboard corresponding to current 

     cursor position is being applied (i.e. note, instrument,     

     1st effect or 2nd effect).                                    γ= 4;

 γ= 4; 3) [Alt][Shift] V toggles "Flipped paste block" operation,=       

 γ= 4;    when block data from clipboard is app= lied vertically flipped.

 γ= 4;                                                                  <= span style=3D'color:#D9D9D9;mso-themecolor:background1;mso-themeshade:217'>γ= 4;

 γ= 4; MANiPULATiON<= /b> WiTH FX = VOLUME iNFORMATiON                          γ= 4;

  ¯¯¯¯¯¯¯¯&m= acr;¯¯¯¯¯¯¯¯¯¯¯¯= ;¯¯¯¯¯¯¯¯¯¯¯¯&m= acr;¯¯¯¯¯                          γ= 4;

  When there is bl= ock marked, which contains some effect        =   

 γ= 4; commands carrying volume information, you can increase/decrease 

 γ= 4; their values with +/- keys.                                      γ= 4;

 γ= 4; Effect commands are processed with following priority:          

 γ= 4;   1) Set instrument volume (Cxx),                                

 γ= 4;      Force instrument volume (=3Dxx)                               γ= 4;

 γ= 4;   2) Set modulator volume (9xx)                                  γ= 4;

 γ= 4;   3) Set carrier volume (Ixx)                                    γ= 4;

 γ= 4;   4) Set global volume (%xx)                                     γ= 4;

 γ= 4; If effect command with higher priority has been processed,      

 γ= 4; all remaining effect commands with lower priority are skipped.  

 └───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┘

 

 

 III= /5. PATTERN LiST WiNDOW= KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─

 

 Up,Down        &= nbsp;         Cursor navigation

 PgUp,PgDn        = ;        Move up/down 20 patterns

 Home,End        =          Move to the top/end of pattern list

 Spa= ce           &nb= sp;        Mark/Unmark pattern

 ^Sp= ace           &n= bsp;       Unmark all marked patterns

 [Sh= ift] ^Space           Reve= rse marks on all patterns

 [Al= t] C (^C)           &= nbsp; Copy pattern to clipboard

 [Al= t] P (^V)           &= nbsp; Paste pattern from clipboard

 [Sh= ift] ^V               Paste pattern data f= rom clipboard

 [Al= t] V                  Paste pattern n= ame from clipboard

 ^N                       Nuke current patte= rn

 [Shift] ^N               Nuke all marked patterns

 ^W<= /b>            =            Swap marked patterns

 [Sh= ift] ^W           &nb= sp;   Swap marked patterns w/o names

 [Sh= ift] Insert           Insert new pattern

 [Sh= ift] Delete           Delete pattern

 Ent= er           &nb= sp;        Rename pattern / Multiple paste

 [Shift] F3               Quick load recent pattern = data

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 III= /6. iNSTRUMENT CONTROL PANEL KEY REFERENCE=

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────

 

 Up,Down                  Cursor navigation

 PgUp,PgDn        = ;        Move up/down 16 instruments

 Home,End        =          Move to the top/end of instrument list

 Spa= ce           &nb= sp;        Mark/Unmark instrument

 MBoard keys <= ;hold down>  Preview instrument

 Ent= er           &nb= sp;        Rename instrument

 ^C<= /b>            =            Copy instrument to clipboard

 [Sh= ift] ^C           &nb= sp;   Copy instrument also with macro-definitions

 ^V<= /b>            =            Paste instrument(s) from clipboard

 [Sh= ift] ^V               Paste instrument data from clipb= oard

 [Al= t] V                &n= bsp; Paste instrument name(s) from clipboard

 ^W<= /b>            =            Swap marked instruments

 [Sh= ift] ^W           &nb= sp;   Swap marked instruments w/o names

 Tab=             = ;          Toggle Instrument Editor window

 [Sh= ift] Tab           &n= bsp;  Toggle Instrument Macro Editor window

 [Shift] O                Toggle operator mode 4OP = / 2OP

 [Sh= ift] M,B,S,T,C,H      Toggle melodic and percussion (BD,SD,TT,TC,HH)

 [Sh= ift] F2             &nb= sp; Save instrument w/ fm-register macro to file

 [Al= t] F2           =       Save instrument bank to file

 ^F2=                    &nb= sp;  Save instrument bank w/ all macros to file

 [Shift] F3               Quick load recent instrume= nt data

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 III= /7. iNSTRUMENT EDiTOR WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────

 

 Up,Down,Left,Right,

 Home,End        =          Cursor navigation

 [Alt] <section hotkey>   Jump to section

 Tab=             = ;          Jump to next setting

 [Sh= ift] Tab           &n= bsp;  Jump to previous setting

 +,-= (PgUp,PgDn)      &nb= sp;   Adjust value

 Spa= ce           &nb= sp;        Select item

 ^Sp= ace (opt.)            Toggle ADSR preview ON/OFF

 [Ctrl] "[","]"           Change current instrument=

 [Ctrl][Shift] "[","]"= ;    Change macro speed<= /o:p>

 [Alt]{Shift} 1..4,0      Set operators for instrument previe= w (*)

 MBoard keys <= ;hold down>  Preview instrument

 Ent= er           &nb= sp;        Toggle carrier/modulator/4OP slot settings

 [Shift] O                Toggle operator mode 4OP = / 2OP

 [Shift] M,B,S,T,C,H      Toggle melodic and percussion (BD,SD,TT,TC,HH)

 [Shift] F2               Save instrument w/ fm-register macro to file

 [Shift] Enter            Copy values from carrier/modu= lator slot

 Esc=             = ;          Return to Instrument Control panel

 

 (*) [Alt] 1..4           Set solo operator

     [Alt][Shift] 1..4    Toggle operator ON/OFF

     [Alt] 0              Reset 

 

 

 III= /8. iNSTRUMENT MACRO EDiTOR <= span class=3DSpellE>WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;─

 

 Up,Down,Left,Right

 Home,End        =          Cursor navigation

 PgUp,PgDown       &nb= sp;      Move up/down 16 lines

 Tab (Enter)          &nbs= p;   Jump to next field in order

 [Sh= ift] Tab             &nb= sp;Jump to previous field in order

 [Sh= ift] Up,Down       =    Synchronous navigation within tables

 [Sh= ift] Home,End       = ;  Move to the start/end of current line in table

 ^Left,^Right             Switch between macro tables<= o:p>

 [Shift] ^Left,^R= ight     Navigate to start/end of macro table=

 ^PgUp,^PgDown       &= nbsp;    Change current arpeggio/vibrato table

 [Ctrl] "[","]"           Change current instrument=

 [Ct= rl][Shift] "[","]"    = Change macro speed

 [Alt]{Shift} 1..4,0      Set operators for inst= rument preview (*)<= /p>

 [Alt] ^C                  [Alt] ^M                 <= /o:p>

 ^C [Sh= ift] ^C           &nb= sp;   Copy column in table

 ^V<= /b>            =            Paste object from clipboard

 ^En= ter           &n= bsp;       Paste data from instrument registers

 [Sh= ift] Enter            Paste data to instrument registers

 [Sh= ift] ^Enter           Paste data from instrument registers w/ selection

 Bac= kspace           = ;     Clear current item in table

 [Sh= ift] Backspace        Clear line in table=

 +,-=              = ;         Adjust value at cursor / current item in table

 ^Home,^End      &nbs= p;        Quick-adjust table length

 [Sh= ift] ^Home,^End       Quick-adjust loop begin position

 [Sh= ift] ^PgUp,^PgDown &nb= sp;  Quick-adjust loop length

 Ins= ert           &n= bsp;       Insert new line in table

 Del= ete           &n= bsp;       Delete line in table

 ^E                       Toggle envelope re= start ON/OFF    

 ^N                       Toggle note retrig= ger ON/OFF      

 ^Z                       Toggle ZERO freque= ncy ON/OFF      

 [Alt] ^E,^N,^Z           Reset all alike flags in table=      FM-register

 ^Ba= ckspace          &nbs= p;    Toggle corresponding column ON/OFF table

 [Al= t] S           &= nbsp;      Set all OFF except current column 

 [Al= t] R           &= nbsp;      Reset flags on all columns         = │<= /span>

 *            =             Reverse ON/OFF on all columns      ┘<= /span>

 \            &= nbsp;           Toggle current item (switch types only)

 Spa= ce           &nb= sp;        Toggle macro-preview mode

 ^Sp= ace           &n= bsp;       Toggle Key-Off loop within macro-preview mode

 ^F2                      Save instrument ban= k w/ all macros to file

 Esc=             = ;          Leave Instrument Macro Editor window

 

 (*) [Alt] 1..4           Set solo operator

     [Alt][Shift] 1..4    Toggle operator ON/OFF

     [Alt] 0              Reset 

 

 

 III= /9. APREGGiO/ViBRATO MACRO EDiTOR WiNDOW KEY REFEREN= CE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;───────

 

 Up,Down,Left,Right

 Home,End        =          Cursor navigation

 PgUp,PgDown       &nb= sp;      Move up/down 16 lines

 Tab (Enter)          &nbs= p;   Jump to next field in order

 [Sh= ift] Tab           &n= bsp;  Jump to previous field in order

 [Sh= ift] Up,Down       =    Synchronous navigation within tables

 ^Left,^Right             Switch between macro tables<= o:p>

 [Shift] ^Left,^R= ight     Navigate to start/end of macro table=

 ^PgUp,^PgDown &nb= sp;          Change current arpeggio/vibrato table

 [Ctrl] "[","]"           Change current instrument=

 [Ctrl][Shift] "[","]"= ;    Change macro speed<= /o:p>

 [Alt]{Shift} 1..4,0      Set operators for inst= rument preview (*)<= /p>

 ^C<= /b>            =            Copy line in table (whole table respectively)<= /span>

 [Sh= ift] ^C           &nb= sp;   Copy column in table

 ^V<= /b>            =            Paste object from clipboard

 Bac= kspace           = ;     Clear current item in table

 [Sh= ift] Backspace        Clear line in table=

 +,-=                     &n= bsp; Adjust value at cursor / current item in table

 ^Home,^End      &nbs= p;        Quick-adjust table length

 [Sh= ift] ^Home,^End       Quick-adjust loop begin position

 [Sh= ift] ^PgUp,^PgDown &nb= sp;  Quick-adjust loop length

 Spa= ce           &nb= sp;        Toggle macro-preview mode

 ^Sp= ace           &n= bsp;       Toggle Key-Off loop within macro-preview mode

 Esc=             = ;          Leave Arpeggio/Vibrato Macro Editor window

 

 (*) [Alt] 1..4           Set solo operator

     [Alt][Shift] 1..4    Toggle operator ON/OFF

     [Alt] 0              Reset 

 

 

 III= /10. iNSTRUMENT MACRO BROWSER KEY REFERENCE=

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;───────

 

 Up,Down,PgUp,PgDown=

 Home,End=                  Cursor navigation

 [Shift] Up,Down<= /span>          Move up/down in macro table=

 [Shift] Left,Rig= ht       Move left/right in macro table

 [Shift] PgUp,PgD= own      Move page up/down in macro table

 [Shift] Home,End=          Move to the start/end of macro t= able

 [Ctrl] Home,End<= /span>          Move to the start/end of line in macro table

 Enter                    Load selected macro d= ata

 ^Enter (opt.)            Load all macro data from bank=

 [Ctrl][Shift] "[","]"= ;    Change macro speed<= /o:p>

 MBoard keys <hold down>  Preview instrument with selected macro = data

 Tab (opt.)               Switch to Arpeggio/Vibrato= Macro Browser window

 Esc                      Leave Instrument Ma= cro Browser window

 

 

 III= /11. ARPEGGiO/ViBRATO MACRO BR= OWSER KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──

 

 Up,Down,PgUp,PgDown=

 Home,End=                  Cursor navigation

 [Shift] Left,Rig= ht       Move left/right in arpeggio table<= span style=3D'mso-spacerun:yes'>     

 [Shift] PgUp,PgD= own      Move page left/right in arpeggio ta= ble │<= /span>

 ^Left,^Right             Move left/right in vibrato table       refer to=

 ^PgUp,^PgDown            Move page left/right in vibrato table  (*)

 [Shift]{Alt} Space       Toggle arpeggio table selection (**)  

 [Ctrl] {Alt} Space       Toggle vibrato table selection  (**)  

 [Shift] Home,End         Navigate to start/e= nd of arpeggio table

 ^Home,^End               Navigate to start/end of v= ibrato table

 [Ctrl] "[","]"           Change current instrument<= /span>

 [Ctrl][Shift] "[","]"= ;    Change macro speed<= /o:p>

 MBoard keys <hold down>  Preview instrument with selected macro = data

 Enter                    Load selected macro d= ata

 ^Enter (opt.)            Load all macro data from bank=

 [Shift] Esc              Apply table indexes to curr= ent instrument

 Esc                      Leave Arpeggio/Vibr= ato Macro Browser window

 

 (*)  Key combination with Ctrl+Shift applies action to both tables

 (**) Alt key invokes no arpeggio resp. vibrato table (index value re= set)

 

 

 III/12. DEBUG iNFO<= /span> WiNDOW KEY REFERENCE

 ── = 472;──────────&= #9472;──────────= ;──────────^= 72;────

 Up,Down,Left,Right

 Home,End        =          Change current track

 Tab                      Toggle details=

 Backspace                Toggle pattern repeat

 Space                    Enter Debug mode / Pr= oceed step (if possible)

 ^Space                   Exit Debug mode

 [Ctrl] Home,End          Skip to previous/n= ext pattern

 +,-                      Same as above; play pattern from start

 ^Enter                   Play next pattern acco= rding to order

 ^Left                    Rewind current patter= n

 ^Right                   Fast-Forward<= /p>

 [Alt] 1..9,0             Toggle track channel ON/OFF = (Shift toggles 1X)

 [Alt] S                  Set all OFF except curr= ent track (solo)

 [Alt] R                  Reset flags on all trac= ks

 *   =                      Reverse ON/OFF on all tracks

 Esc                      Return to Pattern E= ditor or Pattern Order

 

 

 III= /13. REMAP iNSTRUMENT WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────

 

 Up,Down,Left,Right

 Home,End        =          Cursor navigation

 PgUp,PgDown       &nb= sp;      Move up/down 16 instruments

 Tab=             = ;          Jump to next selection

 [Sh= ift] Tab           &n= bsp;  Jump to previous selection

 MBoard keys <= ;hold down>  Preview instrument

 Ent= er           &nb= sp;        Remap

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 III= /14. REARRANGE TRACKS WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────

 

 Up,Down,Left,Right<= /b>,

 Home,End=                   Cursor navigation<= /o:p>

 Tab                       Jump to next selec= tion

 [Shift] Tab               Jump to previous selection=

 ^PgUp,^PgDown          =    Shift track at cursor up/down in the track list

 [Shift] ^PgUp,^PgDown     Rotate track list from cursor upside/downside

 Enter                     Rearrange=

 Esc                       Return to Pattern Editor or Pattern Orde= r

 

 

 III= /15. REPLACE WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────

 

 Up,Down,Left,Right,

 Home,End        =          Cursor navigation

 Tab=             = ;          Jump to next selection

 [Sh= ift] Tab           &n= bsp;  Jump to previous selection

 ^K<= /b>            =            Insert Key-Off in note column

 ^N<= /b>            =            Mark "new" field to clear found item

 ^W                       Swap "to find= " and "replace" mask content

 Delete,Backspace         Delete current/previous characte= r

 ^Backspace               Delete "to find"= or "replace" mask content

 [Shift] ^Backspace       Delete content of both masks<= /o:p>

 Ent= er           &nb= sp;        Replace

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;────

 

 Up,Down,Left,Right       Cursor navigation

 Tab (Enter)          &nbs= p;   Jump to next variable field

 [Sh= ift] Tab           &n= bsp;  Jump to previous variable field

 Spa= ce           &nb= sp;        Select item

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 Up,Down,Left,Right,

 PgUp,PgDown,Home,En= d     Cursor navigation<= /p>

 \ (/ for Linux)          Navigate to root directory

 Backspace                Navigate to parent direct= ory

 [Shift] Backspace        Navigate to program home director= y

 MBoard keys <hold down>  Preview instrument (instrument files on= ly)

 Enter                    Choose file under cur= sor / read instrument bank

 Esc                      Leave without choos= ing file

 III/18. MESSAGE BOARD WiNDOW KEY REFERENCE

 ─────γ= 2;────────── = 472;──────────&= #9472;──────────= ;────

 

 Up,Down,Left,Right<= /b>,

 ^PgUp,^PgDown,

 Home,End,^Home,^End=       Cursor navigation=

 PgUp,PgDown              Move backwards/forwards ove= r text

 ^Left,^Right             Move word left/right

 Backspace,Delete         Delete character left/right=

 ^Backspace,^T            Delete word left/right

 ^K                       Delete characters = to end

 ^Y                       Delete current lin= e

 Tab                      Indent current line=

 ^Space                   Insert row for text at cursor

 [Shift] ^Backspace       Delete row for text at cursor=

 Insert                   Toggle input and overw= rite mode

 Enter                    Wrap line of text

 Esc                      Return to Pattern E= ditor or Pattern Order 

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 Left,Right       &nbs= p;       Move left/right

 Home,End        =          Move to the begin/end

 ^Left,^Right      &n= bsp;      Move word left/right

 Backspace,Delete      &nbs= p;  Delete character left/right

 ^Backspace,^T            Delete word left/right

 ^K                       Delete characters = to end

 ^Y<= /b>            =            Delete string

 Ins= ert           &n= bsp;       Toggle input and overwrite mode

 

 

 III= /20. MiDiBOARD KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;───

 

 Use to enter notes while in MBoard mode (if not already active,
 Shift+Space activates this mode if song is Stopped, or if song is Paused
 with no Trace).
<= /p>

 

 

 

 δ= 4;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┐<= /span>

 γ= 4; WHiLE TRACKER iS iN MBOARD MODE      = ;            &n= bsp;            = ;       

 ζ= 0;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┤<= /span>

 γ= 4; MBoard key copies note in note field= , plays it, and advances song    

 ^= 74; to next row. If used with = Left-Shift key and line marking toggled ON,

  it advances song to next highlighted row.            = ;            &n= bsp;   

  If used with Right-Shift key, it makes a fixed note.           &nbs= p;     

  Space plays row and advances song by one row.            = ;            

  ` inserts Key-Off, releases playing note and advances to next row.   

 └───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9496;

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I= V. iNSTRUMENTS       =     

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 ──────&#= 9472;────

 

 Indicates how fast the sound volume goes to maximum.

 1=3Dslow, 15=3Dfast. 0 means no attack phase= .

 

 

 ──────&#= 9472;───

 

 Indicates how fast the sound goes from maxim= um level to sustain level.

 1=3Dslow, 15=3Dfast. 0 means no decay phase.=

 

 

 ──────&#= 9472;──────

 

 Indicates the sustain level.

 1=3Dloudest, 15=3Dsoftest. 0 means no sustai= n phase.

 

 

 ──────&#= 9472;─────

 

 Indicates how fast the sound goes from susta= in level to zero level.

 1=3Dslow, 15=3Dfast. 0 means no release phas= e.

 

 

 ──────&#= 9472;─────

 

 Ranges from 0 to 63, indicates the attenuati= on according to the

 envelope generator output. In Additive synthesis, varying

 the output level of any operator varies the volume of its corresponding

 channel. In FM synthesis, varying the output level of carrier varies

 the volume of its corresponding channel, but varying the output of

 the modulator will change the frequency spec= trum produced by the carrier.

 

 

 ──────&#= 9472;────────

 

 Specifies the output waveform type.

 The first is closest to pure sine wave, the = last is most distorted.

 

 

[0] SiNE

 

3Dimage001

 

[4] SiNE / EPO

 

 

 3Dimage003

 

[1] HALF-SiNE

3Dimage006

 

[5] ABS-SiNE / EPO

 

3Dimage005

 

[2] ABS-SiNE

 

3Dimage004

 

[6] SQUARE

 

3Dimage007

 

 [3] PULSE-= SiNE

 

  3Dimage008

 

[7] DERiVED SQUARE

 

3Dimage009

 

 

 

 ──────&#= 9472;──────────= ──────

 

 When set, makes the sound softer at higher frequencies.

 With musical instruments, volume decreases as pitch increases.

 Level key scaling values are used to simulate this effect.

 If any (not zero), the diminishing factor ca= n be 1.5 dB/octave,

 3.0 dB/octave, or 6.0 dB/octave.<= /span>

 

 

 ──────&#= 9472;

 

 Gives you abilit= y of controlling output, going to left or right channel,

 standing in the middle respectively.

 The parameter corresponds either with carrier and modulator, therefore

 it is listed only once (within the carrier slot).

 

 

 ──────&#= 9472;──

 

 This is not a hardware parameter.=

 Ranges from -127 to 127, it indicates the nu= mber of frequency units

 shifted up or down for any note playing with= the corresponding instrument.

 The parameter corresponds either with carrier and modulator, therefore

 it is listed only once (within the carrier slot).

 

 

 ──────&#= 9472;──────────=

 

 Ranges from 0 to 7, it indicates the modulat= ion depth

 for the modulator slot FM feedback.

 

 ┌────────= ;────╥─────_= 16;─────┬────&#= 9472;┬─────┬───= ──┬─────┬─γ= 2;───┬─────┐

  FEEDBACK   &#= 9553; [0]  [1]  [2]  [3] <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> [4]  [5]  [6] <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> [7]

 ├────────= ;────╫─────_= 32;─────┼────&#= 9472;┼─────┼───= ──┼─────┼─γ= 2;───┼─────┤

  MODULATiON   0  π/16 │<= /span> π/8 π/4 π/2   π  │<= /span> 2π  4π 

 └────────= ;────╨─────_= 24;─────┴────&#= 9472;┴─────┴───= ──┴─────┴─γ= 2;───┴─────┘

 

 The parameter corresponds either with carrier and modulator, therefore

 it is listed only once (within the carrier slot).

 

 

 CONNECTiON TYPE=

 ──────&#= 9472;────────

 

 Frequency modulation means that the modulator slot modulates the carrier.

 Additive synthesis means that both slots pro= duce sound on their own.

 

 

 [FM] FREQUENCY MODULATiON

 

         ┌───────── = 472;──┐

         │           =

         │    ╔════╗ = ; │         ╔════╗

  P1 ───(+)───║ MO ╟─= ─┴───(+)───║ CA ╟──> OUT

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝=

           &nb= sp;            =    │

           &nb= sp;            =    │

           &nb= sp;            =    P2

 

 

 

 [ADDiTiVE SYNTHESiS] AM<= o:p>

 

         ┌───────── = 472;──┐

         │           =

         │    ╔════╗ = ; │

  P1 ───(+)───║ MO ╟─= ─┴────┐

           &nb= sp;  ╚════╝     &= nbsp; │

           &nb= sp;            =    │

           &nb= sp;            =   (+)──> OUT

           &nb= sp;            =    │

              &= #9556;════╗     &nbs= p; │

  P2 ─────────║= CA ╟───────┘

           &nb= sp;  ╚════╝

 

 

 

 

 The parameter corresponds either with carrier and modulator, therefore

 it is listed only once (within the carrier slot).

 This parameter is also very important when making 4-op instruments,

 because the combination of two instrument connections specifies

 the connection of the 4-op instrument as sho= wn below:

 

 ┌────────= ;──╥────┬──^= 72;─┬────┬───&#= 9472;┐

  SLOT      M1 C1 │<= /span> M2 C2

 ├────────= ;──╫────┼──^= 72;─┼────┼───&#= 9472;┤

  OPERATOR ║<= /span> 1   2  │<= /span> 3   4 

 └────────= ;──╨────┴──^= 72;─┴────┴───&#= 9472;┘

 

 

 

[FM/FM]

 

         ┌───────── = 472;──┐

         │           =

         │    ╔════╗ = ; │         ╔════╗     &= nbsp;   ╔════╗&nb= sp;        ╔════╗

  P1 ───(+)───║ M1 ╟─= ─┴───(+)───║ C1 ╟───(+)───║ M2 ╟= ───(+)───║ C2 ╟──> OUT

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝ = ;   │    ╚════╝ = ;   │    ╚════╝=

           &nb= sp;            =    │           =          &n= bsp;      

           &nb= sp;            =    │          =          &n= bsp;        

           &nb= sp;            =    P2             P3            = ; P4

 

 

 

[FM/AM] (*)

 

         ┌───────── = 472;──┐

         │           =

         │    ╔════╗ = ; │         ╔════╗

  P1 ───(+)───║ M1 ╟─= ─┴───(+)───║ C1 ╟────┐

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝ = ;   │

           &nb= sp;            =    │           =   

           &nb= sp;            =    │          =     

           &nb= sp;            =    P2            (+)&= #9472;─> OUT

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;  ╔════╗     &= nbsp;      ╔════╗&nb= sp;   │

  P3 ─────────║= M2 ╟──────(+)──γ= 2;║ C2 ╟────┘

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝=

           &nb= sp;            =    │

           &nb= sp;            =    │

           &nb= sp;            =    P4

 

 

 

[AM/FM] (*)

 

         ┌───────── = 472;──┐

         │           =

         │    ╔════╗ = ; │

  P1 ───(+)───║ M1 ╟─= ─┴────────γ= 2;────────── = 472;──────────&= #9472;───┐

           &nb= sp;  ╚════╝     &= nbsp;           &nbs= p;            &= nbsp;      │

           &nb= sp;            =             &nb= sp;            =         │

           &nb= sp;            =             &nb= sp;            =         │

           &nb= sp;            =             &nb= sp;            =         │

           &nb= sp;  ╔════╗     &= nbsp;      ╔════╗&nb= sp;        ╔════╗&nb= sp;   │­

  P2 ─────────║= C1 ╟──────(+)──γ= 2;║ M2 ╟───(+)───║ C2 ╟= ───(+)──> OUT

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝ = ;   │    ╚════╝=

                        &= nbsp;  │        &nb= sp;    

           &nb= sp;            =    │           =   

           &nb= sp;            =    P3            = ; P4

 

 

 

[AM/AM]

 

         ┌───────── = 472;──┐

         │           =

         │    ╔════╗ = ; │

  P1 ───(+)───║ M1 ╟─= ─┴────────γ= 2;────────── = 488;

           &nb= sp;  ╚════╝     &= nbsp;           &nbs= p;    │

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;  ╔════╗     &= nbsp;      ╔════╗&nb= sp;   │­

  P2 ─────────║= C1 ╟──────(+)──γ= 2;║ M2 ╟───(+)──> OUT

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝ = ;   │

           &nb= sp;            =    │           =   

           &nb= sp;            =    │           =   

           &nb= sp;            =    P3            = ; │

           &nb= sp;  ╔════╗     &= nbsp;           &nbs= p;    │

  P4 ─────────║= C2 ╟─────────&= #9472;──────────= ;──┘

           &nb= sp;  ╚════╝

 

 

 

 (*) REMA= RK ABOUT 4OP CONNECTiONS

 Please not= e, that since order of 4OP tracks in = the tracker is 2) and 1),

 these non-symmetrical instrument connections are reversed.',

 The preview diagrams in the Instrument Editor <= span class=3DSpellE>window show actual order,

 but here this information is kept in conformity with the official=

 Yamaha YMF= 262 data specification to <= span class=3DSpellE>prevent further confusion.

 

 

  

 TRE= MOLO (AMPLiTUDE MODULATiON)

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 When set, turns tremolo (volume vibrato) ON = for the corresponding slot.

 The repetition rate is 3.7Hz, the depth is optional (1dB/4.8dB).

 

 

 ViBRATO

 ──────&#= 9472;

 

 When set, turns frequency vibrato ON for the corresponding slot.

 The repetition rate is 6.1Hz, the depth is optional (7%/14%).

 

 

 KEY= SCALE RATE (KSR)

 ──────&#= 9472;──────────= ───

 

 When set, makes the sound shorter at higher frequencies.

 With normal musical instruments, the attack = and decay rate becomes faster

 as the pitch increases. The key scale rate controls simulation of

 this effect. An offset (rof) is added to the individual attack, decay,

 and release rates depending on the following formula:

 

 actual_rate =3D = (rate * 4) + rof

 

 The "rof&qu= ot; values for corresponding "rate" value and KSR state are shown

 in the following table:

 

 ┌───────= ;─╥───┬───┬^= 72;──┬───┬───&#= 9516;───┬───┬──= ─┬───┬───┬γ= 2;──┬───┬─── = 516;───┬───┬──&= #9472;┐

  %rate% &#= 9553; 0 = │ 1 = │ 2 = │ 3 = │ 4 = │ 5 = │ 6 = │ 7 = │ 8 = │ 9 = │ A = │ B = │ C = │ D = │ E = │ F = │

 ╞════════= ;╬═══╪═══╪═_= 52;═╪═══╪═══╪&#= 9552;══╪═══╪═══= ╪═══╪═══╪═λ= 2;═╪═══╪═══╪ = 552;══╪═══╪═══&= #9569;

  [OFF]  &#= 9553; 0 = │ 0 = │ 0 = │ 0 = │ 1 = │ 1 = │ 1 = │ 1 = │ 2 = │ 2 = │ 2 = │ 2 = │ 3 = │ 3 = │ 3 = │ 3 = │

 ├────────= ;╫───┼───┼─^= 72;─┼───┼───┼&#= 9472;──┼───┼───= ┼───┼───┼─γ= 2;─┼───┼───┼ = 472;──┼───┼───&= #9508;

  [ON]   &#= 9553; 0 = │ 1 = │ 2 = │ 3 = │ 4 = │ 5 = │ 6 = │ 7 = │ 8 = │ 9 = │ A = │ B = │ C = │ D = │ E = │ F = │

 └────────= ;╨───┴───┴─^= 72;─┴───┴───┴&#= 9472;──┴───┴───= ┴───┴───┴─γ= 2;─┴───┴───┴ = 472;──┴───┴───&= #9496;

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 When set, the sustain level of the voice is maintained until released.

 When clear, the sound begins to decay immediately after hitting

 the sustain phase.

 

 

[OFF]

3Dimage010

 

[ON]

3Dimage011

 

 

 

 ──────&#= 9472;──────────= ────────<= /p>

 

 Sets the multiplier for the frequency data specified by block and

 F-number. This multiplier is applied to the = FM carrier or modulation

 frequencies. The multiplication factor and <= span class=3DSpellE>corresonding harmonic types are

 shown in the following table:

 

 ┌───────= ;┬─────┬───^= 72;──────────&#= 9472;──────────= ──────────γ= 2;┐

  MULT. &#= 9474;  HARMONiC=      &nb= sp;            =          &#= 9474;

 ╞═══════╪= ;═════╪════_= 52;══════════&#= 9552;══════════= ══════════μ= 9;

   [0]  0.5 1 octave below           &nbs= p;         &#= 9474;

   [1]    1  at the voice's specified frequency

   [2]    2  1 octave above           &nbs= p;         &#= 9474;

   [3]    3  1 octave and a 5th above           │<= /span>

   [4]    4  2 octaves above           &nbs= p;        &#= 9474;

   [5]    5  2 octaves and= a Major 3rd above   

   [6]    6  2 octaves and= a 5th above          │<= /span>

   [7]    7  2 octaves and= a Minor 7th above   

   [8]    8  3 octaves above           &nbs= p;        &#= 9474;

   [9]    9  3 octaves and= a Major 2nd above   

   [A]  10  3 octaves and a Major 3rd above   

   [B]  10               ...                    │<= /span>

   [C]  12  3 octaves and a 5th above          │<= /span>

   [D]  12               ...                    │<= /span>

   [E]  15  3 octaves and a Major 7th above   

   [F]  15               ...                    │<= /span>

 └───────= ;┴─────┴───^= 72;──────────&#= 9472;──────────= ──────────γ= 2;┘

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

V. EFFECTS           &n= bsp;    

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

ARPEGGiO

 ──────&#= 9472;───────

 

 This command causes the note to quickly cycle through three notes:

 the note playing, a note 'x' halftones above= ,

 and a note 'y' halftones above.

 This causes an effect similar to old C64 cho= rds.

 Note that the song speed has to be greater or equal to three

 in order to perform arpeggio effect complete= ly.

 

 

FREQUENCY SLiDE UP

 ──────&#= 9472;──────────= ───────

 

 This command slides the frequency up (pitch bend).

 Parameter 'xx' gives speed of slide.

 

 

FREQUENCY SLiDE DOWN<= /p>

 ──────&#= 9472;──────────= ─────────<= /span>

 

 This command slides the frequency down (pitch bend).

 Parameter 'xx' gives speed of slide.

 

 

TONE PORTAMENTO

 ──────&#= 9472;──────────= ────

 

 This command is used together with a note and will slide to its frequency.

 Parameter 'xx' gives speed of slide.

 If you specify 'xx' as '00' then the previous value will be used.

 

 

ViBRATO

 ──────&#= 9472;──────

 

 This command causes the frequency to oscilla= te with depth 'y' at speed 'x'.

 If you specify 'xy' as '00' then the previous value will be used.

 

 

TONE PORTAMENTO WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;

 

 This command executes both Tone portamento and Volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

ViBRATO WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;───

 

 This command executes both Vibrato and Volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FiNE FREQUENCY SLi= DE UP

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command slides the frequency up (pitch bend) once per row.

 Parameter 'xx' gives speed of slide.

 

 

FiNE FREQUENCY SLi= DE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;───

 

 This command slides the frequency down (pitch bend) once per row.

 Parameter 'xx' gives speed of slide.

 

 

SET MODULATOR VOLUME

 ──────&#= 9472;──────────= ─────────<= /span>

 

 This command sets the volume of modulator sl= ot.

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

VOLUME SLiDE

 ──────&#= 9472;──────────= ─

 

 This command fades the volume up or down at = the given speed.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'x' then 'y' is not used, and vice versa.

 

 

PATTERN JUMP=

 ──────&#= 9472;──────────= ─

 

 This command causes the song to jump to order 'xx'.

 This is often used to create looping songs.<= o:p>

 If two 'Bxx' com= mands are given, then the command in the

 higher track will take effect.

 

 

SET iNSTRUMENT VOLUME

 ──────&#= 9472;──────────= ──────────=

 

 This command sets the absolute volume of the instrument.

 It is equal to Ixx command when instrument uses FM connection,

 otherwise both carrier and modulator volume = is updated.

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

PATTERN BREAK

 ──────&#= 9472;──────────= ──

 

 This command signifies the end of the current pattern, and also that

 the next pattern should be played from row '= xx'.

 If two 'Dxx' com= mands are given, then the command in the

 higher track will take effect.

 

 

SET TEMPO

 ──────&#= 9472;────────

 

 This command changes the song tempo (also kn= own as BPM).

 Parameter 'xx' gives hexadecimal value of refresh rate in Hz.

 If two 'Exx' com= mands are given, then the command in the

 higher track will take effect.

 

 

SET SPEED

 ──────&#= 9472;────────

 

 This command changes the song speed.

 Parameter 'xx' gives how many frames to wait before advancing row.

 If two 'Fxx' com= mands are given, then the command in the

 higher track will take effect.

 

 

TONE PORTAMENTO WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────

 

 This command executes both Tone portamento and Fine volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

Vi= BRATO WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────

 

 This command executes both Vibrato and Fine volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

SET CARRiER VOLUME

 ──────&#= 9472;──────────= ───────

 

 This command sets the volume of carrier slot= .

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

SET WAVEFORM=

 ──────&#= 9472;──────────= ─

 

 This command changes the waveform of carrier= or modulator slot.

 Parameter 'x' gives carrier and 'y' modulator waveform type as following:

 

   '0'-'7' means type of waveform,<= /o:p>

   'F' means "no change".=

 

 For more information see chapter IV, part "Waveform select".

 

 

Fi= NE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────

 

 This command fades the volume up or down at = the given speed,

 once per row.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'x' then 'y' is not used, and vice versa.

 

 

RE= TRiG NOTE

 ──────&#= 9472;──────────=

 

 This command retriggs the note after 'xx' frames.

 If no note is specified, last given is used.=

 The lower is the interval, the faster is the retrigger.

 

 

TREMOLO

 ──────&#= 9472;──────

 

 This command causes the volume to oscillate = with depth 'y' at speed 'x'.

 If you specify 'xy' as '00' then the previous value will be used.

 Tremolo acts like vibrato, but changing the volume instead of the pitch.

 

 

TREMOR

 ──────&#= 9472;─────

 

 This command causes the volume to remain nor= mal for 'x' frames,

 then fades the volume to zero for 'y' frames= .

 

 

ARPEGGiO WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 This command executes both Arpeggio and Volu= me slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

AR= PEGGiO WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;─────────

 

 This command executes both Arpeggio and Fine volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

MU= LTi RETRiG NOTE

 ──────&#= 9472;──────────= ──────

 

 This command retriggs the note after 'x' frames with specified

 volume change. Parameter 'y' gives type of volume change:

 

   '0' is None,    '8' is Unused,

   '1' is -1,    &nb= sp; '9' is +1,

   '2' is -2,    &nb= sp; 'a' is +2,

   '3' is -4,    &nb= sp; 'b' is +4,

   '4' is -8,    &nb= sp; 'c' is +8,

   '5' is -16,     '= d' is +16,

   '6' is *2/3,    'e' is *3/2,

   '7' is *1/2,    'f' is= *2.

 

 If no note is specified, last given is used.=

 The lower is the interval, the faster is the retrigger.

 

 

FREQUENCY SLiDE UP WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;───

 

 This command executes both Frequency slide up and Volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FREQUENCY SLiDE DOWN WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────

 

 This command executes both Frequency slide d= own and Volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

Fi= NE FREQUENCY SLiDE UP WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;────────

 

 This command executes both Fine frequency sl= ide up and Volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

Fi= NE FREQUENCY SLiDE DOWN WiTH<= /span> VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────<= o:p>

 

 This command executes both Fine frequency sl= ide down and Volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FREQUENCY SLiDE UP WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;────────

 

 This command executes both Frequency slide up and Fine volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FREQUENCY SLiDE DOWN WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────<= o:p>

 

 This command executes both Frequency slide d= own and Fine volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

Fi= NE FREQUENCY SLiDE UP WITH Fi= NE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──

 

 This command executes both Fine frequency sl= ide up and Fine volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

Fi= NE FREQUENCY SLiDE DOWN WiTH<= /span> FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;────

 

 This command executes both Fine frequency sl= ide down and Fine volume slide.

 Parameter 'xy' g= ives speed of volume slide:

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

SET TREMOLO DEPTH

 ──────&#= 9472;──────────= ──────

 

 This command changes the Tremolo depth of al= l 36 operators.

 Parameter 'x' gives depth:=

 

   '0' is 1dB,

   '1' is 4.8dB.

 

 

SET ViBRATO DEPTH

 ──────&#= 9472;──────────= ──────

 

 This command changes the Vibrato depth of al= l 36 operators.

 Parameter 'x' gives depth:=

 

   '0' is 7%,

   '1' is 14%.

 

 

SET MODULATOR'S ATTACK RATE

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Attack rate".

 

 

SET MODULATOR'S DECAY RATE

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Decay rate".

 

 

SET MODULATOR'S SUSTAiN LEVEL

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Sustain level".

 

 

SET MODULATOR'S RELEASE RATE

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Release rate".

 

 

SET CARRiER'S ATTACK RATE

 ──────&#= 9472;──────────= ──────────γ= 2;───

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Attack rate".

 

 

SET CARRiER'S DECAY RATE

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Decay rate".

 

 

SET CARRiER'S SUST= AiN LEVEL

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Sustain level".

 

 

SET CARRiER'S RELEASE RATE

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Release rate".

 

 

SET FEEDBACK STRENGTH

 ──────&#= 9472;──────────= ──────────=

 

 This command changes the Feedback strength of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Feedback strength".

 

 

SET PANNiNG POSiTiON

 ──────&#= 9472;──────────= ─────────<= /span>

 

 This command changes the panning of current instrument.

 Parameter 'x' gives position:

 

   '0' is center,

   '1' is left,

   '2' is right.

 

 

PATTERN LOOP=

 ──────&#= 9472;──────────= ─

 

 Syntax: ZC0 - Set loopback point<= /span>

         <= span class=3DSpellE>ZCx - Loop x times.

 

 This pattern space-saving feature will cause= the pattern

 to be looped 'x' times back to the last ZC0 command.

 Note that you can only loop within the patte= rn, and each track

 has its own loopback information, so you are supposed to have

 corresponding ZC0 and Z= Cx commands in the same track in order to operate.

 If ZCx commands = are put in both effect columns, only the one in first

 column will operate.

 

 

RE= CURSiVE PATTERN LOOP

 ──────&#= 9472;──────────= ──────────γ= 2;

 

 Syntax: ZD0 - Set loopback point<= /span>

         <= span class=3DSpellE>ZDx - Loop x times.

 

 This command is recursive variant of ZCx effect command.

 It means that when such kind of loop is loca= ted inside other "parent" loop,

 it is proceeded any time it is passed by this loop.

 Note that using ZC0 instead of ZD0 command h= as the same effect.

 Please keep in mind that ZDx command should not be used in combination

 with ZCx command= in other effect column, otherwise it will cause an

 endless loop.

 

 

 [ZE0/ZE1] TOGGLE MACRO KEY-OFF LO= OP

 ─&#= 9472;──────────= ──────────γ= 2;────────── = 472;─

 

 This comm= and temporarily turns on-or-off looping

 of Key-Off phase in macro-table for current instrument.

 Parameter= 'x' gives the state to toggle:

 

   '0' is = OFF,

   '1' is = ON.

 

 Note that "temporarily" means that the change is valid until there will be<= o:p>

 set diffe= rent instrument than is the current one, for which this command

 is to be = used.

 

 

 [ZE2/ZE3] TOGGLE RESTARTiNG ENVOLOPE WiTH TONE PORTAMENTO=

 ─&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──────────= ;──

 This comm= and turns on-or-off restarting of ADSR envelope for current track.

 It means,= that the note key will be retriggered for every row with non-empty

 input in = the note column (rows where note culumn is empty ar= e not affected).

 Parameter= 'x' gives the state to toggle:

 

   '2' is = OFF,

   '3' is = ON.

 

 

 [ZE4] PERFORM RESTART ENVELOPE

 ─&#= 9472;──────────= ──────────γ= 2;───────

 This comm= and restarts ADSR envelope for current instrument.

 

 

 [ZE5/ZE6] TOGGLE 4OP TRACK VOLUME= LOCK

 ─&#= 9472;──────────= ──────────γ= 2;────────── = 472;────

 This comm= and turns on-or-off 4OP Track Volume Lock.

 If 4OP Tr= ack Volume Lock is set, some of the volume effect commands

 will work= in 4OP mode instead of default (2OP) mode. This means,

 that volu= me attenuation is calculated according 4OP connection

 of the 2 = used instruments in track 2) and 1), and you don't have to

 manage carrier/modulator output level to get desired volume level

 during playback.

 Parameter= 'x' gives the state to toggle:

 

   '5' is = OFF,

   '6' is = ON.

 

 Here is a complete list of commands that are affected by this lock:=

 5xy/6xy, = Axy, Cxx, Gxy/Hxy, Kxy, Mxy, Rxy/Sxy, Txy/Uxy,

 Vxy/Wxy, Xxy/Yxy, ^xy, %xx<= /span>

 

 Please no= te that when the 4OP Track Volume Lock is set for particular=

 4OP track= s, setting of 'Volume Scaling' is ignored (it is mandatory ON).

 

 

RELEASE SUSTAiNiNG SOUND

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 This command causes the track volume to fade down immediately.

 Note that it nulls current Attack rate, Decay rate,

 Sustain level, and Release rate.<= /span>

 

 

RESET iNSTRUMENT VOLUME

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command resets back to modulator and ca= rrier volume

 defined in modulator and carrier slot of cur= rent instrument.

 

 

TOGGLE TRACK VOLUME LOCK

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 This comm= and turns on-or-off the Volume Lock for current track.

 It means,= that the track volume will remain constant for entire track.

 This cons= tant is updated when using volume effect commands,

 or when u= sing new instrument.

 Parameter= 'x' gives the state to toggle:

 

   '2' is = ON,

   '3' is = OFF.

 

 

TOGGLE VOLUME PEAK LOCK

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 This comm= and turns on-or-off the Volume Peak Lock for current track.

 It means,= that when performing a Volume Slide, the upper limit of track<= /p>

 volume wi= ll remain lower or equal to volume level specified in carrier

 and modul= ator slot of corresponding instrument.

 Note that= lock affects Volume Slide and Fine Volume Slide effects

 as well as Tremolo, Tremor and Multi Retrig Note effects.<= o:p>

 Parameter= 'x' gives the state of lock to toggle:

 

   '4' is = ON,

   '5' is = OFF.

 

 

TOGGLE MODULATOR VOLUME SLiDES

 ──────&#= 9472;──────────= ──────────γ= 2;────────

 

 This command toggles volume slide for modula= tor slot only. If used together

 with ZF7 effect command, it toggles volume s= lide for both slots.

 Note that command will affect Volume Slide a= nd Fine Volume Slide effects

 as well as Tremolo, Tremor and Multi Retrig Note effects.

 

 

TOGGLE CARRiER VOLUME SLiDES

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 This command toggles volume slide for carrier slot only. If used together

 with ZF6 effect command, it toggles volume s= lide for both slots.

 Note that command will affect Volume Slide a= nd Fine Volume Slide effects

 as well as Tremolo, Tremor and Multi Retrig Note effects.

 

 

TOGGLE DEFAULT VOLUME SLiDES=

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 This command toggles default volume slides.<= o:p>

 It means, that replay routine will distingui= sh which slot (carrier or both)

 to proceed from connection type (see chapter= IV, part "Connection type").

 Note that command will affect Volume Slide a= nd Fine Volume Slide effects

 as well as Tremolo, Tremor and Multi Retrig Note effects.

 

 

TOGGLE TRACK PANNiNG LOCK

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 This command enables the Panning Lock.<= /o:p>

 It means, that current panning position is f= orced for entire track,

 and can be updated only by ZBx effect command.

 This comm= and turns on-or-off the Panning Lock for current track.

 It means,= that current panning position is forced for entire track,

 and can be updated only by ZBx effect command.<= /span>

 Parameter= 'x' gives the state of lock to toggle:

 

   '9' is = ON,

   'A' is = OFF.

 

 

ViBRATO OFF

 ──────&#= 9472;──────────=

 

 This command marks the end of Vibrato effect= .

 It will restore the last frequency before Vibrato effect.

 

 

TREMOLO OFF

 ──────&#= 9472;──────────=

 

 This command marks the end of Tremolo effect= .

 It will restore the last volume before Tremo= lo effect.

 

 

FORCE FiNE ViBRATO= (FORCE FiNE GLOBAL FREQ. S= LiDE)

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──────

 

 This command has to be used together with 4x= y, 6xy or Hxy (>xx, <xx)

 effect command. It will cause the Vibrato (Global Freq. Slide Up/Down)

 effect to= be performed once per row instead of every frame.

 Note that the switch is reset at the end of effect.

 

FORCE FiNE TREMOLO (FORCE EXTRA FiNE GLOBAL FREQ. SLiDE)<= o:p>

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──────────= ;──

 

 This command has to be used together with Mxy (>xx, <xx)

 effect command. It will cause the Tremolo (Global Freq. Slide Up/Down)

 effect to= be performed once per row (once per every four frames).

 Note that the switch is reset at the end of effect.

 

 

FORCE NO RESTART FOR MACRO TABLES

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;

 

 1) This command can be used together with !xx (@xx) effect command.

    It will cause that the arpeggio (vibrato) table is swapped

    without restarting position. It means that the current position

    is maintained as the starting p= oint in new table.

 2) This command can be used while new note is triggered and the instrument

    that is played is using FM-regi= ster macro (arpeggio macro, vibrato

    macro resp.) In such case the m= acro is not restarted, which means that

    the current position in FM-regi= ster (arpeggio, vibrato resp.) macro

    table is maintained.=

 

 

SET CONNECTiON TYPE

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command sets the connection type of cur= rent instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Connection type".

 

 

SET MODULATOR'S MULTiPLiER

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 This command sets the modulator's multiplier= of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Frequency data multiplier".

 

 

SET MODULATOR'S KSL

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command sets the modulator's scaling le= vel of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Key scaling level".

 

 

SET MODULATOR'S TREMOLO

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command sets the modulator's tremolo on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Tremolo (Amplitude modulation)".

 

 

SET MODULATOR'S ViBRATO

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command sets the modulator's vibrato on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Vibrato)".

 

 

SET MODULATOR'S KSR

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command sets the modulator's KSR on-or-= off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Key scale rate".

 

 

SET MODULATOR'S SUSTAiN

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command sets the modulator's sustain on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part &q= uot;Sustain (Envelope generator)".

 

 

SET CARRiER'S MULT= iPLiER

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 This command sets the carrier's multiplier of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Frequency data multiplier".

 

 

SET CARRiER'S KSL

 ──────&#= 9472;──────────= ──────

 

 This command sets the carrier's scaling leve= l of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Key scaling level".

 

 

SET CARRiER'S TREMOLO=

 ──────&#= 9472;──────────= ──────────=

 

 This command sets the carrier's tremolo on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Tremolo (Amplitude modulation)".

 

 

SET CARRiER'S ViBR= ATO

 ──────&#= 9472;──────────= ──────────=

 

 This command sets the carrier's vibrato on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Vibrato)".

 

 

SET CARRiER'S KSR

 ──────&#= 9472;──────────= ──────

 

 This command sets the carrier's KSR on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Key scale rate".

 

 

SET CARRiER'S SUSTAiN

 ──────&#= 9472;──────────= ──────────=

 

 This command sets the carrier's sustain on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Sustain (Envelope generator)".

 

 

PATTERN DELAY (FRAMES)

 ──────&#= 9472;──────────= ──────────γ= 2;

 

 This command will delay the pattern 'x' fram= es.

 If two '&0x' commands are given, then the command in the

 higher track will take effect.

 

 

PATTERN DELAY (ROWS)

 ──────&#= 9472;──────────= ─────────<= /span>

 

 This command will cause a pause on the row f= or effectively 'x' rows longer.

 If two '&1x' commands are given, then the command in the

 higher track will take effect.

 

 

NOTE DELAY

 ──────&#= 9472;─────────

 

 This command will delay the note 'x' frames.=

 

 

NOTE CUT

 ──────&#= 9472;───────

 

 This command cuts the note (Key-Off will be performed) after 'x' frames.

 

 

FiNE-TUNE UP

 ──────&#= 9472;──────────= ─

 

 This command fine-tunes frequency up.

 If used together with a note, it overrides t= he default note frequency

 before the note is outputted (acts like fine-tune parameter

 included in instrument data).

 Parameter 'x' gives frequency shift.

 

 

FiNE-TUNE DOWN

 ──────&#= 9472;──────────= ───

 

 This command fine-tunes frequency down as st= ated above.

 

 

GLOBAL VOLUME SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;

 

 This command fades the global volume up at t= he given speed.

 Parameter 'x' gives speed of slide.

 

 

GLOBAL VOLUME SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 This command fades the global volume down at= the given speed.

 Parameter 'x' gives speed of slide.

 

 

FiNE GLOBAL VOLUME SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 This command fades the global volume up at t= he given speed,

 once per row.

 Parameter 'x' gives speed of slide.

 

 

FiNE GLOBAL VOLUME SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 This command fades the global volume down at= the given speed,

 once per row.

 Parameter 'x' gives speed of slide.

 

 

EXTRA FiNE GLOBAL VOLUME SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;

 

 This command fades the global volume up at t= he given speed,

 once every four frames.

 Parameter 'x' gives speed of slide.

 

 

EXTRA FiNE GLOBAL VOLUME SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──

 

 This command fades the global volume down as stated above.

 

 

EXTRA FiNE VOLUME SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 This command fades the volume up at the given speed,

 once every four frames.

 It means that you can do four times more accurate slide effects.

 Parameter 'x' gives speed of slide.

 

 

EXTRA FiNE VOLUME SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 This command fades the volume down as stated above.

 

 

EXTRA FiNE FREQUENCY SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 This command slides frequency up (pitch bend= ), once every four frames.

 It means that you can do four times more accurate slide effects.

 Parameter 'x' gives speed of slide.

 

 

EXTRA FiNE FREQUENCY SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;─────────

 

 This command slides frequency down as stated above.

 

 

EXTRA FiNE ARPEGGiO

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command is a variant of 0xy (Arpeggio) effect command.

 It executes the arpeggio once every four fra= mes.

 It means that you can do four times more accurate arpeggio effects.

 Note that the song speed doesn't have to be greater or equal to three

 as it is in case of normal arpeggio.

 

 

EXTRA FiNE ViBRATO

 ──────&#= 9472;──────────= ───────

 

 This command is a variant of 4xy (Vibrato) effect command.

 It executes the vibrato once every four fram= es.

 It means that you can do four times more accurate vibrato effects.

 

 

EXTRA FiNE TREMOLO

 ──────&#= 9472;──────────= ───────

 This command is a variant of Mxy (Tremolo) effect command.

 It executes the tremolo once every four fram= es.

 It means that you can do four times more accurate tremolo effects.

 

 

SWAP ARPEGGiO TABLE

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command temporarily swaps the arpeggio table for current instrument.

 Parameter 'xx' gives number of new table.

 Note that the number of arpeggio table in instrument macro-table

 remains intact, and "temporarily" = means that the change is valid until

 there is another note or instrument set.

 

 

SWAP ViBRATO TABLE

 ──────&#= 9472;──────────= ───────

 

 This command temporarily swaps the vibrato t= able for current instrument.

 Parameter 'xx' gives number of new table.

 Note that the number of vibrato table in instrument macro-table

 remains intact, and "temporarily" means that the change is valid until

 there is another note or instrument set.

 

 

FORCE iNSTRUMENT VOLUME

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command is a variant of Cxx (Set Instrument volume) effect command.

 The difference is in modulator's role when affecting volume, because

 it scales the modulator volume according to = 'xx' value, no matter what is

 the connection type of the instrument.<= /o:p>

 Note that the carrier volume is set as usual= .

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

SET GLOBAL VOLUME

 ──────&#= 9472;──────────= ──────

 

 This command sets the global volume of song.=

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

GLOBAL FREQ. SLiDE UP=

 ──────&#= 9472;──────────= ──────────=

 

 This command slides the frequency up (pitch bend) in all tracks

 from curr= ent to last, if it’s not overridden by using another

 '<xx' = or '>xx' in second effect column or one of succeeding tracks.

 Parameter 'xx' gives speed of slide.

 

 Note that= you can also use Fine or Extra Fine variant of this command

 by putting command switch 'ZFD' or 'ZFE' into second effect column.<= /p>

GLOBAL FREQ. SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command slides frequency down as stated above.

SET CUSTOM SPEED TABLE

 ──────&#= 9472;──────────= ──────────γ= 2;

 This comm= and sets custom speed table for Vibrato/Tremolo effect,

 which is generated according given parameter 'xx':
 

   '00' =     Reset default speed table
   '01-FF'  Calculate custom speed table with param= eters
            table size, maximum va= lue and processing speed factor

           ┌───= ─────────┬γ= 2;─────┬──── = 472;───┬──────&= #9472;─┐
           PARAMETE= R  SiZE MAX.   FACTOR
           ╞═══&#= 9552;════════╪═= ═════╪════λ= 2;═══╪══════ = 552;═╡
           [01]..[EF] 32   │<= /span> 01..EF x1     │<= /span>
           [F0]..[F3] 32   FF     x1..x4
           [F4]..[F7] 64   FF     x1..x4
           [F8]..[FB] 128  FF     x1..x4
           [FC]..[FF] 256  FF     x1..x4
           └───&#= 9472;────────┴─= ─────┴────γ= 2;───┴────── = 472;─┘


 For information on custom speed ta= bles please refer to:
 http://www.adlibtracker.net/files/techinfo.htm

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

V= I. SONG VARiABLES     = ;    ∙

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 ──────&#= 9472;─

 

 You can specify how should be the song called here.

 The maximal length of string is 42 character= s.

 

 

 ──────&#= 9472;─

 

 You can specify who was the creative person = that made the song here.

 The maximal length of string is 42 character= s.

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──

 

 These are just values for information about number of common items used.

 You cannot change them since they are calcul= ated by the tracker.

 

 

 ──────&#= 9472;───

 

 With range 1-255, you can specify what will = be the initial song tempo here.

 The value is decimal, the unit used is "frames per second" (Hz).

 However, you can calculate the tempo also in "beats per minute" (BPM)

 with the following formula:

 

   (tempo_in_Hz * 2.5) =3D tempo_in_BPM

 

 

 ──────&#= 9472;───

 

 With range 1-FF, you can specify what will be the initial song speed here.

 The value is hexadecimal, the unit used is "frames per row".

 There is also an Update switch beside the so= ng speed field.

 You can specify there, whether the song speed should be reset to "initial"

 when song loops back to order 0.<= /span>

 

 

 ──────&#= 9472;────

 

 With optional range, you can specify what wi= ll be the multiplying factor

 for macro-definitions here.

 

 i.e. 1 means that the macro commands will be triggered once per frame,

      2 means twice per f= rame (speed-up is 2),

      3 means three times= per frame (speed-up is 3), and so on.

 

 

 ──────&#= 9472;──────────=

 

 You can specify the initial Volume Lock state here.

 If Volume Lock is set, you can also set its initial settings for all

 available tracks in the Initial Lock Setting= s.

 For more information see chapter V, part "Lock track volume".

 

 

 ──────&#= 9472;──────────= ─

 

 You can specify the initial Panning Lock sta= te here.

 If Panning Lock is set, you can also set its initial settings for all

 available tracks in the Initial Lock Setting= s.

 For more information see chapter V, part "Lock track panning".

 

 

 ──────&#= 9472;─────────

 

 You can specify the initial Peak Lock state here.

 If Peak Lock is set, you can also set its initial settings for all

 available tracks in the Initial Lock Setting= s.

 For more information see chapter V, part "Lock volume peak".

 

 

 ──────&#= 9472;──────────= ───

 

 You can specify whether to use the 4-operator track extension

 on corresponding tracks here.

 Note that this adjusts the number of tracks = if neccessary.

 This mode is a bit complicated so it is recommended=

 to experiment to gain familiarity with making 4-op instruments= :-)

 

 

 ──────&#= 9472;──────

 

 You can specify the initial tremolo depth he= re.

 See also chapter V, part "Tremolo"= .

 

 

 ──────&#= 9472;──────

 

 You can specify the initial vibrato depth he= re.

 See also chapter V, part "Vibrato"= .

 

 

 ──────&#= 9472;───────

 

 With range 1-256, you can specify what will = be the pattern length here.

 Note that the pattern length value affects w= hole song.

 

 

 ──────&#= 9472;─────────

 

 With range 1-20, you can specify what will be the number of tracks here.

 Note that value above 18 automatically toggl= es percussion mode ON.

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;────

 

 You can specify whether to use 5 percussion tracks here.

 Note that percussion mode automatically chan= ges the number of tracks to 20,

 but you can decrease the value as neccessary though.

 This mode is slightly hard to use (particularly the "SD/TT/TC/HH" tracks)

 so it is not recommended unless you know how it works or gain familiarity

 with it after several experiments :-)

 

 

 ──────&#= 9472;───────

 

 (iMPORTANT OPTiON)

 You can specify whether to use volume scaling mode here.

 Volume scaling mode differs from default mod= e in handling the volume

 when performing effect commands. When in def= ault mode, the volume is set to

 value requested in effect column whatever is= the base volume specified in

 carrier or modulator cell of instrument.

 When in volume scaling mode, any change of volume with effect command is

 calculated as scaled base volume of instrume= nt.

 

 

 ──────&#= 9472;──────────= ────

 You can specify the initial settings of Pann= ing Lock, Volume Slide type,

 Volume Lock, and Peak Lock for corresponding track here.

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

V= II. GETTiNG STARTED     &nbs= p; ∙

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 Any piece of music written with the /┤= DLiB TR/┤CK3R ][ is built up<= /p>

 from patterns. Each pattern is built up from= 1 to 18/20 tracks.

 A pattern is 1 to 256 lines long. The line w= here the cursor is always

 the one you edit. If you need shorter patter= ns and you don't want

 to shorten the overall pattern length in song variables,

 use the Pattern Break effect command (Bxx).

 A track is built up like this:

 

        &n= bsp;     ┌────┬────γ= 2;────────── = 472;───┬────

        &n= bsp;     │LiNE1     = ;            │ 2

        &n= bsp;     ├────┼────γ= 2;────────── = 472;───┼────

        &n= bsp;     │ 37 │ ···  ··  ···  ··· │ ···

        &n= bsp;     │ 38 │ A#5  01  ···  ··· │ ···

        &n= bsp;     │ 39 │ A-4  ··  330  ··· │ C-2

        &n= bsp;     │ 3A │ ···  ··  300  ··· │ ---

        &n= bsp;     │ 3B │ ···  ··  300  ··· │ ···

        &n= bsp;     │ 3C │ ···  ··  ···  ··· │ D#2

        &n= bsp;     │ 3D │ D#1  02  ···  ··· │ ---

        &n= bsp;     │ 3E │ C-2  01  ···  ··· │ ···

   current ──>│ 3F │ C-4  01  C20  201 │ C-2<= o:p>

   line     &nb= sp; │    │           &n= bsp;       │

        &n= bsp;     │    │       =             │

        &n= bsp;     └────┴────γ= 2;────────── = 472;───┴────

        &n= bsp;            ^    ^   ^    ^

        &n= bsp;            │    │   │    = 474;

        &n= bsp;            │    │   │    = 492;─ effect command 2

        &n= bsp;      note ─┘    │   │

        &n= bsp;            = ;     │   └─ effect command 1

        &n= bsp;            = ;     │

        &n= bsp;            = ;     └─ instrument

 

 The C-4 is the note being played at pattern position 3F,

 01 is the instrument number, and the followi= ng six digits are the

 two effect commands, in this case, Set Volum= e to 20 Hex, and Frequency

 Slide Down by 1 unit per frame. Remember that values for instruments

 and effects are always hexadecimal!

 You can enter the note by switching into MBoard mode while the song

 is Stopped or while the song is Paused with = no Trace or by setting this

 mode OFF (Shift+Space to toggle) then by just typing the note into

 the corresponding fields.<= /p>

 Likewise, you can either type in the instrum= ent number.

 The instrument number corresponds to the act= ive instrument.

 You can check the active instrumet at the bottom of main screen or directly

 in the Instrument Control panel.<= /span>

 If in MBoard mod= e, this will be entered automatically when a note

 is entered through the keyboard (MBoard keys).

 Typing in the instrument number (if "update_ins" option is ON) will affect=

 the numbers in following lines and the active instrument in Instrument

 Control panel. After you have edited all your patterns, you have

 to determine the pattern order. For that sim= ply use the Pattern Order

 editor. Enter (while the song is Stopped or while it is

 Played with no Trace) will toggle the Pattern Order editor.

 Furthermore, you can define a restart positi= on.

 Here's an example:

 

 Let's say you have entered three patterns (numbers 0, 1 and 2) and

 want to play the pattern 2 twice, then patte= rn 0 and finally

 pattern number 1 three times. Afterwards the music should start

 from order 2 (with the pattern 0) again.

 Edit the pattern order like this:=

 

        &n= bsp;     ┌─────────γ= 2;─────

        &n= bsp;     │ 00 0204 = 01

        &n= bsp;     │ 01 02 │ 05 01

        &n= bsp;     │ 02 00 │ 06 82 <───&#= 9472; jump to order 2

        &n= bsp;     │ 03 01 │ 07 80

        &n= bsp;     └─────────γ= 2;─────

        &n= bsp;       ^  ^

        &n= bsp;       │  │

        &n= bsp;       │  └─ pattern number (entry)

        &n= bsp;       │

        &n= bsp;       │

        &n= bsp;     order number

 

 To enter the notes /┤DLiB TR/┤CK3R ][ uses a piano-like keyboard layout

 when in MBoard m= ode (see chapter III, part "I" for the layout).

 The program supports 8 octaves. You can see = the active octave in the bottom

 of main screen or directly in the Octave Con= trol panel.

 When both MBoard= and Tracking mode are OFF, you can type in the notes

 into their corresponding fields.<= /span>

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

V= III. USEFUL TiPS     &n= bsp;    ∙

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

   The tracker= is capable of highlighting corresponding lines.

         Y= ou can toggle this mode on-and-off with Alt+M, and= setup by Alt+L.

 

   You can pre= view an instrument before loading it.

         In the file open dialog or bank browser, use MBoard keys while

         cursor is positioned on instrument you want to preview.

 

   When in Deb= ug mode, you can trace the song row by row

         w= ith Space key from Pattern Editor as well as from Debug info<= /p>

         window toggled by holding Ctrl+Alt. When the so= ng is played

         w= ith Trace, you can temporarily turn on Debug mode and process=

         r= ow by row playing with Space key directly from Debug info window.

 

   When transposing patterns, it's sometimes useful to keep some of

         n= otes intact from changes (e.g. drums).

         Y= ou can do that by holding Right-Shift key while putting notes

         u= sing MBoard keys, or you can remark already put notes to-or-from

         f= ixed state in single steps or in blocks by Shift+Enter.

 

   You can for= ce /┤DLiB TR/┤CK3R ][ to behave like Scream Tracker = or

         <= span class=3DSpellE>FastTracker when typing in commands within the Pattern Editor

         a= nd Macro Editor window.

 

       &nbs= p;            &= nbsp;              ┌─────&= #9472;──────────= ;────────┐=

        &n= bsp;            = ;              ADTRACK2.iNi SETTiNGS 

                                   │<= /span> FOR DEFAULT MODE:     

        &n= bsp;┌&= #9472;──────────= ;───────┬──^= 72;───┤command_typing=3D” AND 
         TYPiNG M= ODE      FLAG cycle_pattern=3D”      

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>╞&= #9552;══════════= ;═══════╪══_= 52;═══╪══════&#= 9552;══════════= ═══════╡<= /span>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> Adlib Tracker II   AT        1/OFF           

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> FastTracker        FT        1/ON &nbs= p;           │<= /span>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> Scream Tracker     ST  │<= /span>       2/OFF           

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>└&= #9472;──────────= ;───────┴──^= 72;───┴──────&#= 9472;──────────= ───────┘<= /span>

 

         Y= ou can set each of these modes as default mode on program start
         with corresponding setting= s in configuration file as shown

         i= n the above table. You can, however, switch over these modes
         anytime later, using respe= ctive combination of keys.

         P= lease note that when you set command typing to 0 (mOrOn),
         you cannot switch over any= of these modes.

 

   You are reminded of changes you have made to the song.

         In the status window, a small diskette icon appears in case there

         w= ere changes since last loading or saving.

 

   You can get information about track properties while Playing,

         Debugging, Tracking or even if song is Paused in the

         u= pper area of Pattern Editor (beside corresponding track number).

 

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>┌&= #9472;────┬─────= ;──────────^= 72;──────────&#= 9488;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> ()  panning Center           │<= /span>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> (   │<= /span> panning Left            = ; │<= /span><─ if panning indicator

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span>  )  panning Right            │<= /span>   changes color, it means that

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>├&= #9472;────┼─────= ;──────────^= 72;──────────&#= 9508;   the Panning Lock has been

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span>1'4OP first 4-op tr= ack (main)     activated/deactivated;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span>2'4OP second 4-op track           f= or more information,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> BD  Bass Drum track          │<= /span>   see chapter V, effect ZBx,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> SD  Snare Drum track            a= nd effect ZF9, and also

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> TT  Tom Tom track            │<= /span>   chapter VI, part "Track Panning

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> TC  Top Cymbal track            Lock"

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> HH  Hi-Hat track&= nbsp;            &#= 9474;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>├&= #9472;────┼─────= ;──────────^= 72;──────────&#= 9508;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> M^  Modulator vol= ume slides  <─ for more information,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> C^  Carrier volume slides       see chapter V, effects ZF6,<= o:p>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> &^  Car w/ M= od volume slides    ZF7 and ZF8

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>├&= #9472;────┼─────= ;──────────^= 72;──────────&#= 9508;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> P+  Peak Lock active         <─ for more information,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> V+  Volume Lock active          see chapter V, effect ZF2,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>└&= #9472;────┴─────= ;──────────^= 72;──────────&#= 9496;   and effect ZF4

 

   You are abl= e to gain different setups for corresponding directory

         by creating directory-specific configuration.

         Simply place your "ini" file where yo= u want to use corresponding

         s= etup, and run the tracker from within this directory (it's useful

         to make a batch file there).

 

   You can use= shortkey [BackSpace] for = upper-dir and [\] for root

         in File Selector.

 

  You can play your songs one after another by pressing Shift+Enter=

         instead of Enter key in File Selector.

 

  While working with 4-op tracks, marking instruments

         in Instrument Control panel will choose a set of instruments=

         f= or corresponding 4-op tracks. Two instruments will be then

         always used as "current" instead of one.

         Y= ou can keep track of them in the Instrument Control panel as well

         a= s in the Status Line.

 

  While working with 4-op tracks, panning works within both

         c= hannels if you have used some AM connection at least in one

         of the two instruments. You are then able for example play some

         operators in one channel and others elsewhere.

 

  While working with instrument macro-definitions, don't forget

         to paste appropriate instrument data to FM-register table

         f= irst in order to use it. You can do that with ^Enter key, which

         pastes default instrument data to current row.

 

  While working with clipboard, you can use paste same copied object

         t= o more pattern(s) quite easily. Simply copy the object to clipboard

         as usual, and press [Alt][Shift] P key.

         T= hen the Pattern List will appear, where you can select a single pattern

         or multiple patterns with [Space] as a destination.

         T= hen press Enter key to apply.

 

  You can load a pattern to a multiple destination--pattern(s) when

         in Pattern List and there are some marked patterns.

         Simply mark one or several patterns with [Space] and load=

         desired pattern file.

 

  If working with percussion mode (respect then :) percussion

         tracks SD/TT/TC/HH may stop responding. Go to the File Variables=

         window and set the percussion mode switch off-and-on.

         A= fter 1-3 retries the tracks should start responding again.

 

  While testing/previewing an instrument within Instrument Control,

         Instrument Editor or bank browser, you can check the macro table=

         k= ey-off phase of this instrument. In order to do that,

         h= old [Ctrl] key before releasing the MBoard key, and note(s) will

         t= rail in key-off phase until you release [Ctrl] key.

         Furthermore, you can check the key-off phase with "key-off loop".=

       &nbs= p; In this case, hold the Ctrl+Alt keys pressed when releasing

         t= he MBoard key.

 

  The tracker featu= res both simple playback mode and playback mode

         w= ith synchronization. The advantage of synchro-playb= ack is that

         y= ou can gain authentic and accurate sound at any time and any point.=

         T= he playback is synchronized everytime when it's neccassary, so

         a= ll the playing effects, song tempo, song speed, song timer a.o. are

         j= ust the same as they are when playing whole song from start.

         T= he disadvantage is that it sometimes takes awhile = (maybe longer :)

         w= hen playback synchronizes (depending on CPU and song structure)

         Anyway, you can leave the sync-mode using [Alt] variant of playback

         <= span class=3DSpellE>shortkey (i.e. Alt+F5, Alt+F8 and Alt+F9) even if the= song

         is already playing. Note that you can set up playing without=

         synchronization as the default action in configuration file (set=

         option "nosync_by_default" to ON).

 

  You can play the current pattern in single-playing mode.

         It means, that you are able to play patterns that are not signed

         in pattern order. The whole pattern is played with repeating then.<= /span>

         Y= ou can toggle this playback mode with Alt+F6.

 

  If working with macro-definitions, you can disable one or more

         columns in FM-register table. This is useful when you need

         to change only single or a few parameters (i.e. volume fading,

         p= itch sliding) with macro-definitions and other parameters

         w= ith pattern effects. This mode works similary as disabling tracks

         in Pattern Editor, but using Ctrl+Backspace for si= ngle

         ON/OFF instead.

 

  When making macro-instruments, it's sometimes useful to reset

         t= he ADSR envelope several times during macro-cycle. You can do this<= /span>

         by setting the note retrigger for appropriate row of macro-table;

         <= span class=3DSpellE>Ctrl+N toggles ON the retrigger for corresponding row= and Ctrl+Alt+N

         resets flags on all rows.

 

  You can control t= he playback from within the Instrument Control

         panel. Following commands are functional:

 

         F5            &= nbsp;  Play

         F6            &= nbsp;  Pause

         F7            &= nbsp;  Stop

         F9            &= nbsp;  Play current pattern or order only=

         [Ctrl] Home,End  * Skip to previous/next p= attern while Tracing

         +,-              * Same as above; play pattern from st= art

 

         N= OTE: Commands marked with asterisk (*) work only while the name

        &n= bsp;      of instrument is not being edited.

 

  You can control current instrument directly in Macro Editor window

         u= sing Ctrl+[] keys. It is even possible to control current instrument
         and octave while in macro-preview mode.

 

  When working with= /┤DLiB TR/┤CK3R ][ native bank files (A2B, A2W),<= br>          you can force loading comp= lete bank instead of going to bank browser.
         This can be done easily by pressing Shift+Enter instead of Enter key
         in File Selector.

 

 TiP 25  All options from config file can be cont= rolled also directly

         f= rom command line. Syntax for usage is as following:

 

           "adtrack2.exe [[/cfg:option] [...]]= "

           e.g. "adtrack2.exe /cfg:sdl_screen_mode=3D2 /cfg:sdl_frame_rate=3D150"

 

 TiP 26  When deleting notes in Note Recorder mode, you can fast-forward=

         or rewind playback while deleting them. All you need to do is

         p= ress Up or Down key while still holding the Backspace key.

         Furthermore, you can delete all notes within marked group of tracks<= o:p>

         a= t once with pressing Ctrl+Backspace.=

 

 TiP 27  When deleting notes in Note Recorder mode, you can fast-forward=

         or rewind playback while deleting them. All you need to do is

         p= ress Up or Down key while still holding the Backspace key.

 

 TiP 28  When working with banks containing 4OP instruments, it may be

         sometimes useful to put instrument data from one of the 2 paired

         instruments only. This can be done by pressing = Shift+Enter

         i= nstead of Enter (which puts instrument data for complete 4OP pair).

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I= X. KNOWN PROBLEMS         ∙<= o:p>

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 There are no major issues known for this version of program J

 REMiNDER
 ────────
 If you are encountering any proble= m with this program, please send
 a bugreport to my email address (stated below in this document).

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

X= . EPiLOGUE       = ;         ∙

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 HON= EST 'THANK YOU' TO FOLLOWiNG PEOPLE<= /span>

 ──────&#= 9472;──────────= ──────────γ= 2;──────────

 

 (in random order)

 

 Florian <= span class=3DSpellE>Klaempfl and others [Free Pascal Compiler 2.6.4]=

 Simple DirectMedia Layer [SDL 1.2.15]

 Daniel F.= Moisset [SDL4Freepascal-1.2.0.0]

 Alexey Khokholov [NukedOPL3 1.6]

 Haruhiko = Okomura & Haruyasu Yoshizaki [LZH algorithm]

 Markus Oberhumer, Laszlo Molnar & John = Reiser [UPX 3.91w]

 

 (further in alphabetical order J)

 

 Daniel Illgen (insane/Altair)

 David Cohen = (Diode Milliampere)

 Dmitry Smagin

 Janwillem Jagersma

 Florian Jung (Windfisch)

 Maan M. Hamze<= /span>

 Mikkel Hastrup (encore)

 Nick Balega

 PissMasterPlus

 Slawomir Bubel (Malfunction/Altair)

 Sven Renn= er (NeuralNET)

 Tyler Montbriand (Corona688)

 

 

 ──────&#= 9472;──────────= ──────────=

htt= p://www.adlibtracker.net

 

 For compl= ete AT2 revision history please refer to:

 http://www.adlibtracker.net/files/revision.htm

 For complete AT2 file format description please refer to:
 http://www.adlibtracker.net/files/techinfo.htm

 

 SEN= D YOUR QUESTiONS, SUGGESTiONS, AND CRiTiCiSM TO

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;

 = subz3ro.altair@gmail.com

                                                =                             W= 29;

∙              &nb= sp;            =             &nb= sp;            =             &nb= sp;          ∙=

∙       &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;     │

└──────&= #9472;─────────∙= ;∙           ∙∙────────γ= 2;─∙∙        &nbs= p;        ∙∙────────γ= 2;────┘

 

 This document was last updated on July 24, 2= 016.

------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/item0033.xml Content-Transfer-Encoding: quoted-printable Content-Type: text/xml ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/props034.xml Content-Transfer-Encoding: quoted-printable Content-Type: text/xml ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/themedata.thmx Content-Transfer-Encoding: base64 Content-Type: application/vnd.ms-officetheme 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 AACbCgAAAAA= ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/colorschememapping.xml Content-Transfer-Encoding: quoted-printable Content-Type: text/xml ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image001.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 97Z7ObX5ucYWx17uKHqbfflsHLF9Tz+3dI3abq2jvCY3ahvJvha9nZHdR6K3tWZ7JHeLn1v91Na3 r8m/Fmv2bsFIx4zeNZmjPu3J074ls9d+NuSPfNrzLa/Be7IZR2TPAP7c4tOoj3T1bbm+bzuKGT0X MrG/jnAhl46vQda5pU9tLmc3TH270Ovqy3uYlRsh28x1Qt/WY62tr5e+LV17uNCxMecgy3Edj2Ru ga8JW/poj3P5oPIrcQpRRe5zkzcS4aRAr1OKJLTyQiY+MWLx+e//47Mv/vDHDn/67Iv/MNjx89// 8bPPqaNs4Jy6Cxnqct9ou5KNuqXfHz/7lH9n8v0Py//T5H9u/tpID+cZ1PN/NjkiC5CjjvaL/hCm 1LfVd7Lfhmzfl///qX6ql23KbjvqVG5yIZOR+yOr/rksOdD6Um9wP3vfk77c98J3a6M8si0/Z2z3 48xx6/vr/6CuEVXy7gfLOUioXh+eAdfr2USVR/8YcmM8OubCik+4/NWAr3/67NOv4tWBr0zum58C dv6tHYGVvZ3B8mQW2ECaPDK/DuArj66xo4tdR9g6bRxVD1yX+YlN9OGvbBs+xXeTYfHwVxok57YX WcksOrcWxhXQ90uz8dUAfFrmj+NDZihnsaWdGGlc6NWRR/v+eL9r72XQZYnlkE5v37IdkJ+K7x5W xuyfrHwRMvINvZ1cD5cBVzqXsfg5epNOHw9+t7kz2LnG2cajPpyjh/jwSZDHKNrUn/MZoAsfmp8J +JTHE/40xBzRduE7epuvgZ05d93DOTc028mW97M6fKcOedVn9DaB+tkYPvmSOjtK7kpn1Hs/A3PY 4h7tspNtzKDpXew1m327zW2LdzsO5pzxoweZDPSOYhN9P7U2rWOsQS7LuCIOV/pA+NL8DR/I7Q9f r7QzTnRmPR0ucol+2EcXOpGx8+VTz2iX3CFYf/mB3lF8Yjystb4m27r+qcXnk8/NfrT1spwva3iK Yy8L8F1xbePp7H9s4I/7SOzNx35emFf8T/BxaL6bnri2W5tBOsJG0537zQA9ppN5WebH9j90eVvs fxH/T+3c58b36d8te2Vqb32QZc7ZfzXn+J3lZqE+rjP2dtnudbptg8WL9uVewmTtumxxb/I2Zu5p 0OfjifGP9AqaT7+WDKOYt7wMGeaMuqxLemLOr4BefACjdl1v6EKv6Wv1dvR+2LT2lzWauugzA40f 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 YDp8nvhOKP6qj9pNp/uivMJXbEVbmzdy0PUsc7nkjNWZTLPZA//bOpaJqn71d+mbv6MKif1b/JQO fLF+q0QVWLvWhrZWZER9u86B/xrrgKyKqMY97SVGdWu4oX9cXy/fUU1oJInzrtzq0vlFm8nmOi8P +uu42z+d93V9fy8nW305Q33VnyOvaqvsdV05o6+nPGNb/XJ/yc70b219OWT7H+wCiaQu+ZhydS2P hSTDNejXZr4Or/78poHFOgmyAMQisAnJcSHaBaTFYsH/S+cL3Bmcs76+0FFHUltfd5g6kl0bAZsD 5ZBp3y9ANi12tPnNDbLY0OJhtnxBCttakLOv2PRFggUt6ljMRv0pU39FVK1uKl4AHQ47z5tMLIQv G4uBBVLt+D7qQ/3VxmRH2qgHWY6NyuUMmj/Z8/EBO7/Qa6AsaAwa0x5kI/uOHuo4qo526tAt29n/ Zjv0cY5vkvP2ZEd9R3bxifM2xpDLZfTnGMkmkA7Vj6B2xTb7Bjj3NslZufd11AfIT85Hc0Ze9uPr x4Nut2Ho+xPXbMdzIPrJV+SpR0Y5Il9oxyZ9hXzTDOg3HI/1v/DT6hxRVv0eNL6sH7ifndxFOfWR j9RdyIQcyHELWa1nywdhgPO0ZkkfcWNTT30baNdYaZP/9HGZ5IP8GqHpiP4aE7jwO+TyeGQrz8cW JIMOXVPq3+TYcy6JqttGxmS1vvqHllpfrZ1zv9HU2u1rvelueleAfXzRNTCS+RggNsQ3x74H/mou uGkY+e/jCxnQX2cCdi76GYif5ii1+X6ofGU/pt3ncLlf8PmxefAct3xWmTbXYbIXOpirTFRtjl90 sqfGPus6zNfQIX8yPA9Ml/LB8yh88XHoHsFs+o0zeWQ6mw3llcniA7LL9XgZAwf1ABnGw/0AtriG t3JPc9vLUG5zvtKfeXG7dkQ+z5+3BfCXur697+M67Uge+f4f9VwP1Lmf6OtAH+TQ5/Ze4PdqFkug +yWfc5MlX5Y4v8TI40z8WAeZL9othqsx6KAPKDw3vE/MXeiUL/jViKq1X8y597U2g/vPPBqW9WfF D+rbOmY6ze7fOuH83xeEE1vLE1X+R2quF66JqvsPsr016FrADxvvy54xeLK6SVQfDGJtx/ZEVaRH xCef77bnsslelVP/LN/3HdVttY9kr2xN+i7Zi/aunJH7zpT7uqs2bK35bnxK9bk9n0u2J6qNpKZc jGvdc3Vl7W5IMtpDfE1u7f1fbDy+kWTBg3i58YCg9iR1qcOGFgTfYEhqW0A0QNeBPAnvzi+Lmic+ vmWiyoZBf/y2stfZYNsmov6mvx/bi6+xeFnAlgV28dUXUDYB8/XCDovKwLbr3ZsYAXkWG6AbEKDF 0BdEA7LU0YYcddigP3VsOC4bdcgA1xHnKtMXUHZ9dp79pg05YqF62QG0Zf+Rk23V70E2pNPtjOpC Vr5iS3ZoZ2zZNjEiFshTx3iyTs5HNhTLZifksEeZGOGHZK9iFG0zcL9Tf/miOALZ4tztG6i7mHNb EFw26vAROenJY6EvaOMx0Ad9w/EkO0B25E+u07jkB/XeZmhtdq78ZX508yzZpjPqmu8G6Wl+hpz8 nAXyGj9QnmQ96KcMNDbZpa9vuNGHOkFykkUGWfqEbl8vWId8XXmBry/S4TYM2S90ho52TluOkfIv ywryUTYko7ijp58H9CMH6KfxcOz1zAB9uqbw9aKvxcXmU3FhHXUbJrO2vvpvGFiZvUD7i6/z0b4J dMsXjeUtwGMUc5GvqwzNhc9b+N/Pg48vZPprTdegyrmf+g5icjEPNk8e58gNEQOvN7ue49qn7dx1 MJfW5vssbVbvc97PrXQ2W1bPtd75cwFiFX5jo+WRrqt8j4BtbGHbfGh+y8ZVLOO6tf7un2QYj3TK zyAjQ3jsrV06BMrUb805MvgnHZo/9QPSy7naqYt4epk8YP6Rwxb5o7qI38uaEuXsh/cb1+d7KOKq a/ziutZ8EFOT13zQtrRbv5HNEfCf8YU+jv6KN6QYnf/P7tvs6PlHe8Thcr7wMe4h8dN9We73mHPv c2XX6hVzzq0O2RdSajllurxsBDWTVKAfWoKkqg/gfKlfCGuztwb5pvlmbQY8rRv8n8s38+9pRsTH j6k+tzl5MlC+ehLZIdc3WfpT1/V1yDZ2Uv1FXdge9ff6wEUdsvSX7yonuSab63pbR3yXbFd3oS/B 6wNDWfRR1/WlTH7lV3+dpFpbzkPWEa1Js/CctmvUriGt0S9t/R83DVzwveBBoMMXIFswfGEwfSwA vmhRx0JidctCowXE6klqFmDqtJFQZ+faAL2OcvS93JziEzR8sAUCm20BtePFuLR4hZ2st194vQ59 bsd8t6PHSeQZveF3jsMumExtDrqh0BFowhkT+tXmdQbqJNsSw44sYNIrPYw7+5dlSHzpVH22TV9s A+mhDRnqfGMLvTOgr4+HxRWdVs52OZc+zpFxOwZst7HHRZHrLmJk/RUj6cXXLIMNcoHzbIcyoB/1 qsNO9tV1gPB3D1mn7MkfIJ1rc45t1XG+phfQnz4jmb3xXMw5ddGfvv9mcc+6tXFKF31dT6pX3LPv 1Eun2zFkf7KcdFDfj2sGWS+2/s2A/t5PZNDPkTbmwW3TL+UrbZJ1HQGNB9BGXcTHb25ZB1lvtA5a ud2cZBtuewD0cdRYgOKmcQhZLl/jwG0ZNB4gvznX9Ucfj5nmPOmfBTroCzhXrKJ9WXNtLbV11dd7 1nGT9VixvnJjSd/os8TR5BVH1mnWYG4KlYs9fNx2bPEwUDeS/RjoYzSKM/U+FwaOHstOJs9tnl+N nTL15EPfdwN+M28x9vkgZ82G78nMWeyHyz5p6PZFn0s7Z09t8+Rzzp4qndbfbHjfpPPQHKEz+8Te jQ3pxDY23M80nqi/sBX3Bz5u8hAZ0+UyUc/rzS+51/uJnB2pp5+uvyzT2gycb825rk3NqaA8wC+t sdRrzmmTLO3Iqa6/pjkfrYs78OuRuBPLmLcWtxzfJr+0+X1XWgfdt6R3GjEf2PH7SK0J5pPrjLmU TXy6mEuTc18MnjPqc2HDQEw1X0kG+UY84weURFq9b8hBWv3XgK2d14UFEVbarvNoBfLH5xHYWNv+ lJ6s/mUQVfKfuVhFzNVu3Rp62Zfy6hNVkaB8vlpO/bfkdb5W7tG39fJ+3tu28kV7nK+W89gH43D5 AbFsbQm53GQhltF21T/bBgP77byTzbpUzh+E5Nd9lX/kImsSuZn2+CnYdeTrSLdeODe9+DPFfsPQ Cx4EOhrRC12+OeBEX2/wT8KszomqXbAuZ+1+cbGB2cXbFjeSn75c1PhqdS5nYPHxVye0gFiwXA99 aGdMtLV2LW4vPnmgsh35nscUbc0uemPsh8Ci5DceaZHRpHNkQURGcmqnnkSgDmjhbLrtXIuY5C/a A9LrOuwcyA796YMM/XvbqtNNz2iTXUMbj8YZZfkhXzlSlh3a3bbqrD9+5Bhpo0Ymx4hzZDjSDihj h3zI/XO8VA/QCTiXjVFct4A+9A/nvBuPYuy2DBqPyhe27XyzPaDxZJ0cqeOcPr1tyrmv4i79cT15 GR1AfVRPrNrcpL7IyQ79vI8dOceW/FLcs5/SPwv552MIXRd+GrJdbFLu69BDP8WIo+Q4dzkDMp2f flPH+qI1h/VOMvRRTmTbGZLNY1mzR5m2/ppQP+o4UvbxRL1vSIFWZ0BGuo/AdYcO9PV+Gtoay5rq 67XWbYsPfXt508FekdfuTaKKTY0bsGZ3Oj8q8E++aZ7ymppvTPO89esuY/I8Crkcu9yf89xvCx5T i7f2S9/30v7HXowN5AzK8aX9Rc5zPe+V5rsTSdou5py9PHRmP/aAfevj9w/ZLiA/iIXk7NjGE/u5 j0P+9WPOMnHfscRhxVfKzGm+pihnGW+nzTCac4Ae2pmzi/0iyrShR7rULn1ZPzLoUx60dRw7BmRG 6+IE/HrkCWKOOSBmec4Ve5P3uKZ1sOXpTdBcLfp8vmyuXKds2libX+Qi88Zc5vnF194PYkPM/Mbd 2iUTel23lRey+n+cdC4kNfSE3EJUL0nqC4KozsZAPrVcADZezxGrF1l9U99RFaEy/4DqRJKcFCGj uoSr/ioj2+lzmQ4XfUN2+H9UB/0v6tWfssFlcn/KHVp99PW6Xl+WS/C6keyKbZdLkKzXqz/lvf6S VZ2dk1f0g6AC4qd1RPuNjuSm8n8WlvvnElXr6xuVDWC5ybB6LlYWJznCRWlyvni4rIFjBjLcfLje WIjon2Wi32InBQZ7ZtdtoEft1PvCEfr4tLW37eXFP5fzRTjkMpDp7R4B/XwBNB3aTICfG2hjwwBq u0DIjOxrIVtrzzLSJTBu+oBV2wb5jMyajR4XOqO/4L4m2WzbL5oM6+ubhp0jp3E0OXSHfsUA3Vln 9plz9Ze81xtcd+jLc5P7z4I+9EWP4ud2k158zH42dDIj3YrFqN1lDK47dDWdBvpfxIg2O0qXfHd5 O47GT3/paXXRT3OT+3Gu8WFH/TjKFlCs3G7I3AL5km1etBtae9iUD247ybc4cuyQx9JBH7qxhrDe us6L8YaOC0R99ldj6XNn2G7HNahPi02Wj3Pqb4170xtwXYaBnL/C19bXWNfXNjzzW+s36/NQJ8Bv xohtxSrH6S3gIvaGPkb4m2OoOPbjUB7165h0qO8t4zddy55pc8ONr+KedcVNuRMR7ZlODNJeHjIO dDLn2nfRyTWxNudbkF7XaX4225FHORYup3uVl5y7ktOYNRb8lK+hd0guqPP5Mn3kXD8XLmOQDHCZ 1O4yVkc9OvJ1zPy6XgPxz3M7guao15dten20j8a0B+vzcp8Uc+77ykDW0HLJ475x/c4C+xc6sZ10 Rrv/24w8l8D8dl9Heddia+2K5WBMEFFe6117hVdkFkI6wvSrvwD7+JKJaiMNBp/HICRW/wtIZRDH 05CJ6hUZMv8uyuncy6ndiVOct3Jut/O9dp2r/aK8196dX5QnbG/KD8p+ztxRTm0qqy6f5/Z23ukm X9baOQq5Xee5zIcgHMk35Vw7jyNryNE13HJf6+xyLUb91R+kLG4ULgSPggXBLmbQFgptYN5mF060 O7hAQT4H3tdAXyC9WQZYXbNzhWgbbACbtpNO99nr1K7yQO8RyC/09FCbHwNrciPdwPt3dT1G9pvO OO/bM9w39Nix1z2Cy0ffK10D2ZFchmxvyWa9WR5kW9LRtwHp4gLsdR5C9JW+DLdrbfJxJAN633rM +NbrzzpzG+dNn8qqs6P6bEF9XN9KW0PXLj9eHfcM9AiDdupkN+PKdzCSM2S5K6S1R/KuC4SONfS6 e18v2qOc23tc6evam1ySOYzo33QFBrLL/vCy3q7JCS4b+8mo3TGK66vG8yBkHznPY+/9z3IXOgKr bVF/6/itb9sHRzYS2r4p2YEMuJhzw5bOWVzm0Y6fyfZY1trRJ5lN2QD1tAsuB7JM4EIutTuoS+09 aNO8jtqB2w59vZx88DaD5HOfI7B+s/nhcTUZx2tsZtgYpPNq7N4e9l41lwMZx/Y4PIcMfFd1BO87 6DcEPkA8RFIvAFm1YyIS/vQT4rgGEcu9ujVsyP6CrwplEvQbI2EjktTIGW0giLbaLxD9L84lG/2b 7mjPtvpyJoZNfmD7og/HJNvKUedI57lvg7V7ffbdjs22ypyv4MJ31XHMfvSgLWz342y6Uv8L/VYf edVyrOVaHN8FUQUil6O2HiO5rb65bdbGGujf61jT2dtdkysUCoXCbTi6ttY6fD5m5+jeckcgnbP2 R/UZWWZW788RbyE2e/Zz+3ucR4gqZKAnCheASEBa7Z7eX4XvYUQSgslRdZS9bkNG9a2tk1VdHK9/ TCmIlcPqdX7xKi71lFOd5FaxInthu6vXebOd6oevBmeM+iOb6vtyhtcb/pay9T9iW305X7Pd5FL5 on7Qv5cZ1fkHIQOSCjJRzR+8kK9raDKzRPUv/vHP/uK//+uf/dX/+Pc/+4u/+x9/Rvl2/PdB3RqQ HWEkC47I7mGkC8zKjuQKhUKhcBuOrK21Dn8czMZdcnuys/qOwPR9mNU7K9NjJPdzx9H43DuWe/rU njGSe+P4lYH79AlwX+/g3Mv/48/+int9r3+pa3Kp7krO60d1S33rH3AffqWj+fxXFu9fga7O62NM a3X0y/0dIet1O/2v6gx9nddv1QHVWbuXkyzHXqfkVNePnTbKe3VbOr3OsCkHrC7r9Loku9YfMJ// 418DnK9A874Ht2dgnbbjX/1j8E98VJ5f/VmlJ+BdiGqhUCgUCoVCoVC4O7jJn8Bf6Dz1o+6iXudd 3ZVcqu/rLjCq83ojJcDLxjOu6kZyqhvUt7oot/o1OdV1tnN/yaqc64b9Q6bJZjnVRX2u8/rcf0Xn pu0VWZVzXZbz+lxnOptc6q86SOUsUZ3BPxrgmdgoolooFAqFQqFQKBQKhWl8iCPkEXI5Ip23AuJb RLVQKBQKhUKhUCgUCofwSKJaT1QLhUKhUCgUCoVCoXAzhkR15jVgyQzkiqgWCoVCoVAoFAqFQuFm 3IWodrJFVAuFQqFQKBQKhUKhcDMaUU2Ek3Jf17AlF/VFVAuFQqFQKBQKhUKhcDMuiKod/87I5a9+ tRwbMeUoRPm/h9yv/s7OTU8R1UKhUCgUCoVCoVAo3AWNqBogn3/xV5BII5h2dAJKm8hqkFHkIanI /cVfLGQ1txdRLRQKhUKhUCgUCoXCzchEVeRTBPTvMgFNRwgtRFayf2X9/tF0nUFU+Ue/vzJFvzKZ QqFQKBQKhUKhUCg8B/7KeB58z7mfiCpPTzP59CelHQEF/jTVCCztTdb65VeFzcbDiCok9R//9d// 7H/8e6FQKBQKhUKhUCgUngH/ytHIJITVuR/k8b8bIKWZfIqs6qmqccOFhBr51OvBGZnUou9hRNXa /vU///3P/vO//svx7//1n3bMoL6ve6t48ZVxCJft72k8hbePyqfCmVhbwyoPC4/CWr5VzhUegbW8 qnwrPBZj3gDeS+5drsvLOJa6f/3P//yzv4NMwv0gj5DP/DR1jYDm76b2gNTySrC/Gmx4JFGFcecJ KhQKhUKhUCgUCoXC+wWklaeqf2ec0LnfX0EmB09TMwHlVV/I6hahBZBYXiE+i6iKgcO8/8e//vuf /aOx6fcG/Mb/PEmAMdL+3zv5QuE1UD756xX/+e/v9ropvA+0fPN1bnmtp5cpFO4N8o1cc9QaVzgB Ld9ijat7t8KjMOINz8KD9HSV66gR1Q88IV0hqQJEFpK69jRVEKn1V4kNZxDVPCC+fPtXGOT41vFX 4B/90XYejxLuvxO0X9lY3st4Cu8Dlk98z9s30X/91z/7u38cyBQK94KvX/9o6xm/LbDcvLGG+9o2 ki8UXoPYV8kx3QSxx9ZeWngYtKfaPRv5xpFy5VvhUeh5w/vlQcu6vDUe534f+GGkvzJCuQF/UhpE dU+W77SeTlSNjbMwuAxGuz5vEvhpwG/8X8azvKvN+H5FEP9ikRn2LxRugeXTX9jx7+yidNLw3q6b wvuC1jlbt8k3NiT/JT+v72QLhdeCnLLc4iaINe7vtMZFHg77FAqvgeUVe6rWOO7dKFe+Fe6OWMec N4x4kLjTe8m9PJ4BD+J+weV49ZenpRDRVZicfhnYMZIB0U6sdC9yGlHNE+Sb1VsHfu4Q1ZAZ9y8U boHlk10nQ6I6lC8UXoNY52x9HhLVQuHueCGqbY2LPBzLFwqvgRFVW9MyUa09tfAYxH4KbzCeIA70 rDyoEdVfGSCh/q9l9vCvgVEbiDZi9dGI6juDj2eNqCJDELs+hcLNsHxiU+UmjteUyL/2v6oKhXuD zciO5Jm/hslmkDeCQuHesJwjxyANlx/GdXKFwp3gRNXu2ZYP4/41nqheyxUK94B4kDhQ4w1PxoOu iOq/ioSuwWSG9T1MjlgVUZ3D2gQVUS08BEVUC2eiiGrhbBRRLZyMIqqFMyEeJA7UeMOT8aCXV38N /kQ1Ec2GjoBe1a+UiRV6i6juY22CiqgWHoIiqoUzUUS1cDaKqBZORhHVwpkQDxIHarzhyXjQC1G1 I+eQ1fYKcJDOQ3WmS/XoK6I6h7UJKqJaeAiKqBbORBHVwtkoolo4GUVUC2dCPEgcqPGGJ+NBL6/+ 2rH9QJIdnYAaIJ36kSQRUK8zGX58CWIq2VyHDLEqojqHtQkqolp4CIqoFs5EEdXC2SiiWjgZRVQL Z0I8SByo8YYn40GXRBXYef7l3ovztbLq4hyiSvlXds5/VkF/EdVtrE1QEdXCQ1BEtXAmiqgWzkYR 1cLJKKJaOBPiQeJAjTc8GQ+6IqrtX9RYHcdhmfMoN+SynSP3K/43qx3RX0R1G2sTVES18BAUUS2c iSKqhbNRRLVwMoqoFs6EeJA4UOMNT8aDrl79FTHVU9FGQHM5kEmsy6cy4Ikq/58V/e+GqHKzLuy1 Z4xkD2BtgoqoFh6CIqqFM1FEtXA2iqgWTkYR1cKZEA8SB2q84WPwoJHcQazxoPGrv0JHPK/KK3WQ 1nf5RJX/0UN/AUf7CaBMfZZz2U7uINYmqIhq4SEoolo4E0VUC2ejiGrhZBRRLZwJ8SBxoMYb4CQD +SncyoNGcgexxoOKqAoEmL78CpRAQHoCqkn0YIVc/uWoLHsAaxNURLXwEBRRLZyJIqqFs1FEtXAy iqgWzoR4kDhQ4w3wkYH8LlZ5kCHLncyDrl79FfFsr/7aub/iq3JCfk1Yr/5m2Xfz6q+CnoOt4GuS FHyOyAt9P+pumKi1CXr3RJVYzMRDcjfErnADnpWoHsmjWbnC6/HMRLXy7W3iWYnq0XyrnDsNT0lU j+TRrFzhLhAPEgdqvAEuMpDfROYz8A7Ob+VBN+bBGg+6fqKaiKaf57Lq1tqj3J6oGuSD+fw2iSrB pI/+7w5BVz0B8f+7k+oztADRv5+kXnYHaxP0rokqcVAi78VEcjOyhdfjGYlqzre9PMqynL/3sb91 PCtR7fNoJAMq387HMxLVo/n2d3GsfDsFT0dUc77N5lzl22kQDxIHarwBHjKQXwXzRR/xGOZQ9W+A B22++qsnpld1KqtddXF8V0SVwBNYW1g8AAQ3B17/JHakFznQJjPp6GV3sDZB75aoEgNiqyTyx+up fSTniHIvV7gvno2o9vnmC1DU97LU55xby83C/RBrKnn2NESVnJnJtyO5WbgfLOeeiqi2PAKRQ2BV rvLtbDwdUc35tpVHnnOVb2dDPEgcqPGGEV/ZAvO1xoNYNz8yD3odUQVZJo7vnqgKOOpthjW9D56g IVFt/sVR9SNIbk92Vm4W0qUkWlu8KNPmsHNk70Uc5AMYtQsaO8ctu5KT7EjmKGZ1ZjkwkhFmdB4l qjM6wawckCzHPdk90F/5wyLkm2vU97Lkl3Iu52YvdxQaz97Ye7kjsiOZo7i37Rm52PTIsymiesR2 lh3JCLM6ZyBdnm+RQ55Hhl4WOeWj5O/lg/zY0yW5PdlZuSN4hO0ZWcu5Q0RV+vbsz/o5KzcLdCjP PJ/II8NIDpu0t9yM+l72CPJ4wEhGyLJbdnu5LdlZzNoGkt2zPanzEFGVTo4bOmdtO47I7oH+LYfi HPR6KV/JGvAhy90C9M6MZ1YOHJGdATqyzpGMMGt7Uk48SByo8YY1vrIG7LxhHnT1HVXlmn/nVKBu cK685VzfUc3tWkPhWObz233114NLAAw4hw4mjiMTBLLTmjxHkpOOO07QKlH1JLY2jqofocnt+JV1 3uD/FTwuwPwWqOt1U24ydk4CcX4XH2LcYNQu+NhDbstultuL+ywO2QYTtmd03kRUw/aU3ISfeTxb OmdA/5Y/cQ5Gekf5tufrDPLYt8aT5fbGfs8YCbM6m59xPpIBLgdCdiRzM1E1mdfaFlwWuR2dM5Bd 5Y/nG3lk6GWRazlp7fSh7i4+xHj2xp7ltuxmna/1T8DmjE63DSZsNz/jfCRzE1Hd0Qma7R0/sxwY yRwB+jzXgJ0r90ZyjKHJhjx1vewRSK+PJ9WPkMfO+UgG9Dq3ZGeRbe/5OWs769yQO05U93VeyE2P Z0fnDOhP7mi9Ui71et0/g2S11u35OoM29jgfyQD5cChGdtzSOYsL24aRjNDGY7jDeMSDxIEab4CT DORXgY03zINWiarI5hVSm/L2oi2Vn4KoUq8JQlbyPZAD9LnjBA2JKsAGPu7Zks8zPs3qnIHHD5jf wkg35SZj5yQQiXMPH9AhjNoF2vFtNp73ipFwb9u0C6N2cJSogtlxy/aeLO33iqV0kUfk0Fq+AZcL SPZePgij9oxZWdrvFSNh1jaYsZ31rckeJaoAXdgftWXs2c44IrsF+nseKd84j7pdWcNMXPcgvTO6 aBdG7Rn38C3jiG1ksD9qy5Dcls6jRHVGJ5DcrJ/CqP0I0HGRb+SRYSSHb/fONyDde7poF0btGbM6 j2DW/hHbkh21BY4T1cCefcnOyAmj9qMgv8gf5RsY6aYu59vaWngLjo77nrKzOKJvVpb2nbGLB4kD Nd4ADxnIrwI74jEcex6Uiap8R66HeBDne+MbYI0Hrb/6G/nGkbKemKquPXGVDIi69urve/j3NEyE fwoweOSNLoJOO+d50pD1uji6jji/4wStElVwg51d3EsnejxeAc7XdNOWF0TKI7lHAt9mx36vGAkf w/YtRPVetjPuqRNd2lC3PuygfjY33wI+pm/3sn0LUQVveV583TLM5JHLpfXtXuNCz71j9LFjPmt/ T+4oUQVHbJ8dJ+y1fGONi7pd2Tgfyd2CR4z77FhmHLG9I3uIqAL0zdo/4ue9gE3PI9auyLlNObCT m0fxMcb9VrAzdvEgcaDGG+AhA/lVMF+ZB2n+fF6pNzQeFEfxIMq57uFE1Y6NfOqo81F5rc7ga6MR 1Tf/72n6CSK4WljQlScIaCI0CGTRQd8HTNAmUX3r8CQP7MWERBG5uCF+hYO4hai+deD/dL4ZZmUL r0esqeTZIaL6lkHezOZRL7clW7gPLOcOE9W3jpZHsVeOZIQ+50YyhbviMFF9D/A8SvdnIxlQ+XY6 xIPEgRpvgKsM5FfBnB3lQYA1FTnQdBjuzIOuiarlIshPTPmAJJNQwetD9uKJa7R7XhvQbz6/3Vd/ 6aOJINiqJzgKOvWSA5Q1QU32/l8iftdEFRCL2XjcELfCjXhGogqO5tszjPk9IDY98uxpiKowm0eS q5w7B5ZzT0dUQeXbm8VTElUwm0eVb6dCPEgcqPEGuMpAfhXMGX0aAU31zm0MHKlXWXLkN2iy9+dB 16/+JqLp57msurX2KLdXfw3ywXx+m0QVKPgEniOPg3OZdoKO49QxSdihDnDe14/sbGBtgt49US28 TTwrUS28TcTNGnn2dES18DZhOfeURLXwZvG0RLXwJiEeJA7UeAM8ZCC/CXgO/UY8CLB+co/4EXjQ +ndUDXpielWXyhdkNY7vjqiCPEkCAcnO5snwiQxoMjkXqc26J7A2QUVUCw9BEdXCmSiiWjgbRVQL J6OIauFMiAeJAzXeABcZyO8ic5xbeZDLh+xBrPGgIqpACwmO0V/IjgpMUi/X5KO97zOBtQkqolp4 CIqoFs5EEdXC2SiiWjgZRVQLZ0I8SByo8Qb4yEB+E2+YB119R1Xk1L9zGrgip6keIOvyUVb7u/iO ag8CLIzaQZbJGMlOYm2CiqgWHoIiqoUzUUS1cDaKqBZORhHVwpkQDxIHarzhyXjQ6o8piWxeIbWJ qF60pfK7JKofCWsTVES18BAUUS2ciSKqhbNRRLVwMoqoFs6EeJA4UOMNT8aD1l/9NV7kJBRY+eKJ qaE9cZUMiDrakPur9/B/VN8I1iaoiGrhISiiWjgTRVQLZ6OIauFkFFEtnAnxIHGgxhuejAdtP1HN 50Iu9+1d+aYnqp/98yef/f2/fPLX//y/7PjPn3z47DdD/Ddr++f/9b8++V//7//75P8LUKZ+JP/W 8dcX4/l/Pp5/YTy/+ZdF5sN1n0LhZlg+ffbX//zJ31t+/cauNa6bz/56IFco3AOxfv03W9t/8y// y/Pury3/ruQKhXvBcu6v/5utcf+8rHGcq/5KtlC4A9hTfY2zfGON+8zuZyvfCo8C923wBHGgZ+VB f2/XFNzwA/cMjO3v//6TD7+xPr+xc45/30FtXjZZr0M21anff7Nz3fua/r/m3gT+qf0CXP0VUb2Y oCKqhYfA8qmIauE0xPpVRLVwGizniqgWzkQR1cKZ+PkSVZO/IKN9OZFTtUtGR7X9tcnKhyKq2yii WjgVlk9FVAunIdavIqqF02A5V0S1cCaKqBbORBFVQyahPxuiys06wXB0bU1G7R1GspMoolo4FZZP RVQLpyHWryKqhdNgOVdEtXAmiqgWzsTDiOob40FTRNXrom1EVHv5d0tUWxACONpPUi+TQduNN/tF VAunwvKpiGrhNMT6VUS1cBos54qoFs5EEdXCmXgIUe05jvMgw5ZMBm135kHD76iKbGYyKuQnpkNZ qxNpfVffUVUA/tnAYHTMzjIYl7GgcRQ8AFGX5Q+giGrhVFg+FVEtnIZYv4qoFk6D5dzTEtVaq98k npaoVr69SdydqIoHidQNeZCdu4xxE9o4b30ew4MuiKrbNHknn3EclZ2s7pQ58kT1XRBVBR4Cqkmh rImgzEA4MnEiqvQD1COb60d2NvC0RJW4CaN2YVaucB9YPj0lUT2SR7Nyhdcj1q+nJKpH861y7hxY zj0lUZ3No1m5wt3wlER1No9m5Qp3w12JKvsx/aZ4UMd3APXIPoAHXRHVnnQ68Yw2L+enqElG8P4h +y5e/WXg9NHkKLi5nqMmTROkQbAIKXi9jgN4OqKqBeu/BbYWL8mRNHuyhfvA8unpiOqRPJJs5ds5 iPXrqYgqeTObR1mucu4cWM49HVFVHu2tcZVvHwVPSVRn8g3knOO8cu7huBtRZS8Wv4FzaG/O9RxH PIj8Bsg+iAfNf0e1O98rc3wXT1QV3H+JiaCshYWygs65yidO0CpR9YVgwo4WjJlFQzpnZPeADi1w YGuRy3KSHckdhY8nMGoXXGZy3iS3p/MQJnXKz1FbhssFRu3A8ukQUZ21DWbsC/eKpez1eTTSTd1s bh6BfJjSRSzvOOdHIJ2ztvfkwJ5srF+Hieo9/XS5wKj9KNAzk0e9HLibD4z7zmOXzlHbLThiG0yP Z8dHy7lDRFU6p/xE14594DoDo/YjQMdsHlGf5e66xk3EyOUCo/Ye03GfxBH7s7ZdbnvODxFV929f p0Nye35qzDPjmQF6ZvKIupyb9863UVsPye7ZnZU7gqZzx9dZOWHHz7sSVXEY+lJW3lIWt2ENVRlI DmQdd+ZB60Q1zkdobXq6muuizPFdfEc1B5e+lAXKCjrnKoM8iJGObGMCh4iqkh0f9mzR3jBoz0Df jM4Z9BuqJ4Shl8OnXg7s+boHxWhm7LRr3GAkA9R+rxgB+bmrM9pnbNPeMGgHlk/HiKrpmrINZmWT 3JbtGdB/lHMjvbNyR+HjmBjPhZxhJCPQPhPLWeBX1rnppwE5l+3aMnqdI5lYvw4R1aZz0Cb0tvdk m5xhJDML12Xo82h2jUNuy9cZaBxbcQfYyXJbdn1cSXYkcxRuUxi0ZyBzdDwjGWA5d4yoZp0bemlv GLQL8nNGdgb0H+XRSO4ha1yMYy/u4Mi4s85X+2hAR7Y/khFmbUvOZQftgWNEVfoCIxmgdsmOZIDG PeHnFOiv3Mn51Ot1uwa1C6PcPAr07o0buA8a955skuvHcgt621s6L+QMIxkhy47aDQ8lqgLl/F1V L+/wII6Us40JvIqoXpTTq79ql4yOans3r/7isCZIE9EmJEBZdZBHybS6qKd8Q/IXUe1wQwwvoBjN jJ12jRuMZIDa7xUjgF9TcY92yQ5lAvLTMWgHlk83EdVd2yDkOI5khCy3ZXsGHkfDTB71MmtyR+Hj mBjPhZxhJCPQPhP3WeCXdLr9rj2Dthnbvc6RTKxfh4iqbO/5eHQ8LmcYyczCdRn6PJpd45Db8nUG GsdW3IUsNxOjGZ2zcJvCoD1jxjY6aJfsSAZYzj2MqMr2XiyRbejaj4L+fR6BWbnX2s97EMehTODI uFssJ2RngI5sfyQj0D5jW3IuO2gPfFSiCiS34+cU6K/cyWtdr5dylhVGa+FRoFfjGbULt8RIfUYy R+Djzzq79gyNZ8Z21jlqNzyMqGI3H2/hQSM7OyiiuoYjE6QgMRGaJC8bkOEcmZGdHdxEVAXVj5Dl ti4gkGVH7UfgF6QhJ8nI/kjuLjdxII1nS9+FnGEkA2bljqD3cyTjSDKbcoYstzZuy6fDRFUYtQvT 4zFkuS3bM6D/bB5Rl+XAa+2D2fFcyBlGMsKs3CzwK+vc9BNM2O51jmRi/Tr8RNUxaBNuHQ8YyczC dRlm8oi60Vo4kj2CPJa98VzIDtoF9yvJjmSOIuvbG3OWHbWDWR8t5w4T1aZzQ2+WOxLLvbHvgf45 hwB5NZKbXQsPIY/FMJQJZLk9u0dkZ4COrHMkI2S5LduTcoeJasZIBszKgQvZQfsR0L/PI9DrpQz2 5G6B6z467jvKziD76OjaM3rZkYwwIfdRiCqy1MFNAOdeNjyIB02/+rtVdvk4z23vh6haEDRBlAUc pV4T1Catk+WcQQNN5MjWBg4R1fcAvyANSorRhiogpwXxLhtqYReWT4eI6ntAzjewNh7qs+x7H/d7 QKxfh4jqWwd5k2/ktvIo51utcefAcu4QUX0PmM0j6mdzs3A3HCKq7wE5j/bWLdpmcrNwN9yXqK7w IMoiqpyLByGvsuQexIOuiWp6YgqUd8IFiR3JWp1I67v7jirHHFx0qd6DE2WQB5F1IJN1TOLpiCpg 8sHMApfltmQL94Hl01MS1dk8mpUr3Aexfj0VUQWzeaT2vbWwcD9Yzj0lUZ3Noyy3J1u4C56OqIIj +TYrW7gLHkJUL3iQHdGles5VBifxoAui6n6Y/NUTUhBtra4vp6Pa3uW/p8E5v+BSPUfqVdYEsQAB BY9fDuZIeWRrA09JVIEWr72Fa0amcD9YPj0dUQUaw8xYKt/OQ6xfT0dUAXk0m2+zsoXXw3Lu6Yiq UPn2JvG0RHUmj2blCnfDXYmq+M0b5EFXRLUnqU4+o+2qLpVbPQjZd0FUgSYDUujOBzQ5tDNpOO6P wHO9gXr65vqRnQ08LVEtvE1YPj0lUS28TcT69ZREtfA2YTn3tES18CbxlES18GZxN6IK2I/pB+fI PIgyR9o/Eg8afkfVCaed7xHRtTr1exev/goKgA/ckN/HbjKGLMO5kCcz651EEdXCqbB8KqJaOA2x fhVRLZwGy7kiqoUzUUS1cCbuSlTBGg/Ke/VH4EGbRFXnPfq2pyCqoAUhQLm/eaeOAWS5LJ9lD6CI auFUWD4VUS2chli/iqgWToPlXBHVwpkoolo4E3cnqoB9mf7CaJ+m7kQeNCSqI+LZykY+vS61S0ZH tb2bV38zCIQwahey3Iz8DoqoFk6F5VMR1cJpiPWriGrhNFjOFVEtnIkiqoUz8RCiCrgXnOE1kskY yU2iiOobRxHVwqmwfCqiWjgNsX4VUS2cBsu5IqqFM1FEtXAmHkZUPxJeRVSv0LWNiC1HXv2VD0VU t1FEtXAqLJ+KqBZOQ6xfRVQLp8Fyrohq4UwUUS2ciZ8vUTVyKeI5IqsXpDQ9Xc11majq3reI6jaK qBZOheVTEdXCaYj1q4hq4TRYzhVRLZyJIqqFM/GzJKpOOE1ecOKpsrWp7HV9OR3VVq/+zqOIauFU WD4VUS2chli/iqgWToPlXBHVwpkoolo4E0VUDZmEFlF9LIqoFk6F5VMR1cJpiPWriGrhNFjOFVEt nIkiqoUz8bMkqozt4tVfO2Yy2hPRp3z1F4dxkIBs3Ugh5zJxPpI5gCKqhVNh+VREtXAaYv0qolo4 DZZzRVQLZ6KIauFMPIyoXvCgri3LODZkDmKeqJr8BRkVcjnJgl5e5+/ux5QUBB9AYDQB1Kl9TeYg iqgWToXlUxHVwmmI9auIauE0WM4VUS2ciSKqhTPxEKJ6Cw9yUtu134BXEdW1p6hql4yOantXr/62 ybGAMADb3PzcJ6DTSVky9Onbb0AR1cKpsHwqolo4DbF+FVEtnAbLuSKqhTNRRLVwJu5OVNmT6Qvv eEM8qIgqg8ch+rnjuRyT1U8S5/9s+Jdof+AEvWuiCvHJGMkIs3KF+8Dy6SmJ6mweZbk92cLrEevX 0xHVI3k0K1e4DyznnpKozubRrFzhbnhKojqbR1luT7ZwF9yPqJr8Hg/iPO/ZnJ/Eg+Zf/U3o20bE luO7+I6qBu6fHNixBburz5scMtSd8EnCuyeqSoqthYu2/2bwpInySK5wP1g+PR1Rnc0j6sFMbhbu g1i/noqo5jxSvq3lEvW1xp0Ly7mnI6o5jyrf3hyejqgeyaPKudNxN6LKXkyfLR4EKVU9Oc35STxo k6iKcGaMSOy7J6qQwRbs1IajmiDp9QkyaII4PnCCxkQ1bAqtfoBZOTArN4O8aHkyRF2O70guy2a5 WzA7dvcLuTgfyQC1S3Ykcwuan4O2jGbbMGoXmr4NOcunw0R1T6cguT3ZC7kd2T14bAw5j1Q3kh3l Zi93FBfjGbQL7tcNsqP2WzBrG0zJJX1rsrF+HSKqW/oyJHdv2S34vBhyvq3lEXX9Gqf+vewR5LHs 6cqyo/aMWblZPMK2x29H1nLuEFGVvr25mbEtNJ0TsnvAbp9HlEdyoJfbGtMMpHdmPEfG3WQHbbdi 1v6F3KTsqC1wiKjmWO7ofZHt6nvM6pvFKN9GPlDXy+75Ooup8aRx78leyO3IzuJC56A9Y1a2yQ3a AnclqjM8KK+h3ifaHsyDLogqti5IJ6/5Grw+14XMHpF9F6/+Xk1Qgk9QQHp9ggy0MdDcr9d9AIeI avZvz65khZEMYEy0z+icQb9ogdEiR7mXA73cYcQ49sYN8ri3ZCV3rxgB5dKeTvk2Y1uywkjG8ukQ UUWPbO/JZYxkBNqbzh3ZPXgcDTmH1jbVUW5ujWkWGsfeeGjLc75qO9pn4n4Eszppm5ILGcmOZGL9 miaq2NvTCWblAO0ZI5lZeGwMfR5RN5IdyW3FdAYax+GxD9oFH1eSHckcxYXtDZ3Ypn12PM3PQTuw nDtMVGfGLjmXHbQL0rOnbxbY6vMIjOQescZpHIrRSEaQrDCSAfhEe4t7134Lsl0wkhFon53zJjto DxwjqtIXGMkAtd8z7jNgnH0OjfLI59DQy43WwqNgDDO5ofHOxmgm7rPw8SedIxlBNoWRDLjSOZZ9 HFFNwAfqR0SV8gk86IqoKscyCb0gr6rry+motvdDVA0KNM7lo4hqdlr9fJKYQE1Saj+IY0QVhH2O qh8hy23JohO5GZ0zWLuJ62NEObfr/BWxXBDjuGuMQu5eMQKzcZdvM7YltyVr+XQTUXWdg3YBOcmu 2Ray3Gvnm/7KnYyR3lm5o7gYj2EkAyS3O/Zov1eMhFmdtDU/u7YM2rLOkUysX4eIarO9I7dnW8hy e7J7cP8MfR6Nbs6QHclR38segcZxeOyDdsHHlWRHMkdxYXtD5xHbFzoH7cBy7k0QVekcyRwBtnL+ 6DiSG+Xmlq8zODIeye3J4lPW+VofgetJOkcywqxtybnsoD3wJojqjM4ZME7lTs6nfvyUs6wwys2j 0Hh24r74IDnDSEbIcls6Z3GL7T3ZK51j2fsSVcNhHmSg7sE86PrV3/zElLKdZ1yQ1pGs1Ym0vp9X fw15ggTK1I8mSKCeSQLIo++GiTpEVIESec9WkzOM2jNmdc4AHf1mOdI7krvHAgc07r2xt3HvyIGm c9B2K2Z1Nj+7+h55PGuylk/HiCqYsA32bAtHdO4BHaM8Gunu5cC9fNDYR+0ZHyNGwqzOI7b3ZGP9 miaqYNb+rBxwuUnZPaBjJo+om83No5gdz5FxS3bUdguwOauzyXb1PWbkLOeOEVVwxPaMrOQMo/Yj wNYoj2bl9nydQRt7V9+jyR2R7epfg0fYntB5jKiC0Dlqz5iw7TiicwazeURdlgN7vs6gjaerH2FW 9ojOWTSdO3HPcnfw86FEVaC8RlS9r4F6uApAfi8OK5gnqibvZNSQc64R0UG5l1fbu3311wNibTgq oiq9o0WnyUnHQGYHh4nqewBxUFJwvhYXj7UBuXttqIVtWD4dIqrvAbN5RD2Yyc3CfRDr1yGi+tZB zijftvJI9bXGnQvLuUNE9a1DeTSzblHf5+ZIrnBXHCKq7wE5j7RubeXcTG4W7ob7EtWew8TR+U1g tIbqvOdBaj+AVxFVL0dbfoqqdsno+L6JqtUp8JQ98Hbc0us6QpYj5ZHcBp6WqGaMZATa6wbuPFg+ PR1RBcq1vbFkuT3ZwusR69dTEVVwJIeOyBZeD8u5pyKqIOfQXh7RXnvqqXg6ogqO5NusbOEueChR Vd5SFg/K5C0DWdcRsnfmQetENc6vyk9HVA30YZIAzvmFZkfqRVK9Po46Z3IePEHvmqiCWrTeJiyf npKogsq3t4dYv56OqB5F5eZ5sJx7OqIKjuQQspVzp+EpieoRVL6dirsSVfrAN+AwWiupF7ehnTLI PAg5cjzL3pkHbX5HVSS0R2tLsrlOpPVdfEcVaPA+STEhbVAG2gGO095PGuf+aJz+UTeys4GnJaqF twnLp6clqoW3h1i/fvZEtXAeLOeekqgW3ix+9kS1cCruRlQzCczch6Me1tHOPeIMD1L90NY6Dj1R dfIZx1HZn5rulDnyRPVdEFWAo/RlAgTKOdiUmQQRUsreh/po6/tMoohq4VRYPhVRLZyGWL+KqBZO g+VcEdXCmSiiWjgT9yOqgTfKgy6IKnYuSOfKE9OrugTvH/Xv4tXfDIKAc+jg2Ae6bx+h7zOJIqqF U2H5VES1cBpi/SqiWjgNlnNFVAtnoohq4UzcnaiCzHNAv0/ndo4j3Li3f7QnqtjnOjX9b5+oNszo MBmC5hMijOTmUES1cCosn4qoFk5DrF9FVAunwXKuiGrhTBRRLZyJhxDVBnTs6bH2E3jQ5ndU956Y znxHFftcp6b/HRHV81FEtXAqLJ+KqBZOQ6xfRVQLp8Fyrohq4UwUUS2ciccS1fNx6Inq6AnpiJyq XTI6qu3dvfr7EVFEtXAqLJ+KqBZOQ6xfRVQLp8Fyrohq4UwUUS2ciSKqhkxCi6g+FkVUC6fC8qmI auE0xPpVRLVwGizniqgWzkQR1cKZKKIa51flIqoPQRHVwqmwfCqiWjgNsX4VUS2cBsu5IqqFM1FE tXAmfr5ENRFRkc+MNdKa69Tv3fwf1TeAIqqFU2H5VES1cBpi/SqiWjgNlnNFVAtnoohq4Uz8bInq iJyCXO9kdafMkSeq74qoEoQes3KOgewkiqgWToXlUxHVwmmI9auIauE0WM4VUS2ciSKqhTPxEKLa +EzCrJxjIDuJKaKqp6iNdK48MW11kkvw/iH77l79xTH6twEbCEyTsfMswzGf03YhP48iqoVTYflU RLVwGmL9KqJaOA2Wc0VUC2eiiGrhTNyfqFq/N8iDht9RFeHUeV92Msq5SKvKAZ2/n39PY31wikDb prZMUBzRp6BzdJk4esDiXPI+Sb3+fRRRLZwKy6enJaqz4yhifh5i/frZE9XKufNgOVdEtXAmfvZE lfWt1rjTcF+ian0aD9LxIA+SvNbag5gnqumJqZftvEcjpZmoStbqGlE1YJ/r1PS/UaJq8nly6E8w Wp0FSHUcKatOOtrExSRRvrCxj6clqlq49havWbnCfWD59JREdTaPstyebOH1iPXr6YjqkRw6Ilt4 PSznnpKozubRrFzhbnhKojqbR1luT7ZwF9yPqJr8Jg9KdRxHPGjEmS5s7OPQE1UnngYnnipH2wWR jXbJ6Ki2d/Hqbw48jnOB+cLS1eO0yoAycgAdyDQdhpGtDTwlUSWWfFrhyRDYk+O4Jle4Hyyfno6o Hskj2irfzkOsX09FVMkb5dxMvs3mZuE+sJx7KqKa86321DeJpyOqozzayjnk9nKzcDfcjaiyF4vf iMN43nb1MzzoX5KOka0NHCeqcX5VfkaiChkk6PTNFxdlnxA7cg4Y3NoEUc/xjhO0SlR9IcBWV9+j yR2R7epvATq0wAkjvSM5yr3cLWjjNozahTbuHTnQdA7absWszuZnV98jj2dN1vLpEFE9ZBvccTyz GOXRSDd1WQ7cw4c2HsOoXchye3abbFf/GszqPGJ7TzbWr0NEddb+rBxwuUnZPaAj59BWvvW5eQ/7 YHY8R8Yt2VHbLcDmrP0m29X3mJGznDtEVA/bnpGVnGHUfgTYGq1xs3J7vs6gjb2r79Hkjsh29bfC 9YE7254YzyGi2mwbRu0ZE7YdR3TOYDaPqMtyYM/XGbTxdPUjzMoe0TmLpnMi7pK7g593JaprPIh1 s+dBXjacxIOmiKrX9WWOibSKqKrM8f0QVUOboATKTI4PKCDZPIiRjmxjAoeIqhIYH/ZsZbkt2SM6 Z9AvcGC0yFHO7Trv5Q4jxnHXGEX7vWIEGCf6dnVG+5HxbMlaPh0jqlnnoF2gTbJrtoUs99r59jga lD9bedTLrMkdxcV4DCMZILndsUf7vWIE0DGrk7bmZ9eW0escycT6NU1UL2zvyGXbm35mOcNIZhbu n6HPI+pGsiO5LV9noHHsxQhkuc0YGZCb0TmLC9sbOo/YvtA5aAeWc8eIatYZsiNIzmUH7Q2hRzqH MgeArVEejeRm18IjUFxmxiO5PVl8yjpf6yPodY5khFnbknPZQXvg/2/v7ZGtR4rt7+f9Xz7nQAQO Fi4OXrs9gNs2Hh4GI3hGgIGJhU0PABfvWphYODfiDoR+c5Uy66RKJVXV3qU8W9rrifiFpKqsL9VS SqvPOTBmVK0/pRYDrL61ns29PIjtAf2ZdryeyvWncQWrN2raHMXW07jvyxwsTqjFGD7uqM9e/NjN eVqMUosBm/XUY+caVaHlgzCfdC1xgT6o+jeqZlS9+TRWJtYbVVdm7R76/1H9xZ9+/os//u3nv/3b //z8F//9t5/jusZ/S93f/u//fv5///ngb//zPz//b2lbi9/ltwLa/E3A8b/l2vMnKQPltY/FuY+r jdPgt7KeP8n8l7X8Z1mPrC+v58sf120wb4yFoy8v6Y0DI7Et0A/4o8zbwHUZh7F8fToKZdwjoG+j Vm+gvnfdI7G9oL+ePnvHRn0rVvT0Czn+UTT7J3nW8Dzhuhpr9K67NbbRG9eD9WVaMj3V+oa+vN7A zDm0+rK4kdhW3AgjffbGtfr8shyRz6A36O4XrX6tz1qdpzW2x+J6YlugL6+1dBTKOIz1R6CxFl/G PULv2nvjQG9cLyNj98b2xInmfisx0Nof//Q/6R1r5ZtYMDo2qNV7EGvU6kdAH1lDer6nN8wtxyJO y8vYUazvVl+oH4mdNT/jjLEttlanIKchx/0R71Q5pnfqs3oDvbEjffbQ+65EmdUn5Lpxr7p59XsE rM+eNdvYE+b5Wj5Iy62sNk6Dpg9K8yxxmqte75T9Sct/K/wCyLXwC1nDL0r/ufmHQJnUyxtVgHgP 6mtjdDBsVMGBgFf0xoGR2CPQD+6HCQQJb69vS4YmqNrL92wwt56198aNMNLnyNhHsY8Y1Vlje0b6 PAL9eL0lHWn5XqzFH2lzFPTT01dvHJg1N88ZYx/FPmJUwex5Iq43tgX68R9yLb1lXVJvh8ya56hR BSNjj6xpBhjPvytxDpqxiNOyWuwoI/30xs6am+eMsRuxQ0YVoL/Z8xzps4XXm+WuWhzGo976+u2N A424t/NBaZ4epzlcm/k00nUlzsdexqjiZtsGeWGUG4R6f41Yj+93kIeM6quDe4L7ZNRiDCS5hJw/ eS9JB48Y1Ven1NuRjnws9XY+jxrVVwbz79WRxeEFSc3F8IhRfXWy3vRdWYsB1NunMGxUr0DWm3Ck o6xNpRZDpvJ2Pgj9e+OZjagrS+yUrYysxkDX6Fs91uv/RBU3HmWWWMoNwnz8te/nSW5pVEGvePFf NRKVOjKfOxpVYHrr0pxSqyNzuaNRNai31+SORhUkHXV8D5jeqLkwbmlUgX2f1eo81Fsop/kgXI/4 IMRO0Pk8owrKcjm/rFEF5UbgZuCIvlCGI8psM31Zrb8HuK1RJa/JXY0qeU30JYZ8djujSl4T0dwt jSp5WW5rVMlL8nY+KI1dUhjPXFZeF2WX+tVfw29SWoSdC34jyk2yDX1ys2hUSSg0qiQSGlUSDY0q CYZGlUTyUj7IvJDvb5BzjKrVW5keV0ZVzpXXNaqWSHCj7eanDZDr2o23TTIiNohGlcyERpVEQqNK oqFRJcHQqJJIPsUHWZz5oBQjhBpVM53+2peV53rtf/XXzu1Xf5XX/omqgRuBG9666b1xndCoklBo VEkk+nJDPqNRJSGI5mhUSSQ0qiSSt/NBGKM0n9Vrj9bBmHqjavXJqAI5F65hVD8JGlUSCo0qiYRG lURDo0qCoVElkbydD8pG1VMYz831TtnqV3+BXAs0qgfQqJJQaFRJJDSqJBoaVRIMjSqJhEYVwICC 8rpWZtcCjeo4NKokFBpVEgmNKomGRpUEQ6NKInlfowrTKSSzWZQlKmWHv/orR/VYNKoH0KiSUGhU SSQ0qiQaGlUSDI0qieS9jaocs1HFtZb5+mqdlplpzX+jCmhUD6FRJaHQqJJIaFRJNDSqJBgaVRLJ +xpVj3ijmhHdXBdlZlT5q7/90KiSUGhUSSQ0qiQaGlUSDI0qiYRGFcCAgrJsr17PV0ZVzpVrGFV5 sTX/55ZR7uOOYjuhUSWh0KiSSGhUSTQ0qiQYGlUSydv5IPS/az7L60rd0d+oKq9vVHGj0V4muvt/ YJtigMZ4ntgoGlUSCo0qiYRGlURDo0qCoVElkZzng4SmD9L6kjN9EPpN/qswm5trj6vbNapAzoXX Nqp249PmFOd209NNcuVok9oJKAO4LvvugEaVhEKjSiKhUSXR0KiSYGhUSSRhPsj7ms/0QWlsj5lO INcrIyqk60qcj73M36iWm4ObUSvLN0nK/EbgHHF/Q6zg++7ktkbV7iWOtXojxUE0RTk5h7sa1V69 AeotjjsbVayj+DuXKqbNWh2Zz12N6qje7vKcXYBbGtWko853ZY7t0Cd5mtN8kOWNWhkwH+Q1gXrE nemD8tge0Zo3oPnaysprZWNUwasa1bRwaWM3F9eWWHDjUW6bVLY1an3U4g64pVHFfUhC12MtBqQ4 WR9Eg7gH7h8Z5I5GtdTbkY5SHPUWxl2NatIcdCQcrSfFCa1cSOZxR6NqOuoxDl5vrVgyhVsa1aSj kRynsbUYMpXTfBDKvA+CBxr1QbWYBv1GVfQF8k9MXVnClUGLFmvm1MeYVtVjXceoWh02pTSq2LyS oz46ecio9o6DuJ7Y3rge0I8lLRPLXt8mJC+sWtwoI+vpjR3ps5eRPkfijmIfMaqfMc8Rst703J7Z EvwXtKQ5OW9pc5Te9Yyse9bcjNGxe2JbcciTckQ+6zaqvWOD3tiRPlugH5+7ko6EapzyWXoDI3Gz 5mf09jkyditWNDdsVGeNbfTG9WJ6S3qCjoRqnJB06eJnzaO3n96198aNMNJnb2xH3LBRnTh2ZiS2 hc9vSUdCLQ7j+djZeuvpqzcOjMT20tvnyNiNuHN8kF5bHfYSHgh1OEcZNF2y6kPoXaNjzKjauV37 svK8Em+mNWkayLVwDaOKjfBgg4BtkG9n5z4ON+GMDSqNKsbAuK2xeuMA4npjW1hfJhKIAde12Bzj zmtxo2AdRq3eQH3vukdie0F/PX32jm1xR7GjRtX3Wav3jM6zFdeD9ZX0Y+daXsaWL18wcw49fSHG qNUbI3320tunxYFavafVJ15kckQ+6zaqNnbvPHvjemJ7QD+mH9NS7UPOj2vxOC/jHsH67V17z7qt z1rdIzwydu96juYpmhsyqo/Ms1bnQV9GrX4E9OH1s6c3YPU+ftYcevqyuJ7Y3rgRRufZM7bNs1an DBlVG7vRZ6J3niN99uD1Y+e1OaDM6u39O2MOI+ux2Nr8PL1xI5wxdkfsaUYV43rM3+C8bGfnPm7v 26tBv1H1ON2tysrromzzq79yLVzHqNoR4/sNQmyq16OB+LQ5Glcbp8FbG1UzDha/9/IdBeswavUG 6nvXPRLbC/rr6bN3bIs7in3UqLbGBr2xI322sL6S3vR8r+9Sb2DmHHr6QoxRqzdG+uylt0+LA7V6 T6vPR4xqq09jNK4ntgf0Y/qx81ru8uP6+DLuEazf3rX3rNv6rNU9wsjYvbEWdzRPGtV1/Kw59PRl cT2xvXEjjM6zZ2ybZ61OuZ1R7X1Xoszq/fu3jBuld92gN3akz17OGLsjNsYHCfA3wK5TvTtP1xpj 7WrjNJhjVHuu5bgyqnKuXOdXf3GT7VhuEGL8ZqSFu2u0q43TYNiojvDgnJ7C7p+J4+jeoM4nRFCL I/3gXh/t+6hRHeWzNGeJCHra0xHiUGcJa6bePmPdj3DGPI/6fMSongHGnDUu+jEdmd72+kadz3Ez 51ArrzFrzEf4jLFHjeoVSHoDDR2hPMfqeS3uTDCHN9PckFE1Zs9z5n1HP0lHLnfV4kDWG+KE2evq oXfMM+b2CWO/ng/S+gfX2G9UVY/pfO/6qM5dQ6uX+IkqbrhtkK8rNwj1OVau0dbj2w5yqlH9LHBP cN96hOs/4mr1ZC5nG9XPIukNOmo8L0mbqrcnn13SwasY1dlkHQlH6/FxzHEx3NGoJh2BDh2lOOUO z9oFeMiovjpZb0Kt3vDa3PvbaTKVT/VBINoHof9sNv25v27VF9fX+dVfwf+XBEss5QaV12VfT3BL owpGxNsbR57nrkbV9Najpd448jx3NaqAentN7mhUwYiOqLlQbmlUQa+OqLdQ5vogaVPzQfBH3veg 3l+XfT1Bv1H1OOO5+l/1FdJ1UWbtLvU3qsAbUCwAN8NvCM6tzOKiN+iqRpW8Jnc1quQ1ubNRJa/J XY0qeVlua1TJSzLdB6Ed/I33QbgGOEeZxVhZra8H6TeqznBurnFu+OuyXq/tNwXUY72uUQXlJtlG 4NzH5HIB1yUPfnzRqJJQaFRJJDSqJBoaVRIMjSqJ5HQf5M99DMpSuWDep8T328mYURXyT0ytzF9b mYtd/cRVYy5lVAFuLtoD2xzcGEs0vn6PszaIRpXMhEaVREKjSqKhUSXB0KiSSM7zQUA9DfDv6l4f 9MD7fcyo2nnrGueVejOtyagCuRZe36gC3GCjvNG4Nnycp2zTCY0qCYVGlURCo0qioVElwdCokkhO 80He49Te0yjzMSW1Nh30G1WPeKOVES2vd8ou9zeqLwCNKgmFRpVEQqNKoqFRJcHQqJJI3s4HZaMK 0wn89VFdJXZlVOVcoVE9gEaVhEKjSiKhUSXR0KiSYGhUSSQ0qnvXnkbsJX/195OgUSWh0KiSSGhU STQ0qiQYGlUSyXsbVX/ur1v1xTV/9bcfGlUSCo0qiYRGlURDo0qCoVElkbyvUfWo8dz8r/pqmY9J aBn/RnUcGlUSCo0qiYRGlURDo0qCoVElkbyvUXWGM1+XlHU715f7v6f5RGhUSSg0qiQSGlUSDY0q CYZGlUTy3kZVyD8xdWWZvdii/pJGVV5s3f8Ty6j38T1tdqBRJaHQqJJIaFRJNDSqJBgaVRLJ2/kg 9JsNqFEYz1xWXhdll/vVX0skuMEyyQz6OrrhiEeMj0dZLbYBjSoJhUaVREKjSqKhUSXB0KiSSE4x qhtfI9dH7+pkHn28cJYPSmMZZjxxtPPadVmmx5VRlXPltX+iihvrN8bf9L1Nsg36m3IU24BGlYRC o0oioVEl0dCokmBoVEkkU30Q3selD0I/6VzYe1+jHPURPiiNBWA21XDm66O6yvXljKrfHJzbhqGv 1iZZW2wQzmsxHdzWqNq9bAm3N47M4a5GlXp7Te5qVE1H1NzrcVej2qsj6i2cWxrVEb31xpIpvJ0P wvhdZtTTiL3E/49qWri08f8lwEwhbjjKbePKthaD+qOYDm5pVJPQZd5GLQakOMFEU/wXDnICdzSq pjckoaSjot6T9KZxR9okc7irUTW9JS1V6o1Sm7UYMpc7GlW8G1POknOw9wyN5EIyjdsZVdNbz7dZ 0qVRqSfTeTsflOZZIvNMlGXltZXp+aX+RhULx831G2R15c1HXYmPwU1Ame+/k4eMau9YNtdanac3 rgf0g3tjokhJztV7UpyhsbW4UWw9PWvqiTFGYnvonSPojW3FPWJUZ43t6Y3rwest6aio93G92hyl d+29cWAktoczxm7FPWJUe8cGvbEjfbZAP6Xean2j7LP1BnpjR/rs5YyxW7GjRnXm2IbF9fZ7BPqA dkxrRi021WmsxdfiHqF3PbPjRhjpcySuETtsVDv6zIzE9ca2yBqSc8tdtTiMV+pt1hx619MbB0Zi e+ntc2Lcy/gg6MNizvRBNtYK052cm/k00nVRlnCxlzGqaGMblBK8w28QSIvWWAP1vn1tnAbDRhXz xlgtQVhcz7wsrtVnD9aXF0dtDun+u/p0FMq4R7A51Mb1fNY9An7sVp+98+zpc9So9o4NWmMb1mcr rgfrK2lJz/f6thdqjhdmzgHU6j1H8/OM9NnLGWO3+nzEqLb6NHrn6eNaffaAfkw/dl7LXX5cH1/G PYL1O+segd64Xh4Ze8Z6Ro3qI2O3Yi0O1OpHwFgjerNYi2/NtQe/9lq94eNa4/bGjdDbp82zZ+yO PoeMqo0NavWe3nmO9NlD77sSZVafvpGFGXMYWY/FRd8j0Nunj2vNsyPu83yQxnlQj/YWVxunQb9R VZ1lI2plnrLM4n29YDlUPdZ1jKodQblBthk5tlJWG6fBQ0bV8OUlvXEAMZh/T2wL68sLpXZvUpzV u2MZ9wi96+mNAyOxvZwxNmKO4h75iero2K3Y3rge0Afml7Sm53vzNZ2lRKXnM+fQ0xdijFq9MdJn LyN9jqznKPYRo2p91uo8rbE9iOmJ6wH9mH5MS7XcZfPzeutZVw+2ntaaeuNA773sZWRsxMza81Gj 2tOnMXOevaCPrB93rMVhTItNcVpexo4ysh7E9MbNmp9hY7f67I0DiME8a3XKaT9RtbFbsdZfT589 eJ2Zlmp9o8zqU54TGveqmxG99d6j3j57GekTMb1xjT4/xQehHOef4YPSPIFqrWlUffnOteXQyxlV lIFyg9KG6DUWWIupjdHBsFG9Aul+qSggBtyvvbicCPW6Fkfm8YhRfXVKve3pyJ7bHm2SOTxiVF+d pCPVUNKRllXjBOotllGjegWSjsCB3kBNm7U4MpVho/rqeL0d6aimN+a403k7H5TmWWK6K8vK66Ls qV/9/eXXn/3y6z9+9s1f//GzX/7urz/DdY1vpO6v//u/P/vfHz746z+k3UGbKt8IX6WNjJeOvg59 /VWxfr+RI+IMi7Fz336AtB6Z/7KWH5b1yPp+Z3P6sm3z8uDegt/psRZj9MaROYiefinH38mz9lW0 D/3huhp7JUb1Rs3FoPnrd6Iz6A26+yVyaRl3NbyOavWeXm2SOYjmvhGNQW+W46x8E3sVRvIW9RbO L+Ve45st5ziUX1lvoFdHFkfNhfFSPsif+/YDNH1QHlfODejNX++V1ahoFf7zl3IfVv5z808DP82o +kmjLzOh/qPK2hg0qvvgXhVC2KU3jjyP6OmWRhX0am5Em+Q5NH/dzqiCXg1Rb7GI5m5nVMGIjqi5 UG5pVAH19pK8hA+yuggfVDOqNbxRPTKtlzGqIC9eQHtMHMeybNVGQB02h0aVXA3R022NKnk9NH/d 0qiS10Q0d0ujSl6W2xpV8pKE+6BNGwF1UT4ozVGOI7R+ulp4u9c1qsBueMlRf7axtkmPji00N4jJ jsxE9ESjSsLQ/EWjSsIQzdGokkhoVEkkb+eDbKya4fS0zKmRfqL6u9UcXtuoAmwS2vdsjuE3Fue1 mA6aG8RkR2YieqJRJWFo/qJRJWGI5mhUSSQ0qiSSMB/U8jZRPqjXqI5QzPf1jaqBm4HJ997wkdgd mhvEZEdmInqiUSVhaP6iUSVhiOZoVEkkNKokkrfzQcmoyrH3J6ag91d/9Tm9jlH9BJobxGRHZiJ6 olElYWj+olElYYjmaFRJJDSqJJK380FmVEegUZ1Hc4OY7MhMRE80qiQMzV80qiQM0RyNKomERpVE 8nY+KBlVIOdGzYj2/sQVcZf7G9VPpLlBTHZkJqInGlUShuYvGlUShmiORpVEQqNKInk7H1QzqjV6 jSqgUe2nuUFMdmQmoicaVRKG5i8aVRKGaI5GlURCo0oieTsflIyqHEfo/dVfhUb1gOYGMdmRmYie aFRJGJq/aFRJGKI5GlUSCY0qieTtfBCN6ufS3CAmOzIT0RONKglD8xeNKglDNEejSiKhUSWRvJ0P SkYVyPkoNcN6yb9RhbNGe6P2IVXGeApnPkJzg5jsyExETzSqJAzNXzSqJAzRHI0qiYRGlUTycj4I sWf6IPT/qFHdo5jv6xtVtE03wVHe9FqMgboHN6m5QUx2ZCaiJxpVEobmLxpVEoZojkaVREKjSiJ5 Ox+UjKoc9346WpYdlRuoR9/6nL6uUcVNRTt/o2s3Pbt5V15rW/bfQXOD3iHZPShu8gCip9sa1V4d UW9xaP56e6NKzcUhmqNRJZHQqArMcWGE+SBg+/qZPiiPLeezKPT6ukYVbfIN1jJM3sqAbQZuVELO kYCAxf5VY8v+O2hu0FWTXb5vrqwG6nHvW3FkDqKn2xlV01mPjizWqMWQeWj+up1RHdEQYpjj4hDN 3dKo9mquN45M45ZGFfrhO/Ul+TQfhNjP8EEYM81Fzg3M1V/vldVIur7C36jmm/uP5Wg3HnXoy256 rd+9DcJ1GduguUE2pyuB+wAhGHv3pTeOzEP0dEujCv3kBCQcxXlqcWQemr9uZVRH8lavNsk8RHO3 M6q9muuNI1O5nVEd0ZGPpd5CeGkfVMZ10PRBNaP6LJc1qlaHvlKdYP36pLO3Qb6PTpob5McFGMPw 5SW9caA3rgf0Y0kLYthLXj7Ox5Zxj2DrqY1bMjtuhNGxR2JrdUD0NGxUR8duxfbG9YJ+LPmYnmp9 o6zU28w59PRlca3Y3rgRRvocjduL1fw1ZFRnje3pjesB/ZiOjFrfPu4svbX6640DvXG9nDV2K1Y0 N2RUrb+e8UfjemJboA+voT0d2Xg9saNY3z19jcb1xPbS22dvHOiIGzaqE8fOjMS2KDW0pyOUlbGz 5tC7HotrxfbGjTDS52jcQWyYD4K3GfVBVj9A0wcloyrHEUyXexT398WNKm6AgBuBPlCOI8pA2S/q jaO4TpobVCY7GxdHX16S40Zii/JHSH0V1Pot4yAcHMu4R8h7KdTqjbzuRhzw+qjVPwL66+kzz7Mo L7G4o1jR05BRHRl7JLYnrhevH6PWt6+3+BlzyOsRavWGxX3GPQK9fY6M3YrV/DVsVGfPM8V1xrZA Hz16S/MrmDE+6M1HI3nL7lGt7hHS+rXP5jyFrvUIrTjR3LBRHRm7K9bihFr9CGlcodTcXlxJa649 2Nqb6xa675HQE9cL+untc2Rs28tanTJkVPPYx30mso4qdZ6RPnuAbkZynI9tzbWHvJ6ivEZv7Eif veQ+O+67xU2Y52k+CO1tbBxRZuVlO+MorpOmD8J9g8Zmgrm7OVzDqKK9x5f7Nj4G9Uax6F6aG1RL dr1jIa4ntjeuB/RjCauVuHwMhINjLW4UW0/PmmbHjdA7RzASdxQrehoyqqB3nr1xoDeuBfox/ZiG QK1/i7X4vbhHQD89ffXGgVlzM0bH7oltxWn+OuUnqqA3dqTPFujHa2hPRxbnY2fOoacvixuJrdU9 yhljt2JFc8O/+jtrbMPievs9An14DRm1WF9vzJgD6O2nd929cSOM9DkS14i95U9Ue3SEMtS1cuEj 9K6nNw6MxPbS2+fI2I24MB+EMiv3bWoxoHd9BU0flIwqkHPDdPdo2WV/9df+awf6wsYB69eSDmJQ BtKNU1ofXzs0N+go2b0q6R469sTbG0fmIXoaNqqvjukoJyDhKI56i0Pz1y3/RrWlNzASS+YgmuPf qCrUWwj8G1UHNXc6b+eD0K+ZzF6gxVq5YTrVNV3HqFod+io3qIb1AUbHV5obdMVkh/sCepJWbxyZ g+jpdkYVPKI3au58NH/dyqgC01FLc6Yz5rg4RHO3M6qgV0c+jpoL4XZGFXgd1eoN0xlzXBin+SBf h75exQeZUYXGSsNZKzsqN0yr+py+rlFFG2wCboZ/wMryhIvBwgCuEWOb7PvopLlBV0925LUQPd3S qJLXRPPX7YwqeV1Ec7c0quRluaVRJS/LVB+UPIxQehj0VZZ/lg9KRhXI+REtc+op5vmaRhXYDTaw SPSTrwXEACu3MrS3stomd9LcICY7MhPRE40qCUPzF40qCUM0R6NKIqFRJZGE+iB7X3+mD6oZ1Zop 7TWqiLvE36ga5SYZvr/NRiplme+3k+YGMdmRmYieaFRJGJq/aFRJGKI5GlUSCY0qieTtfFDNqNa4 pVG1RIKbgPZHNxubZDE4ep748GpuEJMdmYnoiUaVhKH5i0aVhCGao1ElkdCokkjezgeh75rhPKJl WrEWN4fX/omqgUkbtXrDx/XEN2huEJMdmYnoiUaVhKH5i0aVhCGao1ElkdCokkjezgc9YlRbFHO+ hlH9JJobxGRHZiJ6olElYWj+olElYYjmaFRJJDSqJJK380HJqAI5N2o/MR0pu9TfqH4yzQ1isiMz ET3RqJIwNH/RqJIwRHM0qiQSGlUSydv5oGRU5ThC76/+6nNKo3pAc4OY7MhMRE80qiQMzV80qiQM 0RyNKomERpVE8nY+6Mio7hnS1k9XaVT7aW4Qkx2ZieiJRpWEofmLRpWEIZqjUSWR0KiSSN7OByWj CuS8ZjqPymogjr/6209zg5jsyExETzSqJAzNXzSqJAzRHI0qiYRGlUTydj6IRvVzaW4Qkx2ZieiJ RpWEofmLRpWEIZqjUSWR0KiSSN7OB9WM6rNczqjid5XR3ih+dzndJF9f48GPr+YGMdmRmYieaFRJ GJq/aFRJGKI5GlUSCY0qiSTGBxV5s6yvgTbmnwZo+iD0WzObR7R+ulrM87WNqt385NYdfhFlPa5r Zb7fTpobxGRHZiJ6olElYWj+olElYYjmaFRJJDSqJJKX9kG+TSdNH9RrVG/5q7/l5vhzYDcc5X9V cG7l6eYpj4wvNDfoHZLdA8ImDyJ6uq1R7dUR9RaH5q9bGlXoiJp7PURztzWq1NFLclujOqI3ajOM cB9kMZ/lg/IYcu7Npr/eK6txKaOKNrjpthkow9FuupUjDue2QYizJIR63MQHP76aG3TFZJfuiZDE oGV79MaROYiebmlUH9EbNXc+mr9uZ1RNR8xxr4do7pZGtVdH1Fs4tzSqI3rrjSVTOM8HaXvsI66N tL96/hk+CP3WDOcR0GOt3DCt6hpe06jaRsh46Ygyu+noyzYO536TQLHAZ2hu0BWTXbpfAsRwlLws ztiLO5ORMT9jfsassUVPtzOqvTqyuJYuX4VXn18Pmr9uZVRLvR1pqYy9w56+OqK5YaP66vvSqyOL OyPHvfo9+kRONaqfcd9NRy29gTLuM+b7ZrydD6JR1Q3yH0/oq+e/MFj8EzQ3qBQBxjV8eUlvHOiN 6wH9+MRlyasW62MgHBxrcaPYelpr6o0DI7G9nDF2K070NGxUR8duxfbG9YA+vH6MWt++3uJnzcGo 1Xt6Y3vjRhjpczRuL1bz15BRbfVp9MaB3rge0I/X0p6OeuMeAf309GVxI7G1ukd4ZOyR2FodEM0N GdWZYxsjfbZAH9BOmeNqsb7emDWH3vXMjhvB+mz12xsHOuKGjerEsRMW1xPbA3TT805FWRk7aw69 67G4Vmxv3AgjfY7GHcSe54NcHfqCD/I/QbV442COIzR9UDKqQM4N012rrEbS6RV+9TdvEBYv4Eag DyPdFD3fbaPlT9DcoDLZYUzMqTU26rGmnjmOxLZAH5awPLVYX2/iqcWNYnNorSfFYd16r48wfcy4 R0a65x195nkW5SWoTxzEip6GjGqrP09vLOpn3cvUl2D6MWp9+/qcrIQybhT0YXtZq/dYXGvctK5J 98jI8yzKS3rjAGKO5qn5a9yoTpxnjuuI7QF9eL3t5S7EWYwxY3yAtfToY2TdFlurewSM2T026Ijt iRPNDRvVrnsJEKf9HZH61GOtfgT0AY2Zzvb0Bkxnnllz6L5HoDO2p88Rzhi7Y8+HjGoe+7jPBGJm a7MH6MbnuD0docxr0yjjRsnrKcprIKb3Hp2mt8Z993ET5vl2PgjzSnORc683f71XtscljSrae9JN 0XPEW9KxdoYJdC8pNWhuUNkvxjd8eY3ZcT2gH0tWEAOOe31bnI+txY1i6+lZ0+y4EUb67I1txYme howqmDW2YXE9sT14/Ri1OIxn9S1tjtK7nt44MBLbwxljW9xerOavh36iWqsr6Y0d6bMF+jEdGbW+ e+MeAf309GVxI7G1ukc5Y+xWrGjuoZ+o1upKemMtrrffI9AHtONz3F6/I7GjoJ+evmbHjTA69khs rU759J+ogpHYFqWGQC0O45Wxs+bQux6La8X2xo3S2+fI2I3Yl/VBD9L0QTWj+iyX/YmqiQN9+Y3b a2vguozppLlBR8nuVUn3UIAY9hIcKOOeuI+kE9HTsFF9dUxHxpGOfCz1dj6av972f0zJx1FzMYjm bvc/pmQ6Sh9YWlbDx1FvYdzuf0zJdGT0aI56C+M8H6RlaU+1HNT6tbYGrsuYTpo+KBlVOY4APdbK jWK+FzGqcm2JBX0dbRDYbNJOXIPmBl0x2eHeeGoxBuqZ4OIQPd3OqIJevYGRWPIcmr9uaVR7NTQS S55HNHc7owqgH7wra3Ue6i2c2xlVYHpr6ci0ZtRiyFTezgclowrk/IiWOTWSrh/5ieqv/vzTX/3h 7z/91Z///dNfffvnn+K6xrdS9+d///un//7PB3/++79/+u0f6vGHoM2f/y7I0Y9p5ThaOY52/sWV pfYaa+0HSOuR+S9r+U86/l3W963cixTz5Q+bNoQ8jOjpV3L8g2j2zwL0h+tqLCHPorkS+ezPf/97 0t1RfifkaURz0Bi0BpDjrHwTS8gE8A5Fjkt6w3csyqk3chLIafAJKx+UfEM9/pAr+CCMgb5XiDdK lNcC1lKWrerk+K3wKyDXwq9k/hv/ufmHQDzgkUbVFu83o7wu46zMylFm8VY+QHODaFTJTGhUSSQ0 qiQaGlUSDI0qiQQ5bZpRRX4sfU957ePgTazMyhFr8VY+QNMH5bHFD2WzWZQldsrMnPqYZFTlqB7r dY2qYQsx0iKEWgyOnnIzB2luEI0qmQmNKomERpVEQ6NKgqFRJZEgp00zqkbyM46ar7EYHD2i+3R8 8N3e9EHoN42lZnM1By1b4cuL2Lw2OUfflzGqwC+mNj7KgI+z2Fp8J80NolElM6FRJZHQqJJoaFRJ MDSqJBLktOlGFZTepqxHGfBxFluL76Tpg2pjeiOazKecw3yuzGlxjTiLTb/2C+RauIZRHeVgjiM0 N4hGlcyERpVEQqNKoqFRJcHQqJJIkNNOMaqjTHqXN30QxqkZz81569qdX+ZvVF+A5gbRqJKZ0KiS SGhUSTQ0qiQYGlUSCXLaSxjVSTR9EHJ4Npugdu3Ly7qyXs5pVPtpbhCNKpkJjSqJhEaVREOjSoKh USWRIKfRqNauPY1YGtV+mhtEo0pmQqNKIqFRJdHQqJJgaFRJJMhp72lUPc542t+deiO6itOj/xtV GtV+mhtEo0pmQqNKIqFRJdHQqJJgaFRJJMhpNKpA/NHq3F+XaD2N6jjNDaJRJTOhUSWR0KiSaGhU STA0qiQS5LT3NKrih7LZLMrytZbBiFqsmVMfl4yqHNVj0age0NwgGlUyExpVEgmNKomGRpUEQ6NK IkFOe0+jWuKMZ2lEN9dadtmfqGI8fyP2xvcxHmtfa9OguUE0qmQmNKokEhpVEg2NKgmGRpVEgpw2 3agiTwLva/biLMbiPLU2DZo+CP36MRPijcyIevNpZWWMxVlsMqlAroXXN6ppAXJD0iLkiOvaHOxm WZzF7sV30NwgGlUyExpVEgmNKomGRpUEQ6NKIkFOm25Uk7d5UR9kY5bGc3Peey3HS/1EFe38pqRr PdbmkWN0g3Bdi+ukuUFXNqq99+WJ+0cGoVElkdCokmjubFT57LwkNKoCtRkGctpUo2qexnxPutZj bV8tRt7pq3ZlXCdNH2TjHZpPuz6qc9eXMapog5sM/Ji5XI61udTqH0xKzQ26qlHFfTFq9UZvHJnD XY3qiI5648jz3NWomoZ61jISS57nrka1V0e9cWQatzSqvTryca1YMgXktGlGteWDcKzta6QPQv8Y L2FmE0c7L+t8vZX5c+ESRhVj2OZYW7vJuU7PfTuA+KgNuqJRxT0xUSQxFPUG4lIsjo1YMoc7GtWk I6c3XNfiQNKbi63FkHloXryfUVUNJR1V6g3qLR7R3O2MasprqjWjGgdUby1tkmnczqia3nq+zai3 cJDTphhV7Jdo9uV9EPrHeCtUcxgf2LWV+RhfbrGX+BtVjOE3yI+Z64pyA/FH9QM0N6hmVDFmz7iz 43qwvrw49vr29eko1OJGsTnsjeuZHTfCSJ+9sa24R4zqrLE9vXE9oC/TkumpGudiUtxB7Cjop6ev 3jgwEtvDGWO34vTFNWRUe8cGvbEjfbZAP15HpqVaXBk7cw69ffXGjvTZyxljt2JFc0NGtdWfpzfW 4nr7bWG5C/3t6S3FCaXeps1BqdV5ZseNMNLnSFwjdtioftI8uyn1BqpxQOsTWlaLHaV3Pb1xYCS2 l94+J8Yhp51iVP24ua4oNyJ9EPrHeCuc5lbnZX0RY0bVcqh6rNf/1V8cMabnVTaoNKo2v9a4vXFg JLaF9ZMFIuz16+vTUajFjWJz2BvX6I0DI7G9nDF2Ky7CqLZie+N6QT9JS3q+12/t5TtjDjZmT1+9 sb1xI4z0ORq3F3umUbW42bEt0IfXTzoKtThjpt6A77tWb/TGgd64Xh4ZuxXbE/eoUT3q0xiN64nt oUdvwOp9/Iw5WD89fY3G9cT20ttnbxzoiDvNqFpcK7Y3rpfau7IaJ1g93r/2Dq7FjtK7HotrxfbG jTDS52jcQSxy2jSjan7Gfz8Z8Div4IPQP8YzrWHMdO3K8rUv09gUX8RZDr2VUfVJx9pFbFBpVF8d u38mCohh7x7VYmtxZB6PGNVXh3p7XR4xqq+O11DSkZb1xtbiyDxGjeoVQK7KOsJ1UZ/jBOotnGGj +uokHYEOHfVqk0wDOe1TjKrXdKoP8kHoP+mxRDWXz4+utQzzxTF9/wG5Fq7zN6qbOj0v6xAftUFX M6oA9yQZBhNDUe/xsU405CTuaFQB9JOTT6XeML31xJLnuaNRBV5DrfVQb7Hc1ahmKvUe6i2c2xlV AJ31aC7HNOLINJDTphlV0ey+D1Jq+xrpg9A/xlshekvIOeaQr7WsjDEs9pJ/o4oySyy5Ts99m1QH gjboikYV2L2q1Xl648gcbmtUHbV6T28ceZ67GlVAvb0mdzSqYERHI7HkaW5pVEGvjqi3UJDTTjOq r+iD0D/mVzWiR3V713LEf1h5eaMKME7tRqMv27hauXxwhW3QVY0qeU3ualTJa3Jno0pek7saVfKy 3NaokpcEOW2KUQXIj6Lbbh+U442i/gGaPgj9Yx6H5tOuj+rc9WWMKsBYuNFp4nr012UsymFUk1nV Mh8zSHODaFTJTGhUSSQ0qiQaGlUSDI0qiQQ5bZpRBaXvKa99bK4P9EE25gZnPDfXODf8tdZfyqgC tMVNN9IiXL3HbliK1etaXCfNDaJRJTOhUSWR0KiSaGhUSTA0qiQS5LSpRhUgT4p+X9IH2XgrnPFM ptquBTPZvszKLfZT/kbV2jyaHNDeg7KyL7su456guUE0qmQmzqjyI46cTspff0gvUPyHkT/kjzgp p+bIbKAp5DjJa+scB73xXUpOQN+pW6NKvZFzQE47NKqPvluRKz0oK/uy6zLuCZo+CGNk42nnvqyn vLhOP1GVoz6n1zCqn0Rzg5jsyEz0pUqjSkJI+aswqtAcyqk5MhtoCjlONEajSkLQdyqNKokCOe0U o/pJNH0Qcng2m3LMPzG1Mi3flPn4Iu5TjaqAJNGFtKmWB5DmKmJqbpBS64OQUZKWRHN4oabnBs+c Pju1eEKewfIXdAa9QXc+v9faEPIoWW85x8E4fNSV8YQ8S9KV6O1b05vLcbV4Qh7F57dDo6rxXUhf 1fIA0lx7fBCeJzOYGWc8V0ZUyzbXisV+yt+ouja/+lb6QV8vi871cIOutB5yHZbn7A/yQk2JDQ8n ykWH6zhCJgBdCekjTvQG3X2UuzhCZgBNmd7kvZq+DVKOW3RYbUPIM6iu7D/+pv8Yl+qoNzIR0Zl5 gqpR3fig19dfmutpRrWIMV7GqKZ+Xhv7ve79DdK1SP23ck++xRpb4N5VxiKk5A+il2RUYRwq9YTM BPlpMarIU/UYQmZh/2GEOY5EYe9UHGv1hDyL9w2HRlWOtfavRtsHlUa1NJ6166M6u5YjjWqbUaP6 h7//pwmNKumFRpVEQqNKIqFRJdHQqJJTgWlzvuE+RvUPBz5o1Kh6GrGfblSLm9HFI+Z2pE0RO2pU Vz853YNGlbRQHdKokhCgNwH5yT7iaFTJaZje5Bx6SznO19k5IbNQXW2MKvVGZiJ6Ot2oPqLZkTZF 7LhR9TjjmX6d18rKeivzdcKnGlU5pgGRLCxhnMIDfec5/Vs36Mio6gYJuC/JrFbHXPrblhNSQRMF jSoJAXpD/lK90aiSUzG9yTn0lnKcr7NzQmahuqJRJacievK+ocuoQoumx1fBzWlZzyyjatdCNq6V cotNJhXINXxWmp/My+4h2PxDYHqwi8CCtKCjDRIw4LdYpHC4STmRaBziW202cQexHm337b//I9dm VDs2COvJ8yTkSVRLNKokBOhNoFElIZje5Bx6SznO19k5IbNQXdGoklMRPXUb1Yd8kIA4xLfa9MaV aLthH4S4bDrt3Jf1lBfX6Seqcvy0/3saGRA34ltZcNeNzDfvg2objJPqpW/E4Ga3+gbWv8yHRpV8 KqolGlUSAvQm0KiSEExvcg69pRzn6+yckFmormhUyamInh4yqqf5II3Zi9uwxD7kgxCXzaYcqz8x 9WW18uL6NYzqxw3ZveEAcSDVa5yW+TaoX2/K0ibdcBe3ZWmX5pHms7SlUSWfgmqJRpWEAL0JNKok BNObnENvKcf5OjsnZBaqKxpVciqip0eN6iM+aPEt6zbZ81h5juv0QZhL9kG2nhGj6nHG036dF+bT m1EfY3Gv96u/tkHFJlkCSTdZbzrGLcpzm3S9kPtIyLn2n8vRh/Vjm6Mxb2VUYYB6TFBvHJmDaul2 RtV01LOe3jjyPJoPb2lUqbfXw/Qm59BbynG+zs6vyKjeqLkYVFe3NKqjmqvVkTmInh4yquY/EqLN Up85ZvEmuRz9+fJ0vZStfBDOtf9V31n/H+1WplnqphtVX1bGlOWvaVSdIU0T+ohZyqXMbi76S22k HDc+XS+k9nkDBO1jqXPlaJfrlHcxqpa0/q3HWozRG0fmoFq6lVE1DZmOjtZk9a04MgfoTbidUe3V kdUzx8VgepNz6C3lOF9n51fDNNSjI683au58VFe3M6q9OuqNI88henreqKrfMY2uYgrdoj8rR3y6 XkjXXt9lHwbicp1niRs3qjCbheFcnfdey/EV/u9plhta3hy7QYrGpJtpZXpzcyzq0vXCEqvzxLn2 sfSL8qVuiffjChOMqv2v//b8X9HMjuvGEpbH19t6fH3PC7ib5R4v1Oo9s+NGGB17JLZWJ+i9HzGq s3VkcT2xXXj9GCjHWg2LK/H9PIzd85719MaBkdgezhjb4nZi9f6PGNURbSxx7dipegM1HXm9gVqc xT5N37oXemNH+uzljLEPYvXejxhV00aPPkbjemK7gG72clwZV+LrH8buec96BuLwDVWte5SBsYdj a3WC7sGIUR3VUa3OY3E9sYfYnKGbHr2Nxg6BtfSsx+Jasb1xo/T2+WSc3M8ZRnVB+k86XY4oy9c2 tpbnWKD9LbGY1175Unc4vsTMMarl9VGdu355o5pupqAx6bpgFZuuF3zMR53G2galMit30Kgu2Hp8 PY3qARY3ElurE/Te39Ko+pclyrFWw+KMl9cbGInt4YyxLW4nVu//rY2qacnrDfi4UptP07fuhd7Y kT57OWPsg1i99yNGFX0t+qjVrenVkcX1xHZR5jfTUbkmX+/jnsbuec96BuIkH9TrHmVg7OHYWp2g e3CGUcW4PXHWX1+fB9icoRuvN5z7ek8ZC/Zih8Ba+u5RX2xv3Ci9fT4ZJ/fzdKNasIoF2p+P2ZTb fOX8cHyJGTeqHmc8d3/118rd0f8962saVSnzN1JjlpsruKPFp7J0vbDELJvwUaex1q/WL23c+BOM 6iXwCcuSVo0y7ij2JSj2OJRJY6uWRozq5667A6zBf8jVYgzTWU/sp3MTvQnjv/p7Ac15ajHA6qm3 DiaMb3qTc+gt5ThfZ+dXw2uopSOL6Ykd4sWfyVM5WLvqasSojhF4323OpYZMR7U1oa5Xm0NQbyvk 3s8xqvjuc/1rjPc0aXz0p/G5PMXqOdquyiXWyg253psD6k8zqum6jAMu9mWMajKG7sbYTdSHzW5g LjfSzXVt0vXCOlbOtY9UZ+X2MCM21wvvYlRBb9KyuKkJjuyiWhozqhdgREe9ceR5oDdh3KhegFG9 UXPnY3qTc+gt5ThfZ+dXpFdHvXFkDqqr84zqJ9Gro9448hyip+eNqmiz0OdHjJYb6M+3SdcLuY+E nNf6MP0j1uqzJ1vixo2qGs6qEa2VafnKyGpMMqpyfIn/exo1hyun7zdI6nETczlAf9UNcqbW5qrl tf4Tru1bGVXymqiWbmdUyWsCvQm3NKrk9TC9yTn0lnKcr7NzQmahurqdUSWvhejpIaPa44OceUzl AP0d+SCLEz+zxLk+XP8Ja+vmgvLHjKocm0Z1r9xdv5RRxc3DTbUb5kB5umEgxyzXqX0qW1hizahq LM5TbOWnsh5ta/NBexpV8imolmhUSQjQm4D8aR9xNKrkNExvcg69pRzn6+yckFmormhUyamInh42 qk0fhBipzzFyRNvcTtHYJQ5IbG4/4oOWuHGj6nFG1P8678qcFteIs1gZd0Gu9X6lNbl7qO7U/fv1 15/8+uv3P/n19//6ya+/+/4nuK7xndR9/69//eRfP/yQwfVHG+njq1z/64cF9Idr9L1BylGP9ine jnqe2mrsKq6IPRwDSF1q/xGPeX75Imt26/nBrec7aYd6rCn3cTgGIf18FY2B77zGCTkJ6CxpDnqj 5sjJZL0xx5EQFp3lHFeNIeQ5Wj4I5YtvQLzosMujSDnqLVb6yf4G5V7PKU7rcqyeH44BpM6PI+df vpO5rnzQv7Y+SH3dF5x/lfMj0F+tvIbey5XPwvyyl0Rd+W8vsKDfqCqHN07xNy8h1yirxhWxKa4S u0FibBw50qiSz4QfcSQSGlUSCY0qiWXRWc5x1RhCnqPlg7ZGVWlqUmPM/9ix1i7FWYyS4iqxGyTG xpHjdKPqaZlW1KPvSKOaNijFuJsB0s1pYLGeWhzYxB3Elrg2XzBfGlXySfAjjkTijcOSA+txhMyA RpXEsugsaY56I7NRTSXD1vJB2ahqu149WqynFgc2cQexJa7N1ge9m1HN6M1pkW4cznvajMQW6Djb /5LQMKpol+dIyHOsPuK+r8cQMgsaVRIJjSoJRTRGo0pOQzXV74PUNzzkgyy+1a43roKtB/N91KjW jOhI2a+/W/r+HKO6LPrVSXPtNKrYzLzBrg9CRjEt4WW6fMQt16mckMmkF5FQfsRZea0NIY+SdeVz nL43qTdyBqY3y3H2H0aoNzINe2eqx+nxQVfQX5rno0b1Wew+fYpRNXN3BXo26ErrIZfhq+gLH3If iYCQ84DOTG9H+Z2QGUBjX79fNJc+8ioxhMzi19+tc1wthpApiCe4rw+q/MAuxckR5rL3J6ZH5Ub6 qaqg94pGtQbmudogGlUSgOopv1Sv9tyQa6F5DjrLRtWVV9sQ8iiqq2RUNcel7wnqjZyB6U3Ol3fq 9/x2I+eheruvD2oY1RYtc+rxc5AjjWqNzQbRqJIAVE/LS/WCzw25FprnoDMaVXI6qiu8V2lUyemY 3uR8eafSqJITUb3d1wcdGVUg50bvT1f3yj71b1Qvu0E0qiQA1dPyUr3gc0OuheY56OzDqIrmtLza hpBHUV3hvZp/9Rc5jnojZwG9yTG/U/ntRs5C89h9fdCAUW3R+ulqMquC3isa1RqbDaJRJQGonvJL 9WrPDbkWmuegMxpVcjqqK7xXaVRJCNCbHPM7ld9u5Cw0j93XB9GovhabDaJRJQGonvJL9WrPDbkW muegMxpVcjqqK7xXaVRJCNCbHPM7ld9u5Cw0j93XB9GovhabDaJRJQGonvJL9WrPDbkWmuegMxpV cjqqK7xXaVRJCNCbHPM7ld9u5Cw0j93XB/FvVF+LzQbRqJIAVE/5pXq154ZcC81z0BmNKjkd1RXe qzSqJAToTY75ncpvN3IWmsfu64OOjKocZ+LnIEca1RqbDaJRJQGonvJL9WrPDbkWmuegMxpVcjqq K7xXaVRJCNCbHPM7ld9u5Cw0j93XBzWMau9PTI/KjfRTVUHvFY1qjc0G0aiSAFRP+aV6teeGXAvN c9AZjSo5HdUV3qs0qiQE6E2O+Z3KbzdyFprH7uuDnvwb1ZY59fg5yJFGtcZmg2hUSQCqp/xSvdpz Q66F5jnojEaVnI7qCu9VGlUSAvQmx/xO5bcbOQvNY/f1Qfwb1ddis0E0qiQA1VN+qV7tuSHXQvMc dEajSk5HdYX3Ko0qCQF6k2N+p/LbjZyF5rH7+qAnf6Lqaf10NZlVQe8VjWqNzQbRqJIAVE/5pXq1 54ZcC81z0BmNKjkd1RXeqzSqJAToTY75ncpvN3IWmsfu64NoVF+LzQbRqJIAVE/5pXq154ZcC81z 0BmNKjkd1RXeqzSqJAToTY75ncpvN3IWmsfu64P4N6qvxWaDaFRJAKqn/FK92nNDroXmOeiMRpWc juoK71UaVRIC9CbH/E7ltxs5C81j9/VB/BvV12KzQTSqJADVU36pXu25IddC8xx0RqNKTkd1hfcq jSoJAXqTY36n8tuNnIXmsfv6oCOjKscRWj9dTWZV0HtFo1pjs0E0qiQA1VN+qV7tuSHXQvMcdEaj Sk5HdYX3Ko0qCQF6k2N+p/LbjZyF5rH7+qCGUe39ielRuUGj2sFmg2hUSQCqp/xSvdpzQ66F5jno jEaVnI7qCu9VGlUSAvQmx/xO5bcbOQvNY/f1QSf86m+NZFL5q79tNhtEo0oCUD3ll+rVnhtyLTTP QWc0quR0VFd4r9KokhCgNznmdyq/3chZaB67rw+iUX0tNhtEo0oCUD3ll+rVnhtyLTTPQWc0quR0 VFd4r9KokhCgNznmdyq/3chZaB67rw8aMKotWqY1mVVB7xWNao3NBtGokgBUT/mlerXnhlwLzXPQ GY0qOR3VFd6rNKokBOhNjvmdym83chaax+7rg2hUX4vNBtGokgBUT/mlerXnhlwLzXPQGY0qOR3V Fd6rNKokBOhNjvmdym83chaax+7rg/irv6/FZoNoVEkAqqf8Ur3ac0OuheY56IxGlZyO6grvVRpV EgL0Jsf8TuW3GzkLzWP39UEnGNW9MhrVDjYbRKNKAlA95Zfq1Z4bci00z0FnNKrkdFRXeK/SqJIQ oDc55ncqv93IWWgeu68POjKqchyhZlA9yawKeq9oVGtsNohGlQSgesov1as9N+RaaJ6DzmhUyemo rvBepVElIUBvcszvVH67kbPQPHZfH0Sj+lpsNohGlQSgesov1as9N+RaaJ6DzmhUyemorvBepVEl IUBvcszvVH67kbPQPHZfH8Rf/X0tNhtEo0oCUD3ll+rVnhtyLTTPQWc0quR0VFd4r9KokhCgNznm dyq/3chZaB67rw/i/5jSa7HZIBpVEoDqKb9Ur/bckGuheQ46o1Elp6O6wnuVRpWEAL3JMb9T+e1G zkLz2H190IBRbdEyrcmsCnqvaFRrbDaIRpUEoHrKL9WrPTfkWmieg85oVMnpqK7wXqVRJSFAb3LM 71R+u5Gz0Dx2Xx9Eo/pabDaIRpUEoHrKL9WrPTfkWmieg85oVMnpqK7wXqVRJSFAb3LM71R+u5Gz 0Dx2Xx/EX/19LTYbRKNKAlA95Zfq1Z4bci00z0FnNKrkdFRXeK/SqJIQoDc55ncqv93IWWgeu68P olF9LTYbRKNKAlA95Zfq1Z4bci00z0FnNKrkdFRXeK/SqJIQoDc55ncqv93IWWgeu68POjKqchwx py3TmsyqoPeKRrXGZoNoVEkAqqf8Ur3ac0OuheY56IxGlZyO6grvVRpVEgL0Jsf8TuW3GzkLzWP3 9UENozoCjeoENhtEo0oCUD3ll+rVnhtyLTTPQWc0quR0VFd4r9KokhCgNznmdyq/3chZaB67rw86 4Vd/98r4q78dbDaIRpUEoHrKL9WrPTfkWmieg85oVMnpqK7wXqVRJSFAb3LM71R+u5Gz0Dx2Xx80 YFSfxc9BjjSqNTYbRKNKAlA95Zfq1Z4bci00z0FnNKrkdFRXeK/SqJIQoDc55ncqv93IWWgeu68P mmhUaz9J9aSfqgp6r2hUa2w2iEaVBKB6yi/Vqz035FponoPOaFTJ6aiu8F6lUSUhQG9yzO9UfruR s9A8dl8fRKP6Wmw2iEaVBKB6yi/Vqz035FponoPOaFTJ6aiu8F6lUSUhQG9yzO9UfruRs9A8dl8f dMLfqNZIJpV/o9pms0E0qiQA1VN+qV7tuSHXQvMcdEajSk5HdYX3Ko0qCQF6k2N+p/LbjZyF5rH7 +qAnf6Laa1SBn4Mc+4zqb/7y49/8/p8//s1fhN//5ce4roG6v/zznz/+5w8/ZHCd23xZx78smKfw sZ5//lg2KK/n93k9v9+2JeRRVE+/l+fsL/5Zu8pzQ66F5jnkM+gNuvuNK6+2IeRRVFfQGLSW9IYc R72RszC9ic6S5uQ71so3sYQ8g+ax+/qgH+o+COD89/L9Cv5i164sX/syLU/xRdxv5DzNYTkm72nv Cxtz8w+BNKrbDaJRJTOhUSWRaJ6jUSUhqK5oVEkYpjfRGY0qORXNY/f1QS2jqqyMKoABBWVZeS2Y aaVR7WCzQTSqJAAaVRKJ5jkaVRKC6opGlYRhehOd0aiSU9E8dl8f1GlUE/Ita2Z09RNTofoTVy1f GVVB7xWNao3NBtGokgBoVEkkmudoVEkIqisaVRKG6U10RqNKTkXz2H19UI9RlW/Y6nmt7uCaRrWD zQbRqJIAaFRJJJrnaFRJCKorGlUShulNdEajSk5F89h9fVDn36im873rozp3TaPawWaDaFRJADSq JBLNczSqJATVFY0qCcP0JjqjUSWnonnsvj4oyqjKkUa1g80G0aiSAGhUSSSa52hUSQiqKxpVEobp TXRGo0pORfPYfX3QpL9RrcVYHP9GdYDNBtGokgBoVEkkmudoVEkIqisaVRKG6U10RqNKTkXz2H19 0IhRBfI9uzo/utYyGtUBNhtEo0oCoFElkWieo1ElIaiuaFRJGKY30RmNKjkVzWP39UGdv/qbzGZR lq99mZavfuKqMcmoylG/iWlUa2w2iEaVBECjSiLRPEejSkJQXdGokjBMb6IzGlVyKprH7uuDZv5E tUTr+RPVATYbRKNKAqBRJZFonqNRJSGormhUSRimN9EZjSo5Fc1j9/VBk/5GtfoTVy2nUR1gs0E0 qiQAGlUSieY5GlUSguqKRpWEYXoTndGoklPRPHZfH9T5q7/pfO/6qM5d06h2sNkgGlUSAI0qiUTz HI0qCUF1RaNKwjC9ic5oVMmpaB67rw+KMqpypFHtYLNBNKokABpVEonmORpVEoLqikaVhGF6E53R qJJT0Tx2Xx/0zN+oltc437uWI41qB5sNolElAdCokkg0z9GokhBUVzSqJAzTm+iMRpWciuax+/qg SX+jWouxOP6N6gCbDaJRJQHQqJJINM/RqJIQVFc0qiQM05vojEaVnIrmsfv6oJ5f/ZVjMpu+TMtX 1MrddTKqctRvYhrVGpsNolElAdCokkg0z9GokhBUVzSqJAzTm+iMRpWciuax+/qgzr9RbRpVK9Py 1U9cNYZGtYPNBtGokgBoVEkkmudoVEkIqisaVRKG6U10RqNKTkXz2H190DN/o4pzvV4ZWV8n8Fd/ B9hsEI0qCYBGlUSieY5GlYSguqJRJWGY3kRnNKrkVDSP3dcHzf4bVSt3RxrVATYbRKNKAqBRJZFo nqNRJSGormhUSRimN9EZjSo5Fc1j9/VBnb/6m873ro/q3DWNagebDaJRJQHQqJJINM/RqJIQVFc0 qiQM05vojEaVnIrmsfv6oCijKkca1Q42G0SjSgKgUSWRaJ6jUSUhqK5oVEkYpjfRGY0qORXNY/f1 Qc/8jWrrGud2LUca1Q42G0SjSgKgUSWRaJ6jUSUhqK5oVEkYpjfRGY0qORXNY/f1QbP/RrW4Rhz/ RnWAzQbRqJIAaFRJJJrnaFRJCKorGlUShulNdEajSk5F89h9fVDPr/7KMZlNX6blK8ry4joZVTnq NzGNao3NBtGokgBoVEkkmudoVEkIqisaVRKG6U10RqNKTkXz2H19UKdRXYGynvLimka1g80G0aiS AGhUSSSa52hUSQiqKxpVEobpTXRGo0pORfPYfX3QpF/9rf7EFbhY/upvB5sNolElAdCokkg0z9Go khBUVzSqJAzTm+iMRpWciuax+/qgZ4xqUbaKc0eLpVHtYLNBNKokABpVEonmORpVEoLqikaVhGF6 E53RqJJT0Tx2Xx/U86u/4Oj6qM5d06h2sNkgGlUSAI0qiUTzHI0qCUF1RaNKwjC9ic5oVMmpaB67 rw96xKge1e1dy5FGtYPNBtGokgBoVEkkmudoVEkIqisaVRKG6U10RqNKTkXz2H190KS/Ua3FGPwb 1QE2G0SjSgKgUSWRaJ6jUSUhqK5oVEkYpjfRGY0qORXNY/f1QTONanmt0KgOsNkgGlUSAI0qiUTz HI0qCUF1RaNKwjC9ic5oVMmpaB67rw/q+dVfOdr/IFIu8xTlObaoT0ZVjvpNTKNaY7NBNKokABpV EonmORpVEoLqikaVhGF6E53RqJJT0Tx2Xx/UaVRXoMxTlu9c06h2sNkgGlUSAI0qiUTzHI0qCUF1 RaNKwjC9ic5oVMmpaB67rw+a9Ku/m5+iunKL5a/+drDZIBpVEgCNKolE8xyNKglBdUWjSsIwvYnO aFTJqWgeu68PGv2J6tE1zg1/rfU0qh1sNohGlQRAo0oi0TxHo0pCUF3RqJIwTG+iMxpVciqax+7r g3qMKti79jRiaVQ72GwQjSoJgEaVRKJ5jkaVhKC6olElYZjeRGc0quRUNI/d1wc9YlSP6vau5Uij 2sFmg2hUSQA0qiQSzXM0qiQE1RWNKgnD9CY6o1Elp6J57L4+aNLfqNZiDP6N6gCbDaJRJQHQqJJI NM/RqJIQVFc0qiQM05vojEaVnIrmsfv6oGf+RhXnR9daRqM6wGaDaFRJADSqJBLNczSqJATVFY0q CcP0JjqjUSWnonnsvj6o81d/k9ksyvK1L9PY1U9cNSYZVTnqNzGNao3NBtGokgBoVEkkmudoVEkI qisaVRKG6U10RqNKTkXz2H190CO/+uvZq3fXq5+oyjmN6gGbDaJRJQHQqJJINM/RqJIQVFc0qiQM 05vojEaVnIrmsfv6oAeM6uYnplrmY3z5yqgKeq9oVGtsNohGlQRAo0oi0TxHo0pCUF3RqJIwTG+i MxpVciqax+7rg0b+RhXn/nqv3sr8uUCj2sFmg2hUSQA0qiQSzXM0qiQE1RWNKgnD9CY6o1Elp6J5 7L4+qPNvVNN57drTiKVR7WCzQTSqJAAaVRKJ5jkaVRKC6opGlYRhehOd0aiSU9E8dl8f9IhRPao7 iKVR7WCzQTSqJAAaVRKJ5jkaVRKC6opGlYRhehOd0aiSU9E8dl8f9Mj/mJKcl3+jWouxOP6N6gCb DaJRJQHQqJJINM/RqJIQVFc0qiQM05vojEaVnIrmsfv6oBGjCuR7dnV+dK1lNKoDbDaIRpUEQKNK ItE8R6NKQlBd0aiSMExvojMaVXIqmsfu64M6f/U3mc2iLF/7Mo01c7qKk/M0h+VIo1pjs0E0qiQA GlUSieY5GlUSguqKRpWEYXoTndGoklPRPHZfH/Tgr/4eXluZnvMnqgNsNohGlQRAo0oi0TxHo0pC UF3RqJIwTG+iMxpVciqax+7rgx4wqrs/MS3LitiHjOqXrz/68vUfP/rmH//40ZdvBFxX+Ebq/iEx //jhhx/JghK4/kba1uJfHazn643WQy7AN19/9FX0Bd1Bf7iuxhEyCeQz6A26+4Z6IycDjaUcl/TG dyk5GdGb5Th+u5GzMR9knuH2PgjfDF8ngz7tW0Sf363/3PyTwmrgGtsgGlVCHkQeShpVEgnyGY0q iYJGlYSiH7o0qiQC80HmGW7vg/DNUDObz4A+7VtEn18a1R2aG0TIbOShpFElkSCf0aiSKGhUSSj6 oUujSiIwH2Se4fY+CN8MNbP5DP47RJ9fGtUdmhtEyGzsIw46w7PmH1hCTgD5jEaVREGjSkLRD10a VRKB+SDzDLf3QfhmqJnNkt444L9D9PmlUd2huUGEzEYeShpVEgnyGY0qiYJGlYSiH7o0qiQC80Hm GW7vg/DNUDObz+C/Q/T5pVHdoblBhMzGPuKgMzxr/oEl5ASQz2hUSRQ0qiQU/dClUSURmA8yz3B7 H4RvhprZfAb/HaLPL43q+UeaqQAAJ5FJREFUDs0NImQ29hEHneFZ8w8sISeAfEajSqKgUSWh6Icu jSqJwHyQeYbb+yB8M9TM5jP47xB9fmlUd2huECGzsY846AzPmn9gCTkB5DMaVRIFjSoJRT90aVRJ BOaDzDPc3gfhm6FmNp/Bf4fo80ujukNzgwiZjX3EQWd41vwDS8gJIJ/RqJIoaFRJKPqhS6NKIjAf ZJ7h9j4I3ww1s/kM6NO+RfT5pVHdoblBhMxGHkoaVRIJ8hmNKomCRpWEoh+6NKokAvNB5hlu74Pw zVAzm8/gv0P0+aVR3aG5QYTMxj7ioDM8a/6BJeQEkM9oVEkUNKokFP3QpVElEZgPMs9wex+Eb4aa 2XwG/x2izy+N6g7NDSJkNvYRB53hWfMPLCEngHxGo0qioFEloeiHLo0qicB8kHmG2/sgfDPUzGZJ bxzw3yH6/NKo7tDcIEJmIw8ljSqJBPmMRpVEQaNKQtEPXRpVEoH5IPMMt/dB+Gaomc1n8N8h+vzS qO7Q3CBCZmMfcdAZnjX/wBJyAshnNKokChpVEop+6NKokgjMB5lnuL0PwjdDzWw+g/8O0eeXRnWH 5gYRMhv7iIPO8Kz5B5aQE0A+o1ElUdCoklD0Q5dGlURgPsg8w+19EL4ZambzGfx3iD6/NKo7NDeI kNnYRxx0hmfNP7CEnADyGY0qiYJGlYSiH7o0qiQC80HmGW7vg/DNUDObz4A+7VtEn18a1R2aG0TI bOShpFElkSCf0aiSKGhUSSj6oUujSiIwH2Se4fY+CN8MNbP5DOjTvkX0+aVR3aG5QYTMRh5KGlUS CfIZjSqJgkaVhKIfujSqJALzQeYZbu+D8M1QM5vP4L9D9PmlUd2huUGEzMY+4qAzPGv+gSXkBJDP aFRJFDSqJBT90KVRJRGYDzLPcHsfhG+Gmtl8Bv8dos8vjeoOzQ0iZDb2EQed4VnzDywhJ4B8RqNK oqBRJaHohy6NKonAfJB5htv7IHwz1MxmSW8c8N8h+vzSqO7Q3CBCZiMPJY0qiQT5jEaVREGjSkLR D10aVRKB+SDzDLf3QfhmqJnNZ/DfIfr80qju0NwgQmZjH3HQGZ41/8AScgLIZzSqJAoaVRKKfujS qJIIzAeZZ7i9D8I3Q81sPoP/DtHnl0Z1h+YGETIb+4iDzvCs+QeWkBNAPqNRJVHQqJJQ9EOXRpVE YD7IPMPtfRC+GWpm8xn8d4g+vzSqOzQ3iJDZ2EccdIZnzT+whJwA8hmNKomCRpWEoh+6NKokAvNB 5hlu74PwzVAzm8+APu1bRJ9fGtUdmhtEyGzkoaRRJZEgn9GokihoVEko+qFLo0oiMB9knuH2Pgjf DDWz+Qzo075F9PmlUd2huUGEzEYeShpVEgnyGY0qiYJGlYSiH7o0qiQC80HmGW7vg/DNUDObz+C/ Q/T5pVHdoblBhMzGPuKgMzxr/oEl5ASQz2hUSRQ0qiQU/dClUSURmA8yz3B7H4RvhprZfAb/HaLP L43qDs0NImQ29hEHneFZ8w8sISeAfEajSqKgUSWh6IcujSqJwHyQeYbb+yB8M9TM5jP47xB9fmlU d2huECGzsY846AzPmn9gCTkB5DMaVRIFjSoJRT90aVRJBOaDzDPc3gfhm6FmNp/Bf4fo80ujukNz gwiZjX3EQWd41vwDS8gJIJ/RqJIoaFRJKPqhS6NKIjAfZJ7h9j4I3ww1s/kM/jtEn18a1R2aG0TI bOwjDjrDs+YfWEJOAPmMRpVEQaNKQtEPXRpVEoH5IPMMt/dB+Gaomc1n8N8h+vzSqO7Q3CBCZmMf cdAZnjX/wBJyAshnNKokChpVEop+6NKokgjMB5lnuL0PwjdDzWw+A/q0bxF9fmlUd2huECGzkYeS RpVEgnxGo0qioFEloeiHLo0qicB8kHmG2/sgfDPUzOYzoE/7FtHnl0Z1h+YGETIbeShpVEkkyGc0 qiQKGlUSin7o0qiSCMwHmWe4vQ/CN0PNbD6D/w7R55dGdYfmBhEyG/uIg87wrPkHlpATQD6jUSVR 0KiSUPRDl0aVRGA+yDzD7X0QvhlqZvMZ/HeIPr80qjs0N4iQ2dhHHHSGZ80/sIScAPIZjSqJgkaV hKIfujSqJALzQeYZbu+D8M1QM5vP4L9D9PmlUd2huUGEzMY+4qAzPGv+gSXkBJDPaFRJFDSqJBT9 0KVRJRGYDzLPcHsfhG+Gmtk8otXGf4fo80ujukNzgwiZjTyUNKokEuQzGlUSBY0qCUU/dGlUSQTm g8wz3N4H4ZuhZjafwX+H6PNLo7pDc4MImY19xEFneNb8A0vICSCf0aiSKGhUSSj6oUujSiIwH2Se 4fY+CN8MNbP5DP47RJ9fGtUdmhtEyGzsIw46w7PmH1hCTgD5jEaVREGjSkLRD10aVRKB+SDzDLf3 QfhmqJnNZ0Cf9i2izy+N6g7NDSJkNvJQ0qiSSJDPaFRJFDSqJBT90KVRJRGYDzLPcHsfhG+Gmtl8 BvRp3yL6/NKo7tDcIEJmIw8ljSqJBPmMRpVEQaNKQtEPXRpVEoH5IPMMt/dB+Gaomc1n8N8h+vzS qO7Q3CBCZmMfcdAZnjX/wBJyAshnNKokChpVEop+6NKokgjMB5lnuL0PwjdDzWw+g/8O0eeXRnWH 5gYRMhv7iIPO8Kz5B5aQE0A+o1ElUdCoklD0Q5dGlURgPsg8w+19EL4ZambzGfx3iD6/NKo7NDeI kNnYRxx0hmfNP7CEnADyGY0qiYJGlYSiH7o0qiQC80HmGW7vg/DNUDObz+C/Q/T57TCq3//Xl+++ /6/vvl+O6brCd1L3/Q8//JcsJPO9tEF5Lf7VSeuR+a/WI3ys57tVPCHPsegJz9mVnxtyLSzPtfI7 ITOA3qC1BPVGzgZ6M81Rb+Rk0vvUeYbkGy6svbQemf9qPUJeD44b5Fs2UV7XyuxakHFyufdXKE91 ep3Y/FsCWh8yb7dBNKpkKoue8Jxd+bkh18LyXCu/EzID6C2ZBuY4EgH0Zpqj3sjJpPep8wzJN1xY e2k9Mv/VeoS8Hhw3qNmUdqvrWowvS/FaTqPaR3ODaFTJVBY94Tm78nNDroXluVZ+J2QG0FsyDcxx JALozTRHvZGTSe9T5xmSb7iw9tJ6ZP6r9Qh5PTgm1GDuXntasXJOo9pHc4NoVMlUFj3hObvyc0Ou heW5Vn4nZAbQWzINzHEkAujNNEe9kZNJ71PnGZJvuLD20npk/qv1CHk9OCZgNEHt+qjOXcs4+dzP A+WpzpVt/y0BrQ+Zt9sgGlUylUVPeM6u/NyQa2F5rpXfCZkB9JZMA3MciQB6M81Rb+Rk0vvUeYbk Gy6svbQemf9qPUJeD44JNZir66O6SqyMk+v8PFCe6lzZ9t8S0PqQebsNolElU1n0hOfsys8NuRaW 51r5nZAZQG/JNDDHkQigN9Mc9UZOJr1PnWdIvuHC2kvrkfmv1iPk9eC4Qc3mpqy8LspknFzu/RXK U51eJzb/loDWh8zbbRCNKpnKoic8Z1d+bsi1sDzXyu+EzAB6S6aBOY5EAL2Z5qg3cjLpfeo8Q/IN F9ZeWo/Mf7UeIa8Hx4QaTIndlOXzWvnOdRpfj+jT+tV5qTn1/5aA1ofM220QjSqZyqInPGdXfm7I tbA818rvhMwAekumgTmORAC9meaoN3Iy6X3qPEPyDRfWXlqPzH+1HiGvB8eEGk2JXZcZO2UpvhKT xtcjYqxfnZeaU/9vCWh9yLzdBtGokqksesJzduXnhlwLy3Ot/E7IDKC3ZBqY40gE0JtpjnojJ5Pe p84zJN9wYe2l9cj8V+sR8npw3ADTCeRc2n5cC+m6KLN2Ptb7K5RbOyvb/lsCWh8yb7dBNKpkKoue 8Jxd+bkh18LyXCu/EzID6C2ZBuY4EgH0Zpqj3sjJpPep8wzJN1xYe2k9Mv/VeoS8HhwTajBX5zXK +p22NKp9NDeIRpVMZdETnrMrPzfkWliea+V3QmYAvSXTwBxHIoDeTHPUGzmZ9D51niH5hgtrL61H 5r9aj5DXg2NCDebq3Jftxe5c06j20dwgGlUylUVPeM6u/NyQa2F5rpXfCZkB9JZMA3MciQB6M81R b+Rk0vvUeYbkGy6svbQemf9qPcKyHjWXUr8CZWW5K8v538qLsu9oVPs53iBAo0pmQqNK4rE818rv hMwAevv4IKnHEDIN6M00R72Rk0nvU+cZkm+4sPbSemT+q/UIy3qcUZWyBM4z67L0DP6w3J/v5Zjf A6l8KaveKylLrMo3/5YAdHb0IfNeGwRoVMlMaFRJPJbnWvmdkBlAb/njhHojZwO9meaoN3Iy6X3q PEPyDRfWXlqPzH+1HiGvB0cxpDCaAMbUztO1mlW7Xkxqg3y/1GPJNY3qDs0NolElU6FRJfFYnmvl d0JmAL0l08AcRyKA3kxz1Bs5mfQ+dZ4h+YYLay+tR+a/Wo+Q14Mj1ocypTSrnmREW+T7RaPapLlB NKpkKjSqJB7Lc638TsgMoLdkGpjjSATQm2mOeiMnk96nzjMk33Bh7aX1yPxX6xHyenDE+lAmfPy6 rzvXurpRXe7XCulv+RahUW3S3CAaVTIVGlUSj+W5Vn4nZAbQWzINzHEkAujNNEe9kZNJ71PnGZJv uLD20npk/qv1CHk9OOqv/ppB/U6vs3F118mINvj4FqFRbdLcIBpVMhUaVRKP5blWfidkBtBbMg3M cSQC6M00R72Rk0nvU+cZkm+4sPbSemT+q/UIeT04VoxpBmVaVzeqy/1aIeMt3yI0qk2aG0SjSqZC o0risTzXyu+EzAB6S6aBOY5EAL2Z5qg3cjLpfeo8Q/INF9ZeWo/Mf7UeIa8HR6wPZYr9ZBX4crA1 prguyqS/5VuERrVJc4NoVMlUaFRJPJbnWvmdkBlAb8k0MMeRCKA30xz1Rk4mvU+dZ0i+4cLaS+uR +a/WI+T14Ij1oUwozWlpWJMRbfDxLUKj2qS5QTSqZCo0qiQey3Ot/E7IDKC3ZBqY40gE0Jtpjnoj J5Pep84zJN9wYe2l9cj8V+sR8npwxPpQJtCoBtPcIBpVMhUaVRKP5blWfidkBtBbMg3McSQC6M00 R72Rk0nvU+cZkm+4sPbSemT+q/UIeT04Yn0oE2hUg2luEI0qmQqNKonH8lwrvxMyA+gtmQbmOBIB 9Gaao97IyaT3qfMMyTdcWHtpPTL/1XqEvB4csT6UKbt/oyrX/BvVyTQ3iEaVTIVGlcRjea6V3wmZ AfSWTANzHIkAejPNUW/kZNL71HmG5BsurL20Hpn/aj1CXg+OWB/KBDOoGZRpHUhGdMVyv1ZIf8u3 CI1qk+YG0aiSqdCokngsz7XyOyEzgN6SaWCOIxFAb6Y56o2cTHqfOs+QfMOFtZfWI/NfrUfI68FR DGkyqQDneu2N675R3fLxLUKj2qS5QTSqZCo0qiQey3Ot/E7IDKC3ZBqY40gE0JtpjnojJ5Pep84z JN9wYe2l9cj8V+sR8npwxPpQJuSfoqpB5U9UT6a5QTSqZCo0qiQey3Ot/E7IDKC3ZBqY40gE0Jtp jnojJ5Pep84zJN9wYe2l9cj8V+sR8npwxPpQpnij6ssB/0Z1Ms0NolElU6FRJfFYnmvld0JmAL0l 08AcRyKA3kxz1Bs5mfQ+dZ4h+YYLay+tR+a/Wo+Q14Mj1ocyoTSnpWFNRrTBx7cIjWqT5gbRqJKp 0KiSeCzPtfI7ITOA3pJpYI4jEUBvpjnqjZxMep86z5B8w4W1l9Yj81+tR8jrwRHrQ5lAoxpMc4No VMlUaFRJPJbnWvmdkBlAb8k0MMeRCKA30xz1Rk4mvU+dZ0i+4cLaS+uR+a/WI+T14Ij1oUygUQ2m uUE0qmQqNKokHstzrfxOyAygt2QamONIBNCbaY56IyeT3qfOMyTfcGHtpfXI/FfrEfJ6cMT6UKbs /o2qXPNvVCfT3CAaVTIVGlUSj+W5Vn4nZAbQWzINzHEkAujNNEe9kZNJ71PnGZJvuLD20npk/qv1 CHk9OKohNYPK/3uaQJobRKNKpkKjSuKxPNfK74TMAHpLpoE5jkQAvZnmqDdyMul96jxD8g0X1l5a j8x/tR4hrwdHGtXPo7lBNKpkKjSqJB7Lc638TsgMoLdkGpjjSATQm2mOeiMnk96nzjMk33Bh7aX1 yPxX6xHyenDE+lCm8P+eJpDmBtGokqnQqJJ4LM+18jshM4DekmlgjiMRQG+mOeqNnEx6nzrPkHzD hbWX1iPzX61HyOvBEetDmUKjGkhzg2hUyVRoVEk8luda+Z2QGUBvyTQwx5EIoDfTHPVGTia9T51n SL7hwtpL65H5r9Yj5PXgiPWhTCjNaWlYkxFt8PEtQqPapLlBNKpkKjSqJB7Lc638TsgMoLdkGpjj SATQm2mOeiMnk96nzjMk33Bh7aX1yPxX6xHyenDE+lAm0KgG09ygqlE9w7zSEL8HNKokHstzrfxO yAygt2QamONIBNCbaY56IyeT3qfOMyTfcGHtpfXI/FfrEfJ6cMT6UFZha1SX+7NmXfbxLUKj2qS5 QTSQZCo0qiQey3Ot/E7IDKC3ZBqY40gE0JtpjnojJ5Pep84zJN9wYe2l9cj8V+sR8npwxPpQpvD/ RzWQ5gaVRhXlhi9/hjP6JC8KjSqJx/JcK78TMgPoLZkG5jgSAfRmmqPeyMmk96nzDMk3XFh7aT0y /9V6hLweHNWQ1gxqeZ2MaIOPb5FPMaqFsXtZMM/vGhu0xOQ1Sdny8sWmLNfbfnvxfWLTZvRJXp9l 3xcdCXm/VQ+ETGXJX9BZ1lvSHPVGzkK0ZXrLOW7RYT2ekGdYdLXKca6ckHkseQwa+16+2Ve+4ZLa 8+uhUX1BejZoiclrkjLbiGQsn1qztEF73Ltqn+SeLFpZf8R9lBMyF+iKRpVEsrzb1jlu0WE9npBn WHS1ynGunJB5LHkMGns/oyrrQ5lyvf97GpkAytOi9PjqpDXqOW6YXxPO1wlP41GGOuXjpuqN1v6O WOIVlBWbvKrXmJ5+yTXIewnNQU+mMysnZCI5f1BvJIhNjivLCZnIRm/MceQkoCnT1cYH4Vvexdn5 K7Najzw3q/UIKcZ8CJ4rlHmwZjWr65+oLvfnA1yvy/Ccpn7HjOrX//flK/hhOeK6wlep+/rDD/9P FrICZV+l7SUp1rJej6w7I/dGyjO4dvcq3Rvrc5clLvfp+3u4T3I5ZK8ztXpCZkK9kWioNxIJcxwJ pPQMa99wPepr+fAiG/+zw+o5PMI8UO5fx/Bl2397gWuScZJBykXdlWUTZe3FJuEepHOU53tT76ME cfle41rwfef7j3vd2SchhBBCCCGEPEM2k+pvSg+0R2rXQ/JAvn8dw5dt/+0Frnk7owoqG4TyfJ3u 24BRFfymr/oCugfvdq8JIYQQQgghn8fifZz/q/igGqldD+jPecu6/9z82wtcs2eeNpO4EOVaDB9T 25BMYSx7qfZlPNgnIYQQQggh5BxanuFqVNci/iP7P3gSKWtR9rsL+nPesu4/N//2AtfUjOoy6FKX zdWLs6xVrw/X87EBu9g9s/6aLGNU+zLcPtT7IIQQQgghhJxNv2/4aPPK9Kwn+78eLySkdj3Y+Ll/ HcOXbf/tBa7pWtCV6FkPztN90Xuz4vh+VSnbrnBltbaEEEIIIYSQeOT7vOYbLvvdvrMeGtVX4W7r IYQQQgghhMxnxzcceaeXpscHTTeqEl/MgUZ1j7uthxBCCCGEEDKdt/RB043qMq6fA43qHndbDyGE EEIIIWQ6b+mDaFQ/kbuthxBCCCGEEDKdt/RBNKqfyN3WQ64B9EWNkUioORIJ9UYiMb1Rc+Rk3tIH TTeqEl/MgUZ1j7uth1yC9BzJs0adkQioNxLNojk5p+ZIAKY35jhyNklnd/INPeuBN5SyFqldD+iv mAON6h53Ww+5BOk5onEgQVBvJJSkN2qOxEG9kSiS1u7kG3rWA28oZS1Sux7Q96p/HcOXbf/tBa55 yw0iZDLpOeJLlQRBvZFQkt6oORIH9UaiSFq7k2/oWQ+8oZS1SO16QH/FHGhU97jbesglSM8RX6ok COqNhJL0tmju6HuCkFkwx5Eoktbu5Bt61oNcLmUtUrse0F8xh9ONqm+TYg7Y9F/Ub2J8uW/n6nK8 Xu+x6tfiK+tJsT6uFx1nj8345C1Z9PCEzhSvrRrUGwGLHp7Xm+E1ZlBrJJN1cfw9MUzu9wPqjgDT W9JEpX4I1VZJNZa8HUkPFd/gc1GpnZJN3irqNzG1sr06vd5j0wfKK+tJsTlG1idlLVK7Hsp5pGvp w5dt/+0FrkkLlUHKBeU2qEey0PJlQoq7Xo2R2iz9fsR81Oe61E/ZzpWnay3L8UrutzK2lJfrWY0z QjmH3J/2+Wi/5FZkjTyhh9THSl9LfyvtUW9EmKE3sNKX15v1/WT/5CYkXSzamKmJlf6cBmux5L34 yEX1+l4++vnQlz9njiNJE5J/St/gtZH0ouUfucpfS5zXEvrctPmotzGzDst2Vp6ui76s3l1vxpby cj3rcaSNlLXIY7RA38Uc4oyqxpSL9e3K+L021TrfTs5znzrvcpx0nVjKjvrI9WXMIHnMor9n+iT3 YtHD8zrLmtW+Mq68fNbI+7Ho4jm9AdOWz2nrMuqNCFkbk/Wgffq8R70RYHrDsVbfhfWh2sr5DeQc V2lH3grTg+WhlIsEn4sQ4+u8jmrxe22qdb6dnOc+NR+W46TrxFJ21Eeu38RI31LWIrXrAX0Xczjd qPoF+Ri7cb4clGOs2qC+qMtj+Xa+DcbJ8dt5pf6l3JeVfeQxypgHSOO5/o7uKXk/sh6f0AXaZs0W /czon9yHWXpY+lnI5dr3rNxJbkDWyfx3H/rdy3vkfTG9PaWJ1EelHy1bNMfvuXcnaURzUM5FSRsu zsV4zVhbUOrI91vWoy6P5dv5Nhgnx1fmhVgpX5UVfeQxNjHSt5S1SO16cHO1OYQaVb/oVbm1R1lR vm6zXgDi2+N8tMkbVPST4tF+pw9jM86D7M6DvD3QF3TxjM5SH6ZZaowcMENvR6DfnD9PGoNciKS3 RXOr9+0ETGuz3tPkHpjeztIE+jbdzdY0uRZJa6IDe+dV85GLKTW5aHWJ8eXrNutvOsS3x/lok/Va 9JPi0X6nD2M7jvQjZS1Sux4q8zrdqK7auJjNZPY4aGMbtNSty2ttcJ7LXHwV10ceI7WtxI6Afkfm Qd6KpF3RxbM6s2dg0Sx1RurM0tse6DfnT2qQJL0tmns6J6G9svRJrZEtprezNIG+k+aEpzVNLk3S muagnIuA14WLSXnQtd/loA36ro3j5+LbZL2izMVXcX0Y5Tjzjeoyrp/DLYzqahzES1yeg2tj5YhP 80Uba1eCeu0j96XtqvG9pHHd3J7tbxSM1ztm9NyI6nKCzoTUl2n3M7Rm9I6LuM+a45syU28Z68v6 1twZtrcYp2es3jgyD7nfprln7v2Hbg251lw37V3dC8bpHStqTiTzoZV6/TN43T2r6SFGxomaE1np YTcXuZikGdd+l4M26HszDuIlLs/BtbFyi09trF0J6rWP3Je2+4iRvqWsRWrXQ7G+NDeUrea4+bcX uCYtWAYpF7Rq42I2k9nB95v6K+qs3G6235xynNUGGXvzcOPmvlJ8JXaQPA+MPaG/IfQ+VetKoudG kr6gixk6A6k/0+9n6A30jom4z5jfGzNbb9i/pU/tN+fNnTx7BlhL73p648gcnDaeufdon9/Lqt+y LHRve8eKnBNJ5Fz0zL1PfdSQfp0Gq23PYGSsyHm9OUkTmoNyLkr6cHEuJuUp134P32/ZBnWrcRAr MTZ+2cbqUryBdq7PjBs391XGo28pa7Ea74hifUm/KFvNcfNvL3CNv5F+Qas2LmYzmR38DS/b+DFR 52NrbVZ9GXtr2lnPbnwv6Ffnkeb2bH/kViRNiy6e1pmjfE6oOWJM11vuT5mVN8k9SPpYNPJMHqrl NJTld/UTfZN7YXp7RhMrvanmPljqa+3Ie+F1knNR0ouL81pC7nLt90D73F/RpqwDdv1R7uO1zOPn 53FzzX2V8ZiPlLVYjXcE+l71r2P4su2/vcA16ByDlAsqB7SYrg1CfGKJL29mbcwSP85qg7Tv3TVV +rZ21fgObMzVPXiiP3I/Fo08p7MauV/qjjhO0Rv6Sv1Sc6TA6eJZPaR+oK2kr6XPGe9pci9yHnpC E2ibvwNNu0YlnrwnSWuqk6yXpBkX52KSllz7KohPLPGljmtjlvg26COVpXKtK/rMVPrerkfWIGUt Urseyvmka+nDl23/7QWuqd0sXJcDWkzXBgmpX6UcH2V+POvXz8WPkzeoWEu1f9dH7ju1dTEjpDGW PnJ/xTwIWbT4hM6MSvvUt9deUU/ejzP1BtDvR76rx5A3Iult0dyMd1/qC9pSjSWdUWvEYXp7RhNo yzxGWiStqU5285GL6f0OS/06yjo/nvWbYt31R7wrc33lvl2Zn2vuO7X1MdKPlLVI7XqozCHUqPqY 8ibtgjYOX4fr1XjWZ4p1ZTl+Oy+bU0LLElq+6r+MGQH96fi5P5tvLZ68JUmPoouHdSZ89FH0g3LT nkDtkRl6A3v94Poj363ryBuSdLJoZVb+Sf2pxiy3UWvEML09owm0ZR4jLZLWVCe7+cjFdOdBtHH4 OlyvxrM+U6wry/Ef87KxU79atupfy1f9b2KkHylrkftv4eZqcwg2qgeLPSD1rZTlub9ifnkztDy1 t9hUXi/L/bs6YxMzShrT9VfMmZBFl3N0lvSqms39urJqW/JWTNGbkPrZ6M2XSa6rtCNvRtbG3Hef aW3Ke5rcCtPbM5qo6atGrS15H5IOVCf5O1/wuQ4xvq5XN6axMr7sL4+VYrVc821qr7FLeb0s91/U pfpNjPQtZS1Sux583zqHOKOKeunjYzKVCQ2Sxkz9bPv6qJPrdK7Xq/HX16v1IV7Ky/WU4wxj80hU 6slbs9Jtpb6Xld6z3ox6G/J+zNJbzrF7enu2f3IPTCeii9ma+NDy/L7JdfnQRb2+C+ujmt+MJa7a nrwFSWuikdI3ZF0kHS0xH1paysu+esn9WV+ruvUYKRbXq/HX16u5IF7Ky/WsxkEbKWuRx2iBvos5 nG5U1wuq4Pp4iKN+fLnFHVG0ba7nGWpjkrcnPUdIHDO0YRorqcWSt2Sq3oDXmVGLI++J6CF/HJ2h DWqOFIS8U41aG/I2JK21fIPXi+H6eIijfny5xR1RtG2vZ21I90jtekB/q/51jNXcNv/2Atd0bdCV uNt6yCVIzxE0Rp2RABa9Ma+RIDS/MceRKExvzHHkbJLO7uQbWuvBcbpR1X7dHGhU97jbesg1gO6g MeqMREC9kWioNxIJcxwJAjp7Kx+EoxnV5BEVXOeyJSa1S20rZYj9wfoTijnkfnL55t9e4Jq32yBC CCGEEELI2/OWPgjnsynmQKO6x93WQwghhBBCCJnOW/ognM+mmAON6h53Ww8hhBBCCCFkOm/pg3A+ m2IONKp73G09hBBCCCGEkOm8pQ/C+WyKOdCo7nG39RBC7gvyVcFuvt6r1/JW3W5MT1xRVyPFK6uy oo9cptepzGKUavsetN0RrbhNn0YtFvTGdsSkOLAT49tX4x+l1Y+OVZvHijLuKBb0xBBCyImkfHUn 39CzHpzPppgDjeoed1sPIeS+IF+5nJVzVSVf4X91L8UUOd3a1/Lctu+d9wHipG4d+1G/6SfVu/N0 bf242FUfFreUW1w5p1xetO/B2tbmucwHaJwfx9D6Wt92j9BP7r8W6/pexbnYVK/zWsZUithVP1Jf lud47fcRlrks7NfrWDqPw1iL65jb0recN+IIIeQsLG9Zbj/M71egZz04n00xBxrVPe62HkLIrUFu auYql9dw9Dl91b5s69ot9dLW1/s430+KLevX/aA+4coQu+rHjWftrW9/3b2eBn4+1t5Y9VmWpXLP tm/rf91mP66cR65Hna1dx8qgTMvLWN8PjtW+R0n9L/g9MJa6jznl88q4KTbXFXGVvhOp/4XdGEII ORHLXZZTU1613FWJf3m61vPlGMQatXpPjnOksvW7XWLLf3uBa/Y26KjNS7OznssKjhByb1zOwgf+ aAxyW851lTxn9c08uBpjW783Ds7LvjHHJe5jrrlMY/21f99Yf+U4vaBNvd+PsS1uNQ6utczHedZt dvZKOVofyvO4jTYW7+e0nse6j27Qh+LnZyx127Xa2LX57M/x4F4hTqnNgxBCTsXlKgPXl81HO+ux 3LxQMZwlKb5SXoK48l6lsvIebv7tBa7xL5P9BV2Iu62HEHJvXM7a/aA/iEFuy7mukuesvpkHV2Ns 64/GwbUvqxucj7IlXq8F/45KdVJWG6cHtKn1m9aHay2rjrMqK9rvtdnhaH0or/VRa2PxKLN4HHvn sUfqQ/dir746T7TL5Utdnrcc1318rGdvHGB9HMUQQsgpuJxm4LrM/5dB82m5nm1+rZhOA7FGrd6T 4xyprLyHm397gWvSC8Itxi8oLepi7K9HN4kQQk5glTMruXYXtLNchXzdiklxH+O1zADKjuqN1JfE LPOo16Mu1+/1hX5sTvr+SX0jB2tbu7Z5+b424/i+O7D2j663nHtPmxpH69vro9YGMVZm8daHLxsl 9SHj7bX3c/ExNravy9dFX7iu9VGS+jiYyyGp7UK6Z4QQMkDKH5rDjJzbXNxVOFqPz5tiFPfRvjK1 GLCKcaSy8h26+bcXuKa2oLyoi1Ku5errIYRciNEPbpeD0XYvX6+Ng8PapvJau+eMm69H3VJvbOPS eqTOj2nzxNHifMxHmSDXH+O4fjtZz1P7rPSTystxVmUf8zpss8NqfS72qI9aG8RYWWqr7e3atx9h 6Wu/D5SX4y57K+RyrZNzW8869mM9qawyDljaHMfskdraGIQQ8gDIUyW1uKtQXYvlVxyNQ/Op76G9 OJBjEeNIZet3n8SX//YC11iSLxdFCCFknNULoQeXg5e2xpKfLW7z0a/1Vp7qXPxHuz6juprHTj+r eSqb9wvi/Jz0uPQr8bk/11dq89H/R3zRdwdok9sbblwfZ+PlcVZl9Ta570q9x6/P36PquAdtVmMq +bxoP0Kah4y314eNa+OsyOVaJ+cptoxz68F1bRxgsUcxVdwYhBBC9lnlV5yn6yPzqe+hvVhfl+od qWz97pM25b8f/r/ED3o8QBZACCFkEj1511O2XV3XYlxbH78q//KlUW8gbonNcTn2o87Xe6yuFWf0 xBij9zFR9JH7SvUfcwS5LtfX2gBt5+tW9Z4ldtsPytd1H31U+k/lC1ZWsj+HPlIflfLEwThWbu33 4vbWU6PavgPrnxBCyD6r3InrVGbvJYfVeVK7g7jcN+pq5WDzTys2gRUkprYoQggh41Tz7AG1tpuy 8trYK++td+S4ndhV/U4MsLgUa+Vlmbve42iMXXz7Wr2jNo6VfbTXFy/Y1O2z7Wdb9zHux8u91uaw LJe7eXZS9rlC+/+IQf/LGFZudflcr4/X4+f5cb5uP4aNQQghZMsmt+Yyy+sOq/OkdgdxuW/U1coB /n358v8D98EKCAejZ0AAAAAASUVORK5CYIJ= ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image002.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image003.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAAXNSR0IArs4c6QAABW9JREFUSEut Vm+IVFUUP+++e9+fnTdvZ5zZrV0tIwuFMgupD5qa9IfIsloVhKLsQ32IvhiBRCiZFmShqaGIJSYS IeRaRCKRIJlZbSGFGlmQkGma6+Y6Mzt/3nudc8+8t29mNfrQ5TBz3znn/s7v3HPPfc8AGA9gwv8w AsQ4duzBPTsPrnrtaAWuZUgBoPRv8pjM0zFR2SZpfzYhjmmacOP1Wc236Y9/hhZUJnmwjTUs7MMy lkpiErZt1AIjBiLnhG8aSAKg8EiHGRuMPUd5lEoNIU1jlLRkprxLCeux8zRrhsMlKG3ZmN3dPYWu gmyGJPaMleSY5simdB5X2kzWk39tpFwpj6gmY1Iy66SAzIslvTktFXbtTN+jvblcMfYZ9TeEYUSR MBJYk2e8lSjpMrbtL7uZ+w/OL4+8+PKzIxeHTrSuIkKGQYUNo3qCiQGsFGvmgppEyXngIyV64Mt5 c2dO+e7jNXfdeziESpx6soqOT71arUAtaYC24zj2zHAwOuYDPy6cPWPO4d0b5z787TCVZkpMJVll RVFYGr7UICtzsrhBEtZp7omerEd+Wjj95um/HFo/b8H3SK8OMy6XugoaQRBFug8YigKkQXlup4TQ o+j+aZP9I3tXz5y5D5dWYVa8Ku1JaxuNEMvgULWYtMIA6JSAtgVj9DsBap9sfvXuBw4h+iDcB9AR M2jSjBEsIUzHdTwrkzDAUBjgSgOP3FSA0vK+dW/3k89ZmK9d8ahE06bCrNkYAJQ0a7WaAZHnO1dd bXt5XykDag67Sancy8AHIVaoXpsMMLxy8fpN/ZTjoFhEFwidbBpzbv31jTXTjQhTxEOghGkaIsTT Wb54sVqpSmGzp5ErLBGAFrThWSEVz8+eKiq7tGLB5k27Cb1SWEIO2JhkJB938GBW/Zb17GyXlSu6 1Vpw5lxl565FX3z+9frVv592HmFnY8KkpRi8mQRh07V+8rgS8q/lfdve6dfX3g1LU1lq5yiA5NJs 2mjh0QF374eH3t0wdLx0j1YH0u+dKPRmJRADn/0h5IVVj23b3g+4fe6Mt4g7weou1Z7xJZXWEEgQ nPn73PlyJfS7J+CSMAhlttgL2N/YIRDccVt9w/ITAupvPrPjvfcBj0KubxcBJm+BtnKNskIMA58i +LN8qVwpQfamXmITBLKj2AV4N0Xh7bdUXn/uZwBn8/ObdmytZm3IP3GAGJO1DTgOyXodXjMEqVSH 5zm+tPJduIVREEmns4CHN6wHjz80gId3+4q1W9addzqN4tM/NKs6BlxXWdeaB13JzYF5uF6mMH5c Y1yRtdLy86ZhUoFMa+uylzauOe10qmteOIkaM66NEHqvwxRhrkRaj/MwQpd6vWqalvALWGHycby8 5ftuxt/zqb3/qx6/JzfplQuW3+n6najHCYr0fBSea6Vv5fIoLXrPVxkfEfGVU6mOONh1Xh7FeHJL 1P7VwuR1hrixlx1sbY7YB5PasHjljrUffLTvuvFP7cUE0CKkB9JtFR9kBkzsRHuMKfa0XEBhHxMn LBaWmjbTVIowPcBbQigHlAX0y5NYLAf+RRiRV+HNhsITaoUwlMpiTCQhTPwEsEDiDYvSoUXPR3kl BFEZC/Pg1E2lRZtqjerw4FADXwkWMLIwO8DqaOHOi4UiUSyclj0qtB41bNV6S2v06x7CBjAshhRK gkAD/sbCi3EBCpnwUXPE1ifRgZusGZQ1GA+vLSGkklhthiWiBtp0Lom0BENTa2ByTrFBZ9bQwUMo YWALYj/jHDsZ8xHIJflqMSSQoO0/SsqfUlRw6kLPxO4o43dylhjeWPYN9WRyYeM8oAZsaq40b2mO VIPbog4jQ+XAE46rP5HgH9MJcp6kBVhZAAAAAElFTkSuQmCC ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image004.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg /9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIf IiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCAAsACwDASIA AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3 ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3 uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDxyilx RivR9myLiUV3vh7wnYaRpB8T+LkK2mP9FsW4e5PbI64rj9Vvk1LUZbqK1jtImPyQxD5UXsK54VY1 KjhFXt16ehTVlc6Xw3Hv+HfiU4B2tGea42u08Nts+HXiX1LRj+dcZis8PButVXmvyQ5fCi6dOmAy RxXYaH4fsfDOnp4k8TR72PNhp5+9M3ZmHpXR2EGl6LFPqeoWhumgUeRAFzvb3FZj6dqGu37axrXz Tv8A6qD+GFewxXZiY1q1X6tSVl9qXl2RjCpBQ9pL5I5LXdR1jxLfG81GRj/zziHCxr2AFWdEh8Pw 27JrWnX00275XgYBQPxrrP7EX+7Sf2Iv9yuv+z4qkqUG4ry0Zj9bTd2MVdEbwHrkeh2V1ECyCRrh gcntivO/7Om/u16nJp6W/g/Uoz8oknj6VR/sRMD5O3pXJgcPyVq0L3s1vvsjSpXXJF97nW/ZR6Uv 2UelXwopMDFep7RnicxR+yj0o+yj0q/gZo2il7RhzGJryeT4YnGOGuIxVoWvyrx2FW7y0ivrM2sw JjLhyAccjpU2xcDjtXHh1KFarJ/aa/JHRUqJ0oLtf8z/2c== ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image005.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image006.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg /9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIf IiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7 Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCAEuAqYDASIA AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3 ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3 uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtvCfh Pw3c+DtFnn8PaXLLLp8DySPZRszsY1JJJHJJ71rf8IZ4V/6FnSP/AABi/wDiaPBn/IkaD/2Dbf8A 9FrW1QBi/wDCGeFf+hZ0j/wBi/8AiaqX2h+A9M2fb9J8P2u/7vnW0KbvpkV0tcraLpx8R6r/AGyt t9oLL5P2nHMWB93dxjPpR1Anfw94JSzku/7C0RoIh87pZRMB+S+9Jp/h7wZqcLzWnh3SXRJGjJOn xj5h16rWH4qj0m08GzpoQvUtvNbf/ZmCpc4zuJ7fStD4cib+x5jN/amWkJH28Lg+64/WmrO/9dv8 weiRrf8ACGeFf+hZ0j/wBi/+Jo/4Qzwr/wBCzpH/AIAxf/E1tUUgOUutO+HdjO1vd2HhuCZfvRyQ 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image007.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAQUAAACECAMAAACu085qAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAMDAwNTU1KioqODg4OTk5MzMzNDQ0Li4uLy8vNzc3Ozs7 NjY2PT09Pz8/Q0NDRUVFRERETU1NRkZGT09PR0dHTk5OUFBQUVFRUlJSSUlJU1NTVFRUSkpKS0tL VVVVVlZWV1dXWlpaWFhYW1tbXFxcXV1dX19fXl5eWVlZTExMSEhIYGBgYWFhZGRkZWVlZ2dnaGho aWlpa2trbGxsbm5ucHBwcXFxc3NzcnJydHR0dnZ2eHh4dXV1eXl5d3d3e3t7enp6fX19fHx8f39/ fn5+b29vbW1tampqnp6enJycmpqamJiYlZWVl5eXk5OTkZGRj4+PkJCQjo6OioqKjIyMiIiIh4eH hYWFg4ODgICAgYGBlJSUmZmZn5+fv7+/vr6+u7u7ubm5urq6sbGxs7OzuLi4vb29t7e3tbW1tLS0 srKyr6+vra2trKysvLy8qamppaWlpKSktra2oKCgsLCwrq6uqqqqp6eno6OjoqKiqKioq6urzs7O ycnJy8vLwcHBwMDAxsbGx8fHw8PDwsLCxcXFxMTEysrK1NTU9PT09fX17+/v/v7+6+vr8PDw7Ozs +/v78vLy/Pz88fHx7e3t/f397u7u+fn58/Pz+Pj49vb29/f3+vr66urq4ODg////AQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID+UBlNgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAkA 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image008.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image009.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAKysrPT09MTExLCwsODg4KSkpXFxcQkJCS0tLXV1dQ0ND VFRUTU1NWVlZUFBQV1dXT09PVVVVXl5eU1NTW1tbUlJSVlZWSkpKRERETk5OQEBAa2trdHR0cHBw dnZ2b29vbGxsampqaGhoZ2dnZmZmfn5+ZWVlf39/fX19aWlpZGRkbW1td3d3cnJycXFxeXl5enp6 bm5ue3t7fHx8c3NzdXV1YmJiY2Njg4ODkJCQjIyMioqKi4uLh4eHkpKSjo6OgoKClJSUmZmZgICA np6ehISEl5eXlpaWhYWFn5+fkZGRgYGBiYmJmpqanZ2dj4+PnJycjY2NiIiIlZWVk5OTu7u7sLCw tra2urq6tbW1vLy8v7+/vb29t7e3oKCguLi4srKypaWlr6+vs7Ozubm5vr6+qqqqrKysqKiorq6u sbGxpKSkp6enra2toqKiq6uro6Ojpqamqampx8fH0dHRy8vLz8/PzMzM2tra29vb2NjY1dXV0tLS ysrKyMjIzs7O2dnZxMTEw8PDwMDAycnJ1tbWxcXFxsbG09PT3d3d0NDQ1NTU19fXzc3N39/fwsLC 3Nzc3t7ewcHB8fHx5ubm7e3t4uLi+fn57u7u8PDw8/Pz5eXl+/v79vb2/Pz8+vr65OTk8vLy6urq 7Ozs9/f36enp4ODg4+Pj/f394eHh6+vr/v7+6Ojo+Pj49fX15+fn7+/v////AQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDWtGavgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAe3 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image010.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAASYAAACkCAYAAAA6y4O9AAAAAXNSR0ICQMB9xQAAAAlwSFlzAAAS dAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUATWljcm9zb2Z0IE9mZmljZX/tNXEAABuKSURBVHja 7Z2Hl1VFtofnrfffsHwZw4gzwzjjMCiIynsmFJcLGDKiIgo8goANTc4CEgUb6IaWHBWkyaEbEEGa oIgNKhgwZ+vVV9bhXdoON99zzv19a+3VSvdN5+y7a9evdu363fPPP/87mUwmC5PpIshksvAGJmPM f1sbJpPJZAW0x+oHpvVGCCEKy4fWHk0MTKt0TYQQBeY7a0cSA1O5rokQosAct9ZSgUkIESY+sbZK gUkIESbqrI1UYBJChIlaax0UmIQQYeIra4cVmIQQYQLx+0YFJiFEmED8rlBgEkKECYnfQojQgfjd XoFJCBEmEL+rFZiEEGFC4rcQInRI/BZChI6L1kYrMAkhwsQpa+0UmIQQYULitxAidEj8FkKEDsTv 8pwHpq+//tp8++23utwiI3755Rfz1Vdfmc8//9z9FLEF8bskp4Hp9OnTZs6cOWbx4sWmrq5Ol1yk zdtvv22mTZtmxowZY2bOnGkuXLigixJPEL/vzElgYnQ7d+6cGT9+vGnfvr3p2LGjWbhwobl8+bIu u0iZixcvmkmTJpm2bdua1q1bm3bt2pnZs2ebjz76SBcnfuRO/H733XfdyNavXz+zfft2U1lZaXr2 7GlmzZrlUnEhkuXKlSumpKTE9O/f3+zbt8+cOHHC7Nq1y/Tu3du88cYbukDx4y1rN2U9MJ05c8ZM nDjRdO/e3Wzbts39GxoTGVOXLl3MvHnzzCeffKLLL5rl008/NRMmTDB9+vQxVVVV1/1u7969pqam xnz22We6UPHiY2vLsxqYvvjiC7No0SLTrVs3s2bNGvPzzz///6t9/LHTBv7xj3+YDRs2mJ9++km3 QDQJ2iSZ9qZNmxr8/YIFC8zrr7+uCxUvEL/HZi0wEYTQAsrKypwlBqWAS5cuOWerqKhwUzq0KCHq g1+wmjt9+nQ3iDXkJ9988437/bp168wPP/ygixYfEL/bZi0wEWgOHTrk0uumsqGrV6+aAwcOmGPH jqmMQDTI999/73QkVuJ+/PHHBv+GYPXdd985Xzp69KguWnzIrvjN8i3LuUzlmgIxExF8/vz50ppE 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image011.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAPT09Pj4+PDw8Xl5eTExMV1dXUVFRUFBQX19fWlpaTk5O VVVVT09PWFhYWVlZW1tbXV1dU1NTVFRUUlJSVlZWS0tLSkpKfHx8fX19bW1tbm5ucHBwfn5+Z2dn cnJyd3d3dXV1dHR0ZGRka2trcXFxc3Nzampqenp6e3t7YGBgbGxsYWFhdnZ2aWlpYmJif39/eHh4 eXl5b29vY2NjaGhojo6Ol5eXjIyMmZmZhISEgYGBhYWFioqKnZ2dhoaGiIiIn5+flZWVnp6eh4eH i4uLm5ubgoKCjY2NiYmJlpaWk5OTmJiYnJycj4+PlJSUg4ODkJCQgICAkpKSkZGRmpqasrKypaWl tbW1vb29tLS0rKysqampoKCgoaGhurq6u7u7uLi4tra2o6Ojs7OzsLCwpqamv7+/pKSkvr6+r6+v sbGxrq6uq6urubm5qqqqqKiovLy8p6enoqKira2t09PT1dXV29vb3Nzc3d3d2dnZ0tLSwcHBwsLC xMTEwMDAzc3N2traysrK39/fz8/Pzs7O3t7e19fX2NjYy8vLzMzMycnJ1tbWyMjI1NTUxcXFw8PD 0dHRx8fHxsbG8/Pz+/v78vLy9/f3+fn58PDw9fX14uLi/Pz87u7u/f396+vr6enp5eXl7e3t4eHh 7+/v5ubm4+Pj4ODg9vb25OTk9PT05+fn6urq7Ozs+vr66Ojo8fHx/v7++Pj4////AQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDcjw+rgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAhh 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image012.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAASYAAACkCAYAAAA6y4O9AAAAAXNSR0ICQMB9xQAAAAlwSFlzAAAS dAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUATWljcm9zb2Z0IE9mZmljZX/tNXEAABswSURBVHja 7Z0H11RFtobnrvtvWN5sGp3gOGMYFL2Gi9drQJYygopiAFEUUATMYs4ogoAgRswZxURUlGBWggii YFbUuvUUdVxN84XT3Sfs0/0+a+0FC76vQ52qXXu/tavqdxdccMHvZDKZzJKpEWQymV3H5Jw73Nto mUwmK9EG1DumuU4IIcplvbdjah3THLWJEKJkfvC2pNYxzVKbCCFKZpm3neWYhBCW2ORtjhyTEMIS a7xdKMckhLDEKm8HyzEJISzxjbeFckxCCEsgfu8ixySEsATi92w5JiGEJSR+CyHMgfjdT45JCGEJ xO9FckxCCEtI/BZCmEPitxDCHGu9XSTHJISwxEpvB8oxCSEsIfFbCGEOid9CCHMgfs+SYxJCWALx e4IckxDCEojffeWYhBCWkPgthDDHW952lWMSQljic28z5ZiEEJZA/L5YjkkIYQnE77/LMQkhLCHx WwhhDsTv3eSYhBCWQPyeLsckhLDEOm+XyjEJISwh8VsIYQ7E78VyTEIISyB+7y7HJISwxEZvd8sx CSEsIfFbCGGOFd72k2MSQlhC4rcQwhyI37+XYxJCWELitxDCHIjfl8sxCSEsgfi9rxyTEMIS3zqJ 30IIY0j8FkKYA/F7qhyTEMISn3q7Uo5JCGEJxO995JiEEJaQ+C2EMIfEbyGEORC/p8gxCSEsgfg9 SY5JCGEJid9CCHMgfi+RYxJCWOJtb3vIMQkhLLHB2x1yTEIIS1RP/P7888/dxo0b9ei64ZtvvnFb t251P//8s/v000/dl19+qUbpBtpmzZo1oT/9+OOPapAuoF0+++wzt27dOvf1118X9bbLvf3VrGP6 5Zdf3A8//OC+//778OcHH3zgbrnlFnfddde5jz76KPy72MZPP/3kvvvuO/foo4+6RYsWuTfeeMNN mDDBTZkyxW3evFkDL0KfwZjgpk6d6saMGRP606uvvvpbP8OpdzJ8f9riq6++ci+//LK76qqr3IUX Xugeeught379+vB/Ofcnu+L3r7/+6pYtW+buueced8cdd7jp06eHBjrqqKNc//793aWXXuruvPNO 9/HHH3f8YKOT4JBuu+02d+qpp7rRo0eHjnTQQQe54447zt14443u3nvvDYOxkyE6uuuuu0K/uf76 693AgQPd/vvvH/oTbcb/0c9wUjioToTJbf78+aGNbr/9dnfuuee6ww47zB1wwAHu5JNPDk6c8fjg gw+GSConEL/3NOmYcErMZoceeqjr169f6EBDhw4NDXL//feHAcjAu+yyy4Inf++99zquEzGj0Ylm z57tBgwY4A488EB3ww03uIkTJ7qxY8e6xx57zM2YMSN0rEMOOSR0tOeffz6keJ3olK688srQRvSn f/zjH27atGnBoc+dO9eNHz8+DD761LBhw9wLL7wQIvZOggmOPjNkyJAw3o444gh3ySWXhPahnW69 9VY3aNAgt++++7pjjz02THhPPfVUHhOeTfEbp8QMNnz48NCZ8NKXX355aJwEGoRZ74wzznCHH354 GIyvvfZaxzgoZvSHH37YHX300cFw0LQHWsBbb70V0jkgxcMhEW0yGGkrIqtO0p5wSldffXWY2K65 5prQn5jcaqWAN998M/zMpEmT3KhRo9zIkSND+xKRt3sajCa5atWqMMGNGDEifHf6y+TJk92KFSt+ +zkc0H333RfG5BVXXBGCg2OOOSbIKxlPduu9XWPCMZG6oYWgjTB7nXTSSWHW4t974sknnwwNedpp pwVvTqTQ7ukdA4XvfdZZZ7nBgwcHLQnRuzeY8XBORASkLDixLVu2tG07ffHFF+7DDz90N910U2gn Ius0vP322yFaJ9UbN26ce+WVV8Lgbde+9OKLL7pzzjknpP1IJDip3vj222+DPIAjY9wx+aE/ZQTi 994mHNP7778fhNrTTz89OJmnn346VZ5Ph2FQ4sQYdHhwGpdZsh1BmJw3b16Y/fmerCihC6SB9iT9 I4U58cQTw6Aj1WNC6G0CqBr0CQYLETUzO9EA0WMaaAsihfPPPz9EmEx2r7/+etuldjglpAAmOKJu so40TimB9qTvMG5xTkRYGU10NsRvIhzCa7QQBgxpWqMrbgw60jg0lGTQtqOWsnDhwhDxIG4363xJ 4xA30VSYJWfNmlXkUnDu0Bfuvvtud+SRRwZtDeeLQ24EnBPtywRJNEFkQIrcTiDy47hxwPyd8dKM 86U/EZWecMIJIRLPYLUc8fsPpTqmd955J3hqZjVyVWamVldEnn322SDgoRls2LChbToSOgizGx2J dmsF9IJHHnnE3XzzzSEiyDAML5W1a9eGMgCeP86XvkBK1wpE40Tx5513XkMRhVWIsPlOOFt03KVL l7b8mjg1dCmcEzpUi6kvg3ZyqY4JQZuHTjiYNiVJA4OO6IuBR0RW9VSF1AJRlo6EDpcVzHZoL4sX L26LJfLly5eHZW3Siqzq3BhkaHronhdddFGYIKosiJNuMS7ILIiUsoJxRpDBpMD4a2G1jlnyutIc EzrA448/HpxTHpHNzJkzg+70wAMPVHqwob8xIIgqSeWyhpTl2muvdS+99FKldRT0N1YjmeSyTk1x cjhw+hORPdpKVSGqZEyQpmYNcgoROCkiq+tNgvj9l1IcEx2HhsEp5VWoxaxGMRhLw1Ws5sVJMAtR CsBsnZfjIBojEqOYjmigim1FREzUh8bRqJ6UFqJLBjT6FYO7iv2JlAsHS4qb10ojqSGaMZF9k5lK OeI3aj4Nw2DjC+RZkYy+gANkUFeN1atXB6fELM2CQNpVpUYhcl2wYEEQ1RF6qyjy8pnPPvvskErk mWaRBrG8zsropk2bKtVG6IgURZLq1tYEZg0Ob+XKlaEOjD7cBMWL30n6hq6EZkKNSJbaUlcgxjHo ssyni2DJkiWhjfj8RWgazz33XIia8uy0WcOMTPqGMM3CAH/Pu62ojua95syZUymtiSiPGkGKI/Ou 9SPYoByFibUJ54Suc1uhjom6G/SMpBMVAboMK1m8J+F+3o4wq05EpIezKEqUZpBTPc/EkeM+qMxh jxsTHZNc3pAO0YfoT6ecckpIi1pd9Svq2ZJiIUoXUYBMZEkZCtE+1fbvvvtuI6kj4vcNhTkmGgdx jDyd6KVILYPVGpZHqf+pgnD5zDPPBBG36I23OG0iAarEeW/Lq5n0HyY6Ikrq14oEXa4q9U3ouTht ZBPGQVEgPVDYSgkBm/EbkCL4kHsV4pjoRNTe0OnJ0YsWWBlgiHE8HKIBywIvnw1NCeH+k08+KfS9 cdqsOh1//PHhWVlepaOjI3bjlMroT0yuTB7oc5a3rBApkS2wdavV+rdGYaKjnoyNwA1kKsWJ3www 8k2EtzyWKdPAIEOUI8RsUpQrBIpM0TEoEyj6zCkGO+9LHRBmfY8YpymUpYmhL7GKyYkX/GkxukyO D0JbIiAoQ8Yg1SWFxJGnbCPE7z8W4piomOUIBSKWoqOAWqjZIZ0r8zP01InQL84888yQl5e5wZZl ZSYQPo/FqIlFFFbG0ODYqFsWpHFEmByoZg0mGcYdkxwLKWVOMmz4pSSFSSRFjRkC5y25OyZSJ7w1 JQLsaC8TBhziLlGJRRGc7RSE3dRelemYSI3QuVgVxAFYays+z8UXXxwcZ5kgJNOfaCNrJzUwobBJ l60iedV2pYV0EsdE1sTJBCkc0025OyZWxUgLCHctQMNwpgwzSdkPrNYR4DRxSBZOUOT9iUYos6A2 yNKeQz4bRytT6Jjl9pxmQRbgJAOE3mY3wuYBMgAOE+HZwoIPwQC6Jc+ul/6dv/hNOElZAJFAFpsF s4DVJmZbtnhYqW0iNUHIJUqxsNOftBIHTvsgXqI7WVkwIOpmrxcrvBY0MJwRtUEsjaOllD2p8OyI KJlYGHdEchb0Lxw2/YlFnV5O/shX/KbTkNsSBfCnlaM1EC3x2oSVPDwrjomoMmUOXmhbMbEQDeCc LEAFM8+u6BWmntqIyA1d8Iknnig97eX9EeSps8KBWwLHRB1jL7VfiN9/zjViQhTkrBYrnagWbl1h hitbp2APFg6SaIkowNou/2TvU5E1MN3B7I8oT1pg7XIFHHeiX5YpEZC2MebQB6m3srR4waRCeQfl MERN3URy+WlMpHBEJQw2PkTZond3kKZQPlAm6Dcse7Ofz9ryPOkbDpxIgNmuzAFHO6Ersf3EYrU1 EwqpEwWfZQrhOCJWC61ouvVQBY6U0sPKeH6OiYfEzEZ6YtUpIQ4ywxE1lSXuEnYzqyEKUqhn9a48 OlNyiH9Zzon2IT0hFbB4OimaHP0JY7WurMiXiMny7gYCFvRUzlZHtugiasovlWPAsSKQHHpvERqE zoNj4nOWAakbUVvilKxuASEVT/aHlXFSAxF4ct8Zg85i5X6yYIC+Q9RU9KmgREpEavRlVpytwrPD cXPSQTfbefIRvxED0W2YXUkDLJ+MSGeiI7G1oCzHxHVKbJ61vP2DAcd+K44rJiIoGurgSLmrcGkn 0W8ZF4zyfhR7cpyQ9RMi2ONIyU432nP25QKEZnhrNjciwFm/xhvvTWiJDkYBaJHHWOC06UAMOlIT 6we04TipnKdTFQ17rVhhsr5FhjbiuTIGWNAoMmpi8uASDu4XtH4RB5+VlXpOZ+hCoM9eY8IxEW5z DAUHnlflHGlWCvDgRUJUSTjbwhGkhZPcRsMKVFFpJ2E/4jtRZYqqYRPgSNFXi7pGjPSWsg7OJq/K 1WUEATjSLrbzZLslhU7LviWiD/SAqpwfzSzMQyUEL+rIVDoSq1zMGGwsrgo4JI5EIU0vArYzsaWC 89urRPJsiQaKcKb0W26rtroS1xW0C0cg4Zjqar+y3cRL49CBeCBVOjeamT+pUGfFhxknb6fKwgAV sKxMVOmWV5Z4ceBMPnl/bp4BbURFNZpNldqJ/kTGQPaQ95VPjDUWmIjQqjTJMe6QevjcRMQ12VW2 4jdnINOB0l7FbA329CEcsr0g7xwdIZmTF6vUkYDOQ9REqsLAy9NZ4JgQcxG90bWqdoMLWQOLKnmf ZIGAzPsgCVThdNZ6mHwYdyxCRbITvxnI5LdJDUfVwHsjVJKijB49OugoeYHox0HtlAhU4VjWeliS ZpZjryHPO89Uhb5kbdd+WpIqZ8pREMTzcqy0EQWLVby5JTnVluvJkAhippXd0brssGYVroyl5CxB kMNh5DnYWIljlqiiAwdmZSr6ubiAzpRHWxGZ4cCrdPZ4V7DAQYkFKXsegxpnxKouK4BVu7WlFtLd muwhm8sI6JjJdS1l7zvLApwTOXsem2l5TfQlossqznAJaANsXEUbyGN/H32Kjbq8fpVvvaViPjnh Mo/rt9iXxwGMVb6AM4HvwLjbunVr69c3JUd3suyN566SQNkdaCiTJk0KM3ZW0E5s5UCDmzFjRoiW qnixZL3zIEJG4M3yqGJSHjQl9sUx8PK6T68IeMZsfiaboNwhSw0Ih83YY3+elXPFWoHar3jLcevi NwOOMJXit6KuY8qTJOdlU22W9UUM4uTGCDppFbWleoiSSOn4XlmmXOiVaFik1BwHY/mmlrTfZ8KE CaG2D80piwiQNmHxAdEbLasdAgIcE31py5Yt2VwRzoxG/VIVtgukgXSL0Jtl8axOSKQzcpIgRZxE AVVOTxIYDJRWJFe9ZxU1saGaldEq3gjcFaS9ZBOcisBqZlaaHE6OM6DaBRw45vsV4vd1vzkmP/vN anQmp9HpQFVdOekO2oGHnsWNLjg6tDdqf/JcnSkLoiYiZvSUVsEpEQkg5qLBVT3dTeB7kFlksUUl ue2HvkmJS5VT3e66gbfJvzmm/v37z0pqRnqDUJJVAGaAsWPHmjh7OUv4bjgSZrpWnS5pDmdCU4pQ lS0VjQwSUl60JvpAq1oHr8XSt5XTMrMGx0R62go4IlZ1WRFtU7YXv0eNGjWLJWBSjt5gBmBmGzx4 cNjvUuUVpu4GHA6aDsAxEs2uOiWXDJDq0F5VLIDrDVI6HDjCJTN4KwOOqIL+x+JA1bWlenj26IsU ILMC1ez34/eIUqmPalO2F79Xr149i+VZVo7SQAqHSIwe0w7iWz3MbHQkBGuinWY6Eqkbq3BEFERh 7ZKa1INDYjsSe8OahVUrjoChktny2VTNwncich40aJCbNm1aS5E4fZMjmdutjSKI33tvJ37TeL3t TiZ6SM5bYgWrTRsnCNQ4X0oHGDDNfE+0AJwbdUvt2k7AwgdbMKjZaVa0ZuMrp2RaP7KjWYjCWSRi hQ4H1exiEZteWbFsYxDirml4VQ4xF6fEykmr+XIVoOirWWEX50ZVK5FTu0ZLCdR94YSbuZWW9sV5 s2JJJNDO0Bea2T9HQEBUyU3N1C61MduL3y6lY8LzE26zXGn9ILgs4PsyWBo9IA0HjvbWDlW5aUgu n2DwkLY2EiEy0SELlHEIXRkQLTHhNVI2wkrxmDFjwlagdltsqgPxe8+GHFNyTjaREo3azulJAitN nBvDkSh0qLTfGe2N0wSJBDoBIkLSOEoH0NTSlkXQjxDPWSBoh8LTNLD6TXTZyCUYBAGcJU4hcztq ujU0XvnNIGVPXNUO7moFVlOY0REtE+eUBvQE2onVuE6B78ygIyVLC4ONBQIKNNuwJqdLGEMU8Daa cTD+2twpAeL3XxuOmJjZ2BvXKZ2I78ygYSWFUwLTFMmxPwpnRiRQ5V3fjZJUzfPdOXMqzcBjFZgS gXbY75UWatuok6MOMM12HiZD2ol0uQNoTPymOJBOR8WptRs+i4CBk1YEZ9WENI6Vpk6DVV2K/6iz 6Wl2T66QZ4DiyNut+LQ3SPFZ8U0TgaNToi+VcXVWCZDf3pHaMTEwWTZng2WnQhsQPfVUKIlOgg7A tgpSm06D78/KHIbA211kzcRGakzql8cRM9ZhtZZJnsmuJ6ecbCzHgWd5ioNhEL/3SOWY6ER0HlZd OkkzqYUBRmrGOUHd3IcVoI2IlnBO7V4i0F1fSU4IQGPrStBOjoFBJCfl67RoCegbOG92TnTXn5Jj U8aNGxe26XRIlpJe/CYP5twdCug6cXYDHBMpGjUkPW3BId3l+IYsNrVWFZwOfYWSkq6cDs6KIkMc E6lMJzpwwOlwdEl36dzSpUvd8OHDQxrXroWnXcD2gX1SOabkNoOqH53bCsxW5PqsOJF+1N9+wbI3 /8dqC9pJpzpwwIlTRMjqEylI/cBLtmeQ7lbl7sE8wIGznYeVya4KS+lPfmyGnRbtuM+yG/DAk1I5 JtISZr8OyXF7hB3wVL3Xn3CJ40LQpFCwXXfHNwKOmuiSkyhrHRMDEBGXI4bZrNsOZ1O1Am0wcuTI UP/FqlttnRzRZp4XYxiFKtspOzgmqm8RLQEvzR4oqk3pSGLb/Xm0BdW3tVtyGHCkemgmnVQi0B1E TbQRulztXX0sCEycODFES53ulBLnQ5RNnVytfkvfKuKOQ4Ow2fL3Ozgm0hQ2UwLeeujQoaEjVeXq 4bxJDv3ihliWxJMtK0k1LylMB3amHWDmx/EggFP3hubGvyXHwKCvdECxYCqYyEh72fSNQ8LQ6Lho oN33DnYBouTiHRwTq0p4cEBTQVsibelUgbIriCjHjx/vRowYEWZ+Bho3xiJkdsLG5kYguuTcLlJc 6roopuTPdjjPO0s4BoUzrYYMGeIGDhwY2gwdrpMKTyNdi994aMJvThLEKaGXyCltD4ItoiVHWNCB 2PHN/WGkKRps28PkhjPCiTPouFCUlUuxI+hMAwYMcP379w/9CdmgA6NvxO8ruxS/qa/o27evGzZs WMdsrGwGnBP6m1LdnmEVji099Ce2VrTLxRVZggMiCEh0ykTn7UAQv6d26ZiSpV7C8A5apmxqwKHD dXLNUlrQltDmOuUYGNE0XYvfgPdmVQVxUqlJ76iN1E4iM7oWv4UQokQQv/eVYxJCWAJx7XI5JiGE JRC/75ZjEkJYonvxWwghSoIKZYnfQghTIH7vJ8ckhLAE4velckxCCEtI/BZCmAPxe3c5JiGEJSR+ CyHMsdLb3+WYhBCWkPgthDAHZ+JMl2MSQlgC8Xs3OSYhhCUQvxfJMQkhLCHxWwhhDq65vliOSQhh CcTvmXJMQghLIH7vKsckhLCExG8hhDkQv/vKMQkhLIH4PUGOSQhhiU3eZskxCSEsIfFbCGEOid9C CHMgfh8oxySEsATi90VyTEIIS0j8FkKYY5m3XeSYhBCWkPgthDDHKm/95JiEEJZY4+1COSYhhCUQ v2fLMQkhLCHxWwhhDsTvhXJMQghLIH4fLMckhLCExG8hhDkQv+fIMQkhLIH4vbMckxDCEhK/hRDm 2EH8flBtIoQomdXexuKQ/snbn71d7e1dbx96e9XbF96ej3++4u0jb+94W+htY/y/zd5ectvOUHnb 2xve1nubF//vBW+feVvibUV80/nevoy/j9D1urf3vH3g7bWa9+VnXvb2idt2eNRibxvia/LaL3r7 1G3LSZfFv79Y874b4u+sjK/xcs37fhHf64P43q/Hz5K87/z4WVfEz177vvPid3wjfue1sQ02x9/f GNvondhmr9S15auxjd+NP/d5XVuu6aYt58W2XOptefy5+TXvy+ss6OYZfhk/x8du24y0qO4Z0m7r 3LZjTd+MbTkvZVtuim35frTX6tqyp2c4L77Xm/G919U9w43xs66Kn72nZ7igri3nxzZaHtvss7q2 rH2Ga+qe4efx2RQ1HjbXtOWCCo6H2me4tuZ9n695hmnHw9e8No7pn+MX+R9v471d722f+AJ94i/+ zduN3sbFn3vG27/EN9zd20xvp3sb5LZFXv8VG+HfvT3qbYC3kd6mePtjbPyd4pfq5+0yb1d56xsf bJ/YOHt5u83baG//5+1Jb/8aX3sXb3O8nRxtTvy3xfFnnoy/c358jb3ia/aJ79E3vudl8TPMi59p QfyMfNZzvR3j7bH4XXjtneN3HBS/88zYBotimzwT22hcbLO/xTbsE9t0n9jGtPVh3p6N78vv7+Ft urczvR3v7WFv/xnf9z+8zfU20Ntwb9O87Rkf5k7xQf+3t4nervW2X+xQfWKn29vbzd4u8Nbf29M1 z3BXb7O9DfU2xNt98Xvyvv/m7XFvR3sb5W2ytz/FduoTO+EB3q6IdkD8tz7xZ/4Uf+e8+BqPx9dM 2vK++J5D42fYNX4mnuFT3v7X2xhvt3r7S/wuyTPcP06ol3g7OLbBTrFN9oxtNDy22dzYhotjmz4c 2/jM2OZ7xPfdKT6Tw3IeD2d7m+rtDzXP8IX4PS6p2Hh4wNuJ3k7zdo+33WrGw9Oxv6UdD4vJ4P4f D/yhqN9UkWwAAAAASUVORK5CYIJ= ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image013.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAANzc3PDw8Ojo6RUVFUVFRQUFBRkZGWFhYSUlJX19fSkpK XV1dWVlZW1tbUlJSVlZWXl5eVFRUU1NTTExMUFBQWlpaTk5OV1dXcXFxYWFhZWVlcHBwfX19dHR0 bm5uf39/b29vY2NjYmJifHx8aWlpfn5+ZmZmcnJybGxse3t7dXV1d3d3dnZ2eXl5ampqbW1taGho enp6hYWFlZWVhoaGlJSUnJyciIiIgICAlpaWi4uLgoKCiYmJmpqamJiYl5eXn5+fmZmZgYGBnp6e hISEnZ2dk5OTg4ODjY2Nm5ubioqKjo6OkpKSkJCQjIyMj4+Ph4eHkZGRvb29rq6uq6uroaGht7e3 rKysvr6+p6entLS0paWlvLy8r6+vqqqqtra2qKiosrKysbGxu7u7qampsLCwuLi4ra2tpKSko6Oj s7Ozv7+/ubm5urq6oKCgpqamtbW1oqKi2dnZ1dXV3d3d0NDQ1NTU09PTzMzM29vbz8/PysrKxsbG wcHByMjI2tra3t7e0tLSwsLCxcXF19fX0dHRxMTEw8PDycnJzs7Ox8fH3Nzc1tbW39/fy8vLzc3N 5eXl/Pz8+fn55OTk/v7+8/Pz7e3t4+Pj+vr66urq5+fn/f396enp+/v79vb28fHx9PT08vLy4uLi 8PDw9fX19/f36+vr5ubm+Pj44ODg4eHh6Ojo7+/v7Ozs////AQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDG1zwPQAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAbU 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 gk== ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image014.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 JiFESLBnzlQFJiFESLDh2x8UmIQQIYH4vUaBSQgREhK/hRDBgfh9hwKTECIkEL+nKTAJIUJC4rcQ IjgkfgshggPx++8KTEKIkNhhbawCkxAiJBC/H1NgEkKEhMRvIURwsCewxG8hRFAgfp+qwCSECAnE 79EKTEKIkJD4LYQIDsTv4xWYhBAhIfFbCBEcm6z9Q4FJCBESEr+FEMGxx9p0BSYhREggfh+nwCSE CAnE79UKTEKIkJD4LYQIju3WblNgEkKEBOL3DAUmIURIIH4fq8AkhAgJid9CiOBA/D5dgUkIERKI 3yMUmIQQIbHX2iwFJiFESEj8FkIEh8RvIURwIH6focAkhAgJxO9bFZiEECEh8VsIERwbrB2jwCSE CAmJ30KI4NhsraMCkxAiJLZZu1mBSQgREojfsxWYhBAhIfFbCBEciN+rFJiEECGB+N1JgUkIERIS v4UQwYH4PVeBSQgREojfRyswCSFCQuK3ECI4jhC/n1SbCCEazKfWhhGQ/sXaX6xNsLbV2ofWllvb Z+1l/983rH1kbYu1VdZ2+9/tt/aaObiHyjvW3rL2mbWl/nevWPvc2lprG/1Fl1n7wv89QtcKa+9Z +8DamxXX5TWvW/vEHNw8ao21Xf49ee9Xre00B8ekG/z/v1px3V3+bzb593i94rr7/LU+8Nde4T9L dN1l/rNu9J+98rpL/Xd8y3/n7b4N9vu/3+3baItvszdatOVy38Zb/ev2tGjLbTXacqlvy3XW3vWv W1ZxXd5nZY17+IX/HB+bgz3S6hb3kHbbYQ5ua7ret+XSmG2517fl+97ebNGW9e7hUn+t9f7aO1rc w93+s272n73ePVxZcd39vm22+bZa59tuaY17uK3FPdzj701Zz8P+irZc2YTPQ+U93F5x3Zcr7mHc 5+Fr3pvA9K/+i/yvteHW7rHW3r9BO/+Hf7N2n7Vb/OuWWPs3f8Hjrc2wdq21K83BzOu/fSP8p7VF 1i61NsDaVGt/8o1/lP9SHa2NsTbO2un+xrbzjXOStQes3WjtAmvPW/t3/97HWJtrrYe3uf5na/xr nvd/80//Hif592znr3G6v+YY/xmW+s+00n9GPusgaxdbe8Z/F977aP8dr/TfeYZvg9W+TZb4NrrF t9nffBu2823a3rcxbX22tRf9dfn7E6xNt3adtS7Wnrb2X/66v7e2wNrl1q639qi1E/3NPMrf6M7W Rlq7y9qp3qHaeac72dpEazdZO8fa4op7eKy12dZ6Wetm7Qn/Pbnuf1h71tpF1gZbm2Ltz76d2nkn 7GDtdm8d/M/a+df82f/NEP8ez/r3jNryCX/NXv4zHOs/E/fwBWvnWRtqbbK1v/rvEt3D03yHOspa J/+wHOXb5ETfRtf7Nlvg23CNb9OnfRtf59v8BH/do/w9Obvg5+EGa9Os/bHiHr7iv8co/72a5XmY b62rtWuszbR2XMXzsNj7W9znYQ0juP8DV9yR2rtpCScAAAAASUVORK5CYIJ= ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image015.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAANzc3ODg4Ojo6PT09Pz8/XFxcXV1dUFBQXl5eWFhYW1tb UlJSVlZWWVlZVFRUV1dXWlpaVVVVX19fU1NTTExMUVFRTk5OT09PYGBgaGhoYmJiYWFhZGRkZmZm Z2dnaWlpampqa2trbW1tcXFxdHR0eXl5enp6fX19fn5+dnZ2c3Nzb29veHh4fHx8bm5ukZGRk5OT lpaWjY2Ni4uLj4+Ph4eHkpKSlJSUlZWVl5eXnZ2dnp6em5ubmpqakJCQjo6OnJycmJiYjIyMgoKC hISEhoaGiYmJiIiIhYWFn5+fg4ODmZmZgICAgYGBioqKrq6urKysqqqqq6urpqamoaGhsrKyoqKi ra2to6OjqKiov7+/paWlu7u7ubm5tbW1vb29vr6+sbGxoKCgr6+vtLS0s7OzzMzMzs7O0tLSyMjI wsLCxcXFzc3N0dHR09PTxMTEy8vLz8/Px8fHxsbGw8PD39/fycnJ3NzcysrK3d3d29vb2dnZ19fX 2NjY1dXV0NDQ1NTU3t7e1tbWwMDA+fn5+/v7/v7+/f39/Pz89PT09/f34ODg8/Pz9vb29fX18vLy 7u7u+vr67e3t6enp5ubm5OTk4eHh8fHx6urq5eXl4uLi6Ojo4+Pj7+/v////AQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDy2O5sgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAYt 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 RK5CYIJ= ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image016.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image017.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAJycnPDw8Ly8vOjo6NjY2KCgoMTExPj4+KysrKSkpKioq Li4uOTk5NTU1LS0tLCwsMjIyMDAwNzc3UFBQQ0NDSkpKVFRUWFhYTU1NU1NTV1dXXV1dREREQkJC UVFRXl5eWVlZWlpaX19fS0tLT09PUlJSRkZGSEhIXFxcd3d3f39/fX19enp6bm5uYWFhcHBwaGho b29vZGRkaWlpYmJidXV1ZWVla2trZmZmeXl5eHh4Y2NjdHR0cXFxcnJylpaWjY2Njo6Ol5eXiYmJ mJiYk5OTi4uLlZWVhYWFgYGBmZmZhoaGjIyMgICAmpqaj4+PkZGRnp6enZ2dg4ODh4eHnJycsbGx pKSkpqamqqqqp6env7+/tbW1tLS0tra2vr6+oaGhubm5paWlqampo6Ojrq6uurq6qKiorKyst7e3 r6+vsrKys7Oz1NTU3Nzc19fX0tLS29vb2NjYw8PD0dHRzc3N09PTycnJwMDAz8/P3t7e39/fy8vL 2dnZxsbG1dXVzs7Ox8fH0NDQxMTEwsLC3d3d2traysrKzMzMwcHBxcXFyMjI1tbW7u7u7e3t7+/v /Pz88vLy4ODg+Pj48/Pz/v7++fn59vb2/f39+vr65ubm9fX1+/v74eHh7Ozs6+vr8PDw4uLi6urq 5+fn5eXl6Ojo5OTk6enp9PT09/f34+Pj////AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDlVpxbgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAX/ 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 d9njPwAAAABJRU5ErkJggk== ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image018.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 QmCC ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image019.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAQQAAACEAgMAAAALob31AAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAAxQTFRFAAAAAAAA////AQIDb7EEKAAAAAF0Uk5TAEDm2GYAAAAJcEhZ cwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAB09tt6UAAAGySURBVGje7ZdBjsMgDEWz GWnU+7HpPovhJHOBRCPvgwqnnLQphPxiTCZZjFR7B9jf7xNC2q77B3EJB+Owwk0ZlEEZlEEZlEEZ 3obBI8MACZOFiSuMR2DwWECo6ADBAgOszwkggYou2C0DBQsJEBxjUpBMeEaRfxao6EAjjaKCD0IQ M58YXjZSUkwFUYG4BM5VLEgMXILMVDnVjh08W1LO4LGtDfVYmVrfLOJUI8PfH0UzA+sqMhDMuyDE WvBUsEIB74p7LygIsbZcFHZsXCsDukKmrOWiIG4cHwyDR2vI5Na+Z30vCKzsOA6NDB7LXhjQJgUh soI2hoqrhYG7yQVXexgqrhaG3bdDHm0M6CpruTAQnyC7amKouVoYEJLK7GXhJobaB+zB4GXWyvYU GRhXxX15MBy4XxgG8ZDnLU/6TYs2dx2oKkNMZB+SjQw2nwj77pe2fYiuyiyzwlRrUWLaKN0ZrpCQ FB2jOG6ku4tJK8Os1fdmVZyXyJg1wdgwTsYkxWlO/ek+8u7GUIbsgzH9pvtgvjbEd7m3/5+lDMqg DMqgDMqgDMqgDMqgDOcxfH4fjF/uRX0OYFcM4QAAAABJRU5ErkJggk== ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image020.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image021.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAW1tbXV1dX19fVFRUVlZWV1dXXl5eUVFRUFBQYGBgYmJi aGhoa2trb29vcnJydXV1eHh4YWFhZ2dncHBwZGRkcXFxZWVlZmZmbW1taWlpampqbm5udHR0f39/ Y2NjdnZ2bGxseXl5c3Nzfn5+fHx8d3d3fX19g4ODm5ubioqKkZGRn5+fnZ2dnJyciYmJmpqaiIiI mJiYlZWVkJCQlpaWkpKSnp6ej4+PhoaGk5OTgYGBh4eHtLS0qKiorq6ura2to6Ojp6envr6+vLy8 sLCwoqKiqampvb29t7e3ubm5srKypKSkr6+vtbW1urq6q6urpaWlpqamqqqqrKysv7+/sbGxs7Oz 0dHRxcXFyMjIzMzMw8PD3t7exMTEwMDAzc3Nzs7O0tLS2tra39/f0NDQ3d3dy8vLysrKwcHBxsbG 1tbWwsLC19fX2dnZ3Nzc29vbz8/P/Pz88fHx+fn54ODg/f395eXl5OTk+/v78vLy9fX16Ojo9/f3 8/Pz9PT0/v7+7+/v9vb2+Pj46urq5ubm+vr64uLi7u7u6+vr8PDw5+fn////AQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDDTaJQwAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAS+ SURBVHhe7Vv5WxMxEEUQRYWqrYBLqVweFAVBCh6IFFEE5VYUkEM8iicoFAoFBEQFNX+0uy2oQNvN ZCeG/XaWn/i+mffe5CWTZNumpdHj8BFgDn4M6x1cPmMOr5/8d/b8J//Jf+r/zh0BWv+0/p07+/XK 6fxH538HLwDq/9T/HTz9qf87fP+j/d/Z/Y/8J/+dvP/R+c/Z85/8J/+d3P9o/3f2/Cf/yX9A/5tu nAFE2yAUuP+HD8yqLWpgEJnfZu8/bpXj1g/0n7EmpQtgYAi3fOD7v7lgJH0eWwEEr7n86TAk3jQW 5v/C0RFTRMkB/gpcAputf9ziY9Mf9vlf+HYUW4NSPGj9i8eWlOpFJgf7j8wPhxttgeekyID6j0ou Aua/KJKVLAfu//Klz5gCVGOB/Y9mT6vV3HIHkR/uP2OVK4gCQFBDd/VwfysoxyQY4v9qldH7Z3Iw +UFYwctG+CDiBAD5v+qKH/+qQKLRg6vvIUJC/N+iXcuo+YKoAA41hncLAvm/rXTuOFwzZsaVg21o cAL+69y162gCRIBaG0WyEuUI+c++nsDiF8RpRzsEivm/GggLKsdJq7uPgwO//8V5l04i8YvCPHgm mrkrT8x/tlCPxC8IU5c5Lpi5M01s/TP2zY38HgZazdXMAWhKwnhB/9mi59Q1FAGiIJWHnoum/pMn 6j9j33PTUW+i4GL87rwNcNKeBFH/daDNw2pnQEd+7gurAyDuv87847SmaSovA7VuXcCmpTGw4L9+ FSwoKPDmxJ5OSypEk6t0ATq5tl4jeCk1/I8XsP00A7VEdAl/h2EnFvy/NVaR3M+26kTaAsYYeI1h AD++qHEA2pUWK6crEVP5y+Rj8wpMnjBBr8Or07sSEiWu3witWWZnBAT4onvXf0hfUpqW4/HsvWNd l//hb722eMPgz/Z4/s8dI8n6n3C5vPnDwKWAGN7gchW6fYiASaBS9P/hPG/Ra/kKkjMUl2SUSudP 1f9bytLfSBeQisDnKZX8stlk/2/KUrgG9JEJB2SPv8n+35T1VraClPjRs3LpTc9/waxuuQpSo0e0 c3LpTc9/Pe/kCjBBX9GkzgBT/xkLTCgdgM8lUt81mfrPOo6gvWwUGsiflUJpfEkc/rMexV/62TjP V4tQlLn/jN1UewoYQf3Ac+co8fjPehHeswiZs5UUkngV4PGfNby3It9ybqgvBtGF/N1PA5PLf9b3 wXINlgAmYzeh8aAlkMTJXP7HUzVlJ4GpXgmVxyD5/Ge+UT22OSJLhUJcPv8fflQoUaceLZPEz+m/ JHZu2KlH3KHAQD7/gaD2Cef1X1N7DWb9eZLGlNP/TvmvPlMWOPVYTv28/sth3weonP4zD953rvZB 1X8kcPv/ZL7ok0rh3RfaimXw8/rPWPuSDH5ezNDYLOLXPuH+s6JJXqm2iuP2v/2X2roaC2Xwc69/ GeQgzFA/KJw3mNt/XkB7xdnHf0njSv7Dfv8nyQZlsOQ/+a9s8qknpv4P/P2zestQFZD/5D/qhLIb GO3/tP/bbc4i6qX+T/0fcTrZD4r6P/V/+81aNMXU/6n/o00mOwJR/6f+b8d5i6SZ+j/1f6SpZE8Y 6v/U/+05c1FUU/9PY47++w1+zF6eEmSNjgAAAABJRU5ErkJggk== ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image022.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAASYAAACkCAYAAAA6y4O9AAAAAXNSR0ICQMB9xQAAAAlwSFlzAAAS dAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUATWljcm9zb2Z0IE9mZmljZX/tNXEAABHLSURBVHja 7Z2Hd5VFGsbds/8Nx+323lhXBVHBtYG4KrYVG6JrQwREugg2BINIC0HUQFSCoBCkh4TeoqBA6E0F UVBn32eYy7lG0HALd757f79znnMxJrfMN/f9Zp55551TnnvuuVMQQigm0QgIoXgDk3OunakbQggV UB2bBqYqBwBQWLaZOqQHpkm0CQAUmO9N9emBqYI2AYACs9x0GoEJAGJit2kSgQkAYmKzqQeBCQBi Yq2pDYEJAGJiv6mWwAQAMSHz+3QCEwDEhMzviQQmAIgJzG8AiA6Z360JTAAQEzK/FxOYACAmML8B IDowvwEgOhpNvQhMABATa0ytCEwAEBOY3wAQHZjfABAdMr8rCEwAEBMyv3sTmAAgJmR+X0lgAoCY wPwGgOhYYTqDwAQAMbHLVE5gAoCYkPndh8AEADEh8/sKAhMAxATmNwBEh8zvMwlMABATMr/HEZgA ICa2mPoRmAAgJjC/ASA6ZH7XEZgAICZkfp9FYAKAmNhpGktgAoCYwPwGgOhYbbqcwAQAMYH5DQDR IfP7bAITAMQE5jcARIfM7wEEJgCICZnf/yy6wPTzzz+7w4cPu59++olLDJA8DrhiNL+/++47t2DB Ardp0yYuMUDyKE7ze/v27e6ZZ55xH3/8sR89AWTD/v373YYNG/yNjlH4SUHm9+iiC0xff/21q6io cGvWrOESQ9Zs3brVjR071k2YMMF9//33NMhJaHLToKI1vzWlkwAy5dChQ66hocGNGTPGVVZWeu8S 8o7M75ZFFZjSje/q6mpXW1vLdA4yZvPmzW769Olu4cKF/ianvkV/yjvFZ37v3bvXzZ07161fv971 6NHDT+nwBSBTli1b5l566SU/Ylq9erVbsWKFO3jwIA2TX4rP/F63bp03vhWctDKnYTh3OMiUXbt2 ufr6ejdr1iz3xhtveO3evZuGyS8yv0cVVWCSUSmTUiMmgFyhadyMGTP8tO7bb7+lQfL8NTYNLurM 72+++cZ3JEZNAImh+MzvdOQtTZs2zc2cOdP9+OOPXG6AZCDzu76oA5OMy+HDh/tlXwBIBCtN5xRt YNL0benSpW7lypWszEHW6OYm71KJuwcOHKBB8scO00iqCwA0A+0oKC8vd8OGDfP5TZA3it/8FjK/ 9+3bx6gJskILKVVVVT43TmkEkDdWmS4t+sAk8/vDDz/EAIeskDXwww8/+E292jPHjS5vFLf5nWLU qFHutdde43JDTpDHNGfOHLdjxw4aIz/I/D636AOTOpIS45TBy3YCaC4KPEuWLHEbN248+jONlDSV e/XVV30pFMhP07tiMr9lTn7xxRd+qN0U3eGUOsB0DppLXV2de/HFF30uXApt4tXG8Pfff98tXrzY e5eQc7aZhhRNYFq+fLkbOnToMbejfPbZZ66srIx9TtBsVq1a5UaPHu33XTZl0aJFfuvT2rVraag8 NL3pkqIJTJqq9evXz33++ee/+n/KQdHu8HHjxvkVFYxL+D00utbU/1jJudo3p8Rd3Qwh5xSX+a0p nPJLjucjyS+45557/A5xjEvIBpXXUfWKTz/9lJym3FMa5neKbdu2eePy0Ucf/YWhCZAJ8qBUYkfe Jf0pp2jUUFZSmd8aliunSXc7/CbIBlkGffv2dV26dHHz58+nQXKHzO+XS25LivY5Ka9J1QkBsuHL L7907733nqupqWF3Qe6Q+X1xyQUmHe+k4bdWViguD9ny1Vdf+eA0b948qljkhtLI/G6KkuQaGxvd 5MmT/UoeQDYoPUUbez/55BMCU26Q+X1eSVYX0FJw0+Q5gEzQCp08Jh2wygpdTpD5PaIkA5MqDmib ikTqAGSLdh0or0kJvmxVyRqZ36+WdD0m1dcZOXKkL2kBkCkyvt9++213xx13+H10Sk2BjJH5fVHJ BiaVsNA2lbvvvttNmjTJr9bpZwAnikqiaEqn8+fuvPNO36/27NlDw2RGaZrfKeQz6binESNGuHvv vdcNGDDAr65wPj1kioKRdhZ06tTJBylK8GaEzO/zS760robdGn63atXK3X777e6DDz5gdQWy6k+D Bw92DzzwgH9UoUL60wmx3fQGNb9DZ3rzzTd9Jq861NSpU+lMkDHKbZIRfv3117u77rrLffTRR4zE m48C0+sEpjS0QtenTx/34IMP+hU7ZfYqT0WP1N6BE0F9Rgsr2pv58MMP+5ud6oVp1U7bWehPx6W0 ze/joVwUBSf5To888ogPUo8//rhfwZOHIN8gXapqoCOkKUIHTdEoqaGhwQ0cONDdd999vi+pT+nf 6k9aDU7vQ0L9SP9dwiP20ja/fwsNxXv27OmH4u3bt3cdO3Z0Dz30kA9YqvmUrt69e7shQ4b4LQkc RQ7HQsFJfee2225zt9xyi5f6k6yDVB/SNiltl1KypvqeEjZLFJnfFx4NTOPHj6945513nD2esLQC oV37athiYd26db4g2OzZs/0mzbfeesvddNNN7uqrr3bXXXfdUV1zzTXuhhtucE899ZTPZcmk/dB4 P+1RO6dQoC9E8qtuLrox6brrMVdoGqdKqrNmzfLPrdVg3fCuvfZa16ZNG9+H5Es9/fTTvo9pCqjC hqVw7fU5VS1U7XP48OFfekxt27atuPXWW127du1OWGpc5W+osVNf5JS0KqEypfncMLtlyxa3YsWK vC7PqkzKxIkT/akrY8eOPapUoz7//PM+cKktMmnDUpdWReXFaM9ZdXW1e+yxx/yCRHpfUmG2fO9v VGDSF0QjGdWKzxe6iVdWVvqbuvqR+pUWXjSyUp/SaErByr6XRX/t9Rlbt27tq34cPHjwl4HJLkSF hpNNpyrN1QsvvOCHp5r6dOjQwUv/vvnmm1337t19x5Lpp6JauT6tRCMbzeMLuVdJR5FrSqcAlWkb lrrUT3SDU9qG9Unvx2hUkepTN954ox9J6CakRQlJIxFtMcplYFIZZuW06fFkjtSmTJlytI64Ruza z3ks+6DYpCCs741Gk4cOHfrlVM5GGxVNjd0TkWppq0Jk586d/Z1PnSolFdPSz1TaVkNVjaK0vyhX hrHubBqtKWGyUKhjycCUcZlNO5aydNRWr169fIDSF1SnkWjhQTe89P6kvqTRhXT//ff7ShFq91xl 7mt0L+P6ZJfF0ftP+ZR6TBnjpXDtU4a/fe7cm99aAk0tiaZLhl5qqqM7ou56GmFp2peL1QetbigX iS0lyUZfRo16N23adPS6plI2Un1JJW0VrDSC0mgqtTDx7LPP+pNLIPGc3HQBDU0ViOQh9O/f369M dO3a1Wdd64gcEhqhueh0EvlAGimr72gKLY9KW0G0JUTeDYebJpbCJVjKa9LG2dQoStM/GZuMeCAT tHqm1R2tammVVL6mPCLZC5A4Cr8lRaMoLcPLK9AqjIIT5W4hU7RyquDUrVs372tS1z2RFH4TrzwF Dbl15pvygOQVqBY3iYqQKTJSlf+k5Xcd480BAcm7hC6WzG8FooULF/pRk4xxTjiFbNFiiKZ36leQ KOLaK6c7mwxNjZqefPJJn/nLjmzIFPUd5cg88cQTJzUfCbImvtK6ymvSHiEFJyWbsVIHmaIpnSpE aOOscqOUdgCJIM7DCJRopQRMpRZQnhSyRcFJSZhKUdHWJTyn6In3+CYl1mlDrDJ/ZWTSmSBTtMqr Qm3adaCcOVJSoifesiea0mljo6r/ade5loEBMu7pNq2TNaBNwQSm6In3iHCNkLQNQRsYtfta0zuA bNA+RlkEClA60QSiReb3y1EXilNwUuUA5aNQihSypba21u9kZwQeNTK/y6KvYCmfSfufGhsbuWSQ MfKatNNAIybVB+NopWiJ1/xOR6tz6kxKmKOuNmSKkniVfqJtKoMGDTpa96jp7yiAaTcCfa1gJKPm t1botOSrVTqVVAHIBo2ahg8ffsy8JhnjCxYs8Ps3tdEcCoLM70sScRiBRk06PFBDcIBM0YhIXqW8 JtW3V2G6dBSYVJZH1VBVkRQKgszvIYkITCocpnKqx9qiojugNgGnjr8B+D1UJkWFCrVKl45Wg1Wo Tv0Jg7xgJMP8TiGzUp1G9Z3Tqw+ocLvucMV0QgvkD/UdlWBWiZ1C1oiH46Kh6rmJCUwqqaptBXpM NyZT5jjpBNBcNDKSwa2bHfsxoyNZB15qNWXYsGF+SpcemDSCUlBiFQVOBKWfaEFFIyeIChnJlyYm MGl1Tt5A06kcQCZo1U3HlemgVoiK5JjfALlGNzrVaaIueHTI/B6ZqMAkX0ArdDqTjlETZIv8JRnh hTiKHI6LzO9zEhWYlBrQu3fvnJ1HB6WNVuV0LLUqWUA0JMv8FvKYlLWrlTlOU4Fs0WipvLzcVVVV 0RjxoDrILRM3laMKIeQKJexqD+bOnTtpjHjYahqcOPNbIyUd8aSSKABQdOguMSpxgUkZ3t27d3eT J0/2m3p1x2NaB5kir1IjJk3rVGNe+U2czlNQVpjOTlxg0jKvajhrQ+8rr7ziysrKqEgIGaOApPPn Xn/9dZ/TpNymjRs30jCFQ+Z3XeICk/wlldrVo0xLScEKIBOUxzRt2jRfkFBnGU6YMMGPwqFgJM/8 TqEcJgWk6upqP7VjOwpkiqZy2tKkm536kaZ1HFhQUGR+D0pkYFKJE9VurqysxF+CrFEfamhocPX1 9dzkCo/M79GJDEzqPDqgQAmXJFpCtqj2kjb06lQeDlktOMk0v1PoLqcAxdYUyBaVP1EKiqpXUnCw 8JfDJdH8Bsg16fWZuNEVHJnf/yQwAUBMbDENIDABQEzI/B5LYAKAmEi2+Q0ARcl+h/kNAJEh8/ty AhMAxITM734EJgCICcxvAIgOmd9nEZgAICYwvwEgOtaYriAwAUBMYH4DQHToBNJxBCYAiAmZ32cS mAAgJmR+LyYwAUBMYH4DQHQ0mvoQmAAgJmR+lxOYACAmZH6fQWACgJjA/AaA6JD5fSWBCQBiQuZ3 bwITAMTEblMFgQkAYgLzGwCiA/MbAKJD5ncrAhMAxITM714EJgCICcxvAIiO5abTCUwAEBOY3wAQ HWtNrQlMABATmN8AEB0yvycSmAAgJjC/ASA6ZH7XEpgAICZkfrchMAFATGw29SAwAUBMyPyeRGAC gJiQ+X0agQkAYgLzGwCi41fmdyVtAgAFZpOpuwLSH0wXml4yNZg2mOab9phmhsd5pi9N60y1pp3h /+0zfeaOpJGvNC01bTPVhP83y7TdVG9aHV50jmlv+HsZXQtNn5vWmxakva5+Z65poztSPKrOtCM8 p557tmmrOzInXR7+PTvtdXeEv1kTnmNu2uvuCa+1Prz2wvBeUq87J7zX1eG9p79uTfiMS8Nnbgxt sC/8/c7QRutCm81r0pbzQxs3hN/b1aQtNx+nLWtCWy4xrQq/NyftdfU8i45zDfeG9/GVO3JHWtzk GqrdtrgjZU2XhbasaWZb7g5t+UXQgiZt+VvXsCa81rLw2luaXMOd4b2uDe/9t67horTX3RfaZnNo qyWh7WqOcw03N7mGu8K1OVnfh31pbbkogd+H9GvYmPa6M9OuYXO/D9/quRWY/hg+yPWm502vmFqG J2gR/vAy02umnuH3Zpj+FF7wLFO56WFTJ3dk5PWP0Ah/NX1o6mj6n2mU6fzQ+KeGD9Xa1N/0ounK cGFbhMa5yDTC1M10s2ma6c/huU83TTL9N2hS+Fld+J1p4W+eCc9xUXjOFuE1rgyv2T+8h5rwnhaF 96j3+qSpg+mj8Fn03KeFz9gpfOby0AaLQ5vMCG3UM7TZZaENW4Q2bRnaWG3d1vRJeF39/TmmcaYu pjtMU0x/D6/7N1OV6T+mrqYxpnPDxTw1XOhrTC+YhpouDx2qReh0l5iGmZ4z/ds0Pe0anmGaaOps utf0bvicet2/mKaa2pueMpWZLgjt1CJ0wqtMA4OuCj9rEX7ngvA3T4fnmBqeM9WW74bX7Bzewxnh Pekafmy60fSsabjp4vBZUtfwX+GG2tfUJnxZTg1tcm5oo66hzapCG9aFNp0S2rhLaPNzwuueGq5J 2zx/Hx43jTadl3YNZ4XP0Td8rqR8H9433W160DTBdGba92F66G/N/T7UaQb3f7BnsUEorFCqAAAA AElFTkSuQmCC ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image023.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg 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 iiiiiiiiiiiiiiv/2S== ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image024.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg 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 ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image025.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 Nw3+97//B/9qrJQ5EIe7AAAAAElFTkSuQmCC ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/image026.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg 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 K4eYyzvO7yY3MWOTWxRRRRRRRRRRRRRRRX//2X== ------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/header.htm Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="windows-1250"





------=_NextPart_01D1E5D7.64999090 Content-Location: file:///C:/EF521992/adtrack2.files/filelist.xml Content-Transfer-Encoding: quoted-printable Content-Type: text/xml; charset="utf-8" ------=_NextPart_01D1E5D7.64999090-- adlibtracker2-2.4.23/package/ver/sdl/adtrack2.ini0000644000000000000000000003466613176573533020212 0ustar rootroot// // ADLiB TRACK3R II SDL configuration file // version 2.4.23+ // // [PATHS] ; Program Home Directory (used within File Browser window) ; Please specify full path here. If empty, directory where adtrack2.exe ; is located will be used. home_dir_path= ; Directory for storing recorded WAV files ; If you want to record all output to one file, specify it together with path ; including ".wav" extension (e.g. "wav_files\dump.wav" for Windows operating system ; resp. "wav_files/dump.wav" for Linux) otherwise every module being played ; will get its own WAV file with origin name. sdl_wav_directory=wav_files ; The following are static paths used while saving data files. ; To toggle dynamic path system, leave space after equal sign empty. ; In case you will be using nested directories, use correct separator character ; here ('\' for Windows operating system, resp. '/' for Linux). a2m_default_path=modules a2t_default_path=modules a2i_default_path=instr a2p_default_path=modules a2b_default_path=instr a2w_default_path=instr a2f_default_path=instr [STARTUP] init_tempo=50 ; default tempo (1-255) init_speed=6 ; default speed (hex) (1-FF) init_macro_speedup=1 ; default macro speed-up (range is optional!) octave=4 ; default octave (1-8) patt_len=64 ; default pattern length (1-256) nm_tracks=18 ; default number of tracks (1-20) midiboard=on ; default state for MidiBoard mark_lines=off ; default state for line marking [CONTROL] trace_by_default=on ; play with trace as the default action nosync_by_default=off ; play without sync as the default action keep_position=on ; keep position after quick load alt_ins_name=on ; alternative instrument name ("instrXXX") adjust_tracks=on ; adjust number of tracks for corresponding module linefeed=on ; process line feeding in pattern editor update_ins=off ; update active instrument by typing in numbers cycle_pattern=on ; cycle vertical and horizontal moves inside pattern keep_track_pos=off ; keep track position (column) when jumping over tracks remember_ins_pos=on ; remember slot and position for each instrument backspace_dir=1 ; backspace direction: ; [1] forwards ; [2] backwards command_typing=1 ; command typing: ; [0] mOrOn ; [1] FastTracker ; [2] Scream Tracker [CONVERSiON] fix_c_note_bug=on ; fix C-note bug (transpose CFF/HSC halftone up); ; correction is needed to properly replay: ; - CFF modules (any version of BoomTracker) ; - HSC modules (HSC-Tracker version 1.3 or above) accurate_conv=off ; convert CFF/DFM/HSC/MTK modules with highest accuracy ; NOTE: playback will be 100% accurate, but handling ; and further editing will be complicated fmk_flip_stereo=on ; flip stereo option in FM-Kingtracker force_ins=0 ; force type of "ins" file: ; [0] autodetect ; [1] HSC-Tracker/RAD-Tracker ; [2] SAdT ; [3] Amusic/AdLib instrument [TiMiNG] fforward_factor=1 ; mult. factor for fast-forward during playback (1-5) rewind_factor=1 ; mult. factor for rewind during playback (1-5) 18hz_fix=on ; treat 18 Hz tempo as 18.2 Hz [COSMETiCS] mod_description=off ; list description (if any) included in module use_h_for_b=off ; use "h" instead of "b" in note system highlight_controls=on ; highlight common effects (i.e. jump,loop,speed/tempo) decay_bar_rise=3 ; decay bar's rise speed (1-10) decay_bar_fall=3 ; decay bar's fall speed (1-10) scroll_bars=on ; process scrollbars in pattern & order list pattern_layout=0 ; pattern layout: ; [0] AdT2 ; [1] FastTracker ; [2] Scream Tracker [COLORS] // main screen main_background=1 ; background main_title=11 ; title main_border=11 ; border main_stat_line=3 ; status line text main_hi_stat_line=11 ; status line highlighted text main_dis_stat_line=5 ; status line disabled text main_behavior=13 ; behavior mode indicator main_behavior_dis=5 ; behavior mode disabled indicator // scrollbars scrollbar_bckg=3 ; background scrollbar=0 ; text scrollbar_mark=11 ; position mark scrollbar_2nd_mark=15 ; 2nd position mark // status window status_background=1 ; background status_border=14 ; border status_static_txt=11 ; static text status_dynamic_txt=15 ; dynamic text status_play_state=7 ; play state status_text_dis=5 ; disabled text // pattern order window order_background=1 ; background order_hi_bckg=5 ; highlighted background order_border=10 ; border order_entry=3 ; entry order_hi_entry=11 ; highlighted entry order_patt#=7 ; pattern number order_patt#_jump=2 ; pattern number (jump) order_hi_patt#=15 ; highlighted pattern number order_played_b=12 ; currently played order background order_played=0 ; currently played order order_input_bckg=11 ; string input background order_input=0 ; string input text order_input_warn=12 ; string input warning // pattern editor window pattern_bckg=1 ; background pattern_border=15 ; border pattern_pos_indic=11 ; position indicator pattern_pan_indic=3 ; panning indicator pattern_gpan_indic=15 ; track panning indicator pattern_lock_indic=7 ; lock indicator pattern_4op_indic=14 ; 4-OP track indicator pattern_perc_indic=15 ; percussion track indicator pattern_chan_indic=14 ; track OFF indicator pattern_row_bckg=5 ; current row background pattern_row_bckg_p=12 ; currently played row background pattern_block_bckg=2 ; block background pattern_line#=3 ; line number pattern_line#_p=0 ; currently played line number pattern_hi_line#=11 ; highlighted line number pattern_row_bckg_m=11 ; current row background \ pattern_line#_m=11 ; line number > if line marking is active pattern_hi_line#_m=3 ; highlighted line number / pattern_note=7 ; note pattern_hi_note=15 ; highlighted note pattern_note0=3 ; note (nul) pattern_hi_note0=12 ; highlighted note (nul) pattern_note_hid=9 ; hidden note pattern_hi_note_h=7 ; highlighted hidden note pattern_ins#=2 ; instrument number pattern_hi_ins#=10 ; highlighted instrument number pattern_ins#0=2 ; instrument number (nul) pattern_hi_ins#0=10 ; highlighted instrument number (nul) pattern_cmnd=7 ; effect command pattern_hi_cmnd=15 ; highlighted effect command pattern_cmnd0=3 ; effect command (nul) pattern_hi_cmnd0=11 ; highlighted effect command (nul) pattern_fix_note=11 ; fixed note pattern_hi_fx_note=14 ; higlighted fixed note pattern_cmnd_ctrl=13 ; controls if "highlight controls" is ON pattern_note_m=9 ; note \ pattern_note0_m=9 ; note (nul) \ pattern_note_hid_m=13 ; hidden note \ pattern_ins#_m=2 ; instrument number > if line marking is active pattern_ins#0_m=2 ; instrument number / pattern_cmnd_m=9 ; effect command / pattern_cmnd0_m=9 ; effect command (nul) / pattern_fix_note_m=14 ; fixed note \ pattern_note_b=15 ; note \ pattern_note0_b=11 ; note (nul) \ pattern_note_hid_b=5 ; hidden note \ pattern_ins#_b=10 ; instrument number > if block is being marked pattern_ins#0_b=10 ; instrument number / pattern_cmnd_b=15 ; effect command / pattern_cmnd0_b=11 ; effect command (nul) / pattern_fix_note_b=14 ; fixed note / pattern_input_bckg=11 ; string input background pattern_input=0 ; string input text pattern_input_warn=8 ; string input warning // macro editor window macro_background=4 ; background macro_title=11 ; title macro_border=15 ; border macro_topic=12 ; topic macro_topic2=13 ; topic #2 macro_hi_topic=14 ; highlighted topic macro_text=13 ; text macro_hi_text=14 ; highlighted text macro_text_dis=6 ; disabled text macro_text_loop=12 ; text [loop] macro_text_keyoff=3 ; text [key-off] macro_current_bckg=5 ; current line background macro_current=13 ; current line text macro_current_dis=0 ; current line disabled text macro_current_loop=12 ; current line text [loop] macro_current_koff=11 ; current line text [key-off] macro_input_bckg=7 ; string input background macro_input=0 ; string input text macro_def_bckg=12 ; string input default text background macro_def=0 ; string input default text macro_scrbar_bckg=7 ; scrollbar background macro_scrbar_text=0 ; scrollbar text macro_scrbar_mark=15 ; scrollbar position mark macro_hint=7 ; hint macro_item=15 ; item text macro_short=14 ; item shortcut macro_item_dis=7 ; item disabled macro_sel_itm_bckg=7 ; selected item background macro_sel_itm=0 ; selected item text macro_sel_short=4 ; selected item shortcut macro_context=14 ; context macro_context_dis=7 ; disabled context // volume analyzer window analyzer_bckg=1 ; background analyzer=3 ; text analyzer_overallvol=3 ; overall volume analyzer_volumelvl=7 ; volume level analyzer_modulator=2 ; modulator intensity analyzer_carrier=3 ; carrier intensity // debug info window debug_info_bckg=4 ; background debug_info_bckg2=9 ; background of current track debug_info_border=5 ; border debug_info_border2=15 ; border #2 debug_info_title=11 ; title debug_info_topic=14 ; topic debug_info_txt=7 ; text debug_info_hi_txt=15 ; highlighted text debug_info_txt_hid=6 ; hidden text debug_info_mod=2 ; modulator data debug_info_hi_mod=10 ; highlighted modulator data debug_info_car=3 ; carrier data debug_info_hi_car=11 ; highlighted carrier data debug_info_4op=8 ; 4-OP track indicator debug_info_perc=8 ; percussion track indicator // help window help_background=4 ; background help_title=11 ; title help_border=15 ; border help_topic=12 ; topic help_text=7 ; text help_hi_text=12 ; higlighted text help_keys=15 ; keys, keywords help_indicators=14 ; position indicators // instrument editor windows instrument_bckg=4 ; background instrument_title=11 ; title instrument_border=15 ; border instrument_text=7 ; text instrument_hi_text=15 ; highlighted text instrument_glob=13 ; global data instrument_hi_glob=15 ; highlighted global data instrument_hid=6 ; hidden text instrument_mod=2 ; modulator data instrument_car=3 ; carrier data instrument_hi_mod=10 ; highlighted modulator data instrument_hi_car=11 ; highlighted carrier data instrument_context=14 ; context instrument_con_dis=5 ; disabled context instrument_adsr=6 ; ADSR preview (background) // instrument activity indicators instrument_ai_off=6 ; never played instrument_ai_on=13 ; already played instrument_ai_trig=14 ; currently triggered // dialog boxes dialog_background=4 ; background dialog_title=11 ; title dialog_border=15 ; border dialog_text=13 ; text dialog_hi_text=14 ; highlighted text dialog_hid=6 ; hidden text dialog_item=15 ; item text dialog_short=14 ; item shortcut dialog_item_dis=5 ; disabled item dialog_sel_itm_bckg=7 ; selected item background dialog_sel_itm=0 ; selected item text dialog_sel_short=4 ; selected item shortcut dialog_context=14 ; context dialog_context_dis=7 ; disabled context dialog_context_dis2=9 ; disabled context #2 dialog_input_bckg=7 ; string input background dialog_input=0 ; string input text dialog_def_bckg=12 ; string input default text background dialog_def=0 ; string input default text dialog_prog_bar1=9 ; progress bar color #1 dialog_prog_bar2=11 ; progress bar color #2 dialog_topic=13 ; topic dialog_hi_topic=14 ; highlighted topic dialog_mod_text=10 ; modulator specific text dialog_car_text=11 ; carrier specific text // RGB color palette color00=00,00,00 ; color #0 color01=05,10,30 ; color #1 color02=00,30,30 ; color #2 color03=00,30,40 ; color #3 color04=00,00,20 ; color #4 color05=15,25,35 ; color #5 color06=00,10,25 ; color #6 color07=20,30,40 ; color #7 color08=45,35,50 ; color #8 color09=10,20,30 ; color #9 color10=20,40,40 ; color #10 color11=20,40,50 ; color #11 color12=25,35,50 ; color #12 color13=30,35,45 ; color #13 color14=35,60,60 ; color #14 color15=40,50,55 ; color #15 [SYSTEM SETTiNGS] // program screen sdl_screen_mode=0 ; program screen mode: ; [0] classic screen (90x40 @ 720x480p) ; [1] enhanced screen (120x50 @ 960x800p) ; [2] wide enhanced screen (180x60 @ 1440x960p) sdl_frame_rate=100 ; SDL screen frame rate in fps (50-200) ; DEFAULT: 100 fps ; NOTE: use smaller values for less CPU occupation, ; increase for smoother screen moves sdl_timer_slowdown=2 ; SDL timer slow-down factor in % (0-50) ; DEFAULT: 2% (measured with genuine Yamaha YMF262 chip) ; NOTE: only change the default value if you know ; what you are trying to do and why :-) // keyboard sdl_typematic_delay=150 ; typematic delay in ms (1-2000) sdl_typematic_rate=30 ; typematic rate in ms (1-100) adlibtracker2-2.4.23/package/ver/sdl/linux/0000755000000000000000000000000013176573533017136 5ustar rootrootadlibtracker2-2.4.23/package/ver/sdl/linux/adtrack2_hq1.sh0000644000000000000000000000010613176573533021733 0ustar rootroot#!/bin/sh ./adtrack2 /cfg:sdl_screen_mode=1 /cfg:sdl_frame_rate=150 adlibtracker2-2.4.23/package/ver/sdl/linux/adtrack2.png0000644000000000000000000000614413176573533021344 0ustar rootroot‰PNG  IHDR üí£ +IDATxÚ ßóýÖÖL°¤Äƒ†Õ÷þþþþ%" ÿÿúýÿýýýýõõüþþþëþÿúøö÷öø  RQÿÿ¾ÄNöøy€jøòðÛþÿûýýÁÅH>:(ͲŠFOËþ ýûùù÷úýÿÌÓO3,3È®|FSÎø(ÿÿþõóôüÿÿÐØN/'.ÜÆ‘KSÎúû:ýüýýÿÿÿÿÿBз„GJÆù=ÿüüþñÿÿÿÿÿÿ6ú´—…_jåîFÿ   éúÿÿ-õ}R”¯êNÿ/-=>úúúÿ  úÿ ýþûú'óX‘–¯îU?0Ý‹Š3ÿÿÿþöòòù÷ù  þþþþêåí~S—–®÷` þþþ«¤ð¸©   ùúýèë÷¤ªUîèñ   þ þþýá×ì}Ržœ¯ $q ÿýPööéýéý& Ó$óõýÿÌ»æïƒ[ž ¯ :þÿþÿÿýýèñëíö÷þþýþ ÿÿþý61û’}ÛûŒf¢¡¦ Rªÿÿÿÿéöôö÷õ +þýý ÿþ5.÷‰lÚ—r–¢›ù ^Áþÿÿÿÿþý ÿýÿþûý\MÌ ~Ž™íeÒþþ üý›w{“Šçtáýÿþþÿÿþþÿþÿþÿûûùý ý°¶ÖÇ÷xäþþÿýÿøö÷÷ùø  ÝT_T$ýÿþþÿþýþýûþ ýþ þýþÿýÿÿ ÿýþþýÿýÿýþþþÿþÿÿúüùóîðüÿÿ ýÿÿýþü ýþþÿÿþÿþÿþþÿþþÿÿÿÿåïÿÎÿwÊÿýýýýýýÿûøðöý  ð€²üLIEND®B`‚adlibtracker2-2.4.23/package/ver/sdl/linux/adtrack2_hq2.sh0000644000000000000000000000010613176573533021734 0ustar rootroot#!/bin/sh ./adtrack2 /cfg:sdl_screen_mode=2 /cfg:sdl_frame_rate=150 adlibtracker2-2.4.23/package/ver/sdl/revision.txt0000644000000000000000000005615313176573533020410 0ustar rootroot+====================- -=+ | | | /|DLiB TR/|CK3R ][ SDL Revision History | | | +=- -=======================+ For complete AT2 revision history refer to: http://www.adlibtracker.net/files/revision.htm * version 2.4.23 released: 07/27/2016 . fixed typing behavior bugs in Message Board window . fixed pattern names not being read from A2M file . fixed typing with Alt-codes; changed alternative hotkey for adjusting volume of sound output (new hotkey: [Alt][Shift] Up,Down) . fixed ADSR preview being shown for KSR instead of Envelope type . fixed incorrect pitch calculation in instrument preview . fixed bug when preview of non-macro instrument in File Selector overwritten macro data of current instrument . fixed interface bug occurring on instrument preview in File Selector . fixed replace function for Key-Off notes . added back and improved 'per instrument' positional memory . improved functionality of Pattern List window . added operator preview functionality to Instrument and Macro Editor . added automatic 4OP track volume manipulation (4OP+) for much more convenient work with volume for some volume-based commands and added command switches for toggling old (2OP) handling (for more information, refer to documentation of extended command 'ZE5/ZE6') . fixed 'Bxx' command not being evaluated correctly in 2nd effect column . fixed mistyped frequency multiplier values . added 'reset envelope' and 'ZERO frequency' triggers to FM-macro table . added short keys for copying data between carrier/modulator column in Macro Editor window and copying data between carrier/modulator slot in Instrument Editor window . added possibility to apply table indexes to current instrument in Arpeggio/Vibrato Macro Editor window . completely redesigned handling of notes within 4OP channels and improved user interface . fixed slow reading of instrument bank files . fixed preview of empty instrument with FM-register macro . slightly fixed channel ON/OFF for percussion tracks SD/TT/TC/HH . added possibility to slow down SDL timer so playback speed is more accurate to real hardware (refer to option 'sdl_timer_slowdown' in config file) . implemented new (improved) OPL3 emulator * version 2.4.22 released: 09/20/2015 (* 12/17/2015) . changes/improvements in Instrument Editor window: - added operator connection graphics - added browsing through all 4 operators with Enter and Tab/Shift+Tab keys - added status hints for current operator/instrument/4OP track - rearranged carrier/modulator/general settings - improved browsing through radio button sections - added separate color for percussive instruments - added section hotkeys for quick navigation - removed 'per instrument' positional memory (obsolete now) . improved speed of user interface in Macro Editor window . improved changing current instrument when 4OP instrument is selected . changed behaviour after releasing MBoard keys in instrument preview mode to Key-Off trailing . fixed Key-Off phase preview with 4OP instruments . improved functionality of Macro Browser under different conditions of use . fixed unintentional setting of octave while forcing KeyOff trailing with Ctrl key upon instrument preview . fixed interface bug in Macro Editor window when changing current instrument upon macro preview . fixed interface bug when loading complete content from A2B/A2W files . fixed macro restart with 4OP tracks upon note retrigger . changed compression algorithm to LZH / new file format versions . added fast-forward / rewind multiplication factor options (refer to options "fforward_factor" and "rewind_facotr" in config file) . updated file system and overall improved manipulation for more convenience when working with 4OP instruments . added new effect commands for restarting envelope (refer to "ZEx") . fixed non-functional hotkey for operation Paste object from clipboard to more patterns (new hotkey: [Alt][Shift] P) . added one step undo operation in Pattern Editor window (hotkey: ^Z) . added hotkey to delete complete note/instrument columns of track group when in when in Note Recorder mode (hotkey: ^Backspace) . fixed program freeze upon reaching last marked line when jump to next marked line was activated while cycle pattern was disabled . added option to keep track position (column) when jumping over tracks with Tab/Shift+Tab keys (refer to option "keep_track_pos" in config file) . improved seeking to pattern / position when song is played without trace . fixed several bugs in OPL3 recording; invoke of recording mode 'per channel' is now ignored when recording to single file is set by user configuration . pretty much improved internal logic for preview of 4OP instruments . added key shortcut for Instrument Editor window (hotkey: ^E); changed hotkey for Arpeggio/Vibrato Macro Editor window (new hotkey: ^G) . added Message Board window (hotkey: ^B) . (LINUX) fixed case sensitivity issue for filename extension * fixed bug that may lead to program crash when previewing TT/HH instrument * fixed cursor behavior on typing instrument name and in Message Board window * upgraded SDL to version 1.2.15 * version 2.4.21 released: 04/12/2015 (* 05/11/2015) . fixed/improved precision of playback calibration with pattern jumps . fixed typing in effect columns with NUMPAD keys . added alternative key combo for setting volume level of sound output on keyboards without NUMPAD keys (hotkey: [Alt] Up,Down) . fixed reading RGB color palette settings from config file . fixed occasional playback mute issue with F7 key in MBoard mode . fixed occasional messy behavior of +/- keys in Macro Editor window . fixed/improved fast-forward/rewind speed . added 'per instrument' positional memory to Instrument Editor window . improved track data processing during playback * fixed interface bug (misplaced cursor) in Instrument Editor window * added option to turn off positional memory for Instrument Editor (refer to option 'remember_ins_pos' in config file) * fixed sound glitch in OPL3 emulation for channels with null ADSR data * fixed some bugs in Macro Arpeggio / Vibrato performer * version 2.4.20 released: 12/23/2014 (* 01/08/2015) . changed hotkey for toggle of typing modes (hotkey: F11) . added toggle of line feed (hotkey: F12) . added toggle of jump to marked line (hotkey: [Shift] F12) . added back quick file load for modules (hotkey: [Shift] F3) . enhanced MBoard and Note Recorder with jump to marked line option . fixed stuck keyboard issues in MBoard mode . fixed fade in WAV recording with impossible start of playback . added possibility to remove song trace and continue playing while cursor position is maintained (hotkey: [Shift] Esc) . changes in Note Recorder mode: - fixed quick reset last group of tracks action - fixed behavior of some keys for mode exit - added row correction parameter . changes in Macro Browser: - fixed return to browser after selecting arp/vib table - improved arpeggio/vibrato table selection and indication . added Global Freq. Slide Up/Down commands and added command switches for Fine resp. Extra Fine variant (refer to new commands "xx" and enhanced functionality of old "ZFD","ZFE" commands) . fixed processing of new effects in Debug Info window . fixed some typing check bugs in Replace window . fixed bug when after swapping instruments one name was incomplete . fixed cursor key navigation within Remap and Replace window . removed sdl_sample_rate and sdl_sample_buffer options . added Rearrange Tracks function (hotkey: ^X) . added automatic activation of debug mode and switchover from offline to normal debug mode with Space when in Debug Info window . fixed/improved precision of fast-forward/rewind pattern function . added navigation to program home directory in File Browser window with Shift+Backspace key (refer also to option "home_dir_path") . added quick selection for muting track numbers above 9 with Shift key . fixed treating of all +/- combos for keyboards without NUMPAD . fixed player calibration issue with pattern break command * fixed interface bugs in Instrument Editor window * fixed fast-forward/rewind outside Pattern Editor window; added functionality to Instrument Control panel * fixed interface bug with ~xy effect command in 2nd effect column * fixed bug when entering notes for 4OP tracks in midiboard mode caused putting wrong instrument in left track of the pair * fixed rearrange function (faulty reordering of tracks) * version 2.4.19 released: 10/27/2014 (* 11/04/2014) . fixed switchover from offline to normal Debug mode with ^Enter . fixed not working instrument selection with no 4OP track extension . fixed position bugs in File Selector and updated layout for Linux . fixed lately introduced bug in Tone Portamento (arrgh) . fixed Tone Portamento with offline Debug mode and Note Recorder . fixed usage of non-NUMPAD asterisk (*) key for track ON/OFF flags . fixed/improved Replace function and added new shortkey functions . fixed pattern/order editor refresh bug occuring with small song speeds . added synchronized instrument/command processing for selected tracks when Note Recorder mode is armed . added quick reset of track group selection (hotkey: [Alt] Q) . improved layout in Instrument Control panel * fixed interface bug in Remap window occuring with sdl_screen_mode=2 * version 2.4.18 released: 09/05/2014 . changes in Note Recorder feature: - fixed bug when deleting notes was operating in wrong track if current track view on screen was moved by user; fixed precision with high song speeds (all notes are deleted now :) - added possibility to switch between using custom instrument and using present instruments in tracks (hotkey: Space / [Alt] Space) - improved keyboard reference on Help screen * version 2.4.17 released: 07/28/2014 (* 07/30/2014) . fixed ADSR preview update with enhanced screen modes . added Note Recorder feature (hotkey: ^Space) . changed file cache buffer for OPL3 recording to 512kb . added startup files for HQ-modes to program package * fixed some missing usage of non-NUMPAD +/- keys * version 2.4.16 released: 07/14/2014 . fixed cursor blink speed for non-default sdl_frame_rate value . improved current track movement in Debug Info window . added macro details section to Debug Info window . added flipped paste block feature (hotkey: Alt+Shift+V) . fixed/improved File Browser and Replace window . enhanced cursor movement in File Browser and Replace window . fixed in MAME OPL3 emulator: - experimental treatment of ADSR envelope restart for instruments with Attack Rate = 0 . enhanced Help screen navigation for effect columns . added FX volume information processing in marked block . small changes in user interface * version 2.4.15 released: 06/13/2014 . added 'Set Custom Speed Table' effect command (`xx) . fixed speed of decay bars for different sdl_frame_rate values; also minimum sdl_frame_rate value was limitied to 50 due to key processing issues with too low values . fixed conversion of FMK files . fixed listing of modules with '.' in filename within File Selector . fixed Tone Portamento in KeyOff-ed channel . fixed processing of Force instrument volume effect for 'AM' connections . fixed bug in processing of Arpeggio effect . fixed non-responding keyboard issue (hopefully :-) . small fixes in Arpeggio import from S3M files . fixed/improved/enhanced ADSR preview feature . optimized/enhanced color scheme options in config file . added possibility to control config file options with command line (refer to tip #25 in program documentation) . fixed handling of ON/OFF flags for 4-OP track pair . added positional memory for Song variables and Replace window . majorly improved Debug Info window functionality (hotkey: ^D) . fixed worse keyboard responsiveness upon instrument preview * SDL/Linux version 2.4.14 released: 04/24/2014 . Linux port made from SDL/Win32 2.4.14 sources * SDL/Win32 version 2.4.14 released: 04/09/2014 . fixed current instrument control in Macro Browser window . fixed macro speed manipulation and Song Variables value update . fixed filename sorting/filtering in File Selector window . fixed macro table preview bug with positive/negative columns . added macro speed control to Instrument Editor window . added FM-register macro table preview to Instrument Macro Browser . fixed FM-register table interface bug occurring with enhanced screen modes in Macro Editor window . improved layout in Arpeggio/Vibrato Macro Editor window . improved positional memory logic . major fixes/cleanups/optimizations of source code . updated incomplete key reference information in Help and .mht file . fixed waiting for key release when putting notes with MidiBoard . fixed non-blinking track flag and file overwrite bug in ‘per track’ recording mode . reverted back to “FT” as default typing mode * SDL/Linux version 2.4.13 released: 03/17/2014 . Linux port made from SDL/Win32 2.4.13 sources * SDL/Win32 version 2.4.13 released: 03/14/2014 . fixed faulty behavior of save-required notification with A2W files . fixed wrong instrument naming when loading complete A2W bank . fixed position behavior of instrument selection for load/paste register data operation in Macro Editor window; fixed interface bug in Instrument Control panel occurring upon these operations with enhanced screen . fixed arpeggio/vibrato macro table pointer in Macro Editor window * SDL/Win32 version 2.4.12 released: 03/11/2014 . added “per track” mode to WAV recorder (alter key: [Ctrl]) . added fully-featured macro browser . added bank browser for A2B and A2W files (finally :) . added file-dependent positional memory to all bank browsers . added positional memory to Macro Editor window . fixed command typing bug in arpeggio macro table . fixed not showing save-required notification . fixed sorting of filenames, filtered extra filename characters and optimized layout in File Selector window . switched back from MPRESS executable packer to UPX (due to reported malware alerts with some antivirus software) . improved paste operation in more places of the tracker . improved navigation system in Macro Editor window . improved layout of Macro Editor window . overall major improvements in macro data exchange and user handling * SDL/Linux version 2.4.11 released: 03/04/2014 . fixed case-sensitiveness problem when saving files . file issue fixed in more places (2.4.11.2) * SDL/Win32 version 2.4.11 released: 02/21/2014 . fixed cursor and decay bar speed to match DOS version parameters . fixed occasionally appearing interface bug in Pattern Editor window . improved CPU saving feature (refer to option “sdl_frame_rate”) . improved screen rendering routine (back to pure assembler roots :) . added Fade in/out feature for WAV recorder (alter key: [Shift]) . added new modules from Diode Milliampere . removed emergency unfreeze flash screen confirmation and changed key combo (Ctrl+Tab does the job now) . fixed in MAME OPL3 emulator: - rollback of current (experimental) changes for treating 4-OP channel volume attenuation - completely rewritten (according YMF262 specification) parts of code responsible for setting and changing total output level for 4-OP channels * SDL/Linux version 2.4.10 released: 02/14/2014 . first Linux port by Florian Jung * SDL/Win32 version 2.4.10 released: 02/13/2014 . fixed drive list being not shown in File Selector window . removed DBOPL emulation core (no more necessary I think :) . added WAV recording feature (hotkey: [Alt] F11/F12); check out config file and comments around option “sdl_wav_directory” for more information about how to setup output files * SDL/Win32 version 2.4.09 released: 02/12/2014 . fixed bug in playback calibration (macros were not processed) . fixed interface bug with long filenames in Status window . fixed not working block marking to left/right . fixed some false recognized key presses . fixed bad keyboard responsiveness when testing instrument in Instrument Editor window . fixed back treating of maximum macro speedup value (IRQ at 1000Hz with SDL works surprisingly without issues now :) . added emergency unfreeze command (hotkey: Ctrl+Shift+F10) . added command typing behavior mode handling in Macro Editor window . added instrument type indicators in Macro Editor window . added instrument type indicators and possibility to change current instrument in Instrument Editor window . added some new modules (Madbrain’s awesome A2M collection is hopefully complete now :) and a bit put to order some old ones . changed length of filename in File Selector to 23 chars . changed handling of F2/F3 related actions over instrument data . added wide enhanced screen mode (option “sdl_screen_mode=2”); extended screen content to 180/60 chars at 1440x960 pixels . fixed cursor position in Pattern Order with wide enhanced screen * SDL/Win32 version 2.4.08 released: 02/06/2014 . fixed interface bugs in Transpose and Pattern List window . fixed some non-functional keyboard combinations . changed F2/F3 related key combos: - some quick-load functionality was disabled for safety reasons; only single instruments and patterns can be quick loaded now - all quick-save functionality disabled except for saving A2M file in Pattern Editor / Pattern Order window - hot key for saving instrument bank w/ macros ([Shift] ^F2) in Instrument Control panel was simplified to [Shift] F2 . changed loading process of A2W files: - only FM-register / FM-register Macro Table instrument data is loaded within Instrument Control panel - only Arpeggio/Vibrato Macro Table data is loaded within Arpeggio/Vibrato Macro Table Editor window . fixed in MAME OPL3 emulator: - increased volume level by 50% for 4OP instruments with AM-AM, FM-AM and AM-FM connection (experimental) . improved playback rewind with low song speed values . improved enhanced screen mode; extended screen content to 120/50 chars at screen resolution 960x800 (check yourself with setting “sdl_screen_mode=1” :) * SDL/Win32 version 2.4.07 released: 01/30/2014 . fixed division by zero bug in playback fade out routine . added some modules from OxygenStar, a.o. to Modules directory . added new “AT” command typing behavior mode (like FT but without cycling pattern moves) (hotkey: Shift+F11); if not overriden by config file, this mode is set by default . removed console window (here you go Mikkel :) . added window icon and activated window close button functionality . fixed wrong position of bye-bye screen under some circumstances . fixed in MAME OPL3 emulator: - increased volume attenuation level in rhythm mode for all percussion channels except BD (experimental) * SDL/Win32 version 2.4.06 released: 01/26/2014 . fixed bug in replay routine (playback never advanced to order #7f) . fixed Status window update during playback calibration . fixed bug in treating KSL by MAME emulator (lucky at 4th attempt :); rollback of all previous changes to KSL – this trivial bug caused all the annoying discrepancies in sound compared to DBOPL emulator . fixed some serious interface bugs in Macro Editor and Remap Instrument window, which raised during portation to Free Pascal (btw, those ‘wtf’ table pointers had their meaning, Dmitry :) . added quick access key for Macro Editor window (^Q) . added macro-preview mode for Arpeggio/Vibrato Macro Editor window . added possibility to change current instrument directly within Macro Editor window (new key combo: Ctrl+[]) . added possibility to change current instrument and octave while macro-preview mode is activated . fixed treating of macro speedup (if unsafe, forced to lower value); SDL seems to have max. usable timer frequency at 650Hz, while DOS has been working just fine all the way up to 1000Hz ? * SDL/Win32 version 2.4.05 released: 01/22/2014 . fixed bug in replay routine (frequency data output for 4OP channels) . fixed bug with channel calculation in 4OP binding mode . added ADSR preview indication to Instrument Control panel . fixed first bugfix of KSL in MAME emulator ? * SDL/Win32 version 2.4.04 released: 01/20/2014 . fixed drive listing in File Selector (no more ‘insert disk’ messages without accesing drive :) . fixed calculation of KSL table in MAME OPL3 emulator (leads in those arcade-like Benjamin Gerardin’s songs sound finally correct :) * SDL/Win32 version 2.4.03 released: 01/17/2013 . fixed track binding not being displayed without panning lock on in Song Variables window . fixed binding of two 4OP instruments in Instrument Control panel . fixed toggle of ADSR preview (new key combo: Ctrl+LShift/RShift) . improved program exit procedure (it’s more DOS-like again :) . MAME OPL3 emulator: - updated according latest modifications from MAME (0.148u1) - fixed bug with setting KSL on 4OP channels . DOSBox OPL3 emulator: - added DBOPL emulator from DOSBox 0.74 - fixed stereo panning bug on percussion channels . added key combo for switching over OPL3 emulators ([Alt] F11/F12); current OPL3 emulator is always indicated by flag “MME” resp. “DBE” in Status window . added options to config file: - set sampling rate (sdl_sample_rate) - set sample buffer size (sdl_sample_buffer) - set default OPL3 emulator core (sdl_opl3_emulator) . complete conversion and update of program documentation (mht,htm) * SDL/Win32 version 2.4.02 released: 12/23/2013 . fixed program freeze with marking block at 4OP channel . fixed quick setting of octave and some other keyboard related issues * SDL/Win32 version 2.4.01 released: 12/18/2013 . code cleanup . removed MPU-401 code (not functional within SDL Win32) . removed some obsolete options from config file . fixed song timer / refresh rate decay bars . upgraded SDL to version 1.2.14.0 adlibtracker2-2.4.23/adtrack2.pas0000644000000000000000000005031113176573533015226 0ustar rootrootprogram AdLib_Tracker_2; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} {$IFDEF WINDOWS} {$APPTYPE GUI} {$R adtrack2.res} {$ENDIF} {$IFDEF GO32V2} uses CRT,GO32, AdT2opl3,AdT2unit,AdT2sys,AdT2extn,AdT2ext2,AdT2text,AdT2keyb,AdT2data,AdT2vesa, TxtScrIO,StringIO,DialogIO,ParserIO,MenuLib1,MenuLib2; const scan_addresses: array[1..7] of Word = ($388,$210,$220,$230,$240,$250,$260); var fade_buf,fade_buf2: tFADE_BUF; temp,index: Word; mem_info: tMemInfo; free_mem: Longint; opl3detected: Boolean; dos_dir: String; mouse_sx,mouse_sy,mouse_sd: Word; procedure LoadFont(var font_data); var regs: tRealRegs; dos_sel,dos_seg: Word; dos_mem_adr: Dword; begin dos_mem_adr := global_dos_alloc(4096); dos_sel := WORD(dos_mem_adr); dos_seg := WORD(dos_mem_adr SHR 16); dosmemput(dos_seg,0,font_data,4096); FillChar(regs,SizeOf(regs),0); regs.ax := $1100; regs.bh := 16; regs.bl := 0; regs.es := dos_seg; regs.ds := dos_seg; regs.bp := 0; regs.cx := 256; regs.dx := 0; RealIntr($10,regs); global_dos_free(dos_sel); end; function mouse_driver_installed: Boolean; const iret = $0cf; var driver_ofs,driver_seg: Word; begin driver_ofs := MEMW[0:$0cc]; driver_seg := MEMW[0:$0ce]; If (driver_seg <> 0) and (driver_ofs <> 0) and (MEM[driver_seg:driver_ofs] <> iret) then mouse_driver_installed := TRUE else mouse_driver_installed := FALSE; end; var old_exit_proc: procedure; procedure new_exit_proc; begin ExitProc := @old_exit_proc; If mouse_active then asm mov ax,1ah mov bx,mouse_sx mov cx,mouse_sy mov dx,mouse_sd int 33h end; If (ExitCode <> 0) then begin asm mov ax,03h; xor bh,bh; int 10h end; WriteLn(prog_exception_title); WriteLn('PROGRAM VERSION: ',at2ver,' from ',at2date,', ',at2link); WriteLn('ERROR_ID #'+Num2str(ExitCode,10)+' at '+ExpStrL(Num2str(LONGINT(ErrorAddr),16),8,'0')); WriteLn('STEP #1 -> ',_last_debug_str_); WriteLn('STEP #2 -> ',_debug_str_); WriteLn; WriteLn('Please send this information with brief description what you were doing'); WriteLn('when you encountered this error to following email address:'); WriteLn; WriteLn('subz3ro.altair@gmail.com'); WriteLn; WriteLn('Thanks and sorry for your inconvenience! :-)'); WriteLn; WriteLn; reset_player; sys_done; If (pattdata <> NIL) then FreeMem(pattdata,PATTERN_SIZE*max_patterns); ErrorAddr := NIL; HALT(ExitCode); end; end; procedure halt_startup(exitcode: Byte); begin sys_done; If (pattdata <> NIL) then FreeMem(pattdata,PATTERN_SIZE*max_patterns); ExitProc := @old_exit_proc; If (dos_dir <> '') then ChDir(dos_dir); HALT(exitcode); end; {$ELSE} uses SDL_Timer, AdT2sys,AdT2keyb,AdT2opl3,AdT2unit,AdT2extn,AdT2ext2,AdT2ext3,AdT2text,AdT2data, StringIO,DialogIO,ParserIO,TxtScrIO,MenuLib1,MenuLib2; var temp: Longint; {$ENDIF} begin { MAIN } {$IFDEF GO32V2} @old_exit_proc := ExitProc; ExitProc := @new_exit_proc; {$i-} GetDir(0,dos_dir); {$i+} If (IOresult <> 0) then dos_dir := ''; ShowStartMessage; // WriteLn('******************************************'); // WriteLn('** TEST VERSION -- DO NOT DISTRIBUTE! **'); // WriteLn('******************************************'); // WriteLn; { init system things } sys_init; For index := 1 to ParamCount do If (Lower(ParamStr(index)) = '/debug') then _debug_ := TRUE; If _debug_ then WriteLn('-------- DEBUG --------'); If _debug_ then WriteLn('--- detecting available dos memory'); asm mov bx,0ffffh mov ah,48h int 21h mov dos_memavail,bx end; If (dos_memavail*16 DIV 1024 < 120) then begin WriteLn('ERROR(1) - Insufficient DOS memory!'); halt_startup(1); end; If _debug_ then WriteLn('--- detecting available linear frame buffer'); Get_MemInfo(mem_info); free_mem := mem_info.available_memory; If _debug_ then WriteLn('--- ## ',free_mem/1024/1000:0:2,'MB lfb found'); If NOT (free_mem DIV 1024 > 5*1024) then begin WriteLn('ERROR(1) - Insufficient memory!'); halt_startup(1); end; temp := 128; Repeat If (free_mem > PATTERN_SIZE*temp) then begin max_patterns := temp; BREAK; end else If (temp-16 >= 16) then Dec(temp,16) else begin WriteLn('ERROR(1) - Insufficient memory!'); halt_startup(1); end; until FALSE; { allocate memory for patterns } If _debug_ then WriteLn('--- allocating frame buffer for patterns'); GetMem(pattdata,PATTERN_SIZE*max_patterns); If NOT iVGA then begin WriteLn('ERROR(2) - Insufficient video equipment!'); halt_startup(2); end; If (max_patterns <> $80) then WriteLn('WARNING: Maximum number of patterns is ',max_patterns,'!'); { read and process adtrack2.ini file } If _debug_ then WriteLn('--- updating user configuration'); process_config_file; { detect mouse } If _debug_ then WriteLn('--- detecting mouse'); If NOT mouse_disabled then mouse_active := mouse_driver_installed; If NOT mouse_disabled and NOT mouse_active then If is_scrollable_screen_mode then WriteLn('WARNING: Mouse driver not installed!'); {$ELSE} screen_ptr := ptr_screen_emulator; ShowStartMessage; { init system things } sys_init; { read and process adtrack2.ini file } If _debug_ then WriteLn('--- updating user configuration'); process_config_file; program_screen_mode := sdl_screen_mode; { allocate memory for patterns } If _debug_ then WriteLn('--- allocating frame buffer for patterns'); max_patterns := 128; GetMem(pattdata,PATTERN_SIZE*max_patterns); {$ENDIF} {$IFDEF GO32V2} { detect opl3 } If _debug_ then WriteLn('--- processing opl3 detection'); index := 1; If (opl3port <> 0) then If (opl3port < $100) then WriteLn('OPL3 interface base address forced to ',ExpStrL(Num2str(opl3port,16),2,'0'),'h') else If (opl3port < $1000) then WriteLn('OPL3 interface base address forced to ',ExpStrL(Num2str(opl3port,16),3,'0'),'h') else WriteLn('OPL3 interface base address forced to ',ExpStrL(Num2str(opl3port,16),4,'0'),'h') else begin opl3detected := FALSE; Repeat opl3port := scan_addresses[index]; Inc(index); Write('Autodetecting OPL3 interface at ', Num2str(opl3port,16),'h ... '); If NOT detect_OPL3 then begin If (index < 8) then Write(#13) else begin WriteLn('not responding!'); WriteLn; WriteLn('Force base address in configuration file (section TROUBLESHOOTiNG)'); WriteLn('or directly from command-line using "/cfg:adlib_port=XXXX" option;'); WriteLn('XXXX range is 1-FFFFh'); halt_startup(3); end; end else begin opl3detected := TRUE; WriteLn('ok'); BREAK; end; until opl3detected or (index > 7); end; {$ENDIF} { intialize player routine } If _debug_ then WriteLn('--- initializing player routine'); {$IFDEF GO32V2} If (opl_latency <> 0) then opl3out := opl2out; {$ENDIF} init_player; { initialize unit data } DialogIO_Init; StringIO_Init; TxtScrIO_Init; MenuLib1_Init; MenuLib2_Init; If _debug_ then WriteLn('--- initializing songdata'); tempo := init_tempo; speed := init_speed; init_songdata; songdata_source := ''; instdata_source := ''; songdata_title := 'noname.'; bank_position_list_size := 0; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); play_status := isStopped; current_octave := default_octave; If use_h_for_b then b_note := 'h'; For temp := 1 to 12*8+1 do If (note_layout[temp][1] = '%') then If NOT use_h_for_b then note_layout[temp][1] := 'B' else note_layout[temp][1] := 'H'; If _debug_ then WriteLn('--- executing program core'); {$IFDEF GO32V2} WriteLn('Available memory: ',free_mem DIV 1024,'k (DOS: ',dos_memavail*16 DIV 1024,'k)'); For temp := 1 to 50 do WaitRetrace; fade_speed := 16; fade_buf.action := first; VgaFade(fade_buf,fadeOut,delayed); For temp := 1 to 31 do If NOT _custom_svga_cfg[temp].flag or (_custom_svga_cfg[temp].value = -1) then begin custom_svga_mode := FALSE; BREAK; end; { initializing interface (phase:1) } If NOT is_VESA_emulated_mode then Case program_screen_mode of 0: SetCustomVideoMode(36); // 90x30 1: If NOT custom_svga_mode then set_svga_txtmode_100x38 // 100x38 else begin svga_txtmode_cols := _custom_svga_cfg[1].value; svga_txtmode_rows := _custom_svga_cfg[2].value; For temp := 1 to 29 do svga_txtmode_regs[temp].val := _custom_svga_cfg[2+temp].value; set_custom_svga_txtmode; end; 2: If NOT custom_svga_mode then set_svga_txtmode_128x48 // 100x48 else begin svga_txtmode_cols := _custom_svga_cfg[1].value; svga_txtmode_rows := _custom_svga_cfg[2].value; For temp := 1 to 29 do svga_txtmode_regs[temp].val := _custom_svga_cfg[2+temp].value; set_custom_svga_txtmode; end; 3: Case comp_text_mode of 0: SetCustomVideoMode(34); // 80x30 1: SetCustomVideoMode(25); // 80x25 end; 4: set_svga_txtmode_100x38; // 100x38 5: set_svga_txtmode_128x48; // 100x48 end else Case get_VESA_emulated_mode_idx of 0: begin VESA_Init; VESA_SetMode(VESA_800x600); VESA_SegLFB := Allocate_LDT_Descriptors(1); Set_Segment_Base_Address(VESA_SegLFB, Get_Linear_Addr(DWORD(VESA_FrameBuffer), VESA_VideoMemory*64*1024)); Set_Segment_Limit(VESA_SegLFB,VESA_VideoMemory*64*1024-1); For temp := 0 to 15 do SetRGBitem(temp,rgb_color[temp].r, rgb_color[temp].g, rgb_color[temp].b); end; 1: begin VESA_Init; VESA_SetMode(VESA_800x600); VESA_SegLFB := Allocate_LDT_Descriptors(1); Set_Segment_Base_Address(VESA_SegLFB, Get_Linear_Addr(DWORD(VESA_FrameBuffer), VESA_VideoMemory*64*1024)); Set_Segment_Limit(VESA_SegLFB,VESA_VideoMemory*64*1024-1); For temp := 0 to 15 do SetRGBitem(temp,rgb_color[temp].r, rgb_color[temp].g, rgb_color[temp].b); end; 2: begin VESA_Init; VESA_SetMode(VESA_1024x768); VESA_SegLFB := Allocate_LDT_Descriptors(1); Set_Segment_Base_Address(VESA_SegLFB, Get_Linear_Addr(DWORD(VESA_FrameBuffer), VESA_VideoMemory*64*1024)); Set_Segment_Limit(VESA_SegLFB,VESA_VideoMemory*64*1024-1); For temp := 0 to 15 do SetRGBitem(temp,rgb_color[temp].r, rgb_color[temp].g, rgb_color[temp].b); end; end; For temp := 0 to 15 do Case temp of 0..5, 7: SetRGBitem(temp, rgb_color[temp].r,rgb_color[temp].g,rgb_color[temp].b); 6: SetRGBitem(temp+14,rgb_color[temp].r,rgb_color[temp].g,rgb_color[temp].b); 8..15: SetRGBitem(temp+48,rgb_color[temp].r,rgb_color[temp].g,rgb_color[temp].b); end; If is_VESA_emulated_mode then begin VESA_GetPalette(fade_buf); FillChar(fade_buf2,SizeOf(fade_buf2),0); VESA_InitStepFade(fade_buf,fade_buf2,1); VESA_StepFade; end; { initializing interface (phase:2) } If NOT is_VESA_emulated_mode then begin HideCursor; LoadFont(font8x16); TXTSCRIO.initialize; hard_maxcol := MaxCol; hard_maxln := MaxLn; If NOT (program_screen_mode in [4,5]) then SetSize(MAX_COLUMNS,MAX_ROWS) else SetSize(SCREEN_RES_X DIV scr_font_width,MAX_ROWS); TXTSCRIO.initialize; do_synchronize := FALSE; end else begin v_seg := 0; v_ofs := Ofs(screen_emulator); screen_ptr := ptr_screen_emulator; mn_environment.v_dest := screen_ptr; TxtScrIO_Init; end; { initializing interface (phase:3) } work_MaxCol := MAX_COLUMNS; If (program_screen_mode in [4,5]) or ((program_screen_mode = 3) and (comp_text_mode = 4)) then work_MaxLn := MAX_ROWS else work_MaxLn := MAX_ROWS-10; If NOT is_VESA_emulated_mode then begin fade_buf.action := first; fade_speed := 1; VgaFade(fade_buf,fadeOut,fast); fade_speed := 32; end; asm mov ah,03h mov al,05h mov bl,typematic_rate mov bh,typematic_delay int 16h mov ax,1003h xor bl,bl int 10h end; If mouse_active then asm xor ax,ax int 33h mov ax,1bh int 33h mov mouse_sx,bx mov mouse_sy,cx mov mouse_sd,dx mov ax,04h xor cx,cx xor dx,dx int 33h mov ax,1ah mov bx,mouse_hspeed mov cx,mouse_vspeed mov dx,mouse_threshold int 33h mov ax,07h mov cx,0 mov dx,SCREEN_RES_x int 33h mov ax,08h mov cx,0 mov dx,SCREEN_RES_y int 33h end; {$ELSE} vid_SetVideoMode(TRUE); {$ENDIF} { initializing interface (phase:4) } PROGRAM_SCREEN_init; POSITIONS_reset; decay_bars_refresh; status_refresh; If (command_typing <> 0) then GotoXY(08+pos4[pattern_hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)) else GotoXY(08+pos3[pattern_hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)); ThinCursor; { initializing timer } init_timer_proc; { initializing keyboard } keyboard_init; stop_playing; {$IFDEF GO32V2} { initializing interface (phase:5) } realtime_gfx_poll_proc; _draw_screen_without_vsync := TRUE; draw_screen; WaitRetrace; If NOT is_VESA_emulated_mode then begin For temp := 1 to 10 do WaitRetrace; VgaFade(fade_buf,fadeIn,delayed); end else begin VESA_InitStepFade(fade_buf2,fade_buf,20); For temp := 1 to 20 do begin VESA_StepFade; If keypressed then keyboard_reset_buffer; end; end; {$ENDIF} { main loop } _debug_str_ := 'redirecting to main loop'; do_synchronize := TRUE; fkey := kENTER; Repeat If (fkey = kENTER) then PATTERN_edit(pattern_patt,pattern_page,pattern_hpos); If (fkey = kENTER) then PATTERN_ORDER_edit(pattord_page,pattord_hpos,pattord_vpos); until (fkey = kESC) or (fkey = kF10) or _force_program_quit; { terminating program (phase:1) } If NOT tracing then ThinCursor; do_synchronize := FALSE; {$IFDEF GO32V2} draw_screen; If NOT is_VESA_emulated_mode then fade_out_playback(TRUE) else begin VESA_InitStepFade(fade_buf,fade_buf2,20); For temp := 1 to 20 do begin VESA_StepFade; If (overall_volume > 3) then Dec(overall_volume,3) else overall_volume := 0; set_global_volume; If keypressed then keyboard_reset_buffer; end end; {$ELSE} fade_out_playback(TRUE); {$ENDIF} stop_playing; FillChar(decay_bar,SizeOf(decay_bar),0); FillChar(volum_bar,SizeOf(volum_bar),0); done_timer_proc; keyboard_done; {$IFDEF GO32V2} opl3exp($0004); opl3exp($0005); {$ELSE} opl3_done; {$ENDIF} { terminating program (phase:2) } _realtime_gfx_no_update := TRUE; {$IFDEF GO32V2} set_vga_txtmode_80x25; HideCursor; fade_buf.action := first; fade_speed := 1; VgaFade(fade_buf,fadeOut,fast); fade_speed := 32; GOTOXY_xshift := 0; GotoXY(1,1); C3WriteLn(ascii_line_01,$08,$09,$01); C3WriteLn(ascii_line_02,$08,$09,$01); C3WriteLn(ascii_line_03,$08,$09,$01); C3WriteLn(ascii_line_04,$08,$09,$01); C3WriteLn(ascii_line_05,$08,$09,$01); C3WriteLn(ascii_line_06,$08,$09,$01); C3WriteLn(ascii_line_07,$08,$09,$01); C3WriteLn(ascii_line_08,$08,$09,$01); C3WriteLn(ascii_line_09,$08,$09,$01); C3WriteLn(ascii_line_10,$08,$09,$01); C3WriteLn(ascii_line_11,$08,$09,$01); C3WriteLn(ascii_line_12,$08,$09,$01); C3WriteLn(ascii_line_13,$08,$07,$01); C3WriteLn(ascii_line_14,$08,$09,$03); C3WriteLn(ascii_line_15,$08,$09,$01); C3WriteLn(ascii_line_16,$08,$09,$01); C3WriteLn(ascii_line_17,$08,$09,$01); C3WriteLn(ascii_line_18,$08,$09,$01); C3WriteLn(ascii_line_19,$08,$09,$01); C3WriteLn(ascii_line_20,$08,$09,$01); C3WriteLn(ascii_line_21,$08,$09,$01); C3WriteLn(ascii_line_22,$08,$09,$01); C3WriteLn(ascii_line_23,$08,$09,$01); Move(vga_font8x16,font8x16,SizeOf(font8x16)); dosmemput(v_seg,v_ofs,screen_ptr^,(SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2); For temp := 1 to 50 do WaitRetrace; VgaFade(fade_buf,fadeIn,delayed); ThinCursor; For temp := 1 to 50 do WaitRetrace; { terminating program (phase:3) } sys_done; FreeMem(pattdata,PATTERN_SIZE*max_patterns); ExitProc := @old_exit_proc; If (dos_dir <> '') then ChDir(dos_dir); {$ELSE} program_screen_mode := 0; TxtScrIO_Init; vid_SetVideoMode(FALSE); vid_SetRGBPalette(Addr(vga_rgb_color)^); temp := screen_scroll_offset DIV 16 + 3; HideCursor; C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+01,ascii_line_01,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+02,ascii_line_02,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+03,ascii_line_03,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+04,ascii_line_04,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+05,ascii_line_05,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+06,ascii_line_06,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+07,ascii_line_07,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+08,ascii_line_08,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+09,ascii_line_09,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+10,ascii_line_10,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+11,ascii_line_11,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+12,ascii_line_12,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+13,ascii_line_13,$08,$07,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+14,ascii_line_14,$08,$09,$03); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+15,ascii_line_15,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+16,ascii_line_16,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+17,ascii_line_17,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+18,ascii_line_18,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+19,ascii_line_19,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+20,ascii_line_20,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+21,ascii_line_21,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+22,ascii_line_22,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+23,ascii_line_23,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+24,ascii_line_24,$08,$09,$01); Move(vga_font8x16,font8x16,SizeOf(font8x16)); draw_screen; SDL_Delay(3000); { terminating program (phase:3) } sys_done; snd_done; FreeMem(pattdata,PATTERN_SIZE*max_patterns); {$ENDIF} end. adlibtracker2-2.4.23/adt2opl3.pas0000644000000000000000000004276713176573533015203 0ustar rootrootunit AdT2opl3; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface {$IFDEF GO32V2} const ___OPL3OUT_UNIT_DATA_START___: Dword = 0; {$ENDIF} procedure opl2out(reg,data: Word); procedure opl3out_proc(reg,data: Word); procedure opl3exp(data: Word); type tOPL3OUT_proc = procedure(reg,data: Word); const opl3out: tOPL3OUT_proc = opl3out_proc; {$IFDEF GO32V2} const opl3port: Word = 0; opl_latency: Byte = 0; function detect_OPL3: Boolean; {$ELSE} const renew_wav_files_flag: Boolean = TRUE; opl3_channel_recording_mode: Boolean = FALSE; opl3_record_channel: array[1..20] of Boolean = ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); procedure flush_WAV_data; procedure opl3_init; procedure opl3_done; procedure snd_init; procedure snd_done; procedure snd_SetTimer(value: Longint); procedure update_recorded_channels; const opl3_flushmode: Boolean = FALSE; const WAV_BUFFER_SIZE = 18*512*1024; // cache buffer size -> 512k per file var wav_buffer_len: Longint; wav_buffer: array[0..18,0..PRED(WAV_BUFFER_SIZE)] of Byte; {$ENDIF} {$IFDEF GO32V2} const ___OPL3OUT_UNIT_DATA_END___: Dword = 0; {$ENDIF} implementation {$IFDEF GO32V2} uses GO32, AdT2sys, TxtScrIO; {$IFDEF GO32V2} procedure ___OPL3OUT_IRQ_CODE_START___; begin end; {$ENDIF} var _opl_regs_cache: array[WORD] of Word; procedure opl2out(reg,data: Word); begin If (_opl_regs_cache[reg] <> data) then _opl_regs_cache[reg] := data else EXIT; asm mov ax,reg mov dx,word ptr [opl3port] or ah,ah jz @@1 add dx,2 @@1: out dx,al mov ecx,6 @@2: in al,dx loop @@2 inc dl mov ax,data out dx,al dec dl mov ecx,36 @@3: in al,dx loop @@3 end; end; procedure opl3out_proc(reg,data: Word); begin If (_opl_regs_cache[reg] <> data) then _opl_regs_cache[reg] := data else EXIT; asm mov ax,reg mov dx,word ptr [opl3port] or ah,ah jz @@1 add dx,2 @@1: out dx,al inc dl mov ax,data out dx,al dec dl mov ecx,26 @@2: in al,dx loop @@2 end; end; procedure opl3exp(data: Word); begin if (_opl_regs_cache[(data AND $ff) OR $100] <> data SHR 8) then _opl_regs_cache[(data AND $ff) OR $100] := data SHR 8 else EXIT; asm mov ax,data mov dx,word ptr [opl3port] add dx,2 out dx,al mov ecx,6 @@1: in al,dx loop @@1 inc dl mov al,ah out dx,al mov ecx,36 @@2: in al,dx loop @@2 end; end; {$IFDEF GO32V2} procedure ___OPL3OUT_IRQ_CODE_END___; begin end; {$ENDIF} function detect_OPL3: Boolean; var result: Boolean; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2OPL3.PAS:detect_OPL3'; asm push dword 04h push dword 80h push dword 04h push dword 60h call opl2out call WaitRetrace call opl2out call WaitRetrace mov dx,opl3port in al,dx and al,0e0h mov bl,al push dword 04h push dword 21h push dword 02h push dword 0ffh call opl2out call WaitRetrace call opl2out call WaitRetrace mov dx,opl3port in al,dx and al,0e0h mov bh,al cmp bx,0c000h jnz @@1 push dword 04h push dword 80h push dword 04h push dword 60h call opl2out call WaitRetrace call opl2out call WaitRetrace mov dx,opl3port in al,dx and al,6 or al,al jnz @@1 mov result,TRUE jmp @@2 @@1: mov result,FALSE @@2: end; detect_OPL3 := result; end; {$ELSE} uses MATH,SysUtils, AdT2unit,AdT2sys,TxtScrIO,StringIO, SDL_Types,SDL_Audio,OPL3EMU; const opl3_sample_buffer_ptr: Pointer = NIL; opl3_sample_buffer_chan_ptr: array[1..18] of Pointer = ( NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL); var sample_frame_size: Longint; sdl_audio_spec: SDL_AudioSpec; procedure flush_WAV_data; type tWAV_HEADER = Record file_desc: array[0..3] of Char; // =="RIFF" file_size: Dword; // ==filesize-8 wav_desc: array[0..3] of Char; // =="WAVE" format_desc: array[0..3] of Char; // =="fmt " wav_size: Dword; // ==16 wav_type: Word; // ==1 (PCM) num_channels: Word; // ==2 (Stereo) samples_sec: Dword; // sampling frequency bytes_sec: Dword; // ==num_channels*samples_sec*bits_sample/8 block_align: Word; // ==num_channels*bits_sample/8 bits_sample: Word; // ==16 data_desc: array[0..3] of Char; // "data" data_size: Dword; // size of data end; const wav_header: tWAV_HEADER = (file_desc: 'RIFF'; file_size: SizeOf(tWAV_HEADER)-8; wav_desc: 'WAVE'; format_desc: 'fmt '; wav_size: 16; wav_type: 1; num_channels: 2; samples_sec: 49716; bytes_sec: 2*49716*16 DIV 8; block_align: 2*16 DIV 8; bits_sample: 16; data_desc: 'data'; data_size: 0); var wav_file: File; temp,bytes_to_write: Longint; idx,from_ch,to_ch: Byte; filename_suffix: String; begin bytes_to_write := wav_buffer_len; // flush when at least 1 sec of recorded data If (bytes_to_write < 2*sdl_sample_rate*16 DIV 8) then EXIT; If NOT ((play_status = isPlaying) and (sdl_opl3_emulator <> 0)) then EXIT; // prepare output directory If NOT DirectoryExists(Copy(sdl_wav_directory,1,Length(sdl_wav_directory)-Length(NameOnly(sdl_wav_directory)))) then If NOT CreateDir(Copy(sdl_wav_directory,1,Length(sdl_wav_directory)-Length(NameOnly(sdl_wav_directory)))) then EXIT; wav_buffer_len := 0; If NOT opl3_channel_recording_mode then begin from_ch := 0; to_ch := 0; end else begin from_ch := 1; If NOT percussion_mode then to_ch := songdata.nm_tracks else to_ch := 18; end; For idx := from_ch to to_ch do begin filename_suffix := ''; If (idx <> 0) then If NOT (opl3_record_channel[idx]) or (is_4op_chan(idx) and NOT (idx in _4op_tracks_hi)) then CONTINUE else If NOT is_4op_chan(idx) then If percussion_mode then Case idx of 16: filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+'_BD)'; 17: filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+'_SD_HH)'; 18: filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+'_TT_TC)'; else filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+')'; end else filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+')' else filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+'_' +ExpStrL(Num2str(idx+1,10),2,'0')+'_4OP)'; If opl3_flushmode then Assign(wav_file,Copy(sdl_wav_directory,1,Length(sdl_wav_directory)-Length(NameOnly(sdl_wav_directory)))+ BaseNameOnly(sdl_wav_directory)+filename_suffix+'.wav') else Assign(wav_file,sdl_wav_directory+BaseNameOnly(songdata_title)+filename_suffix+'.wav'); // update WAV header {$i-} If renew_wav_files_flag then begin RewriteF(wav_file); wav_header.file_size := 0; wav_header.data_size := 0; end else ResetF(wav_file); {$i+} If renew_wav_files_flag or (IOresult <> 0) then begin {$i-} RewriteF(wav_file); {$i+} If (IOresult <> 0) then begin Close(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; wav_header.samples_sec := sdl_sample_rate; wav_header.bytes_sec := 2*sdl_sample_rate*16 DIV 8; wav_header.file_size := bytes_to_write; wav_header.data_size := bytes_to_write; {$i-} BlockWriteF(wav_file,wav_header,SizeOf(wav_header),temp); {$i+} If (IOresult <> 0) or (temp <> SizeOf(wav_header)) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; end else begin {$i-} BlockReadF(wav_file,wav_header,SizeOf(wav_header),temp); {$i+} If (IOresult <> 0) or (temp <> SizeOf(wav_header)) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; wav_header.file_size := wav_header.file_size+bytes_to_write; wav_header.data_size := wav_header.data_size+bytes_to_write; {$i-} ResetF_RW(wav_file); {$i+} If (IOresult <> 0) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; {$i-} BlockWriteF(wav_file,wav_header,SizeOf(wav_header),temp); {$i+} If (IOresult <> 0) or (temp <> SizeOf(wav_header)) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; {$i-} SeekF(wav_file,FileSize(wav_file)); {$i+} If (IOresult <> 0) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; end; // write sample data {$i-} BlockWriteF(wav_file,wav_buffer[idx],bytes_to_write,temp); {$i+} If (IOresult <> 0) or (temp <> bytes_to_write) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; end else CloseF(wav_file); end; renew_wav_files_flag := FALSE; end; procedure opl2out(reg,data: Word); begin // relevant only for DOS version -> option opl_latency=1 opl3out_proc(reg,data); end; procedure opl3out_proc(reg,data: Word); begin OPL3EMU_WriteReg(reg,data); end; procedure opl3exp(data: Word); begin OPL3EMU_WriteReg((data AND $ff) OR $100,data SHR 8); end; procedure opl3_init; begin OPL3EMU_init; end; procedure opl3_done; begin SDL_PauseAudio(1); end; // value in Hz for timer procedure snd_SetTimer(value: Longint); begin If (value < 18) then value := 18; sample_frame_size := ROUND(sdl_sample_rate/value*(1+sdl_timer_slowdown/100)); end; function get_num_files: Byte; var idx,result: Byte; begin result := 18; For idx := 1 to 18 do If NOT opl3_record_channel[idx] then Dec(result); If (result <> 0) then get_num_files := result else get_num_files := 1; end; procedure update_recorded_channels; var idx: Byte; begin For idx := 1 to 20 do If channel_flag[idx] then opl3_record_channel[idx] := TRUE else opl3_record_channel[idx] := FALSE; For idx := SUCC(songdata.nm_tracks) to 20 do opl3_record_channel[idx] := FALSE; If percussion_mode then begin If NOT channel_flag[19] then opl3_record_channel[18] := FALSE; If NOT channel_flag[20] then opl3_record_channel[17] := FALSE; end; end; procedure playcallback(var userdata; stream: pByte; len: Longint); cdecl; const counter_idx: Longint = 0; var counter: Longint; idx: Byte; IRQ_freq_val: Longint; buffer_ptr_table: array[1..18] of pDword; buf_size: Longint; begin If NOT rewind then IRQ_freq_val := IRQ_freq else IRQ_freq_val := IRQ_freq * 20; For counter := 0 to PRED(len DIV 4) do begin Inc(counter_idx); If (counter_idx >= sample_frame_size) then begin counter_idx := 0; If (ticklooper > 0) then If (fast_forward or rewind) and NOT replay_forbidden then poll_proc else else If NOT replay_forbidden then poll_proc; If (macro_ticklooper = 0) then macro_poll_proc; Inc(ticklooper); If (ticklooper >= IRQ_freq_val DIV tempo) then ticklooper := 0; Inc(macro_ticklooper); If (macro_ticklooper >= IRQ_freq_val DIV (tempo*macro_speedup)) then macro_ticklooper := 0; end; // update partial channel sample buffer pointers For idx := 1 to 18 do buffer_ptr_table[idx] := opl3_sample_buffer_chan_ptr[idx]+counter*4; // update one step OPL3EMU_PollProc(opl3_sample_buffer_ptr+counter*4,buffer_ptr_table); end; // update SDL Audio sample buffer Move(opl3_sample_buffer_ptr^,stream^,len); If (play_status = isStopped) then begin wav_buffer_len := 0; EXIT; end; // calculate cache buffer size If opl3_channel_recording_mode then buf_size := WAV_BUFFER_SIZE DIV 18 * get_num_files else buf_size := WAV_BUFFER_SIZE DIV 18; // WAV dumper If (sdl_opl3_emulator <> 0) then If (wav_buffer_len+len <= buf_size) then begin // update main sample buffer Move(opl3_sample_buffer_ptr^,wav_buffer[0][wav_buffer_len],len); // update partial channel sample buffers For idx := 1 to 18 do Move(opl3_sample_buffer_chan_ptr[idx]^,wav_buffer[idx][wav_buffer_len],len); Inc(wav_buffer_len,len); end else begin // sample buffers full -> flush to disk! flush_WAV_data; // update main sample buffer Move(opl3_sample_buffer_ptr^,wav_buffer[0][wav_buffer_len],len); // update partial channel sample buffers For idx := 1 to 18 do Move(opl3_sample_buffer_chan_ptr[idx]^,wav_buffer[idx][wav_buffer_len],len); Inc(wav_buffer_len,len); end; end; procedure snd_init; var idx: Byte; begin GetMem(opl3_sample_buffer_ptr,sdl_sample_buffer*4); For idx := 1 to 18 do GetMem(opl3_sample_buffer_chan_ptr[idx],sdl_sample_buffer*4); sample_frame_size := ROUND(sdl_sample_rate/50*(1+sdl_timer_slowdown/100));; opl3_init; sdl_audio_spec.freq := sdl_sample_rate; sdl_audio_spec.format := AUDIO_S16; sdl_audio_spec.channels := 2; sdl_audio_spec.samples := sdl_sample_buffer; @sdl_audio_spec.callback := @playcallback; sdl_audio_spec.userdata := NIL; If (SDL_Openaudio(@sdl_audio_spec,NIL) < 0) then begin WriteLn('SDL: Audio initialization error'); HALT(1); end; WriteLn(' Sample buffer size: ',sdl_audio_spec.samples,' samples (requested ',sdl_sample_buffer,')'); WriteLn(' Sampling rate: ',sdl_audio_spec.freq,' Hz (requested ',sdl_sample_rate,')'); sdl_sample_rate := sdl_audio_spec.freq; sdl_sample_buffer := sdl_audio_spec.samples; SDL_PauseAudio(0); end; procedure snd_done; var idx: Byte; begin SDL_PauseAudio(1); SDL_CloseAudio; FreeMem(opl3_sample_buffer_ptr); For idx := 1 to 18 do FreeMem(opl3_sample_buffer_chan_ptr[idx]); opl3_sample_buffer_ptr := NIL; end; {$ENDIF} {$IFDEF GO32V2} var old_exit_proc: procedure; procedure new_exit_proc; begin Lock_Data(___OPL3OUT_UNIT_DATA_START___,DWORD(Addr(___OPL3OUT_UNIT_DATA_END___))-DWORD(Addr(___OPL3OUT_UNIT_DATA_START___))); Lock_Code(@___OPL3OUT_IRQ_CODE_START___,DWORD(@___OPL3OUT_IRQ_CODE_END___)-DWORD(@___OPL3OUT_IRQ_CODE_START___)); ExitProc := @old_exit_proc; end; begin FillWord(_opl_regs_cache,SizeOf(_opl_regs_cache) DIV SizeOf(WORD),NOT 0); Lock_Data(___OPL3OUT_UNIT_DATA_START___,DWORD(Addr(___OPL3OUT_UNIT_DATA_END___))-DWORD(Addr(___OPL3OUT_UNIT_DATA_START___))); Lock_Code(@___OPL3OUT_IRQ_CODE_START___,DWORD(@___OPL3OUT_IRQ_CODE_END___)-DWORD(@___OPL3OUT_IRQ_CODE_START___)); @old_exit_proc := ExitProc; ExitProc := @new_exit_proc; {$ENDIF} end. adlibtracker2-2.4.23/adt2play/0000755000000000000000000000000013176573533014546 5ustar rootrootadlibtracker2-2.4.23/adt2play/m.bat0000644000000000000000000000230113176573533015466 0ustar rootroot@echo off echo. echo ************************************ echo ** ** echo ** STEP 1/2 ** echo ** Compiling sources ** echo ** ** echo ************************************ ..\utils\val2 ..\iloaders.inc iloaders.inc if not exist *.exe goto :no_exe_file del *.exe >nul :no_exe_file if not exist *.ppu goto :no_ppu_file del *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del *.o >nul :no_o_file if not exist !log goto :no_log_file del !log >nul :no_log_file ppc386 -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Tgo32v2 adt2play >!log if not exist adt2play.exe goto :compile_error if not exist *.ppu goto :no_ppu_file del *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del *.o >nul :no_o_file if not exist !log goto :no_log_file del !log >nul :no_log_file echo. echo ************************************ echo ** ** echo ** STEP 2/2 ** echo ** UPX: Compressing executable ** echo ** ** echo ************************************ c:\utils\upx -9 adt2play.exe >nul echo. :compile_error adlibtracker2-2.4.23/adt2play/parserio.pas0000644000000000000000000000653013176573533017103 0ustar rootrootunit ParserIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface function SensitiveScan(var buf; skip,size: Longint; str: String): Longint; function Update16(var buf; size: Longint; crc: Word): Word; function Update32(var buf; size: Longint; crc: Longint): Longint; implementation function SensitiveScan(var buf; skip,size: Longint; str: String): Longint; var result: Longint; begin asm mov edi,[buf] add edi,skip lea esi,[str] mov ecx,size sub ecx,skip xor eax,eax jecxz @@3 cld lodsb cmp al,1 jb @@5 ja @@1 lodsb repne scasb jne @@3 jmp @@5 @@1: xor ah,ah mov ebx,eax dec ebx mov edx,ecx sub edx,eax jb @@3 lodsb add edx,2 @@2: dec edx mov ecx,edx repne scasb jne @@3 mov edx,ecx mov ecx,ebx rep cmpsb je @@4 sub ecx,ebx add esi,ecx add edi,ecx inc edi or edx,edx jne @@2 @@3: xor eax,eax jmp @@6 @@4: sub edi,ebx @@5: mov eax,edi sub eax,dword ptr [buf] @@6: dec eax mov result,eax end; SensitiveScan := result; end; var CRC16_table: array[BYTE] of Word; CRC32_table: array[BYTE] of Longint; function Update16(var buf; size: Longint; crc: Word): Word; var result: Word; begin asm mov esi,[buf] lea edi,[CRC16_table] mov bx,crc mov ecx,size jecxz @@2 @@1: xor ax,ax lodsb mov dl,bh xor dh,dh xor bh,bh xor bx,ax and ebx,000000ffh shl ebx,1 mov bx,[edi+ebx] xor bx,dx loop @@1 @@2: mov ax,bx mov result,ax end; Update16 := result; end; function Update32(var buf; size: Longint; crc: Longint): Longint; var result: Longint; begin asm mov esi,[buf] lea edi,[CRC32_table] mov ebx,crc mov ecx,size jecxz @@2 @@1: xor eax,eax lodsb xor ebx,eax mov edx,ebx and ebx,000000ffh shl ebx,2 mov ebx,[edi+ebx] shr edx,8 and edx,00ffffffh xor ebx,edx loop @@1 @@2: mov eax,ebx mov result,eax end; Update32 := result; end; procedure make_table_16bit; var crc: Word; n,index: Byte; begin For index := 0 to 255 do begin crc := index; For n := 1 to 8 do If Odd(crc) then crc := crc SHR 1 XOR $0a001 else crc := crc SHR 1; CRC16_table[index] := crc; end; end; procedure make_table_32bit; var crc: Dword; n,index: Byte; begin For index := 0 to 255 do begin crc := index; For n := 1 to 8 do If Odd(crc) then crc := crc SHR 1 XOR $0edb88320 else crc := crc SHR 1; CRC32_table[index] := crc; end; end; begin make_table_16bit; make_table_32bit; end. adlibtracker2-2.4.23/adt2play/a2scrio.pas0000644000000000000000000003457013176573533016626 0ustar rootrootunit A2scrIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const _title_xpos = 10; _title_ypos = 8; _title_color = 160; _title_offset = 320*40; _timer_xpos = 198; _timer_ypos = 5; _timer_color = 1; _place_holder_color = 150; _progress_xpos = 8; _progress_ypos = 155; _progress_color = 251; _fname_xpos = 8; _fname_ypos = 170; _fname_color = 255; _pos_str_xpos = 8; _pos_str_ypos = 186; _pos_str_color = 252; const _decay_bars_initialized: Boolean = FALSE; _decay_bar_xpos = 10; _decay_bar_ypos = 140; _decay_bar_palette_start = 250; _picture_mode: Boolean = FALSE; _window_top: Byte = 8; var correction: Integer; entries, entries2: Byte; delay_counter: Byte; procedure refresh_decay_bar(xpos: Word; level: Byte); procedure decay_bars_refresh; procedure wtext(xstart,ystart: Word; txt: String; color: Byte); procedure wtext2(xstart,ystart: Word; txt: String; color: Byte); procedure C3Write(str: String; atr1,atr2,atr3: Byte); procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte); procedure CWriteLn(str: String; atr1,atr2: Byte); function _progress_str: String; function _timer_str: String; function _position_str: String; function _position_str2: String; procedure toggle_picture_mode; procedure fade_out; implementation uses GO32, A2data,A2player,A2fileIO, StringIO,TxtScrIO; const _ptr_font8x8: Pointer = @font8x8; _ptr_font8x16: Pointer = @font8x16; _ptr_picture_palette: Pointer = @picture_palette; _ptr_picture_bitmap: Pointer = @picture_bitmap; const decay_bar_rise: Real = 50.0; decay_bar_fall: Real = 5.00; var old_decay_bar_value: array[1..25] of Byte; vmem_320x200: array[0..PRED(320*200)] of Byte; vmem_320x200_mirror: array[0..PRED(320*200)] of Byte; fade_buf,fade_buf2: tFADE_BUF; procedure refresh_decay_bar(xpos: Word; level: Byte); var _data_ofs: Dword; begin _data_ofs := DWORD(Addr(vmem_320x200)); asm mov edi,_data_ofs mov edx,[_ptr_picture_palette] mov esi,[_ptr_picture_bitmap] mov eax,_decay_bar_ypos mov ebx,320 mul ebx movzx ebx,xpos add eax,ebx add edi,eax cmp level,BYTE_NULL jnz @@1 mov level,0 jmp @@2 @@1: cmp level,2 jae @@2 mov level,2 @@2: mov ecx,10 jecxz @@10 @@3: push ecx push edi mov ecx,63*4/3 jecxz @@9 @@4: mov ebx,63*4/3 sub ebx,ecx movzx eax,level cmp ebx,eax jnae @@5 mov ebx,edi sub ebx,_data_ofs add ebx,esi movzx eax,byte ptr [ebx] jmp @@8 @@5: mov eax,63*4/3 push edx xor edx,edx sub eax,ecx mov ebx,5 div ebx mov eax,edx pop edx cmp eax,3 jbe @@6 mov ebx,edi sub ebx,_data_ofs add ebx,esi movzx eax,byte ptr [ebx] jmp @@8 @@6: or eax,eax jnz @@7 xor eax,eax jmp @@8 @@7: add eax,_decay_bar_palette_start cmp level,2 jnbe @@8 mov eax,_place_holder_color @@8: mov byte ptr [edi],al sub edi,320 loop @@4 @@9: pop edi pop ecx inc edi loop @@3 @@10: end; end; procedure decay_bars_refresh; var temp: Byte; begin _debug_str_:= 'A2SCRIO.PAS:decay_bars_refresh'; If NOT _picture_mode then EXIT; dosmemget($0a000,_title_offset,vmem_320x200[_title_offset], 320*_decay_bar_ypos-_title_offset); If NOT _decay_bars_initialized then begin _decay_bars_initialized := TRUE; For temp := 1 to 25 do old_decay_bar_value[temp] := BYTE_NULL; For temp := 1 to 25 do begin decay_bar[temp].lvl := 0; decay_bar[temp].dir := -1; refresh_decay_bar(_decay_bar_xpos+PRED(temp)*12,0); end; end; For temp := 1 to 25 do begin If (decay_bar[temp].dir = 1) then decay_bar[temp].lvl := decay_bar[temp].lvl+ decay_bar[temp].dir*(decay_bar_rise/IRQ_freq*100) else decay_bar[temp].lvl := decay_bar[temp].lvl+ decay_bar[temp].dir*(decay_bar_fall/IRQ_freq*100); If (decay_bar[temp].lvl < 0) then decay_bar[temp].lvl := 0; If (decay_bar[temp].lvl > decay_bar[temp].max_lvl) then begin decay_bar[temp].dir := -1; If (decay_bar[temp].lvl > 63) then decay_bar[temp].lvl := 63; end; If (old_decay_bar_value[temp] <> ROUND(decay_bar[temp].lvl*4/3)) then begin refresh_decay_bar(_decay_bar_xpos+PRED(temp)*12, ROUND(decay_bar[temp].lvl*4/3)); old_decay_bar_value[temp] := ROUND(decay_bar[temp].lvl*4/3); end; end; dosmemput($0a000,_title_offset,vmem_320x200[_title_offset], 320*_decay_bar_ypos-_title_offset); end; procedure wtext(xstart,ystart: Word; txt: String; color: Byte); var x,y: Word; temp,i,j,b: Word; begin _debug_str_:= 'A2SCRIO.PAS:wtext'; If NOT _picture_mode then EXIT; dosmemget($0a000,320*ystart,vmem_320x200[320*ystart],(8+1)*320); Move(pGENERIC_IO_BUFFER(_ptr_picture_bitmap)^[320*ystart], vmem_320x200_mirror[320*ystart],(8+1)*320); x := xstart+1; y := ystart+1; For temp := 1 to Length(txt) do begin For j := 0 to 7 do begin b := tCHAR8x8(_ptr_font8x8^)[txt[temp]][j]; For i := 7 downto 0 do If (b OR (1 SHL i) = b) then vmem_320x200_mirror[x+7-i+(y+j)*320] := 0 end; Inc(x,8); end; x := xstart; y := ystart; For temp := 1 to Length(txt) do begin For j := 0 to 7 do begin b := tCHAR8x8(_ptr_font8x8^)[txt[temp]][j]; For i := 7 downto 0 do If (b OR (1 SHL i) = b) then vmem_320x200[x+7-i+(y+j)*320] := color else vmem_320x200[x+7-i+(y+j)*320] := vmem_320x200_mirror[x+7-i+(y+j)*320]; end; Inc(x,8); end; dosmemput($0a000,320*ystart,vmem_320x200[320*ystart],(8+1)*320); end; procedure wtext2(xstart,ystart: Word; txt: String; color: Byte); const _double: array[0..15] of Byte = (0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7); var x,y: Word; temp,i,j,b: Word; begin _debug_str_:= 'A2SCRIO.PAS:wtext2'; If NOT _picture_mode then EXIT; dosmemget($0a000,320*ystart,vmem_320x200[320*ystart],(16+1)*320); Move(pGENERIC_IO_BUFFER(_ptr_picture_bitmap)^[320*ystart], vmem_320x200_mirror[320*ystart],(16+1)*320); x := xstart+1; y := ystart+1; For temp := 1 to Length(txt) do begin For j := 0 to 15 do begin b := tCHAR8x16(_ptr_font8x16^)[txt[temp]][j]; For i := 15 downto 0 do If (b OR (1 SHL _double[i]) = b) then vmem_320x200_mirror[x+15-i+(y+j)*320] := 0 end; Inc(x,16); end; x := xstart; y := ystart; For temp := 1 to Length(txt) do begin For j := 0 to 15 do begin b := tCHAR8x16(_ptr_font8x16^)[txt[temp]][j]; For i := 15 downto 0 do If (b OR (1 SHL _double[i]) = b) then vmem_320x200[x+15-i+(y+j)*320] := color else vmem_320x200[x+15-i+(y+j)*320] := vmem_320x200_mirror[x+15-i+(y+j)*320]; end; Inc(x,16); end; dosmemput($0a000,320*ystart,vmem_320x200[320*ystart],(16+1)*320); end; procedure C3Write(str: String; atr1,atr2,atr3: Byte); begin _debug_str_:= 'A2SCRIO.PAS:CWrite'; If _picture_mode then EXIT; dosmemget($0b800,0,screen_ptr^,MAX_SCREEN_MEM_SIZE); ShowC3Str(screen_ptr^,WhereX,WhereY,str,atr1,atr2,atr3); dosmemput($0b800,0,screen_ptr^,MAX_SCREEN_MEM_SIZE); GotoXY(1,WhereY); end; procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte); begin _debug_str_:= 'A2SCRIO.PAS:C3WriteLn'; If _picture_mode then EXIT; ShowC3Str(screen_ptr^,WhereX,WhereY,str, atr1,atr2,atr3); WriteLn; end; procedure CWriteLn(str: String; atr1,atr2: Byte); var temp: Word; attr,posx,posy: Byte; color2: Boolean; begin _debug_str_:= 'A2SCRIO.PAS:CWriteLn'; If _picture_mode then EXIT; color2 := FALSE; attr := atr1; posx := WhereX; posy := WhereY; For temp := 1 to Length(str) do If (str[temp] <> '~') then begin dosmemput($0b800,(posx-1+(posy-1)*MaxCol) SHL 1,BYTE(str[temp]),1); dosmemput($0b800,(posx-1+(posy-1)*MaxCol) SHL 1+1,attr,1); If (posx < MaxCol) then Inc(posx) else begin posx := 1; Inc(posy); If (posy > MaxLn) then begin asm mov ah,06h mov al,1 mov bh,07h mov ch,_window_top mov cl,1 mov dh,MaxLn mov dl,MaxCol dec ch dec cl dec dh dec dl int 10h end; Dec(posy); end; end; end else begin color2 := NOT color2; If color2 then attr := atr2 else attr := atr1; end; Inc(posy); If (posy > MaxLn) then begin asm mov ah,06h mov al,1 mov bh,07h mov ch,_window_top mov cl,1 mov dh,MaxLn mov dl,MaxCol dec ch dec cl dec dh dec dl int 10h end; Dec(posy); end; posx := 1; GotoXY(posx,posy); end; function __progress_str(value: Byte): String; var result: String; begin result := ''; Repeat If (value > 4) then begin result := result+#4; Dec(value,4); end; If (value <= 4) and (value <> 0) then result := result+CHR(0+value) until (value <= 4); __progress_str := result; end; function _progress_str: String; begin If (songdata.patt_len = 0) then EXIT; If (entries <> 0) then _progress_str := ExpStrR(__progress_str( ROUND(4*38/entries*(current_order-correction+ 1/songdata.patt_len*(current_line+1)))),38,#0) else _progress_str := ExpStrR('',38,#0); end; function _timer_str: String; begin _timer_str := ExpStrL(Num2str(song_timer DIV 60,10),2,'0')+':'+ ExpStrL(Num2str(song_timer MOD 60,10),2,'0')+'.'+ Num2str(song_timer_tenths DIV 10,10); end; function _position_str: String; begin If (songdata.patt_len = 0) then EXIT; If (entries <> 0) then _position_str := 'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+ ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+ 'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+ 'row '+ExpStrL(Num2str(current_line,10),3,'0')+' '+ '['+ExpStrL(Num2str(ROUND(100/entries*(current_order-correction+ 1/songdata.patt_len*(current_line+1))),10),3,'0')+'%] '+ '['+_timer_str+']'+' ' else _position_str := 'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+ ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+ 'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+ 'row '+ExpStrL(Num2str(current_line,10),3,'0')+' '+ '['+ExpStrL('',3,'0')+'%] '+ '['+_timer_str+']'+' '; end; function _position_str2: String; begin _position_str2 := 'Order '+ExpStrL(Num2str(current_order,10),3,'0')+'/'+ ExpStrL(Num2str(PRED(entries2),10),3,'0')+', '+ 'pattern '+ExpStrL(Num2str(current_pattern,10),3,'0')+', '+ 'row '+ExpStrL(Num2str(current_line,10),3,'0')+' '; end; procedure toggle_picture_mode; var index: Byte; begin _debug_str_:= 'A2SCRIO.PAS:toggle_picture_mode'; If NOT _picture_mode then begin fade_speed := 16; fade_buf.action := first; VgaFade(fade_buf,fadeOut,delayed); For index := 1 to 20 do WaitRetrace; asm mov ax,13h; int 10h end; For index := 1 to 20 do WaitRetrace; For index := 0 to 255 do SetRGBitem(index,tRGB_PALETTE(_ptr_picture_palette^)[index].r, tRGB_PALETTE(_ptr_picture_palette^)[index].g, tRGB_PALETTE(_ptr_picture_palette^)[index].b); fade_speed := 16; fade_buf.action := first; VgaFade(fade_buf2,fadeOut,fast); dosmemput($0a000,0,_ptr_picture_bitmap^,320*200); _picture_mode := NOT _picture_mode; wtext(_title_xpos,_title_ypos,'/´T2 PLAYER',_title_color); VgaFade(fade_buf2,fadeIn,delayed); end else begin _picture_mode := NOT _picture_mode; VgaFade(fade_buf2,fadeOut,delayed); asm mov ax,03h xor bh,bh int 10h end; end; end; procedure fade_out; var temp: Byte; begin _debug_str_:= 'A2SCRIO.PAS:fade_out'; For temp := overall_volume downto 0 do begin set_overall_volume(temp); delay_counter := 0; While (delay_counter < overall_volume DIV 20) do begin If timer_200hz_flag then begin timer_200hz_flag := FALSE; Inc(delay_counter); C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0); wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color); If timer_50hz_flag then begin timer_50hz_flag := FALSE; decay_bars_refresh; end; end; MEMW[0:$041c] := MEMW[0:$041a]; end; end; end; end. adlibtracker2-2.4.23/adt2play/iss_tim.pas0000644000000000000000000002106013176573533016721 0ustar rootroot { þ Inquisition's Timer Services Unit þ } { þ This file is part of the Inquisition Sound Server for the Free þ } { þ Pascal Compiler (http://www.freepascal.org) but also can be þ } { þ be distributed separately. The source code is FREE FOR ANY NON þ } { þ COMMERCIAL USAGE. þ } { þ You can modify this file, but you musn't distribute the þ } { þ modified file, only the original version. Instead, send your þ } { þ modification to us, so we can add it to the official version. þ } { þ Please note, that we can't quarantee the compatibility with þ } { þ previous versions. þ } { þ If we'll stop the development of this unit in the future, þ } { þ the source code will be freely available for any use. þ } { þ You can always download the newest version from our website, þ } { þ http://scenergy.dfmk.hu/inqcoders/ þ } { þ About Inquisition itself, see þ } { þ http://scenergy.dfmk.hu/inquisition/ þ } { þ Comments, notes, suggestions, bug reports are welcome. þ } { þ Send your mails to charlie@scenergy.dfmk.hu þ } { þ Please prefer hungarian or english languages. þ } { þ ISS_TIM - Timer Unit (GO32V2 Only!) þ } { þ Coding Starts : 10. October. 1998. þ } { þ Last Modification : 01. March. 2001. þ } { þ Note: req. FPC version 1.0.0+ for GO32V2 to compile þ } {$ASMMODE INTEL} {$MODE FPC} Unit ISS_Tim; Interface Uses GO32; Const ISS_TimerSpeed : DWord = 1193180; ISS_MaxTimers = $8; { þ Maximum Number of Timers þ } TimerIRQ = $8; { þ HW IRQ Number þ } ISS_TENoFree = $01; { þ Can't add new timer. All timers locked. þ } ISS_TENotFound = $02; { þ Can't find specified Timer, to stop. þ } Type TTimerStruc = Record TSpeed : DWord; TCount : DWord; { þ Tick Counter þ } TPrevCount : DWord; { þ Tick Counter state at prev. activity þ } TProc : Pointer; { þ Procedure To Call Offset þ } TActive : Boolean; { þ 1 If The Timer Is On þ } End; Var ISS_TimersData : Array[1..ISS_MaxTimers] Of TTimerStruc; ISS_TimerError : DWord; { þ Contains the last timer error code. þ } Function ISS_StartTimer(Var NewTProc : Pointer; NewTSpeed : DWord) : Boolean; Function ISS_StopTimer(Var TimerProc : Pointer) : Boolean; Function ISS_GetTimerNumber(TimerProc : Pointer) : DWord; Implementation Var TimerSpeed : DWord; OldTimer : TSegInfo; OldTimerCnt : DWord; NewIRQActive : Boolean; NewTimerHandler : TSegInfo; BackupDS : Word; External Name '___v2prt0_ds_alias'; Procedure UpdateUserTimers; Type Proc = Procedure; Var Counter : Word; Begin For Counter:=1 To ISS_MaxTimers Do Begin With ISS_TimersData[Counter] Do Begin If TActive Then Begin Inc(TCount,TimerSpeed); If (TCount>TSpeed) Then Begin Dec(TCount,TSpeed); TPrevCount:=TCount; Proc(TProc); { þ Calling the specified routine þ } End; End; End; End; End; Procedure UpdateUserTimers_Dummy; Begin End; Procedure SysTimerIRQ; Assembler; Asm CLI PUSH DS PUSH ES PUSH FS PUSH GS PUSHAD MOV AX,CS:[BackupDS] MOV DS,AX MOV ES,AX MOV AX,DosMemSelector MOV FS,AX CALL UpdateUserTimers MOV EAX,TimerSpeed ADD OldTimerCnt,EAX CMP OldTimerCnt,$10000 JB @NotUpdateClock SUB OldTimerCnt,$10000 INC WORD PTR FS:[1132] JNZ @Timer_2 INC WORD PTR FS:[1134] @Timer_2: MOV AX,$018 CMP FS:[1134],AX JNZ @Timer_3 MOV AX,$0B0 CMP FS:[1132],AX JNZ @Timer_3 MOV WORD PTR FS:[1134],$0 MOV WORD PTR FS:[1132],$0 MOV BYTE PTR FS:[1136],$1 @Timer_3: @NotUpdateClock: MOV DX,$20 { þ Interrupt request acknowledge þ } MOV AL,$20 OUT DX,AL POPAD POP GS POP FS POP ES POP DS IRET End; Procedure SysTimerIRQ_Dummy; Begin End; Procedure SetTimerSpeed(NewTimerSpeed : DWord); Begin If NewTimerSpeed<>TimerSpeed Then Begin Asm PUSH EAX CLI MOV AL,00110110B OUT 43H,AL MOV EAX,NEWTIMERSPEED OUT 40H,AL MOV AL,AH OUT 40H,AL STI POP EAX End; TimerSpeed:=NewTimerSpeed; End; End; Function GetTimerSpeed : DWord; Var Counter : DWord; TFastest : DWord; Begin TFastest:=$10000; For Counter:=1 To ISS_MaxTimers Do Begin If ISS_TimersData[Counter].TActive And (ISS_TimersData[Counter].TSpeed < TFastest) Then TFastest:=ISS_TimersData[Counter].TSpeed; End; GetTimerSpeed:=TFastest; End; Function ISS_StartTimer(Var NewTProc : Pointer; NewTSpeed : DWord) : Boolean; Var Counter : Word; TNumber : Word; Begin Counter:=0; TNumber:=0; Repeat Inc(Counter); If Not ISS_TimersData[Counter].TActive Then TNumber:=Counter; Until (TNumber<>0) Or (Counter=ISS_MaxTimers); If TNumber=0 Then Begin ISS_TimerError:=ISS_TENoFree; ISS_StartTimer:=False; Exit; End; If Not NewIRQActive Then Begin Lock_Data(ISS_TimersData,SizeOf(ISS_TimersData)); Lock_Data(DosMemSelector,SizeOf(DosMemSelector)); Lock_Code(@SysTimerIRQ,DWord(@SysTimerIRQ_Dummy)-DWord(@SysTimerIRQ)); Lock_Code(@UpdateUserTimers,DWord(@UpdateUserTimers_Dummy)-DWord(@UpdateUserTimers)); NewTimerHandler.Offset:=@SysTimerIRQ; NewTimerHandler.Segment:=Get_CS; Get_PM_Interrupt(TimerIRQ,OldTimer); Set_PM_Interrupt(TimerIRQ,NewTimerHandler); End; ISS_TimersData[TNumber].TSpeed:=NewTSpeed; ISS_TimersData[TNumber].TCount:=0; ISS_TimersData[TNumber].TProc:=NewTProc; ISS_TimersData[TNumber].TActive:=True; SetTimerSpeed(GetTimerSpeed); ISS_StartTimer:=True; End; Function ISS_StopTimer(Var TimerProc : Pointer) : Boolean; Var TNumber : Word; Counter : Word; LastTimer : Boolean; Begin Disable; TNumber:=0; For Counter:=1 To ISS_MaxTimers Do Begin With ISS_TimersData[Counter] Do Begin If TActive And (TProc=TimerProc) Then TNumber:=Counter; End; End; If TNumber=0 Then Begin ISS_TimerError:=ISS_TENotFound; ISS_StopTimer:=False; Enable; End Else Begin ISS_TimersData[TNumber].TActive:=False; LastTimer:=True; For Counter:=1 To ISS_MaxTimers Do Begin If ISS_TimersData[Counter].TActive=True Then LastTimer:=False; End; If LastTimer Then Begin TimerSpeed:=0; SetTimerSpeed($10000); Set_PM_Interrupt(TimerIRQ,OldTimer); Unlock_Data(DosMemSelector,SizeOf(DosMemSelector)); Unlock_Data(ISS_TimersData,SizeOf(ISS_TimersData)); UnLock_Code(@SysTimerIRQ,DWord(@SysTimerIRQ_Dummy)-DWord(@SysTimerIRQ)); UnLock_Code(@UpdateUserTimers,DWord(@UpdateUserTimers_Dummy)-DWord(@UpdateUserTimers)); End; ISS_StopTimer:=True; Enable; End; End; Function ISS_GetTimerNumber(TimerProc : Pointer) : DWord; Var Counter : DWord; Begin For Counter:=1 To ISS_MaxTimers Do Begin With ISS_TimersData[Counter] Do Begin If TActive And (TProc=TimerProc) Then Begin ISS_GetTimerNumber:=Counter; Exit; End; End; End; End; Begin FillChar(ISS_TimersData,SizeOf(ISS_TimersData),#0); NewIRQActive:=False; TimerSpeed:=0; End. { þ ISS_TIM.PAS - (C) 1998-2001 Charlie/Inquisition þ } { þ Changelog : þ } { þ 1.1.1 - Some code cleanup for less compiler hacking... þ } { þ - Webpage and email addresses fixed in the header comment. þ } { þ [01.march.2001] þ } { þ 1.1.0 - Major update, a new IRQ routine which contains less compiler þ } { þ hacking. Based on the docs of FPC 1.0.2. Not tested with þ } { þ versions below 1.0.0. GNU AS no longer required to compile. þ } { þ [03.december.2000] þ } { þ 1.0.2 - Header comment fixed. þ } { þ [18.apr.2000] þ } { þ 1.0.1 - Removed a limitation which made smartlinking impossible. þ } { þ (Reported by Surgi/Terror Opera) þ } { þ [13.apr.2000] þ } { þ 1.0.0 - First Public Version þ } { þ [08.jan.2000] þ } adlibtracker2-2.4.23/adt2play/typconst.inc0000644000000000000000000002751613176573533017137 0ustar rootrootconst NULL = $0ffffffff; BYTE_NULL = BYTE(NULL); WORD_NULL = WORD(NULL); DWORD_NULL = LONGINT(NULL); const FFVER_A2M = 13; FFVER_A2T = 13; FFVER_A2I = 10; FFVER_A2F = 2; FFVER_A2P = 11; FFVER_A2B = 10; FFVER_A2W = 3; type tFM_INST_DATA = Record AM_VIB_EG_modulator, AM_VIB_EG_carrier, KSL_VOLUM_modulator, KSL_VOLUM_carrier, ATTCK_DEC_modulator, ATTCK_DEC_carrier, SUSTN_REL_modulator, SUSTN_REL_carrier, WAVEFORM_modulator, WAVEFORM_carrier, FEEDBACK_FM: Byte; end; type tADTRACK2_INS = Record fm_data: tFM_INST_DATA; panning: Byte; fine_tune: Shortint; perc_voice: Byte; end; type tOLD_ADTRACK2_INS = Record fm_data: tFM_INST_DATA; panning: Byte; fine_tune: Shortint; end; type tARPEGGIO_TABLE = Record length, speed, loop_begin, loop_length, keyoff_pos: Byte; data: array[1..255] of Byte; end; type tVIBRATO_TABLE = Record length, speed, delay, loop_begin, loop_length, keyoff_pos: Byte; data: array[1..255] of Shortint; end; type tREGISTER_TABLE_DEF = Record fm_data: tFM_INST_DATA; freq_slide: Smallint; panning: Byte; duration: Byte; end; type tREGISTER_TABLE = Record length, loop_begin, loop_length, keyoff_pos, arpeggio_table, vibrato_table: Byte; data: array[1..255] of tREGISTER_TABLE_DEF; end; type tMACRO_TABLE = Record arpeggio: tARPEGGIO_TABLE; vibrato: tVIBRATO_TABLE; end; type tARP_VIB_MACRO_TABLE = array[1..255] of tMACRO_TABLE; type tFM_PARAMETER_TABLE = Record adsrw_car, adsrw_mod: Record attck,dec,sustn,rel, wform: Byte; end; connect, feedb, multipM,kslM,tremM,vibrM,ksrM,sustM, multipC,kslC,tremC,vibrC,ksrC,sustC: Byte; end; type tDIS_FMREG_COL = array[0..27] of Boolean; type tINS_4OP_FLAGS = Record num_4op: Byte; idx_4op: array[1..128] of Byte; end; type pOLD_FIXED_SONGDATA = ^tOLD_FIXED_SONGDATA; tOLD_FIXED_SONGDATA = Record songname: String[42]; composer: String[42]; instr_names: array[1..250] of String[32]; instr_data: array[1..250] of tOLD_ADTRACK2_INS; pattern_order: array[0..$7f] of Byte; tempo: Byte; speed: Byte; common_flag: Byte; end; const MB_SIGNATURE = 'MB_1'; // Message Board v1.0 MB_HSIZE = 50; // 50x20 chr MB_VSIZE = 20; type pMESSAGE_BOARD_DATA = ^tMESSAGE_BOARD_DATA; tMESSAGE_BOARD_DATA = Record signature: array[0..3] of Char; data: array[1..MB_VSIZE] of String[MB_HSIZE]; end; type pFIXED_SONGDATA = ^tFIXED_SONGDATA; tFIXED_SONGDATA = Record songname: String[42]; composer: String[42]; instr_names: array[1..255] of String[42]; instr_data: array[1..255] of tADTRACK2_INS; instr_macros: array[1..255] of tREGISTER_TABLE; macro_table: tARP_VIB_MACRO_TABLE; pattern_order: array[0..$7f] of Byte; tempo: Byte; speed: Byte; common_flag: Byte; patt_len: Word; nm_tracks: Byte; macro_speedup: Word; flag_4op: Byte; lock_flags: array[1..20] of Byte; pattern_names: array[0..$7f] of String[42]; dis_fmreg_col: array[1..255] of tDIS_FMREG_COL; ins_4op_flags: tINS_4OP_FLAGS; reserved_data: array[0..PRED(1024)] of Byte; end; type tOLD_CHUNK = Record note: Byte; instr_def: Byte; effect_def: Byte; effect: Byte; end; type tCHUNK = Record note: Byte; instr_def: Byte; effect_def: Byte; effect: Byte; effect_def2: Byte; effect2: Byte; end; type tOLD_VARIABLE_DATA1 = array[0..$0f] of array[0..$3f] of array[1..9] of tOLD_CHUNK; type tOLD_VARIABLE_DATA2 = array[0..7] of array[1..18] of array[0..$3f] of tOLD_CHUNK; type tVARIABLE_DATA = array[0..7] of array[1..20] of array[0..$0ff] of tCHUNK; type tPATTERN_DATA = array[0..15] of tVARIABLE_DATA; type tPLAY_STATUS = (isPlaying,isPaused,isStopped); type tByteSet = Set of Byte; const INSTRUMENT_SIZE = SizeOf(tADTRACK2_INS); CHUNK_SIZE = SizeOf(tCHUNK); PATTERN_SIZE = 20*256*CHUNK_SIZE; type tCHAR8x8 = array[char] of array[0..7] of Byte; tCHAR8x16 = array[char] of array[0..15] of Byte; type tRGB = Record r,g,b: Byte end; tRGB_PALETTE = array[0..255] of tRGB; const ef_Arpeggio = 0; ef_FSlideUp = 1; ef_FSlideDown = 2; ef_TonePortamento = 3; ef_Vibrato = 4; ef_TPortamVolSlide = 5; ef_VibratoVolSlide = 6; ef_FSlideUpFine = 7; ef_FSlideDownFine = 8; ef_SetModulatorVol = 9; ef_VolSlide = 10; ef_PositionJump = 11; ef_SetInsVolume = 12; ef_PatternBreak = 13; ef_SetTempo = 14; ef_SetSpeed = 15; ef_TPortamVSlideFine = 16; ef_VibratoVSlideFine = 17; ef_SetCarrierVol = 18; ef_SetWaveform = 19; ef_VolSlideFine = 20; ef_RetrigNote = 21; ef_Tremolo = 22; ef_Tremor = 23; ef_ArpggVSlide = 24; ef_ArpggVSlideFine = 25; ef_MultiRetrigNote = 26; ef_FSlideUpVSlide = 27; ef_FSlideDownVSlide = 28; ef_FSlUpFineVSlide = 29; ef_FSlDownFineVSlide = 30; ef_FSlUpVSlF = 31; ef_FSlDownVSlF = 32; ef_FSlUpFineVSlF = 33; ef_FSlDownFineVSlF = 34; ef_Extended = 35; ef_Extended2 = 36; ef_SetGlobalVolume = 37; ef_SwapArpeggio = 38; ef_SwapVibrato = 39; ef_ForceInsVolume = 40; ef_Extended3 = 41; ef_ExtraFineArpeggio = 42; ef_ExtraFineVibrato = 43; ef_ExtraFineTremolo = 44; ef_SetCustomSpeedTab = 45; ef_GlobalFSlideUp = 46; ef_GlobalFSlideDown = 47; ef_ex_SetTremDepth = 0; ef_ex_SetVibDepth = 1; ef_ex_SetAttckRateM = 2; ef_ex_SetDecayRateM = 3; ef_ex_SetSustnLevelM = 4; ef_ex_SetRelRateM = 5; ef_ex_SetAttckRateC = 6; ef_ex_SetDecayRateC = 7; ef_ex_SetSustnLevelC = 8; ef_ex_SetRelRateC = 9; ef_ex_SetFeedback = 10; ef_ex_SetPanningPos = 11; ef_ex_PatternLoop = 12; ef_ex_PatternLoopRec = 13; ef_ex_ExtendedCmd = 14; ef_ex_cmd_MKOffLoopDi = 0; ef_ex_cmd_MKOffLoopEn = 1; ef_ex_cmd_TPortaFKdis = 2; ef_ex_cmd_TPortaFKenb = 3; ef_ex_cmd_RestartEnv = 4; ef_ex_cmd_4opVlockOff = 5; ef_ex_cmd_4opVlockOn = 6; ef_ex_ExtendedCmd2 = 15; ef_ex_cmd2_RSS = 0; ef_ex_cmd2_ResetVol = 1; ef_ex_cmd2_LockVol = 2; ef_ex_cmd2_UnlockVol = 3; ef_ex_cmd2_LockVP = 4; ef_ex_cmd2_UnlockVP = 5; ef_ex_cmd2_VSlide_mod = 6; ef_ex_cmd2_VSlide_car = 7; ef_ex_cmd2_VSlide_def = 8; ef_ex_cmd2_LockPan = 9; ef_ex_cmd2_UnlockPan = 10; ef_ex_cmd2_VibrOff = 11; ef_ex_cmd2_TremOff = 12; ef_ex_cmd2_FVib_FGFS = 13; ef_ex_cmd2_FTrm_XFGFS = 14; ef_ex_cmd2_NoRestart = 15; ef_ex2_PatDelayFrame = 0; ef_ex2_PatDelayRow = 1; ef_ex2_NoteDelay = 2; ef_ex2_NoteCut = 3; ef_ex2_FineTuneUp = 4; ef_ex2_FineTuneDown = 5; ef_ex2_GlVolSlideUp = 6; ef_ex2_GlVolSlideDn = 7; ef_ex2_GlVolSlideUpF = 8; ef_ex2_GlVolSlideDnF = 9; ef_ex2_GlVolSldUpXF = 10; ef_ex2_GlVolSldDnXF = 11; ef_ex2_VolSlideUpXF = 12; ef_ex2_VolSlideDnXF = 13; ef_ex2_FreqSlideUpXF = 14; ef_ex2_FreqSlideDnXF = 15; ef_ex3_SetConnection = 0; ef_ex3_SetMultipM = 1; ef_ex3_SetKslM = 2; ef_ex3_SetTremoloM = 3; ef_ex3_SetVibratoM = 4; ef_ex3_SetKsrM = 5; ef_ex3_SetSustainM = 6; ef_ex3_SetMultipC = 7; ef_ex3_SetKslC = 8; ef_ex3_SetTremoloC = 9; ef_ex3_SetVibratoC = 10; ef_ex3_SetKsrC = 11; ef_ex3_SetSustainC = 12; const ef_fix1 = $80; ef_fix2 = $90; const _panning: array[0..2] of Byte = ($30,$10,$20); const _instr_data_ofs: array[1..13] of Byte = (1,0,3,2,5,4,7,6,9,8,10,11,12); _instr: array[0..11] of Byte = ($20, $20, $40, $40, $60, $60, $80, $80, $0e0,$0e0, $0c0, $0bd); type tTRACK_ADDR = array[1..20] of Word; const { 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 } _chmm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$006,$007,$008,$103,$100,$104,$101,$105,$102,$106,$107,$108,BYTE_NULL,BYTE_NULL); _chmm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$010,$011,$012,$108,$100,$109,$101,$10a,$102,$110,$111,$112,BYTE_NULL,BYTE_NULL); _chmm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$013,$014,$015,$10b,$103,$10c,$104,$10d,$105,$113,$114,$115,BYTE_NULL,BYTE_NULL); { BD SD TT TC HH } _chpm_n: tTRACK_ADDR = ($003,$000,$004,$001,$005,$002,$106,$107,$108,$103,$100,$104,$101,$105,$102,$006,$007,$008,$008,$007); _chpm_m: tTRACK_ADDR = ($008,$000,$009,$001,$00a,$002,$110,$111,$112,$108,$100,$109,$101,$10a,$102,$010,$014,$012,$015,$011); _chpm_c: tTRACK_ADDR = ($00b,$003,$00c,$004,$00d,$005,$113,$114,$115,$10b,$103,$10c,$104,$10d,$105,$013,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL); var _chan_n: tTRACK_ADDR; _chan_m: tTRACK_ADDR; _chan_c: tTRACK_ADDR; const _4op_tracks_hi: Set of Byte = [1,3,5,10,12,14]; _4op_tracks_lo: Set of Byte = [2,4,6,11,13,15]; _4op_main_chan: array[1..6] of Byte = (2,4,6,11,13,15); const _debug_str_: String = ''; adlibtracker2-2.4.23/adt2play/adt2play.pas0000644000000000000000000004107313176573533017000 0ustar rootrootprogram AdT2_Player; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} uses DOS,GO32, A2player,A2fileIO,A2scrIO, StringIO,TxtScrIO; const VERSION_STR = '0.45'; const modname: array[1..15] of String[39] = ( '/´DLiB TR/´CK3R ][ module', '/´DLiB TR/´CK3R ][ G3 module', '/´DLiB TR/´CK3R ][ tiny module', '/´DLiB TR/´CK3R ][ G3 tiny module', 'Amusic module', 'XMS-Tracker module', 'BoomTracker 4.0 module', 'Digital-FM module', 'HSC AdLib Composer / HSC-Tracker module', 'MPU-401 tr’kkîr module', 'Reality ADlib Tracker module', 'Scream Tracker 3.x module', 'FM-Kingtracker module', 'Surprise! AdLib Tracker module', 'Surprise! AdLib Tracker 2.0 module'); var fkey: Word; index,last_order: Byte; dirinfo: SearchRec; dos_memavail: Word; mem_info: TFPCHeapStatus; free_mem: Longint; var temp,temp2: Byte; _ParamStr: array[0..255] of String[80]; const jukebox: Boolean = FALSE; const kBkSPC = $0e08; kESC = $011b; kENTER = $1c0d; function keypressed: Boolean; assembler; asm mov ah,01h int 16h mov al,TRUE jnz @@1 mov al,FALSE @@1: end; procedure _list_title; begin If iVGA then begin CWriteLn('',$07,0); CWriteLn(' subz3ro''s',$09,0); CWriteLn(' ÄÂÄ ÄÄ',$09,0); CWriteLn(' /´DLiB³R/´CK3R ³³ PLAYER',$09,0); CWriteLn(' ³ ³ ÄÄ '+VERSION_STR,$09,0); CWriteLn('',$07,0); end else begin WriteLn; WriteLn(' subz3ro''s'); WriteLn(' ÄÂÄ ÄÄ'); WriteLn(' /´DLiB³R/´CK3R ³³ PLAYER'); WriteLn(' ³ ³ ÄÄ '+VERSION_STR); WriteLn; end; end; function _gfx_mode: Boolean; var result: Boolean; temp: Byte; begin result := FALSE; For temp := 1 to ParamCount do If (Lower(_ParamStr[temp]) = '/gfx') then begin result := TRUE; BREAK; end; _gfx_mode := result; end; var old_exit_proc: procedure; procedure new_exit_proc; var temp: Byte; begin asm mov ax,03h; xor bh,bh; int 10h end; ExitProc := @old_exit_proc; If (ExitCode <> 0) then begin WriteLn('ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ'); WriteLn('Û ABNORMAL PROGRAM TERMiNATiON Û'); WriteLn('ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß'); WriteLn('PROGRAM VERSION: ',VERSION_STR); WriteLn('ERROR #'+Num2str(ExitCode,10)+' at '+ExpStrL(Num2str(LONGINT(ErrorAddr),16),8,'0')); WriteLn('DEBUG INFO -> ',_debug_str_); WriteLn; WriteLn('Please send this information with brief description what you were doing'); WriteLn('when you encountered this error to following email address:'); WriteLn; WriteLn('subz3ro.altair@gmail.com'); WriteLn; WriteLn('Thanks and sorry for your inconvenience! :-)'); ErrorAddr := NIL; HALT(ExitCode); end else HALT(0); end; begin For temp := 0 to 255 do _ParamStr[temp] := ParamStr(temp); asm mov bx,0ffffh mov ah,48h int 21h mov dos_memavail,bx end; If (dos_memavail*16 DIV 1024 < 120) then begin If _gfx_mode then _list_title; WriteLn('ERROR(1) - Insufficient DOS memory!'); HALT(1); end; If NOT iVGA then begin WriteLn('ERROR(2) - Insufficient video equipment!'); HALT(2); end; For temp := 1 to ParamCount do If (Lower(_ParamStr[temp]) = '/jukebox') then jukebox := TRUE; For temp := 1 to ParamCount do If (Lower(_ParamStr[temp]) = '/latency') then opl3out := opl2out; index := 0; If (ParamCount = 0) then begin If _gfx_mode then _list_title; CWriteLn('Syntax: '+BaseNameOnly(_ParamStr[0])+' files|wildcards [files|wildcards{...}] [options]',$07,0); CWriteLn('',$07,0); CWriteLn('Command-line options:',$07,0); CWriteLn(' /jukebox play modules w/ no repeat',$07,0); CWriteLn(' /gfx graphical interface',$07,0); CWriteLn(' /latency compatibility mode for OPL3 latency',$07,0); HALT; end; @old_exit_proc := ExitProc; ExitProc := @new_exit_proc; mem_info := GetFPCHeapStatus; free_mem := mem_info.CurrHeapFree*1000; error_code := 0; temp := $80; Repeat If (free_mem > PATTERN_SIZE*temp) then begin max_patterns := temp; BREAK; end else If (temp-$10 >= $10) then Dec(temp,$10) else begin error_code := -2; BREAK; end; until FALSE; If (error_code <> -2) then GetMem(pattdata,PATTERN_SIZE*max_patterns); FillChar(decay_bar,SizeOf(decay_bar),0); play_status := isStopped; init_songdata; init_timer_proc; If _gfx_mode then toggle_picture_mode else begin FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); dosmemput($0b800,0,screen_ptr^,MAX_SCREEN_MEM_SIZE); GotoXY(1,1); _list_title; end; Repeat If NOT (index <> 0) then begin CWriteLn(FilterStr(DietStr('úù-Ä--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄ--ùú úù-ÄÄ-Äùú', PRED(MaxCol)), '.',' '),$01,0); CWriteLn( ' ~[~SPACE~]~ Fast-Forward ~[~Ä~]~ Restart ~[~ÄÙ~]~ Next ~[~ESC~]~ Quit',$09,$01); CWriteLn(FilterStr(DietStr('úù-ÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Äùú', PRED(MaxCol)), '.',' '),$01,0); CWriteLn('',$07,0); _window_top := WhereY; end; Inc(index); If (_ParamStr[index][1] <> '/') then begin FindFirst(_ParamStr[index],AnyFile-VolumeID-Directory,dirinfo); If (DosError <> 0) then begin CWriteLn(DietStr('ERROR(2) - No such file "'+ Lower(_ParamStr[index])+'"', PRED(MaxCol)),$07,0); CWriteLn('',$07,0); FindNext(dirinfo); CONTINUE; end; While NOT (DosError <> 0) do begin If (PathOnly(_ParamStr[index]) <> '') then songdata_source := Upper(PathOnly(_ParamStr[index])+dirinfo.name) else songdata_source := Upper(dirinfo.name); C3Write(DietStr('Loading "'+songdata_source+'" (please wait)', PRED(MaxCol)),$07,0,0); wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color); wtext2(_fname_xpos,_fname_ypos,ExpStrR(NameOnly(songdata_source),12,' '),_fname_color); wtext(_pos_str_xpos,_pos_str_ypos,ExpStrR('Loading...',35,' '),_pos_str_color); For temp := 1 to 10 do WaitRetrace; limit_exceeded := FALSE; load_flag := BYTE_NULL; _decay_bars_initialized := FALSE; // If _gfx_mode then decay_bars_refresh; a2m_file_loader; If (load_flag = BYTE_NULL) then a2t_file_loader; If (load_flag = BYTE_NULL) then amd_file_loader; If (load_flag = BYTE_NULL) then cff_file_loader; If (load_flag = BYTE_NULL) then dfm_file_loader; If (load_flag = BYTE_NULL) then mtk_file_loader; If (load_flag = BYTE_NULL) then rad_file_loader; If (load_flag = BYTE_NULL) then s3m_file_loader; If (load_flag = BYTE_NULL) then fmk_file_loader; If (load_flag = BYTE_NULL) then sat_file_loader; If (load_flag = BYTE_NULL) then sa2_file_loader; If (load_flag = BYTE_NULL) then hsc_file_loader; If (load_flag = BYTE_NULL) or (load_flag = $7f) then begin CWriteLn(DietStr(ExpStrR('ERROR(3) - Invalid module ('+songdata_source+')', PRED(MaxCol),' '), PRED(MaxCol)),$07,0); CWriteLn('',$07,0); FindNext(dirinfo); CONTINUE; end; last_order := 0; entries := 0; If limit_exceeded then begin CWriteLn(DietStr(ExpStrR('ERROR(1) - Insufficient memory!', PRED(MaxCol),' '), PRED(MaxCol)),$07,0); CWriteLn('',$07,0); FindNext(dirinfo); CONTINUE; end; count_order(entries); correction := calc_following_order(0); entries2 := entries; If (correction <> -1) then Dec(entries,correction) else entries := 0; CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+ songdata_source+'"', PRED(MaxCol),' '), PRED(MaxCol)),$07,0); temp2 := PRED(WhereY); If (entries = 0) then begin If NOT _picture_mode then GotoXY(1,temp2); CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+ songdata_source+'"', PRED(MaxCol),' '), PRED(MaxCol)),$08,0); CWriteLn(DietStr(ExpStrR(''+NameOnly(songdata_source)+' [stopped] ['+ ExpStrL(Num2str(TRUNC(time_playing) DIV 60,10),2,'0')+ ':'+ExpStrL(Num2str(TRUNC(time_playing) MOD 60,10),2,'0')+']', PRED(MaxCol),' '), PRED(MaxCol)),$07,0); CWriteLn('',$07,0); FindNext(dirinfo); CONTINUE; end; start_playing; set_overall_volume(63); Repeat If (overall_volume = 63) then C3Write(DietStr(_position_str+' ',PRED(MaxCol)),$0f,0,0); wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color); If (inportb($60) = $39) { SPACE pressed } then begin If (overall_volume > 32) then For temp := 63 downto 32 do begin set_overall_volume(temp); delay_counter := 0; While (delay_counter < overall_volume DIV 20) do begin If timer_200hz_flag then begin timer_200hz_flag := FALSE; Inc(delay_counter); C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0); wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color); If timer_50hz_flag then begin timer_50hz_flag := FALSE; If NOT fast_forward then decay_bars_refresh; end; end; MEMW[0:$041c] := MEMW[0:$041a]; end; end else begin If timer_200hz_flag then begin timer_200hz_flag := FALSE; C3Write(DietStr(_position_str+'',PRED(MaxCol)),$0f,0,0); wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+'',_pos_str_color); If timer_50hz_flag then begin timer_50hz_flag := FALSE; If NOT fast_forward then decay_bars_refresh; end; end; MEMW[0:$041c] := MEMW[0:$041a]; end; fast_forward := TRUE; end else If (inportb($60) = $0b9) { SPACE released } then begin fast_forward := FALSE; If (overall_volume < 63) then For temp := 32 to 63 do begin set_overall_volume(temp); delay_counter := 0; While (delay_counter < overall_volume DIV 20) do begin If (timer_200hz_counter = 0) then begin Inc(delay_counter); C3Write(DietStr(_position_str+' ',PRED(MaxCol)),$0f,0,0); wtext2(_timer_xpos,_timer_ypos,_timer_str,_timer_color); wtext(_progress_xpos,_progress_ypos,_progress_str,_progress_color); wtext(_pos_str_xpos,_pos_str_ypos,_position_str2+' ',_pos_str_color); If timer_50hz_flag then begin timer_50hz_flag := FALSE; decay_bars_refresh; end; end; MEMW[0:$041c] := MEMW[0:$041a]; end; end; end; If (NOT fast_forward and timer_50hz_flag) or (fast_forward and timer_20hz_flag) then begin If NOT fast_forward then timer_50hz_flag := FALSE else timer_20hz_flag := FALSE; decay_bars_refresh; end; If NOT keypressed then fkey := WORD_NULL else asm xor ax,ax int 16h mov fkey,ax end; MEMW[0:$041c] := MEMW[0:$041a]; If jukebox and (last_order <> current_order) then begin If (last_order > current_order) and (last_order = PRED(entries2)) then BREAK else last_order := current_order; end; If (fkey = kBkSPC) then begin fade_out; stop_playing; set_overall_volume(63); start_playing; end; until (fkey = kENTER) or (fkey = kESC); fade_out; stop_playing; If NOT _picture_mode then GotoXY(1,temp2); CWriteLn(DietStr(ExpStrR('Playing '+modname[load_flag]+' "'+ songdata_source+'"', PRED(MaxCol),' '), PRED(MaxCol)),$08,0); CWriteLn(DietStr(ExpStrR(''+NameOnly(songdata_source)+' [stopped] ['+ ExpStrL(Num2str(TRUNC(time_playing) DIV 60,10),2,'0')+ ':'+ExpStrL(Num2str(TRUNC(time_playing) MOD 60,10),2,'0')+']', PRED(MaxCol),' '), PRED(MaxCol)),$07,0); CWriteLn('',$07,0); If (fkey = kESC) then BREAK; FindNext(dirinfo); end; end; until (index = ParamCount); done_timer_proc; end. adlibtracker2-2.4.23/adt2play/iloaders.inc0000644000000000000000000060712013176573533017051 0ustar rootroot{ function check_byte(var data; _byte: Byte; size: Longint): Boolean; procedure import_old_a2m_event1(patt,line,chan: Byte; old_chunk: tOLD_CHUNK; processing_whole_song: Boolean); procedure replace_old_adsr(patterns: Byte); procedure import_old_a2m_patterns1(block: Byte; count: Byte); procedure import_old_a2m_event2(patt,line,chan: Byte; old_chunk: tOLD_CHUNK); procedure import_old_a2m_patterns2(block: Byte; count: Byte); procedure import_old_flags; procedure import_old_songdata(old_songdata: pOLD_FIXED_SONGDATA); procedure import_old_instruments(old_songdata: pOLD_FIXED_SONGDATA; new_songdata: pFIXED_SONGDATA; instr,count: Byte); procedure import_single_old_instrument(old_songdata: pOLD_FIXED_SONGDATA; pos,instr: Byte); function insert_command(cmd,cmd2: Word; patterns: Byte; chan: Byte; exceptions: tByteSet): Boolean; procedure a2m_file_loader; procedure a2t_file_loader; procedure a2p_file_loader; function dec2hex(dec: Byte): Byte; function truncate_string(str: String): String; procedure amd_file_loader; procedure import_cff_event(patt,line,chan,byte0,byte1,byte2: Byte); procedure import_cff_patterns(var data; patterns: Byte); procedure cff_file_loader; procedure import_standard_instrument(inst: Byte; var data); procedure dfm_file_loader; procedure import_hsc_event(patt,line,chan: Byte; event: Word); procedure import_hsc_patterns(var data; patterns: Byte); procedure import_hsc_instrument(inst: Byte; var data); procedure hsc_file_loader; procedure mtk_file_loader; procedure rad_file_loader; procedure fix_s3m_commands(patterns: Byte); procedure fix_single_pattern(patt: Byte); procedure s3m_file_loader; procedure fix_fmk_commands(patterns: Byte); procedure import_fin_instrument(inst: Byte; var data); procedure fmk_file_loader; procedure import_sat_instrument(inst: Byte; var data); function import_sat_instrument_name(var data; inst: Byte): String; procedure sat_file_loader; function _sal(op1,op2: Word): Byte; function _sar(op1,op2: Word): Byte; procedure import_sa2_effect(effect,def1,def2: Byte; var out1,out2: Byte); procedure sa2_file_loader; } function check_byte(var data; _byte: Byte; size: Longint): Boolean; var result: Boolean; begin asm mov edi,[data] mov ecx,size jecxz @@1 mov al,_byte repnz scasb jnz @@1 mov result,TRUE jmp @@2 @@1: mov result,FALSE @@2: end; check_byte := result; end; var adsr_carrier: array[1..9] of Boolean; procedure import_old_a2m_event1(patt,line,chan: Byte; old_chunk: tOLD_CHUNK; processing_whole_song: Boolean); const fx_Arpeggio = $00; fx_FSlideUp = $01; fx_FSlideDown = $02; fx_FSlideUpFine = $03; fx_FSlideDownFine = $04; fx_TonePortamento = $05; fx_TPortamVolSlide = $06; fx_Vibrato = $07; fx_VibratoVolSlide = $08; fx_SetOpIntensity = $09; fx_SetInsVolume = $0a; fx_PatternBreak = $0b; fx_PatternJump = $0c; fx_SetTempo = $0d; fx_SetTimer = $0e; fx_Extended = $0f; fx_ex_DefAMdepth = $00; fx_ex_DefVibDepth = $01; fx_ex_DefWaveform = $02; fx_ex_ManSlideUp = $03; fx_ex_ManSlideDown = $04; fx_ex_VSlideUp = $05; fx_ex_VSlideDown = $06; fx_ex_VSlideUpFine = $07; fx_ex_VSlideDownFine = $08; fx_ex_RetrigNote = $09; fx_ex_SetAttckRate = $0a; fx_ex_SetDecayRate = $0b; fx_ex_SetSustnLevel = $0c; fx_ex_SetReleaseRate = $0d; fx_ex_SetFeedback = $0e; fx_ex_ExtendedCmd = $0f; var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); chunk.note := old_chunk.note; chunk.instr_def := old_chunk.instr_def; chunk.effect_def := old_chunk.effect_def; chunk.effect := old_chunk.effect; Case old_chunk.effect_def of fx_Arpeggio: chunk.effect_def := ef_Arpeggio; fx_FSlideUp: chunk.effect_def := ef_FSlideUp; fx_FSlideDown: chunk.effect_def := ef_FSlideDown; fx_FSlideUpFine: chunk.effect_def := ef_FSlideUpFine; fx_FSlideDownFine: chunk.effect_def := ef_FSlideDownFine; fx_TonePortamento: chunk.effect_def := ef_TonePortamento; fx_TPortamVolSlide: chunk.effect_def := ef_TPortamVolSlide; fx_Vibrato: chunk.effect_def := ef_Vibrato; fx_VibratoVolSlide: chunk.effect_def := ef_VibratoVolSlide; fx_SetInsVolume: chunk.effect_def := ef_SetInsVolume; fx_PatternJump: chunk.effect_def := ef_PositionJump; fx_PatternBreak: chunk.effect_def := ef_PatternBreak; fx_SetTempo: chunk.effect_def := ef_SetSpeed; fx_SetTimer: chunk.effect_def := ef_SetTempo; fx_SetOpIntensity: If (old_chunk.effect DIV 16 <> 0) then begin chunk.effect_def := ef_SetCarrierVol; chunk.effect := 3+(old_chunk.effect DIV 16)*4; end else If (old_chunk.effect MOD 16 <> 0) then begin chunk.effect_def := ef_SetModulatorVol; chunk.effect := 3+(old_chunk.effect MOD 16)*4; end else chunk.effect_def := 0; fx_Extended: Case old_chunk.effect DIV 16 of fx_ex_DefAMdepth: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetTremDepth*16+old_chunk.effect MOD 16; end; fx_ex_DefVibDepth: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetVibDepth*16+old_chunk.effect MOD 16; end; fx_ex_DefWaveform: begin chunk.effect_def := ef_SetWaveform; Case old_chunk.effect MOD 16 of 0..3: chunk.effect := (old_chunk.effect MOD 16)*16+$0f; 4..7: chunk.effect := $0f0+(old_chunk.effect MOD 16)-4; end; end; fx_ex_VSlideUp: begin chunk.effect_def := ef_VolSlide; chunk.effect := (old_chunk.effect MOD 16)*16; end; fx_ex_VSlideDown: begin chunk.effect_def := ef_VolSlide; chunk.effect := old_chunk.effect MOD 16; end; fx_ex_VSlideUpFine: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := (old_chunk.effect MOD 16)*16; end; fx_ex_VSlideDownFine: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := old_chunk.effect MOD 16; end; fx_ex_ManSlideUp: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneUp*16+old_chunk.effect MOD 16; end; fx_ex_ManSlideDown: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneDown*16+old_chunk.effect MOD 16; end; fx_ex_RetrigNote: begin chunk.effect_def := ef_RetrigNote; chunk.effect := SUCC(old_chunk.effect MOD 16); end; fx_ex_SetAttckRate: begin chunk.effect_def := ef_Extended; chunk.effect := old_chunk.effect MOD 16; If NOT adsr_carrier[chan] then Inc(chunk.effect,ef_ex_SetAttckRateM*16) else Inc(chunk.effect,ef_ex_SetAttckRateC*16); end; fx_ex_SetDecayRate: begin chunk.effect_def := ef_Extended; chunk.effect := old_chunk.effect MOD 16; If NOT adsr_carrier[chan] then Inc(chunk.effect,ef_ex_SetDecayRateM*16) else Inc(chunk.effect,ef_ex_SetDecayRateC*16); end; fx_ex_SetSustnLevel: begin chunk.effect_def := ef_Extended; chunk.effect := old_chunk.effect MOD 16; If NOT adsr_carrier[chan] then Inc(chunk.effect,ef_ex_SetSustnLevelM*16) else Inc(chunk.effect,ef_ex_SetSustnLevelC*16); end; fx_ex_SetReleaseRate: begin chunk.effect_def := ef_Extended; chunk.effect := old_chunk.effect MOD 16; If NOT adsr_carrier[chan] then Inc(chunk.effect,ef_ex_SetRelRateM*16) else Inc(chunk.effect,ef_ex_SetRelRateC*16); end; fx_ex_SetFeedback: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetFeedback*16+old_chunk.effect MOD 16; end; fx_ex_ExtendedCmd: If (old_chunk.effect MOD 16 in [0..9]) then begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16; Case old_chunk.effect MOD 16 of 0: Inc(chunk.effect,ef_ex_cmd2_RSS); 1: Inc(chunk.effect,ef_ex_cmd2_LockVol); 2: Inc(chunk.effect,ef_ex_cmd2_UnlockVol); 3: Inc(chunk.effect,ef_ex_cmd2_LockVP); 4: Inc(chunk.effect,ef_ex_cmd2_UnlockVP); 5: begin If processing_whole_song then chunk.effect_def := 255 else chunk.effect_def := 0; chunk.effect := 0; adsr_carrier[chan] := TRUE; end; 6: begin If processing_whole_song then chunk.effect_def := 255 else chunk.effect_def := 0; If processing_whole_song then chunk.effect := 1 else chunk.effect := 0; adsr_carrier[chan] := FALSE; end; 7: Inc(chunk.effect,ef_ex_cmd2_VSlide_car); 8: Inc(chunk.effect,ef_ex_cmd2_VSlide_mod); 9: Inc(chunk.effect,ef_ex_cmd2_VSlide_def); end; end else begin chunk.effect_def := 0; chunk.effect := 0; end; end; end; put_chunk(patt,line,chan,chunk); end; procedure replace_old_adsr(patterns: Byte); var chunk,chunk2: tCHUNK; temp2,temp3: Byte; patt_break: Byte; order,patt: Byte; patts: String; begin patts := ''; FillChar(adsr_carrier,SizeOf(adsr_carrier),0); order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; patt_break := BYTE_NULL; For temp2 := 0 to $3f do For temp3 := 1 to 9 do begin get_chunk(patt,temp2,temp3,chunk); chunk2 := chunk; If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then patt_break := temp2; If (chunk.effect_def in [$ff,ef_Extended]) then begin If (chunk.effect_def = $ff) then begin chunk2.effect_def := 0; chunk2.effect := 0; If (temp2 <= patt_break) then Case chunk.effect of 0: adsr_carrier[temp3] := TRUE; 1: adsr_carrier[temp3] := FALSE; end; end; If (chunk.effect_def = ef_Extended) then Case chunk.effect DIV 16 of ef_ex_SetAttckRateM, ef_ex_SetAttckRateC: If adsr_carrier[temp3] then chunk2.effect := ef_ex_SetAttckRateC*16+chunk.effect MOD 16 else chunk2.effect := ef_ex_SetAttckRateM*16+chunk.effect MOD 16; ef_ex_SetDecayRateM, ef_ex_SetDecayRateC: If adsr_carrier[temp3] then chunk2.effect := ef_ex_SetDecayRateC*16+chunk.effect MOD 16 else chunk2.effect := ef_ex_SetDecayRateM*16+chunk.effect MOD 16; ef_ex_SetSustnLevelM, ef_ex_SetSustnLevelC: If adsr_carrier[temp3] then chunk2.effect := ef_ex_SetSustnLevelC*16+chunk.effect MOD 16 else chunk2.effect := ef_ex_SetSustnLevelM*16+chunk.effect MOD 16; ef_ex_SetRelRateM, ef_ex_SetRelRateC: If adsr_carrier[temp3] then chunk2.effect := ef_ex_SetRelRateC*16+chunk.effect MOD 16 else chunk2.effect := ef_ex_SetRelRateM*16+chunk.effect MOD 16; end; If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then If (chunk.effect_def <> chunk2.effect_def) or (chunk.effect <> chunk2.effect) then put_chunk(patt,temp2,temp3,chunk2); end; end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); end; procedure import_old_a2m_patterns1(block: Byte; count: Byte); procedure get_old_chunk(pattern,line,channel: Byte; var chunk: tOLD_CHUNK); begin chunk := old_hash_buffer[pattern][line][channel]; end; var patt,line,chan: Byte; chunk: tOLD_CHUNK; begin { import_old_a2m_patterns1 } For patt := 0 to max(PRED(count),15) do For line := 0 to $3f do For chan := 1 to 9 do begin get_old_chunk(patt,line,chan,chunk); import_old_a2m_event1(block*16+patt,line,chan,chunk,TRUE); end; end; procedure import_old_a2m_event2(patt,line,chan: Byte; old_chunk: tOLD_CHUNK); const ef_ManualFSlide = 22; var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); chunk.note := old_chunk.note; chunk.instr_def := old_chunk.instr_def; If (old_chunk.effect_def <> ef_ManualFSlide) then begin chunk.effect_def := old_chunk.effect_def; chunk.effect := old_chunk.effect; end else If (old_chunk.effect DIV 16 <> 0) then begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneUp*16+old_chunk.effect DIV 16; end else begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneDown*16+old_chunk.effect MOD 16; end; put_chunk(patt,line,chan,chunk); end; procedure import_old_a2m_patterns2(block: Byte; count: Byte); procedure get_old_chunk(pattern,line,channel: Byte; var chunk: tOLD_CHUNK); begin chunk := hash_buffer[pattern][channel][line]; end; var patt,line,chan: Byte; chunk: tOLD_CHUNK; begin { import_old_a2m_patterns2 } For patt := 0 to max(PRED(count),7) do For line := 0 to $3f do For chan := 1 to 18 do begin get_old_chunk(patt,line,chan,chunk); import_old_a2m_event2(block*8+patt,line,chan,chunk); end; end; procedure import_old_flags; var temp: Byte; begin If (songdata.common_flag OR 2 = songdata.common_flag) then For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] OR $10; If (songdata.common_flag OR 4 = songdata.common_flag) then For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] OR $20; If (songdata.common_flag OR $20 = songdata.common_flag) then For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] AND NOT 3; end; procedure import_old_songdata(old_songdata: pOLD_FIXED_SONGDATA); var temp: Byte; begin songdata.songname := old_songdata^.songname; songdata.composer := old_songdata^.composer; For temp := 1 to 250 do begin songdata.instr_names[temp] := old_songdata^.instr_names[temp]; songdata.instr_data[temp].fm_data := old_songdata^.instr_data[temp].fm_data; songdata.instr_data[temp].panning := old_songdata^.instr_data[temp].panning; songdata.instr_data[temp].fine_tune := old_songdata^.instr_data[temp].fine_tune; songdata.instr_data[temp].perc_voice := 0; end; Move(old_songdata^.pattern_order, songdata.pattern_order, SizeOf(old_songdata^.pattern_order)); songdata.tempo := old_songdata^.tempo; songdata.speed := old_songdata^.speed; songdata.common_flag := old_songdata^.common_flag; import_old_flags; end; function insert_command(cmd,cmd2: Word; patterns: Byte; chan: Byte; exceptions: tByteSet): Boolean; var chunk: tCHUNK; temp2,temp3: Byte; patt_break: Byte; order,patt: Byte; patts: String; begin patts := ''; order := 0; patt := BYTE_NULL; insert_command := FALSE; Repeat If (Pos(CHR(songdata.pattern_order[order]),patts) <> 0) or (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; patt_break := songdata.patt_len; For temp3 := 1 to songdata.nm_tracks do For temp2 := 0 to PRED(songdata.patt_len) do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) or (chunk.effect_def2 in [ef_PositionJump,ef_PatternBreak]) then patt_break := temp2; If (temp3 = chan) and (temp2 <= patt_break) then If (cmd2 = 0) then If (chunk.effect_def+chunk.effect = 0) or (chunk.effect_def SHL 8 + chunk.effect = cmd) or (chunk.effect_def in exceptions) then begin chunk.effect_def := HI(cmd); chunk.effect := LO(cmd); put_chunk(patt,temp2,temp3,chunk); insert_command := TRUE; EXIT; end else If (chunk.effect_def2+chunk.effect2 = 0) or (chunk.effect_def2 SHL 8 + chunk.effect2 = cmd2) or (chunk.effect_def2 in exceptions) then begin chunk.effect_def2 := HI(cmd); chunk.effect2 := LO(cmd); put_chunk(patt,temp2,temp3,chunk); insert_command := TRUE; EXIT; end else else If ((chunk.effect_def+chunk.effect = 0) or (chunk.effect_def SHL 8 + chunk.effect = cmd) or (chunk.effect_def in exceptions)) and ((chunk.effect_def2+chunk.effect2 = 0) or (chunk.effect_def2 SHL 8 + chunk.effect2 = cmd2) or (chunk.effect_def2 in exceptions)) then begin chunk.effect_def := HI(cmd); chunk.effect := LO(cmd); chunk.effect_def2 := HI(cmd2); chunk.effect2 := LO(cmd2); put_chunk(patt,temp2,temp3,chunk); insert_command := TRUE; EXIT; end; end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); end; procedure a2m_file_loader; type tOLD_HEADER = Record ident: array[1..10] of Char; crc32: Longint; ffver: Byte; patts: Byte; b0len: Word; b1len: Word; b2len: Word; b3len: Word; b4len: Word; b5len: Word; b6len: Word; b7len: Word; b8len: Word; end; type tHEADER = Record ident: array[1..10] of Char; crc32: Longint; ffver: Byte; patts: Byte; b0len: Longint; b1len: array[0..15] of Longint; end; const id = '_A2module_'; const old_a2m_header_size = 26; var f: File; header: tHEADER; header2: tOLD_HEADER; temp,temp2: Longint; crc: Longint; xlen: array[0..6] of Word; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); EXIT; end; load_flag := $7f; If NOT (header.ffver in [1..FFVER_A2M]) then begin CloseF(f); EXIT; end; init_old_songdata; If (header.ffver in [1..4]) then begin FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE)); ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); EXIT; end; xlen[0] := header2.b2len; xlen[1] := header2.b3len; xlen[2] := header2.b4len; SeekF(f,old_a2m_header_size); If (IOresult <> 0) then begin CloseF(f); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 0 to 2 do If ((header2.patts-1) DIV 16 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header2.b0len,2,crc); crc := Update32(header2.b1len,2,crc); For temp2 := 0 to 2 do crc := Update32(xlen[temp2],2,crc); If (crc <> header2.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; SeekF(f,old_a2m_header_size); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; Case header2.ffver of 4: Move(buf1,old_songdata,header2.b0len); 3: LZSS_decompress(buf1,old_songdata,header2.b0len); 2: LZW_decompress(buf1,old_songdata); 1: SIXPACK_decompress(buf1,old_songdata,header2.b0len); end; For temp := 1 to 250 do old_songdata.instr_data[temp].panning := 0; BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); EXIT; end; Case header2.ffver of 4: Move(buf1,old_hash_buffer,header2.b1len); 3: LZSS_decompress(buf1,old_hash_buffer,header2.b1len); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b1len); end; import_old_a2m_patterns1(0,16); For temp2 := 0 to 2 do If ((header2.patts-1) DIV 16 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); EXIT; end; Case header2.ffver of 4: Move(buf1,old_hash_buffer,xlen[temp2]); 3: LZSS_decompress(buf1,old_hash_buffer,xlen[temp2]); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,xlen[temp2]); end; import_old_a2m_patterns1(SUCC(temp2),16); end; replace_old_adsr(header2.patts); import_old_songdata(Addr(old_songdata)); end; If (header.ffver in [5..8]) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); EXIT; end; xlen[0] := header2.b2len; xlen[1] := header2.b3len; xlen[2] := header2.b4len; xlen[3] := header2.b5len; xlen[4] := header2.b6len; xlen[5] := header2.b7len; xlen[6] := header2.b8len; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 0 to 6 do If ((header2.patts-1) DIV 8 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header2.b0len,2,crc); crc := Update32(header2.b1len,2,crc); For temp2 := 0 to 6 do crc := Update32(xlen[temp2],2,crc); If (crc <> header2.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 18 else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; SeekF(f,SizeOf(header2)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; Case header2.ffver of 8: Move(buf1,old_songdata,header2.b0len); 7: LZSS_decompress(buf1,old_songdata,header2.b0len); 6: LZW_decompress(buf1,old_songdata); 5: SIXPACK_decompress(buf1,old_songdata,header2.b0len); end; BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); EXIT; end; Case header2.ffver of 8: Move(buf1,hash_buffer,header2.b1len); 7: LZSS_decompress(buf1,hash_buffer,header2.b1len); 6: LZW_decompress(buf1,hash_buffer); 5: SIXPACK_decompress(buf1,hash_buffer,header2.b1len); end; import_old_a2m_patterns2(0,8); For temp2 := 0 to 6 do If ((header2.patts-1) DIV 8 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); EXIT; end; Case header2.ffver of 8: Move(buf1,hash_buffer,header2.b2len); 7: LZSS_decompress(buf1,hash_buffer,header2.b2len); 6: LZW_decompress(buf1,hash_buffer); 5: SIXPACK_decompress(buf1,hash_buffer,header2.b2len); end; import_old_a2m_patterns2(SUCC(temp2),8); end; import_old_songdata(Addr(old_songdata)); end; If (header.ffver in [9,10,11]) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header.b0len,2,crc); For temp2 := 0 to 15 do crc := Update32(header.b1len[temp2],2,crc); If (crc <> header.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); EXIT; end; If (header.ffver = 9) then import_old_flags; APACK_decompress(buf1,pattdata^[0]); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); EXIT; end; If (temp2*8+8 <= max_patterns) then APACK_decompress(buf1,pattdata^[temp2]) else limit_exceeded := TRUE; end; end; If (header.ffver in [12,FFVER_A2M]) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header.b0len,2,crc); For temp2 := 0 to 15 do crc := Update32(header.b1len[temp2],2,crc); If (crc <> header.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; LZH_decompress(buf1,songdata,header.b0len); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); EXIT; end; LZH_decompress(buf1,pattdata^[0],header.b1len[0]); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); EXIT; end; If (temp2*8+8 <= max_patterns) then begin LZH_decompress(buf1,pattdata^[temp2],header.b1len[temp2]); end else limit_exceeded := TRUE; end; end; speed := songdata.speed; tempo := songdata.tempo; CloseF(f); songdata_title := NameOnly(songdata_source); Case header.ffver of 1..4: load_flag := 1; else load_flag := 2; end; end; procedure a2t_file_loader; type tOLD_HEADER1 = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; b0len: Word; b1len: Word; b2len: Word; b3len: Word; b4len: Word; b5len: Word; end; type tOLD_HEADER2 = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; b0len: Word; b1len: Word; b2len: Word; b3len: Word; b4len: Word; b5len: Word; b6len: Word; b7len: Word; b8len: Word; b9len: Word; end; type tOLD_HEADER3 = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; patln: Word; nmtrk: Byte; mcspd: Word; b0len: Longint; b1len: Longint; b2len: Longint; b3len: Longint; b4len: array[0..15] of Longint; end; type tOLD_HEADER4 = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; patln: Word; nmtrk: Byte; mcspd: Word; is4op: Byte; locks: array[1..20] of Byte; b0len: Longint; b1len: Longint; b2len: Longint; b3len: Longint; b4len: array[0..15] of Longint; end; type tHEADER = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; patln: Word; nmtrk: Byte; mcspd: Word; is4op: Byte; locks: array[1..20] of Byte; b0len: Longint; b1len: Longint; b2len: Longint; b3len: Longint; b4len: Longint; b5len: array[0..15] of Longint; end; const id = '_A2tiny_module_'; var f: File; header: tHEADER; header2: tOLD_HEADER1; header3: tOLD_HEADER2; header4: tOLD_HEADER3; header5: tOLD_HEADER4; temp,temp2: Longint; crc: Longint; xlen: array[0..6] of Word; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); EXIT; end; load_flag := $7f; If NOT (header.ffver in [1..FFVER_A2T]) then begin CloseF(f); EXIT; end; init_old_songdata; If (header.ffver in [1..4]) then begin FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE)); ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); EXIT; end; xlen[0] := header2.b3len; xlen[1] := header2.b4len; xlen[2] := header2.b5len; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b2len,temp); If NOT (temp = header2.b2len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 0 to 2 do If ((header2.patts-1) DIV 16 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header2.b0len,2,crc); crc := Update32(header2.b1len,2,crc); crc := Update32(header2.b2len,2,crc); For temp2 := 0 to 2 do crc := Update32(xlen[temp2],2,crc); If (crc <> header2.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; SeekF(f,SizeOf(header2)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; old_songdata.tempo := header2.tempo; old_songdata.speed := header2.speed; Case header2.ffver of 4: Move(buf1,old_songdata.instr_data,header2.b0len); 3: LZSS_decompress(buf1,old_songdata.instr_data,header2.b0len); 2: LZW_decompress(buf1,old_songdata.instr_data); 1: SIXPACK_decompress(buf1,old_songdata.instr_data,header2.b0len); end; For temp := 1 to 250 do old_songdata.instr_data[temp].panning := 0; BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); EXIT; end; Case header2.ffver of 4: Move(buf1,old_songdata.pattern_order,header2.b1len); 3: LZSS_decompress(buf1,old_songdata.pattern_order,header2.b1len); 2: LZW_decompress(buf1,old_songdata.pattern_order); 1: SIXPACK_decompress(buf1,old_songdata.pattern_order,header2.b1len); end; BlockReadF(f,buf1,header2.b2len,temp); If NOT (temp = header2.b2len) then begin CloseF(f); EXIT; end; FillChar(old_hash_buffer,SizeOf(old_hash_buffer),0); Case header2.ffver of 4: Move(buf1,old_hash_buffer,header2.b2len); 3: LZSS_decompress(buf1,old_hash_buffer,header2.b2len); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b2len); end; import_old_a2m_patterns1(0,16); For temp2 := 0 to 2 do If ((header2.patts-1) DIV 16 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); EXIT; end; FillChar(old_hash_buffer,SizeOf(old_hash_buffer),0); Case header2.ffver of 4: Move(buf1,old_hash_buffer,header2.b3len); 3: LZSS_decompress(buf1,old_hash_buffer,header2.b3len); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b3len); end; import_old_a2m_patterns1(SUCC(temp2),16); end; replace_old_adsr(header2.patts); import_old_songdata(Addr(old_songdata)); end; If (header.ffver in [5..8]) then begin ResetF(f); BlockReadF(f,header3,SizeOf(header3),temp); If NOT ((temp = SizeOf(header3)) and (header3.ident = id)) then begin CloseF(f); EXIT; end; xlen[0] := header3.b3len; xlen[1] := header3.b4len; xlen[2] := header3.b5len; xlen[3] := header3.b6len; xlen[4] := header3.b7len; xlen[5] := header3.b8len; xlen[6] := header3.b9len; crc := DWORD_NULL; BlockReadF(f,buf1,header3.b0len,temp); If NOT (temp = header3.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header3.b1len,temp); If NOT (temp = header3.b1len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header3.b2len,temp); If NOT (temp = header3.b2len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 0 to 6 do If ((header3.patts-1) DIV 8 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header3.b0len,2,crc); crc := Update32(header3.b1len,2,crc); crc := Update32(header3.b2len,2,crc); For temp2 := 0 to 6 do crc := Update32(xlen[temp2],2,crc); If (crc <> header3.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 18 else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; SeekF(f,SizeOf(header3)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header3.b0len,temp); If NOT (temp = header3.b0len) then begin CloseF(f); EXIT; end; old_songdata.tempo := header3.tempo; old_songdata.speed := header3.speed; old_songdata.common_flag := header3.cflag; Case header3.ffver of 8: Move(buf1,old_songdata.instr_data,header3.b0len); 7: LZSS_decompress(buf1,old_songdata.instr_data,header3.b0len); 6: LZW_decompress(buf1,old_songdata.instr_data); 5: SIXPACK_decompress(buf1,old_songdata.instr_data,header3.b0len); end; BlockReadF(f,buf1,header3.b1len,temp); If NOT (temp = header3.b1len) then begin CloseF(f); EXIT; end; Case header3.ffver of 8: Move(buf1,old_songdata.pattern_order,header3.b1len); 7: LZSS_decompress(buf1,old_songdata.pattern_order,header3.b1len); 6: LZW_decompress(buf1,old_songdata.pattern_order); 5: SIXPACK_decompress(buf1,old_songdata.pattern_order,header3.b1len); end; BlockReadF(f,buf1,header3.b2len,temp); If NOT (temp = header3.b2len) then begin CloseF(f); EXIT; end; FillChar(hash_buffer,SizeOf(hash_buffer),0); Case header3.ffver of 8: Move(buf1,hash_buffer,header3.b2len); 7: LZSS_decompress(buf1,hash_buffer,header3.b2len); 6: LZW_decompress(buf1,hash_buffer); 5: SIXPACK_decompress(buf1,hash_buffer,header3.b2len); end; import_old_a2m_patterns2(0,8); For temp2 := 0 to 6 do If ((header3.patts-1) DIV 8 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); EXIT; end; FillChar(hash_buffer,SizeOf(hash_buffer),0); Case header3.ffver of 8: Move(buf1,hash_buffer,header3.b3len); 7: LZSS_decompress(buf1,hash_buffer,header3.b3len); 6: LZW_decompress(buf1,hash_buffer); 5: SIXPACK_decompress(buf1,hash_buffer,header3.b3len); end; import_old_a2m_patterns2(SUCC(temp2),8); end; import_old_songdata(Addr(old_songdata)); end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header4,SizeOf(header4),temp); If NOT ((temp = SizeOf(header4)) and (header4.ident = id)) then begin CloseF(f); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header4.b0len,temp); If NOT (temp = header4.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b1len,temp); If NOT (temp = header4.b1len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b2len,temp); If NOT (temp = header4.b2len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b3len,temp); If NOT (temp = header4.b3len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b4len[0],temp); If NOT (temp = header4.b4len[0]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header4.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header4.b4len[temp2],temp); If NOT (temp = header4.b4len[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header4.b0len,2,crc); crc := Update32(header4.b1len,2,crc); crc := Update32(header4.b2len,2,crc); crc := Update32(header4.b3len,2,crc); For temp2 := 0 to 15 do crc := Update32(header4.b4len[temp2],2,crc); If (crc <> header4.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header4)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header4.b0len,temp); If NOT (temp = header4.b0len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header4.b1len,temp); If NOT (temp = header4.b1len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header4.b2len,temp); If NOT (temp = header4.b2len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header4.b3len,temp); If NOT (temp = header4.b3len) then begin CloseF(f); EXIT; end; songdata.tempo := header4.tempo; songdata.speed := header4.speed; songdata.common_flag := header4.cflag; songdata.patt_len := header4.patln; songdata.nm_tracks := header4.nmtrk; songdata.macro_speedup := header4.mcspd; import_old_flags; APACK_decompress(buf1,songdata.pattern_order); BlockReadF(f,buf1,header4.b4len[0],temp); If NOT (temp = header4.b4len[0]) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,pattdata^[0]); For temp2 := 1 to 15 do If ((header4.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header4.b4len[temp2],temp); If NOT (temp = header4.b4len[temp2]) then begin CloseF(f); EXIT; end; If (temp2*8+8 <= max_patterns) then APACK_decompress(buf1,pattdata^[temp2]) else limit_exceeded := TRUE; end; end; If (header.ffver = 10) then begin ResetF(f); BlockReadF(f,header5,SizeOf(header5),temp); If NOT ((temp = SizeOf(header5)) and (header5.ident = id)) then begin CloseF(f); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header5.b0len,temp); If NOT (temp = header5.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b1len,temp); If NOT (temp = header5.b1len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b2len,temp); If NOT (temp = header5.b2len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b3len,temp); If NOT (temp = header5.b3len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b4len[0],temp); If NOT (temp = header5.b4len[0]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header5.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header5.b4len[temp2],temp); If NOT (temp = header5.b4len[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header5.b0len,2,crc); crc := Update32(header5.b1len,2,crc); crc := Update32(header5.b2len,2,crc); crc := Update32(header5.b3len,2,crc); For temp2 := 0 to 15 do crc := Update32(header5.b4len[temp2],2,crc); If (crc <> header5.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header5)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header5.b0len,temp); If NOT (temp = header5.b0len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header5.b1len,temp); If NOT (temp = header5.b1len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header5.b2len,temp); If NOT (temp = header5.b2len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header5.b3len,temp); If NOT (temp = header5.b3len) then begin CloseF(f); EXIT; end; songdata.tempo := header5.tempo; songdata.speed := header5.speed; songdata.common_flag := header5.cflag; songdata.patt_len := header5.patln; songdata.nm_tracks := header5.nmtrk; songdata.macro_speedup := header5.mcspd; songdata.flag_4op := header5.is4op; Move(header5.locks,songdata.lock_flags,SizeOf(songdata.lock_flags)); APACK_decompress(buf1,songdata.pattern_order); BlockReadF(f,buf1,header5.b4len[0],temp); If NOT (temp = header5.b4len[0]) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,pattdata^[0]); For temp2 := 1 to 15 do If ((header5.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header5.b4len[temp2],temp); If NOT (temp = header5.b4len[temp2]) then begin CloseF(f); EXIT; end; If (temp2*8+8 <= max_patterns) then APACK_decompress(buf1,pattdata^[temp2]) else limit_exceeded := TRUE; end; end; If (header.ffver = 11) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b5len[temp2],temp); If NOT (temp = header.b5len[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header.b0len,2,crc); crc := Update32(header.b1len,2,crc); crc := Update32(header.b2len,2,crc); crc := Update32(header.b3len,2,crc); crc := Update32(header.b4len,2,crc); For temp2 := 0 to 15 do crc := Update32(header.b5len[temp2],2,crc); If (crc <> header.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,songdata.dis_fmreg_col); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); EXIT; end; songdata.tempo := header.tempo; songdata.speed := header.speed; songdata.common_flag := header.cflag; songdata.patt_len := header.patln; songdata.nm_tracks := header.nmtrk; songdata.macro_speedup := header.mcspd; songdata.flag_4op := header.is4op; Move(header.locks,songdata.lock_flags,SizeOf(songdata.lock_flags)); APACK_decompress(buf1,songdata.pattern_order); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); EXIT; end; APACK_decompress(buf1,pattdata^[0]); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b5len[temp2],temp); If NOT (temp = header.b5len[temp2]) then begin CloseF(f); EXIT; end; If (temp2*8+8 <= max_patterns) then APACK_decompress(buf1,pattdata^[temp2]) else limit_exceeded := TRUE; end; end; If (header.ffver in [12,FFVER_A2T]) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b5len[temp2],temp); If NOT (temp = header.b5len[temp2]) then begin CloseF(f); EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header.b0len,2,crc); crc := Update32(header.b1len,2,crc); crc := Update32(header.b2len,2,crc); crc := Update32(header.b3len,2,crc); crc := Update32(header.b4len,2,crc); For temp2 := 0 to 15 do crc := Update32(header.b5len[temp2],2,crc); If (crc <> header.crc32) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; temp := LZH_decompress(buf1,buf2,header.b0len); Move(buf2,songdata.ins_4op_flags,SizeOf(songdata.ins_4op_flags)); Move(buf2[SizeOf(songdata.ins_4op_flags)],songdata.reserved_data, SizeOf(songdata.reserved_data)); Move(buf2[SizeOf(songdata.ins_4op_flags)],songdata.reserved_data, SizeOf(songdata.reserved_data)); Move(buf2[SizeOf(songdata.ins_4op_flags)+ SizeOf(songdata.reserved_data)],songdata.instr_data, temp-SizeOf(songdata.ins_4op_flags)+ SizeOf(songdata.reserved_data)); If (header.b1len <> 0) then begin BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); EXIT; end; LZH_decompress(buf1,songdata.instr_macros,header.b1len); end; If (header.b2len <> 0) then begin BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); EXIT; end; LZH_decompress(buf1,songdata.macro_table,header.b2len); end; If (header.b3len <> 0) then begin BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); EXIT; end; LZH_decompress(buf1,songdata.dis_fmreg_col,header.b3len); end; BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); EXIT; end; songdata.tempo := header.tempo; songdata.speed := header.speed; songdata.common_flag := header.cflag; songdata.patt_len := header.patln; songdata.nm_tracks := header.nmtrk; songdata.macro_speedup := header.mcspd; songdata.flag_4op := header.is4op; Move(header.locks,songdata.lock_flags,SizeOf(songdata.lock_flags)); LZH_decompress(buf1,songdata.pattern_order,header.b4len); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); EXIT; end; LZH_decompress(buf1,pattdata^[0],header.b5len[0]); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b5len[temp2],temp); If NOT (temp = header.b5len[temp2]) then begin CloseF(f); EXIT; end; If (temp2*8+8 <= max_patterns) then begin LZH_decompress(buf1,pattdata^[temp2],header.b5len[temp2]); end else limit_exceeded := TRUE; end; end; speed := songdata.speed; tempo := songdata.tempo; CloseF(f); songdata_title := NameOnly(songdata_source); Case header.ffver of 1..4: load_flag := 3; else load_flag := 4; end; end; function dec2hex(dec: Byte): Byte; begin dec2hex := (dec DIV 10)*16 +(dec MOD 10); end; function truncate_string(str: String): String; begin While (Length(str) > 0) and (str[Length(str)] in [#0,#32,#255]) do Delete(str,Length(str),1); truncate_string := str; end; procedure amd_file_loader; type tPATDAT = array[0..$24] of array[0..$3f] of array[1..9] of array[0..2] of Byte; type tINSDAT = Record iName: array[1..23] of Char; { Instrument name } iData: array[0..10] of Byte; { Instrument data } end; type tHEADER = Record sname: array[1..24] of Char; { Name of song [ASCIIZ] } aname: array[1..24] of Char; { Name of author [ASCIIZ] } instr: array[0..25] of tINSDAT; { 26 instruments } snlen: Byte; { Song length } nopat: Byte; { Number of patterns -1 } order: array[0..$7f] of Byte; { Pattern table } ident: array[1..9] of Char; { ID } versn: Byte; { Version 10h=normal module } { 11h=packed module } end; const id_amd = ' 0) then chunk.instr_def := (byte2 SHR 4)+(byte1 AND 1) SHL 4; If (byte1 SHR 4 in [1..12]) and ((byte1 SHR 1) AND 7 in [0..7]) then chunk.note := 12*((byte1 SHR 1) AND 7)+(byte1 SHR 4); param := byte3 AND $7f; Case byte2 AND $0f of { ARPEGGIO } $00: begin chunk.effect_def := ef_Arpeggio; chunk.effect := dec2hex(param); end; { SLIDE FREQUENCY UP } $01: begin chunk.effect_def := ef_FSlideUp; chunk.effect := param; end; { SLIDE FREQUENCY DOWN } $02: begin chunk.effect_def := ef_FSlideDown; chunk.effect := param; end; { SET CARRIER/MODULATOR INTENSITY } $03: If (param DIV 10 in [1..9]) then begin chunk.effect_def := ef_SetCarrierVol; chunk.effect := (param DIV 10)*7; end else If (param MOD 10 in [1..9]) then begin chunk.effect_def := ef_SetModulatorVol; chunk.effect := (param MOD 10)*7; end; { SET THE VOLUME } $04: begin chunk.effect_def := ef_SetInsVolume; If (param < 64) then chunk.effect := param else chunk.effect := 63; end; { JUMP INTO PATTERN } $05: begin chunk.effect_def := ef_PositionJump; If (param < 100) then chunk.effect := param else chunk.effect := 99; end; { PATTERNBREAK } $06: begin chunk.effect_def := ef_PatternBreak; If (param < 64) then chunk.effect := param else chunk.effect := 63; end; { SET SONGSPEED } $07: If (param < 99) then If (param in [1..31]) then begin chunk.effect_def := ef_SetSpeed; chunk.effect := param; end else begin chunk.effect_def := ef_SetTempo; If (param = 0) then chunk.effect := 18 else chunk.effect := param; end; { TONEPORTAMENTO } $08: begin chunk.effect_def := ef_TonePortamento; chunk.effect := param; end; { EXTENDED COMMAND } $09: If (param < 60) then Case param DIV 10 of { DEFINE CELL-TREMOLO } 0: If (param MOD 10 < 2) then begin chunk.effect_def := ef_Extended; chunk.effect := dec2hex(param); end; { DEFINE CELL-VIBRATO } 1: If (param MOD 10 < 2) then begin chunk.effect_def := ef_Extended; chunk.effect := $10+dec2hex(param); end; { INCREASE VOLUME FAST } 2: begin chunk.effect_def := ef_VolSlide; chunk.effect := (param MOD 10)*16; end; { DECREASE VOLUME FAST } 3: begin chunk.effect_def := ef_VolSlide; chunk.effect := param MOD 10; end; { INCREASE VOLUME FINE } 4: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_VolSlideUpXF*16+(param MOD 10); end; { DECREASE VOLUME FINE } 5: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_VolSlideDnXF*16+(param MOD 10); end; end; end; // specific corrections for Amusic event If (chunk.note = 0) then chunk.instr_def := 0; put_chunk(pattern,line,channel,chunk); end; procedure import_amd_packed_patterns(var data; patterns: Byte); var temp,temp2,temp3,temp4,temp5: Word; count: Byte; var tracks: Word; track_order: array[0..$3f] of array[1..9] of Word; track: array[0..$3f] of tCHUNK; begin temp := (patterns+1)*9*SizeOf(WORD); Move(data,track_order,temp); tracks := pBYTE(@data)[temp]+(pBYTE(@data)[temp+1]) SHL 8; Inc(temp,2); temp3 := 0; temp4 := 0; count := 0; Repeat If (count = 0) then begin If (temp3 = 0) then begin temp2 := pBYTE(@data)[temp]+(pBYTE(@data)[temp+1]) SHL 8; Inc(temp,2); end; If (pBYTE(@data)[temp] OR $80 <> pBYTE(@data)[temp]) then begin If (temp2 DIV 9 <= $3f) and (temp2 MOD 9 < 9) then import_amd_event(temp2 DIV 9,temp3,temp2 MOD 9 +1, pBYTE(@data)[temp+2], pBYTE(@data)[temp+1], pBYTE(@data)[temp+0]); Inc(temp,3); end else begin count := (pBYTE(@data)[temp] AND $7f)-1; Inc(temp); end; end else Dec(count); Inc(temp3); If (temp3 > $3f) then begin temp3 := 0; count := 0; Inc(temp4); end; until NOT (temp4 < tracks); For temp := 0 to patterns do For temp2 := 1 to 9 do begin temp3 := track_order[temp][temp2]; temp4 := temp3 DIV 9; If (temp3 < 64*9) then begin For temp5 := 0 to $3f do get_chunk(temp4,temp5,temp3 MOD 9 +1,track[temp5]); For temp5 := 0 to $3f do put_chunk( temp,temp5,temp2,track[temp5]); end; end; end; function get_byte(var pos: Longint): Byte; begin If (pos = SizeOf(buf1)) then begin Move(buf3,buf1,SizeOf(buf3)); pos := 0; end; get_byte := buf1[pos]; Inc(pos); end; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and ((header.ident = id_amd) or (header.ident = id_xms))) then begin CloseF(f); EXIT; end; load_flag := $7f; If NOT (header.versn in [$10,$11]) then begin CloseF(f); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); EXIT; end; tmp2 := WORD_NULL; If (temp = SizeOf(buf1)) then begin FillChar(buf3,SizeOf(buf3),0); BlockReadF(f,buf3,SizeOf(buf3),tmp2); If (IOresult <> 0) then begin CloseF(f); EXIT; end; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 50; speed := 6; songdata.tempo := tempo; songdata.speed := speed; For temp2 := 0 to header.snlen-1 do If (temp2 < 128) and (header.order[temp2] in [0..header.nopat]) then songdata.pattern_order[temp2] := header.order[temp2]; For temp2 := 0 to 25 do begin import_amd_instrument(temp2+1,header.instr[temp2].iData); songdata.instr_names[temp2+1] := Copy(songdata.instr_names[temp2+1],1,9)+ truncate_string(header.instr[temp2].iName); end; temp := 0; If (header.versn = $10) then For temp2 := 0 to header.nopat do For temp3 := 0 to $3f do For temp4 := 1 to 9 do begin byte3 := get_byte(temp); byte2 := get_byte(temp); byte1 := get_byte(temp); import_amd_event(temp2,temp3,temp4,byte1,byte2,byte3); end else import_amd_packed_patterns(buf1,header.nopat); songdata.common_flag := songdata.common_flag OR $80; songdata.songname := CutStr(asciiz_string(header.sname)); songdata.composer := CutStr(asciiz_string(header.aname)); import_old_flags; CloseF(f); songdata_title := NameOnly(songdata_source); If (header.ident = id_amd) then load_flag := 5 else load_flag := 6; end; procedure import_hsc_instrument(inst: Byte; var data); forward; procedure import_cff_event(patt,line,chan,byte0,byte1,byte2: Byte); var chunk: tCHUNK; temp1,temp2,temp3,temp4: Byte; begin FillChar(chunk,SizeOf(chunk),0); temp1 := byte2; temp2 := temp1 DIV 16; temp3 := temp1 MOD 16; Case CHAR(byte1) of { SET SPEED } 'A': If (temp1 > 0) then begin chunk.effect_def := ef_SetSpeed; chunk.effect := temp1; end; { SET CARRIER WAVEFORM } 'B': If (temp1 < 4) then begin chunk.effect_def := ef_SetWaveform; chunk.effect := temp1*16; end; { SET MODULATOR VOLUME } 'C': begin chunk.effect_def := ef_SetModulatorVol; If (temp1 < 64) then chunk.effect := 63-temp1 else chunk.effect := 0; end; { VOLUME SLIDE UP/DOWN } 'D': begin chunk.effect_def := ef_VolSlide; chunk.effect := temp1; end; { SLIDE DOWN } 'E': If (temp1 <> 0) then begin chunk.effect_def := ef_FSlideDown; chunk.effect := temp1; end; { SLIDE UP } 'F': If (temp1 <> 0) then begin chunk.effect_def := ef_FSlideUp; chunk.effect := temp1; end; { SET CARRIER VOLUME } 'G': begin chunk.effect_def := ef_SetCarrierVol; If (temp1 < 64) then chunk.effect := 63-temp1 else chunk.effect := 0; end; { SET TEMPO } 'H': If (temp1 > 0) then begin chunk.effect_def := ef_SetTempo; If NOT (temp1 > 21) then temp1 := 125; temp4 := 1412926 DIV LONGINT(temp1 SHR 1); chunk.effect := 1; While (1193180 DIV chunk.effect > temp4) and (chunk.effect < 255) do Inc(chunk.effect); end; { SET INSTRUMENT } 'I': If (temp1 < 47) then begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; chunk.instr_def := temp1+1; end; { ARPEGGIO } 'J': begin chunk.effect_def := ef_Arpeggio; chunk.effect := temp1; end; { JUMP TO ORDER } 'K': If (temp1 < 128) then begin chunk.effect_def := ef_PositionJump; chunk.effect := temp1; end; { JUMP TO NEXT PATTERN IN ORDER } 'L': chunk.effect_def := ef_PatternBreak; { SET TREMOLO HIGHER / SET VIBRATO DEEPER } 'M': begin chunk.effect_def := ef_Extended; If (temp2 = 1) and (temp3 = 0) then chunk.effect := dec2hex(01); If (temp2 = 0) and (temp3 = 1) then chunk.effect := dec2hex(10); If (temp2 = 1) and (temp3 = 1) then chunk.effect := dec2hex(11); end; end; Case byte0 of { REGULAR NOTE } 1..12*8+1: begin If NOT fix_c_note_bug then chunk.note := byte0 else begin chunk.note := byte0+1; If (chunk.note > 12*8+1) then chunk.note := 12*8+1; end; end; { PAUSE } $6d: chunk.note := BYTE_NULL; end; put_chunk(patt,line,chan,chunk); end; procedure import_cff_patterns(var data; patterns: Byte); type tPATDAT = array[0..$24] of array[0..$3f] of array[1..9] of array[0..2] of Byte; var voice: array[1..9] of Byte; arpgg: array[1..9] of Byte; chunk: tCHUNK; temp,temp2,temp3,temp4: Byte; order,patt: Byte; patt_break: Byte; patts: String; function _empty_event(var data): Boolean; begin _empty_event := (pBYTE(@data)[0] = 0) and (pBYTE(@data)[1] = 0) and (pBYTE(@data)[2] = 0); end; begin patts := ''; FillChar(arpgg,SizeOf(arpgg),0); If NOT accurate_conv then For temp := 1 to 9 do voice[temp] := temp else For temp := 1 to 9 do voice[temp] := 0; For temp := 0 to $24 do For temp2 := 0 to $3f do For temp3 := 1 to 9 do If NOT _empty_event(tPATDAT(data)[temp][temp2][temp3]) then import_cff_event(temp,temp2,temp3,tPATDAT(data)[temp][temp2][temp3][0], tPATDAT(data)[temp][temp2][temp3][1], tPATDAT(data)[temp][temp2][temp3][2]); order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] > $24) then Inc(order) else begin patt := songdata.pattern_order[order]; patt_break := BYTE_NULL; For temp2 := 0 to $3f do For temp3 := 1 to 9 do begin get_chunk(patt,temp2,temp3,chunk); temp4 := tPATDAT(data)[patt][temp2][temp3][2]; Case CHAR(tPATDAT(data)[patt][temp2][temp3][1]) of { SET MODULATOR VOLUME } 'C': If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; { SET CARRIER VOLUME } 'G': If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; { SET INSTRUMENT } 'I': If (temp4 < 47) then If (temp2 <> patt_break) then begin voice[temp3] := temp4+1; If NOT accurate_conv then chunk.instr_def := voice[temp3]; end; { ARPEGGIO } 'J': begin chunk.effect_def := ef_Arpeggio; If (temp4 <> 0) then begin chunk.effect := temp4; arpgg[temp3] := temp4; end else chunk.effect := arpgg[temp3]; end; { JUMP TO ORDER } 'K': If (temp4 < 128) then patt_break := temp2+1; { JUMP TO NEXT PATTERN IN ORDER } 'L': patt_break := temp2+1; end; Case tPATDAT(data)[patt][temp2][temp3][0] of { REGULAR NOTE } 1..12*8+1: begin If accurate_conv then If (voice[temp3] = 0) then begin voice[temp3] := temp3; chunk.instr_def := voice[temp3]; end; If NOT accurate_conv then chunk.instr_def := voice[temp3]; end; end; If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then put_chunk(patt,temp2,temp3,chunk); end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $40); end; procedure cff_file_loader; type tHEADER = Record ident: array[1..16] of Char; { Identification } versn: Byte; { Format version } fsize: Word; { Filesize -32 } cflag: Byte; { Flag 1=compressed data } resrv: array[0..11] of Byte; { Reserved } end; type tINSDAT = Record iData: array[0..11] of Byte; { Instrument data } iName: array[1..20] of Char; { Instrument name } end; type tHEADR2 = Record instr: array[0..46] of tINSDAT; { 47 instruments } nopat: Byte; { Number of patterns } ascii: array[1..31] of Char; { ASCII blab } writr: array[1..20] of Char; { Song writer } sname: array[1..20] of Char; { Song name } order: array[0..64] of Byte; { Pattern order } end; const _PRE_ASCII_BLAB_SIZE = $5e1; // SizeOf(tHEADR2.instr)+SizeOf(tHEADR2.nopat) const id = ''+#26+CHR($de)+CHR($e0); ascii_blab = 'CUD-FM-File - SEND A POSTCARD -'; var f: File; header: tHEADER; headr2: tHEADR2; temp,temp2: Longint; offs,out_size: Longint; function LZTYR_decompress(var input,output): Longint; type tSTRING = array[0..255] of Byte; var input_idx: Longint; the_string, temp_string: tSTRING; old_code_length: Byte; repeat_length: Byte; repeat_counter: Longint; output_length: Longint; code_length: Byte; bits_buffer: Longint; bits_left: Word; old_code: Longint; new_code: Longint; idx: Word; _cff_heap_length: Word; _cff_dictionary_length: Word; _cff_dictionary: array[0..32767] of Pointer; function get_code: Longint; var code: Longint; begin While (bits_left < code_length) do begin bits_buffer := bits_buffer OR (pBYTE(@input)[input_idx] SHL bits_left); Inc(input_idx); Inc(bits_left,8); end; code := bits_buffer AND ((1 SHL code_length)-1); bits_buffer := bits_buffer SHR code_length; Dec(bits_left,code_length); get_code := code; end; procedure translate_code(code: Longint; var str: tSTRING); var translated_string: tSTRING; begin If (code >= $104) then Move(_cff_dictionary[code-$104]^,translated_string, BYTE(_cff_dictionary[code-$104]^)+1) else begin translated_string[0] := 1; translated_string[1] := (code-4) AND $0ff; end; Move(translated_string,str,256); end; procedure startup; var idx: Longint; begin old_code := get_code; translate_code(old_code,the_string); If (the_string[0] > 0) then For idx := 0 to the_string[0]-1 do begin pBYTE(@output)[output_length] := the_string[idx+1]; Inc(output_length); end; end; procedure cleanup; begin code_length := 9; bits_buffer := 0; bits_left := 0; _cff_heap_length := 0; _cff_dictionary_length := 0; end; procedure expand__cff_dictionary(str: tSTRING); begin If (str[0] >= $0f0) then EXIT; Move(str,buf3[_cff_heap_length],str[0]+1); _cff_dictionary[_cff_dictionary_length] := Addr(buf3[_cff_heap_length]); Inc(_cff_dictionary_length); Inc(_cff_heap_length,str[0]+1); end; begin input_idx := 0; output_length := 0; cleanup; startup; Repeat new_code := get_code; // $00: end of data If (new_code = 0) then BREAK; // $01: end of block If (new_code = 1) then begin cleanup; startup; CONTINUE; end; // $02: expand code length If (new_code = 2) then begin Inc(code_length); CONTINUE; end; // $03: RLE If (new_code = 3) then begin old_code_length := code_length; code_length := 2; repeat_length := get_code+1; code_length := 4 SHL get_code; repeat_counter := get_code; For idx := 0 to PRED(repeat_counter*repeat_length) do begin pBYTE(@output)[output_length] := pBYTE(@output)[output_length-repeat_length]; Inc(output_length); end; code_length := old_code_length; startup; CONTINUE; end; If (new_code >= $104+_cff_dictionary_length) then begin Inc(the_string[0]); the_string[the_string[0]] := the_string[1]; end else begin translate_code(new_code,temp_string); Inc(the_string[0]); the_string[the_string[0]] := temp_string[1]; end; expand__cff_dictionary(the_string); translate_code(new_code,the_string); For idx := 0 to PRED(the_string[0]) do begin pBYTE(@output)[output_length] := the_string[idx+1]; Inc(output_length); end; old_code := new_code; until FALSE; LZTYR_decompress := output_length; end; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) or (FileSize(f) > SizeOf(buf1)) then begin CloseF(f); EXIT; end; load_flag := $7f; If (header.cflag = 1) then begin FillChar(buf1,SizeOf(buf1),0); ResetF(f); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); EXIT; end; CloseF(f); temp := LZTYR_decompress(buf1[$30],hash_buffer); out_size := temp; offs := SensitiveScan(hash_buffer,0,temp,ascii_blab); If (offs <> _PRE_ASCII_BLAB_SIZE) then begin EXIT; end; FillChar(buf1,SizeOf(buf1),0); Move(hash_buffer,headr2,SizeOf(headr2)); Move(POINTER(Ofs(hash_buffer)+SizeOf(headr2))^,buf1,out_size-SizeOf(headr2)); end else begin BlockReadF(f,headr2,SizeOf(headr2),temp); If NOT ((temp = SizeOf(headr2)) and (headr2.ascii = ascii_blab)) then begin CloseF(f); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); EXIT; end; CloseF(f); end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 51; speed := 6; songdata.tempo := tempo; songdata.speed := speed; For temp2 := 0 to 64 do If (headr2.order[temp2] in [0..headr2.nopat]) then songdata.pattern_order[temp2] := headr2.order[temp2]; For temp2 := 0 to 46 do begin import_hsc_instrument(temp2+1,headr2.instr[temp2].iData); songdata.instr_data[temp2+1].fine_tune := 0; songdata.instr_names[temp2+1] := Copy(songdata.instr_names[temp2+1],1,9)+ truncate_string(headr2.instr[temp2].iName); end; songdata.common_flag := songdata.common_flag OR 2; songdata.songname := CutStr(headr2.sname); songdata.composer := CutStr(headr2.writr); import_old_flags; import_cff_patterns(buf1,headr2.nopat); songdata_title := NameOnly(songdata_source); load_flag := 7; end; procedure import_standard_instrument(inst: Byte; var data); begin With songdata.instr_data[inst] do begin fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[6]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[7]; fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 3; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3; fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f; end; songdata.instr_data[inst].panning := 0; songdata.instr_data[inst].fine_tune := 0; end; procedure dfm_file_loader; const id = 'DFM'+#26; var header: Record ident: array[1..4] of Char; versn: Word; sname: String[32]; tempo: Byte; instn: array[1..32] of String[11]; instd: array[1..32] of tFM_INST_DATA; order: array[1..128] of Byte; patts: Byte; end; var f: File; temp,temp2,temp3: Longint; pattern,line,channel,byte1,byte2: Byte; procedure import_dfm_event(patt,line,chan,byte1,byte2: Byte); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); If (byte1 AND $0f in [1..12,15]) and ((byte1 SHR 4) AND 7 in [0..7]) then If (byte1 AND $0f <> 15) then chunk.note := SUCC(PRED(byte1 AND $0f)+((byte1 SHR 4) AND 7)*12) else chunk.note := BYTE_NULL; Case byte2 SHR 5 of { INSTRUMENT CHANGE } 1: chunk.instr_def := SUCC(byte2 AND $1f); { SET INSTRUMENT VOLUME } 2: begin chunk.effect_def := ef_SetInsVolume; chunk.effect := (byte2 AND $1f)*2; end; { TEMPO CHANGE } 3: begin chunk.effect_def := ef_SetSpeed; chunk.effect := SUCC(byte2 AND $1f); end; { SLIDE UP } 4: begin chunk.effect_def := ef_FSlideUpFine; chunk.effect := byte2 AND $1f; end; { SLIDE DOWN } 5: begin chunk.effect_def := ef_FSlideDownFine; chunk.effect := byte2 AND $1f; end; { END OF PATTERN } 7: chunk.effect_def := ef_PatternBreak; end; put_chunk(patt,line,chan,chunk); end; procedure process_dfm_patterns(patterns: Byte); var chunk: tCHUNK; temp2,temp3: Byte; order,patt: Byte; patts: String; instr_cache: array[1..18] of Byte; begin patts := ''; FillChar(instr_cache,SizeOf(instr_cache),0); order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; For temp2 := 0 to $3f do For temp3 := 1 to 9 do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.instr_def <> 0) then begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; instr_cache[temp3] := chunk.instr_def; If NOT (chunk.note in [1..12*8+1]) and NOT accurate_conv then chunk.instr_def := 0; end else If (chunk.note in [1..12*8+1]) and (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := instr_cache[temp3]; If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then put_chunk(patt,temp2,temp3,chunk); end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); end; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); EXIT; end; load_flag := $7f; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 135; speed := SUCC(header.tempo); songdata.songname := CutStr(header.sname); songdata.tempo := tempo; songdata.speed := speed; songdata.common_flag := songdata.common_flag OR 1; songdata.common_flag := songdata.common_flag OR 2; songdata.common_flag := songdata.common_flag OR 8; songdata.common_flag := songdata.common_flag OR $10; import_old_flags; For temp2 := 1 to 128 do If (header.order[temp2] in [0..$7f]) then songdata.pattern_order[temp2-1] := header.order[temp2] else If (header.order[temp2] = $80) then BREAK else songdata.pattern_order[temp2-1] := $80+temp2; For temp2 := 1 to 32 do begin songdata.instr_names[temp2] := Copy(songdata.instr_names[temp2],1,9)+ CutStr(header.instn[temp2]); While (BYTE(songdata.instr_names[temp2][ Length(songdata.instr_names[temp2])]) < 32) and (Length(songdata.instr_names[temp2]) <> 0) do Delete(songdata.instr_names[temp2], Length(songdata.instr_names[temp2]),1); import_standard_instrument(temp2,header.instd[temp2]); end; temp2 := 0; temp3 := 0; Repeat pattern := buf1[temp2]; If (pattern > 127) then begin CloseF(f); EXIT; end; Inc(temp2); Inc(temp3); For line := 0 to $3f do For channel := 1 to 9 do begin byte1 := buf1[temp2]; If (temp2 >= temp) then begin CloseF(f); EXIT; end else Inc(temp2); If (byte1 OR $80 <> byte1) then byte2 := 0 else begin byte2 := buf1[temp2]; Inc(temp2); end; import_dfm_event(pattern,line,channel,byte1,byte2); end; until (temp2 >= temp); process_dfm_patterns(temp3); CloseF(f); songdata_title := NameOnly(songdata_source); load_flag := 8; end; type tHSC_PATTERNS = array[0..$31] of array[0..$3f] of array[1..9] of Word; type tHSC_DATA = Record instr: array[0..$7f] of array[0..$0b] of Byte; order: array[0..$31] of Byte; patts: tHSC_PATTERNS; end; procedure import_hsc_event(patt,line,chan: Byte; event: Word); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); Case HI(event) of { REGULAR NOTE } 1..12*8+1: If NOT fix_c_note_bug then chunk.note := HI(event) else begin chunk.note := HI(event)+1; If (chunk.note > 12*8+1) then chunk.note := 12*8+1; end; { PAUSE } $7f: chunk.note := BYTE_NULL; { INSTRUMENT } $80: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; chunk.instr_def := LO(event)+1; chunk.note := BYTE_NULL; end; end; If (HI(event) <> $80) then Case (LO(event) AND $0f0) of { PATTERNBREAK } $00: If (LO(event) AND $0f = 1) then chunk.effect_def := ef_PatternBreak; { MANUAL SLIDE UP } $10: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneUp*16+ max(LO(event) AND $0f +1,15); end; { MANUAL SLIDE DOWN } $20: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneDown*16+ max(LO(event) AND $0f +1,15); end; { SET CARRIER VOLUME } $a0: begin chunk.effect_def := ef_SetCarrierVol; chunk.effect := 63-(LO(event) AND $0f)*4; chunk.instr_def := LO(event)+1; end; { SET MODULATOR VOLUME } $b0: begin chunk.effect_def := ef_SetModulatorVol; chunk.effect := 63-(LO(event) AND $0f)*4; end; { SET INSTRUMENT VOLUME } $c0: begin chunk.effect_def := ef_SetInsVolume; chunk.effect := 63-(LO(event) AND $0f)*4; end; { SET SPEED } $f0: begin chunk.effect_def := ef_SetSpeed; chunk.effect := (LO(event) AND $0f)+1; end; end; put_chunk(patt,line,chan,chunk); end; procedure import_hsc_patterns(var data; patterns: Byte); var voice: array[1..9] of Byte; event: Word; chunk: tCHUNK; temp,temp2,temp3: Byte; order,patt: Byte; patt_break: Byte; patts: String; function _hsc_event(patt,line,chan: Byte): Word; begin _hsc_event := LO(tHSC_PATTERNS(data)[patt][line][chan+1])+ HI(tHSC_PATTERNS(data)[patt][line][chan]) SHL 8; end; begin { import_hsc_patterns } patts := ''; If NOT accurate_conv then For temp := 1 to 9 do voice[temp] := temp else For temp := 1 to 9 do voice[temp] := 0; For temp := 0 to $31 do For temp2 := 0 to $3f do For temp3 := 1 to 9 do If (_hsc_event(temp,temp2,temp3) <> 0) then import_hsc_event(temp,temp2,temp3,_hsc_event(temp,temp2,temp3)); order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] > $31) then Inc(order) else begin patt := songdata.pattern_order[order]; patt_break := BYTE_NULL; For temp2 := 0 to $3f do For temp3 := 1 to 9 do begin get_chunk(patt,temp2,temp3,chunk); event := _hsc_event(patt,temp2,temp3); Case HI(event) of { REGULAR NOTE } 1..12*8+1: begin If accurate_conv then If (voice[temp3] = 0) then begin voice[temp3] := temp3; chunk.instr_def := voice[temp3]; end; If NOT accurate_conv then chunk.instr_def := voice[temp3]; end; { INSTRUMENT } $80: If (temp2 <> patt_break) then begin voice[temp3] := LO(event)+1; If NOT accurate_conv then begin chunk.instr_def := voice[temp3]; chunk.note := BYTE_NULL; end; end; end; If (HI(event) <> $80) then Case (LO(event) AND $0f0) of { PATTERNBREAK } $00: If (LO(event) AND $0f = 1) then patt_break := temp2+1; { SET CARRIER VOLUME } $a0: If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; { SET MODULATOR VOLUME } $b0: If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; { SET INSTRUMENT VOLUME } $c0: If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; end; If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then put_chunk(patt,temp2,temp3,chunk); end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); end; procedure import_hsc_instrument(inst: Byte; var data); begin With songdata.instr_data[inst] do begin fm_data.AM_VIB_EG_carrier := pBYTE(@data)[0]; fm_data.AM_VIB_EG_modulator := pBYTE(@data)[1]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[2]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[3]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[4]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[5]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[6]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[7]; fm_data.FEEDBACK_FM := pBYTE(@data)[8] AND $0f; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3; fm_data.WAVEFORM_modulator := pBYTE(@data)[10] AND 3; end; songdata.instr_data[inst].panning := 0; songdata.instr_data[inst].fine_tune := pBYTE(@data)[11] SHR 4; end; var hscbuf: tHSC_DATA; procedure hsc_file_loader; const HSC_KSL: array[0..3] of Byte = (0,3,2,1); var f: File; temp,temp2,temp3: Longint; begin If (Lower(ExtOnly(songdata_source)) <> 'hsc') then begin load_flag := $7f; EXIT; end; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; FillChar(hscbuf,SizeOf(hscbuf),0); BlockReadF(f,hscbuf,SizeOf(hscbuf),temp); If (temp < SizeOf(hscbuf.instr)+SizeOf(hscbuf.order)) then begin CloseF(f); EXIT; end; For temp2 := 0 to $31 do If (hscbuf.order[temp2] > $b0) then hscbuf.order[temp2] := $080; temp3 := 0; While (temp3 < temp-SizeOf(hscbuf.instr)-SizeOf(hscbuf.order)) do begin If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3+1] in [1..12*8+1,$00,$7f,$80]) or NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3] AND $0f0 in [$00,$10,$20,$a0,$b0,$c0,$f0]) then begin If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3+1] in [1..12*8+1,$00,$7f,$80]) then pBYTE(@Addr(hscbuf.patts)^)[temp3+1] := $00; If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3] AND $0f0 in [$00,$10,$20,$a0,$b0,$c0,$f0]) then pBYTE(@Addr(hscbuf.patts)^)[temp3] := 0; end; Inc(temp3,2); end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 18; speed := 2; songdata.common_flag := songdata.common_flag OR 2; songdata.tempo := tempo; songdata.speed := speed; import_old_flags; For temp2 := 0 to $31 do songdata.pattern_order[temp2] := hscbuf.order[temp2]; import_hsc_patterns(hscbuf.patts,(temp-SizeOf(hscbuf.instr) -SizeOf(hscbuf.order)-1) DIV $480); // specific corrections for HSC-Tracker instrument For temp2 := 0 to $7f do begin import_hsc_instrument(temp2+1,hscbuf.instr[temp2]); With songdata.instr_data[temp2+1].fm_data do begin KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $3f+ HSC_KSL[KSL_VOLUM_modulator SHR 6] SHL 6; KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $3f+ HSC_KSL[KSL_VOLUM_carrier SHR 6] SHL 6; end; end; CloseF(f); songdata_title := NameOnly(songdata_source); load_flag := 9; end; type tMTK_DATA = Record sname: String[33]; compo: String[33]; instn: array[0..$7f] of String[33]; instt: array[0..$7f] of array[0..$0b] of Byte; order: array[0..$7f] of Byte; patts: tHSC_PATTERNS; dummy: Byte; end; var buffer2: tMTK_DATA; procedure mtk_file_loader; var f: File; temp,temp2: Longint; crc: Word; old_c_fix: Boolean; const id = 'mpu401tr'#146'kk'#238'r@data'; var header: Record id_string: array[1..18] of Char; crc_16bit: Word; data_size: Word; end; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id_string = id)) then begin CloseF(f); EXIT; end; load_flag := $7f; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); crc := 0; crc := Update16(buf1,temp,crc); If (crc <> header.crc_16bit) then begin CloseF(f); EXIT; end; FillChar(buffer2,SizeOf(buffer2),0); temp2 := RDC_decompress(buf1,buffer2,temp); If NOT (temp2 = header.data_size) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 18; speed := 2; songdata.common_flag := songdata.common_flag OR 2; songdata.tempo := tempo; songdata.speed := speed; import_old_flags; For temp2 := 0 to $31 do If (buffer2.order[temp2] <> $ff) then songdata.pattern_order[temp2] := buffer2.order[temp2] else songdata.pattern_order[temp2] := $080; old_c_fix := fix_c_note_bug; fix_c_note_bug := FALSE; import_hsc_patterns(buffer2.patts, (header.data_size-SizeOf(buffer2.sname) -SizeOf(buffer2.compo) -SizeOf(buffer2.instn) -SizeOf(buffer2.instt) -SizeOf(buffer2.order)-1) DIV $480); fix_c_note_bug := old_c_fix; // specific corrections for MPU-401 TRAKKER instrument For temp2 := 0 to $7f do begin import_hsc_instrument(temp2+1,buffer2.instt[temp2]); With songdata.instr_data[temp2+1].fm_data do begin If (KSL_VOLUM_modulator > 128) then KSL_VOLUM_modulator := KSL_VOLUM_modulator DIV 3; If (KSL_VOLUM_carrier > 128) then KSL_VOLUM_carrier := KSL_VOLUM_carrier DIV 3; end; songdata.instr_names[temp2+1] := Copy(songdata.instr_names[temp2+1],1,9)+ truncate_string(Copy(buffer2.instn[temp2],10,32)); end; songdata.songname := CutStr(buffer2.sname); songdata.composer := CutStr(buffer2.compo); CloseF(f); songdata_title := NameOnly(songdata_source); load_flag := 10; end; procedure rad_file_loader; const id = 'RAD by REALiTY!!'; var header: Record ident: array[1..16] of Char; { Use this to recognize a RAD tune } rmver: Byte; { Version of RAD file (10h) } xbyte: Byte; { bit7 Set if a description follows } end; { bit6 Set if it's a "slow-timer" tune } { bit[4..0] The initial speed of the tune } var f: File; dscbuf: array[0..PRED(80*22)] of Char; pattoffs: array[0..$1f] of Word; temp,temp2,temp3,temp4,temp5,offs0: Longint; procedure import_rad_event(pattern,line,channel,byte1,byte2,byte3: Byte); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); If ((byte2 SHR 4)+(byte1 SHR 7) SHL 4 <> 0) then chunk.instr_def := (byte2 SHR 4)+(byte1 SHR 7) SHL 4; If (byte1 AND $0f in [1..12]) then chunk.note := 12*((byte1 SHR 4) AND 7)+(byte1 AND $0f)+1 else If (byte1 AND $0f = $0f) then chunk.note := BYTE_NULL; Case byte2 AND $0f of { PORTAMENTO (FREQUENCY SLIDE) UP } $01: begin chunk.effect_def := ef_FSlideUp; chunk.effect := byte3; end; { PORTAMENTO (FREQUENCY SLIDE) DOWN } $02: begin chunk.effect_def := ef_FSlideDown; chunk.effect := byte3; end; { PORTAMENTO TO NOTE } $03: begin chunk.effect_def := ef_TonePortamento; chunk.effect := byte3; end; { PORTAMENTO TO NOTE WITH VOLUME SLIDE } $05: If (byte3 in [1..49]) then begin chunk.effect_def := ef_TPortamVolSlide; chunk.effect := max(byte3,15); If (byte3 > 15) then begin chunk.effect_def2 := ef_TPortamVolSlide; chunk.effect2 := max(byte3-15,15); end; end else If (byte3 in [51..99]) then begin chunk.effect_def := ef_TPortamVolSlide; chunk.effect := max(byte3-50,15)*16; If (byte3-50 > 15) then begin chunk.effect_def2 := ef_TPortamVolSlide; chunk.effect2 := max(byte3-50-15,15); end; end; { VOLUME SLIDE } $0a: If (byte3 in [1..49]) then begin chunk.effect_def := ef_VolSlide; chunk.effect := max(byte3,15); If (byte3 > 15) then begin chunk.effect_def2 := ef_VolSlide; chunk.effect2 := max(byte3-15,15); end; end else If (byte3 in [51..99]) then begin chunk.effect_def := ef_VolSlide; chunk.effect := max(byte3-50,15)*16; If (byte3-50 > 15) then begin chunk.effect_def2 := ef_VolSlide; chunk.effect2 := max(byte3-50-15,15); end; end; { SET VOLUME } $0c: begin chunk.effect_def := ef_SetInsVolume; If (byte3 < 64) then chunk.effect := byte3 else chunk.effect := 63; end; { JUMP TO NEXT PATTERN IN ORDER LIST } $0d: begin chunk.effect_def := ef_PatternBreak; If (byte3 < 64) then chunk.effect := byte3 else chunk.effect := 63; end; { SET SPEED } $0f: begin chunk.effect_def := ef_SetSpeed; chunk.effect := byte3; end; end; // specific corrections for RAd-Tracker event If (chunk.effect_def in [ef_TonePortamento, ef_TPortamVolSlide]) and (chunk.note = BYTE_NULL) then chunk.note := 0; If (chunk.effect_def in [ef_TonePortamento, ef_TPortamVolSlide]) then chunk.instr_def := 0; If (chunk.note = 0) then chunk.instr_def := 0; put_chunk(pattern,line,channel+1,chunk); end; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); EXIT; end; load_flag := $7f; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); EXIT; end; temp2 := 0; offs0 := SizeOf(header); If (header.xbyte OR $80 = header.xbyte) then begin While (temp2 < temp) and (buf1[temp2] <> 0) do Inc(temp2); If (temp2 >= temp) then begin CloseF(f); EXIT; end; Inc(offs0,temp2+1); Dec(temp,temp2+1); Move(buf1,dscbuf,temp2+1); Move(buf1[temp2+1],buf1,temp); end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; If (header.xbyte OR $40 = header.xbyte) then tempo := 18 else tempo := 50; If (header.xbyte AND $1f in [1..31]) then speed := header.xbyte AND $1f else speed := 2; songdata.tempo := tempo; songdata.speed := speed; temp2 := 0; Repeat temp3 := buf1[temp2]; Inc(temp2); If (temp3 <> 0) and (temp2+11 < temp) then begin import_hsc_instrument(temp3,buf1[temp2]); songdata.instr_data[temp3].fine_tune := 0; Inc(temp2,11); end; until (temp3 = 0) or (temp3 >= temp); Inc(offs0,temp2); Dec(temp,temp2); Move(buf1[temp2],buf1,temp); Inc(offs0,buf1[0]+1); If (buf1[0] <> 0) then Move(buf1[1],songdata.pattern_order,buf1[0]); Inc(offs0,32*SizeOf(WORD)); Dec(temp,buf1[0]+1+32*SizeOf(WORD)); Move(buf1[buf1[0]+1],pattoffs,32*SizeOf(WORD)); Move(buf1[buf1[0]+32*SizeOf(WORD)+1],buf1,temp); temp5 := temp; For temp := 0 to 31 do begin temp2 := 0; temp3 := 0; If (pattoffs[temp] <> 0) and (pattoffs[temp] <= FileSize(f)) then Repeat temp2 := buf1[pattoffs[temp]-offs0+temp3]; Repeat Inc(temp3); temp4 := buf1[pattoffs[temp]-offs0+temp3]; If (buf1[pattoffs[temp]-offs0+temp3+2] AND $0f <> 0) then begin If (temp4 AND $0f in [0..8]) then import_rad_event(temp,temp2 AND $3f,temp4 AND $0f, buf1[pattoffs[temp]-offs0+temp3+1], buf1[pattoffs[temp]-offs0+temp3+2], buf1[pattoffs[temp]-offs0+temp3+3]); Inc(temp3,3); end else begin If (temp4 AND $0f in [0..8]) then import_rad_event(temp,temp2 AND $3f,temp4 AND $0f, buf1[pattoffs[temp]-offs0+temp3+1], buf1[pattoffs[temp]-offs0+temp3+2], 0); Inc(temp3,2); end; until (temp4 OR $80 = temp4) or (temp3 > temp5); Inc(temp3); until (temp2 OR $80 = temp2) or (temp3 > temp5); end; CloseF(f); songdata_title := NameOnly(songdata_source); load_flag := 11; end; const temp_ef_Arpeggio = $0f0; temp_ef_rep = $0f1; temp_ef_XFVSlide = $0f2; var ins_c4factor: array[1..99] of Shortint; procedure fix_s3m_commands(patterns: Byte); var chunk,chunk2: tCHUNK; temp,temp4: Byte; patt_break: Byte; order,patt: Byte; patts: String; ins_cache, misc_cache, arpg_cache, volsld_cache, slide_cache, note_cache, patloop_cache: array[1..20] of Byte; prev_cache: array[1..20] of Record effect_def, effect, effect_def2, effect2: Byte; end; procedure fix_single_pattern(patt: Byte); var temp2,temp3: Byte; begin FillChar(prev_cache,SizeOf(prev_cache),0); FillChar(patloop_cache,SizeOf(patloop_cache),BYTE_NULL); patt_break := BYTE_NULL; For temp2 := 0 to $3f do For temp3 := 1 to 20 do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then patt_break := temp2; If (chunk.instr_def <> 0) and (temp2 <= patt_break) then ins_cache[temp3] := chunk.instr_def; If (chunk.note in [1..12*8+1]) and (temp2 <= patt_break) then note_cache[temp3] := chunk.note; If (chunk.instr_def <> 0) or ((chunk.instr_def = 0) and (chunk.note in [1..12*8+1]) and (ins_cache[temp3] <> 0)) then begin If (chunk.instr_def <> 0) then temp4 := chunk.instr_def else temp4 := ins_cache[temp3]; If (ins_c4factor[temp4] <> 0) and NOT (Pos(CHR(songdata.pattern_order[order]),patts) <> 0) then begin If (ins_c4factor[temp4] <> -127) then chunk.note := min(max(chunk.note+ins_c4factor[temp4],12*8+1),1) else chunk.note := 1; put_chunk(patt,temp2,temp3,chunk); end; end; If (chunk.effect_def = ef_Extended) and (chunk.effect DIV 16 = ef_ex_PatternLoop) and (chunk.effect MOD 16 <> 0) then If NOT (patloop_cache[temp3] in [0,BYTE_NULL]) and (temp2 <> 0) then begin If (prev_cache[temp3].effect_def = 0) and (prev_cache[temp3].effect = 0) then begin get_chunk(patt,PRED(temp2),temp3,chunk2); chunk2.effect_def := ef_Extended; chunk2.effect := ef_ex_PatternLoop*16; If NOT ((chunk2.effect_def = chunk2.effect_def2) and (chunk2.effect = chunk2.effect2)) then begin put_chunk(patt,PRED(temp2),temp3,chunk2); prev_cache[temp3].effect_def := chunk.effect_def; prev_cache[temp3].effect := chunk.effect; end; end else If (prev_cache[temp3].effect_def2 = 0) and (prev_cache[temp3].effect2 = 0) then begin get_chunk(patt,PRED(temp2),temp3,chunk2); chunk2.effect_def2 := ef_Extended; chunk2.effect2 := ef_ex_PatternLoop*16; If NOT ((chunk2.effect_def2 = chunk2.effect_def) and (chunk2.effect2 = chunk2.effect)) then begin put_chunk(patt,PRED(temp2),temp3,chunk2); prev_cache[temp3].effect_def2 := chunk.effect_def2; prev_cache[temp3].effect2 := chunk.effect2; end; end; end else If (patloop_cache[temp3] <> 0) and (temp2 <> 0) then begin get_chunk(patt,0,temp3,chunk2); If (chunk2.effect_def = 0) and (chunk2.effect = 0) then begin chunk2.effect_def := ef_Extended; chunk2.effect := ef_ex_PatternLoop*16; If NOT ((chunk2.effect_def = chunk2.effect_def2) and (chunk2.effect = chunk2.effect2)) then put_chunk(patt,0,temp3,chunk2); end else If (chunk2.effect_def2 = 0) and (chunk2.effect2 = 0) then begin chunk2.effect_def2 := ef_Extended; chunk2.effect2 := ef_ex_PatternLoop*16; If NOT ((chunk2.effect_def2 = chunk2.effect_def) and (chunk2.effect2 = chunk2.effect)) then put_chunk(patt,0,temp3,chunk2); end; end; If (temp2 <= patt_break) then begin If (chunk.effect DIV 16 <> 0) then misc_cache[temp3] := chunk.effect AND $0f0+ misc_cache[temp3] AND $0f else If (chunk.effect_def in [ef_Vibrato, ef_ExtraFineVibrato, ef_Tremolo, ef_Tremor, ef_MultiRetrigNote]) then begin chunk.effect := misc_cache[temp3] AND $0f0+ chunk.effect AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect MOD 16 <> 0) then misc_cache[temp3] := misc_cache[temp3] AND $0f0+ chunk.effect AND $0f else If (chunk.effect_def in [ef_Vibrato, ef_ExtraFineVibrato, ef_Tremolo, ef_Tremor, ef_MultiRetrigNote]) then begin chunk.effect := chunk.effect AND $0f0+ misc_cache[temp3] AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = temp_ef_Arpeggio) then If (chunk.effect <> 0) then arpg_cache[temp3] := chunk.effect else begin chunk.effect := arpg_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, ef_FSlideUp,ef_FSlideUpFine, ef_TonePortamento]) then If (chunk.effect <> 0) then slide_cache[temp3] := chunk.effect else begin chunk.effect := slide_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; // experimental method to fix up frequency slide If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, ef_FSlideUp,ef_FSlideUpFine, ef_Vibrato, ef_ExtraFineVibrato, ef_TonePortamento]) then If (note_cache[temp3] <> 0) then begin If (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato]) then begin temp := chunk.effect AND $0f0; chunk.effect := chunk.effect MOD 16; end; Case SUCC(PRED(note_cache[temp3]) DIV 12) of 1: chunk.effect := max(Round(chunk.effect*0.55),255); 2: chunk.effect := max(Round(chunk.effect*0.75),255); 3: chunk.effect := max(Round(chunk.effect*0.95),255); 4: chunk.effect := max(Round(chunk.effect*1.15),255); 5: chunk.effect := max(Round(chunk.effect*1.35),255); 6: chunk.effect := max(Round(chunk.effect*1.55),255); 7: chunk.effect := max(Round(chunk.effect*1.75),255); 8: chunk.effect := max(Round(chunk.effect*1.95),255); end; If (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato]) then chunk.effect := max(chunk.effect,15)+temp; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = ef_Extended2) and (chunk.effect DIV 16 in [ef_ex2_FreqSlideDnXF,ef_ex2_FreqSlideUpXF]) then If (chunk.effect MOD 16 <> 0) then slide_cache[temp3] := chunk.effect MOD 16 else begin chunk.effect := chunk.effect AND $0f0+slide_cache[temp3] AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_TPortamVolSlide,ef_VibratoVolSlide, ef_VolSlide,ef_VolSlideFine]) and (temp2 <= patt_break) then begin If (chunk.effect <> 0) then volsld_cache[temp3] := chunk.effect else begin chunk.effect := volsld_cache[temp3];; put_chunk(patt,temp2,temp3,chunk); end; end; If (chunk.effect_def = ef_Extended2) and (chunk.effect DIV 16 in [ef_ex2_VolSlideDnXF,ef_ex2_VolSlideUpXF]) then If (chunk.effect MOD 16 <> 0) then Case chunk.effect DIV 16 of ef_ex2_VolSlideDnXF: volsld_cache[temp3] := chunk.effect MOD 16; ef_ex2_VolSlideUpXF: volsld_cache[temp3] := chunk.effect MOD 16 SHL 4; end else begin Case chunk.effect DIV 16 of ef_ex2_VolSlideDnXF: chunk.effect := chunk.effect AND $0f0+volsld_cache[temp3] AND $0f; ef_ex2_VolSlideUpXF: chunk.effect := volsld_cache[temp3] AND $0f0+chunk.effect AND $0f; end; put_chunk(patt,temp2,temp3,chunk); end; end; If (prev_cache[temp3].effect_def in [ef_Vibrato,ef_ExtraFineVibrato,ef_VibratoVolSlide]) and NOT (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato,ef_VibratoVolSlide]) then If (chunk.effect_def = 0) and (chunk.effect = 0) then begin chunk2 := chunk; chunk2.effect_def := ef_Extended; chunk2.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff; If NOT ((chunk2.effect_def = chunk2.effect_def2) and (chunk2.effect = chunk2.effect2)) then begin put_chunk(patt,temp2,temp3,chunk2); chunk := chunk2; end; end else If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then begin chunk2 := chunk; chunk2.effect_def2 := ef_Extended; chunk2.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff; If NOT ((chunk2.effect_def2 = chunk2.effect_def) and (chunk2.effect2 = chunk2.effect)) then begin put_chunk(patt,temp2,temp3,chunk2); chunk := chunk2; end; end; If (chunk.effect_def = ef_Extended) and (chunk.effect DIV 16 = ef_ex_PatternLoop) then patloop_cache[temp3] := chunk.effect MOD 16; prev_cache[temp3].effect_def := chunk.effect_def; prev_cache[temp3].effect := chunk.effect; prev_cache[temp3].effect_def2 := chunk.effect_def2; prev_cache[temp3].effect2 := chunk.effect2; If (chunk.effect_def = temp_ef_Arpeggio) then begin chunk2 := chunk; chunk2.effect_def := ef_Arpeggio; put_chunk(patt,temp2,temp3,chunk2); end; end; end; begin { fix_s3m_commands } FillChar(ins_cache,SizeOf(ins_cache),0); FillChar(note_cache,SizeOf(note_cache),0); FillChar(volsld_cache,SizeOf(volsld_cache),0); FillChar(slide_cache,SizeOf(slide_cache),0); FillChar(misc_cache,SizeOf(misc_cache),0); FillChar(arpg_cache,SizeOf(arpg_cache),0); patts := ''; order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; If NOT (Pos(CHR(patt),patts) <> 0) then fix_single_pattern(patt); Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); For patt := 0 to PRED(patterns) do If NOT (Pos(CHR(patt),patts) <> 0) then fix_single_pattern(patt); end; procedure s3m_file_loader; type tS3M_HEADER = Record songname: array[1..28] of Char; { ASCIIZ } byte1a: Byte; { 1Ah } ftype: Byte; { File type: 16=ST3 module } resrvd1: array[0..1] of Byte; ordnum: Word; { Number of orders in file (should be even!) } insnum: Word; { Number of instruments in file } patnum: Word; { Number of patterns in file } flags: Word; { [ These are old flags for Ffv1. Not supported in ST3.01 } { | +1:st2vibrato } { | +2:st2tempo } { | +4:amigaslides } { | +32:enable filter/sfx with sb } { ] } { +8: 0vol optimizations } { Automatically turn off looping notes whose volume } { is zero for >2 note rows. } { +16: amiga limits } { Disallow any notes that go beyond the amiga hardware } { limits (like amiga does). This means that sliding } { up stops at B#5 etc. Also affects some minor amiga } { compatibility issues. } { +64: st3.00 volumeslides } { Normally volumeslide is NOT performed on first } { frame of each row (this is according to amiga } { playing). If this is set, volumeslide is performed } { ALSO on the first row. This is set by default } { if the Cwt/v files is 0x1300 } { +128: special custom data in file (see below) } cwt_v: Word; { Created with tracker / version: &0xfff=version, >>12=tracker } { ST3.00:0x1300 (NOTE: volumeslides on EVERY frame) } { ST3.01:0x1301 } { ST3.03:0x1303 } { ST3.20:0x1320 } ffi: Word; { File format information } { 1=[VERY OLD] signed samples } { 2=unsigned samples } id: array[1..4] of Char; { "SCRM" } g_v: Byte; { global volume (see next section) } i_s: Byte; { initial speed (command A) } i_t: Byte; { initial tempo (command T) } m_v: Byte; { master volume (see next section) 7 lower bits } { bit 8: stereo(1) / mono(0) } u_c: Byte; { ultra click removal } d_p: Byte; { 252 when default channel pan positions are present } { in the end of the header (xxx3). If !=252 ST3 doesn't } { try to load channel pan settings. } resrvd2: array[0..7] of Byte; special: Word; chan_set: array[1..32] of Byte; end; type tS3M_ADLINS = Record itype: Byte; { 2:amel 3:abd 4:asnare 5:atom 6:acym 7:ahihat } dosname: array[1..12] of Char; id0: array[0..2] of Char; fmdata: array[0..11] of Byte; { D00..D0B contains the adlib instrument specs packed like this: } { modulator: carrier: } { D00=[freq.muliplier]+[?scale env.]*16+[?sustain]*32+ =D01 } { [?pitch vib]*64+[?vol.vib]*128 } { D02=[63-volume]+[levelscale&1]*128+[l.s.&2]*64 =D03 } { D04=[attack]*16+[decay] =D05 } { D06=[15-sustain]*16+[release] =D07 } { D08=[wave select] =D09 } { D0A=[modulation feedback]*2+[?additive synthesis] } { D0B=unused } vol: Byte; { Default volume 0..64 } dsk: Byte; resrvd1: array[0..1] of Byte; c2spd: Word; { 'Herz' for middle C. ST3 only uses lower 16 bits. } { Actually this is a modifier since there is no } { clear frequency for adlib instruments. It scales } { the note freq sent to adlib. } hi_c2sp: Word; resrvd2: array[0..11] of Byte; smpname: array[1..28] of Char; { ASCIIZ } id: array[1..4] of Char; { "SCRI" or "SCRS" } end; const id_mod = 'SCRM'; id_ins_adl = 'SCRI'; id_ins_smp = 'SCRS'; var f: File; header: tS3M_HEADER; order_list: array[0..254] of Byte; paraptr_ins: array[1..99] of Word; default_vol: array[1..99] of Byte; paraptr_pat: array[0..99] of Word; temp,temp2: Longint; insdata: tS3M_ADLINS; pat,row,chan: Byte; note,ins,vol,cmd,info: Byte; patlen,index: Word; procedure import_s3m_event(pattern,line,channel,note,ins,vol,cmd,info: Byte); var chunk: tCHUNK; function scale_slide(slide: Byte): Byte; begin If (slide > 16) then scale_slide := Round(16+slide/8) else scale_slide := Round(slide*(2-slide/16)); end; begin FillChar(chunk,SizeOf(chunk),0); chunk.instr_def := ins; Case note of 254: chunk.note := BYTE_NULL; 255: chunk.note := 0; else If (note AND $0f in [0..11]) then chunk.note := 12*((note SHR 4) AND 7)+(note AND $0f)+1 end; If (vol <> BYTE_NULL) then begin chunk.effect_def2 := ef_SetInsVolume; chunk.effect2 := max(vol,63); end else If NOT (note in [254,255]) and (ins <> 0) and (max(default_vol[ins],63) <> 63) then begin chunk.effect_def2 := ef_SetInsVolume; chunk.effect2 := max(default_vol[ins],63); end; Case CHR(cmd+ORD('A')-1) of { NONE } '@': chunk.effect := info; { SET SPEED } 'A': If (info <> 0) then begin chunk.effect_def := ef_SetSpeed; chunk.effect := info; end; { JUMP TO ORDER } 'B': If (info <= 254) then begin chunk.effect_def := ef_PositionJump; chunk.effect := info; end; { BREAK PATTERN } 'C': If (info < 64) then begin chunk.effect_def := ef_PatternBreak; chunk.effect := Str2num(Num2str(info,16),10); end; { VOLUME SLIDE } 'D': { VOLUME SLIDE DOWN } Case info DIV 16 of { NORMAL } 0: begin chunk.effect_def := ef_VolSlide; chunk.effect := info MOD 16; end; { FINE } 15: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := info MOD 16; end; else { VOLUME SLIDE UP } Case info MOD 16 of { NORMAL } 0: begin chunk.effect_def := ef_VolSlide; chunk.effect := info AND $0f0; end; { FINE } 15: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := info AND $0f0; end; end; end; { SLIDE DOWN } 'E': Case info DIV 16 of { NORMAL } 0..13: begin chunk.effect_def := ef_FSlideDown; chunk.effect := scale_slide(info); end; { EXTRA FINE } 14: begin chunk.effect_def := ef_Extended2; If (info <> 0) then chunk.effect := ef_ex2_FreqSlideDnXF*16+min((info AND $0f) DIV 4,1) else chunk.effect := ef_ex2_FreqSlideDnXF*16; end; { FINE } 15: begin chunk.effect_def := ef_FSlideDownFine; chunk.effect := info AND $0f; end; end; { SLIDE UP } 'F': Case info DIV 16 of { NORMAL } 0..13: begin chunk.effect_def := ef_FSlideUp; chunk.effect := scale_slide(info); end; { EXTRA FINE } 14: begin chunk.effect_def := ef_Extended2; If (info <> 0) then chunk.effect := ef_ex2_FreqSlideUpXF*16+min((info AND $0f) DIV 4,1) else chunk.effect := ef_ex2_FreqSlideUpXF*16; end; { FINE } 15: begin chunk.effect_def := ef_FSlideUpFine; chunk.effect := info AND $0f; end; end; { TONE PORTAMENTO } 'G': begin chunk.effect_def := ef_TonePortamento; chunk.effect := scale_slide(info); end; { VIBRATO } 'H': begin chunk.effect_def := ef_Vibrato; chunk.effect := info; end; { FINE VIBRATO } 'U': begin chunk.effect_def := ef_ExtraFineVibrato; chunk.effect := info; end; { TREMOR } 'I': begin chunk.effect_def := ef_Tremor; chunk.effect := info; end; { ARPEGGIO } 'J': begin chunk.effect_def := temp_ef_Arpeggio; chunk.effect := info; end; { VIBRATO + VOLUME SLIDE } 'K': begin chunk.effect_def := ef_VibratoVolSlide; chunk.effect := info; end; { TONE PORTAMENTO + VOLUME SLIDE } 'L': begin chunk.effect_def := ef_TPortamVolSlide; chunk.effect := info; end; { RETRIG NOTE + VOLUME SLIDE } 'Q': begin chunk.effect_def := ef_MultiRetrigNote; chunk.effect := (info MOD 16)*16+info DIV 16; end; { TREMOLO } 'R': begin chunk.effect_def := ef_Tremolo; chunk.effect := info; end; { SPECIAL COMMAND } 'S': Case info DIV 16 of { PATTERN LOOP } $0b: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_PatternLoop*16+info MOD 16; end; { NOTE CUT } $0c: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_NoteCut*16+info MOD 16; end; { NOTE DELAY } $0d: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_NoteDelay*16+info MOD 16; end; { PATTERN DELAY } $0e: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_PatDelayRow*16+info MOD 16; end; end; { TEMPO } 'T': If (info >= 32) then begin chunk.effect_def := ef_SetTempo; chunk.effect := Round(info/2.5); end; { SET GLOBAL VOLUME } 'V': begin chunk.effect_def := ef_SetGlobalVolume; chunk.effect := max(info,63); end; end; If (chunk.effect_def = 0) and (chunk.effect <> 0) then chunk.effect := 0; put_chunk(pattern,line,channel,chunk); end; // experimental method to fix up note fine-tuning function find_scale_factor(freq: Longint; var fine_tune: Shortint): Shortint; const _factor: array[-3..3+1] of Real = (1/8,1/4,1/2,1,2,4,8,16); const _freq: array[1..12+1] of Word = { C-2 C#2 D-2 } ( 33453 DIV 4,35441 DIV 4,37679 DIV 4, { D#2 E-2 F-2 } 39772 DIV 4,42441 DIV 4,44744 DIV 4, { F#2 G-2 G#2 } 47727 DIV 4,50416 DIV 4,53426 DIV 4, { A-2 A#2 B-2 } 56370 DIV 4,59658 DIV 4,63354 DIV 4, { C-3 } 33453 DIV 2); const _fm_freq: array[1..12+1] of Word = ($156, $16b, $181, $198, $1b0, $1ca, $1e5, $202, $220, $241, $263, $287, $2ae); var factor: Real; temp,scaler: Shortint; begin scaler := -3; fine_tune := 0; For scaler := -3 to 3+1 do For temp := 1 to 12 do begin factor := _factor[scaler]; If (freq >= Round(_freq[temp]*factor)) and (freq <= Round(_freq[SUCC(temp)]*factor)) then If (freq-Round(_freq[temp]*factor) < Round(_freq[SUCC(temp)]*factor)-freq) then begin fine_tune := Round((_fm_freq[SUCC(temp)]-_fm_freq[temp])/ (_freq[SUCC(temp)]-_freq[temp])* (freq-Round(_freq[temp]*factor))); find_scale_factor := scaler*12+PRED(temp); EXIT; end else begin fine_tune := Round((_fm_freq[SUCC(temp)]-_fm_freq[temp])/ (_freq[SUCC(temp)]-_freq[temp])* (freq-Round(_freq[SUCC(temp)]*factor))); If (temp <> 12) then find_scale_factor := scaler*12+temp else find_scale_factor := SUCC(scaler)*12; EXIT; end; end; find_scale_factor := -127; fine_tune := 0; end; (* // another method -- it's hard to say whether more or less accurate :) function find_scale_factor(freq: Longint; var fine_tune: Shortint): Shortint; const _factor: array[-3..3+1] of Real = (1/8,1/4,1/2,1,2,4,8,16); _finetune_factor: array[-3..3+1] of Real = (8,4,2,1,1/2,1/4,1/8,1/16); const _freq: array[1..12+1] of Word = { C-2 C#2 D-2 } ( 33453 DIV 4,35441 DIV 4,37679 DIV 4, { D#2 E-2 F-2 } 39772 DIV 4,42441 DIV 4,44744 DIV 4, { F#2 G-2 G#2 } 47727 DIV 4,50416 DIV 4,53426 DIV 4, { A-2 A#2 B-2 } 56370 DIV 4,59658 DIV 4,63354 DIV 4, { C-3 } 33453 DIV 2); var factor: Real; temp,scaler: Shortint; begin scaler := -3; fine_tune := 0; For scaler := -3 to 3+1 do For temp := 1 to 12 do begin factor := _factor[scaler]; If (freq >= Round(_freq[temp]*factor)) and (freq <= Round(_freq[SUCC(temp)]*factor)) then If (freq-Round(_freq[temp]*factor) < Round(_freq[SUCC(temp)]*factor)-freq) then begin fine_tune := Round((freq-Round(_freq[temp]*factor))/ Round(16/_finetune_factor[scaler])); find_scale_factor := scaler*12+PRED(temp); EXIT; end else begin If (temp = 12) then Inc(scaler); fine_tune := Round((freq-Round(_freq[SUCC(temp)]*factor))/ Round(16/_finetune_factor[scaler])); If (temp = 12) then temp := 0; find_scale_factor := scaler*12+temp; EXIT; end; end; find_scale_factor := -127; fine_tune := 0; end; *) begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id = id_mod)) then begin CloseF(f); EXIT; end; load_flag := $7f; If (header.byte1a <> $1a) or (header.ftype <> $10) then begin CloseF(f); EXIT; end; BlockReadF(f,order_list,header.ordnum,temp); If (IOresult <> 0) or (temp <> header.ordnum) then begin CloseF(f); EXIT; end; BlockReadF(f,paraptr_ins,header.insnum*2,temp); If (IOresult <> 0) or (temp <> header.insnum*2) then begin CloseF(f); EXIT; end; BlockReadF(f,paraptr_pat,header.patnum*2,temp); If (IOresult <> 0) or (temp <> header.patnum*2) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; If (header.i_s <> 0) then speed := header.i_s else speed := 1; If (Round(header.i_t/2.5) < 255) then tempo := Round(header.i_t/2.5) else tempo := 255; songdata.tempo := tempo; songdata.speed := speed; songdata.songname := truncate_string(asciiz_string(header.songname)); songdata.common_flag := songdata.common_flag OR $80; import_old_flags; For temp := 32 downto 1 do If (header.chan_set[temp] <> 255) then BREAK; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := max(temp,18) else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; For temp := 1 to max(header.ordnum,128) do Case order_list[temp-1] of 254: songdata.pattern_order[temp-1] := $80+temp; 255: songdata.pattern_order[temp-1] := $80; else songdata.pattern_order[temp-1] := order_list[temp-1]; end; FillChar(ins_c4factor,SizeOf(ins_c4factor),0); For temp := 1 to header.insnum do begin SeekF(f,paraptr_ins[temp]*16); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,insdata,SizeOf(insdata),temp2); If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then begin CloseF(f); EXIT; end; If (truncate_string(insdata.smpname) <> '') then songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ Copy(truncate_string(asciiz_string(insdata.smpname)),1,32) else songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ truncate_string(insdata.dosname); If (insdata.itype in [2..7]) then begin If (insdata.id <> id_ins_adl) and (insdata.id <> id_ins_smp) then begin CloseF(f); EXIT; end; import_standard_instrument(temp,insdata.fmdata); end; default_vol[temp] := insdata.vol; If (insdata.c2spd <> 0) and (insdata.c2spd <> 8363) then ins_c4factor[temp] := find_scale_factor(insdata.c2spd,songdata.instr_data[temp].fine_tune); end; For pat := 0 to PRED(header.patnum) do begin SeekF(f,paraptr_pat[pat]*16); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,patlen,SizeOf(patlen),temp2); If (temp2 <> SizeOf(patlen)) then begin CloseF(f); EXIT; end; If (patlen = 0) then CONTINUE; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,patlen-2,temp2); index := 0; row := 0; Repeat If (buf1[index] <> 0) then begin note := BYTE_NULL; ins := 0; vol := BYTE_NULL; cmd := 0; info := 0; temp := buf1[index]; Inc(index); chan := SUCC(temp AND 31); If (temp OR $20 = temp) then begin note := buf1[index]; Inc(index); ins := buf1[index]; Inc(index); end; If (temp OR $40 = temp) then begin vol := buf1[index]; Inc(index); end; If (temp OR $80 = temp) then begin cmd := buf1[index]; Inc(index); info := buf1[index]; Inc(index); end; If (chan > songdata.nm_tracks) then songdata.nm_tracks := max(chan,18); If (chan in [1..songdata.nm_tracks]) then import_s3m_event(pat,row,chan,note,ins,vol,cmd,info); end else begin Inc(row); Inc(index); end; until (row = 64); end; fix_s3m_commands(header.patnum); CloseF(f); songdata_title := NameOnly(songdata_source); load_flag := 12; end; procedure fix_fmk_commands(patterns: Byte); var chunk,chunk2, chunk3: tCHUNK; patt_break: Byte; order,patt: Byte; patts: String; ins_cache, misc_cache, arpg_cache, forcevol_cache, volsld_cache, xfvolsld_cache, slide_cache: array[1..20] of Byte; _1st_ins_load: array[1..20] of Boolean; _speed_table_fixed: array[0..$7f] of Boolean; prev_cache: array[1..20] of Record effect_def, effect, effect_def2, effect2: Byte; end; procedure fix_single_pattern(patt: Byte); var temp2,temp3: Byte; begin FillChar(prev_cache,SizeOf(prev_cache),0); patt_break := BYTE_NULL; If NOT _speed_table_fixed[patt] then For temp2 := 0 to $3f do begin For temp3 := 1 to 20 do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.effect_def = 0) then begin chunk.effect_def := ef_SetCustomSpeedTab; chunk.effect := $0fa; put_chunk(patt,temp2,temp3,chunk); _speed_table_fixed[patt] := TRUE; end else If (chunk.effect_def2 = 0) then begin chunk.effect_def2 := ef_SetCustomSpeedTab; chunk.effect2 := $0fa; put_chunk(patt,temp2,temp3,chunk); _speed_table_fixed[patt] := TRUE; end; If _speed_table_fixed[patt] then BREAK; end; If _speed_table_fixed[patt] then BREAK; end; For temp2 := 0 to $3f do For temp3 := 1 to 20 do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.effect_def = temp_ef_rep) then begin chunk.effect_def := prev_cache[temp3].effect_def; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = temp_ef_XFVSlide) then begin chunk.effect_def := ef_Extended2; If (xfvolsld_cache[temp3] <> 0) then chunk.effect := ef_ex2_VolSlideUpXF*16+volsld_cache[temp3] DIV 16 else chunk.effect := ef_ex2_VolSlideDnXF*16+volsld_cache[temp3] MOD 16; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then patt_break := temp2; If (temp2 <= patt_break) and (chunk.instr_def <> ins_cache[temp3]) and (chunk.effect_def2 <> ef_ForceInsVolume) then If (chunk.instr_def <> 0) then forcevol_cache[temp3] := 0; If ((chunk.effect_def = ef_Extended) and (chunk.effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol)) or ((chunk.effect_def2 = ef_Extended) and (chunk.effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol)) then forcevol_cache[temp3] := 0; If (chunk.effect_def2 = ef_ForceInsVolume) and (temp2 <= patt_break) then forcevol_cache[temp3] := 1; If (chunk.instr_def <> 0) and (temp2 <= patt_break) then ins_cache[temp3] := chunk.instr_def; If (chunk.instr_def <> 0) or ((chunk.instr_def = 0) and (chunk.note in [1..12*8+1]) and (ins_cache[temp3] <> 0)) then put_chunk(patt,temp2,temp3,chunk); If (temp2 <= patt_break) then begin If (chunk.effect DIV 16 <> 0) then misc_cache[temp3] := chunk.effect AND $0f0+ misc_cache[temp3] AND $0f else If (chunk.effect_def in [ef_Vibrato, ef_Tremolo]) then begin chunk.effect := misc_cache[temp3] AND $0f0+ chunk.effect AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect MOD 16 <> 0) then misc_cache[temp3] := misc_cache[temp3] AND $0f0+ chunk.effect AND $0f else If (chunk.effect_def in [ef_Vibrato, ef_Tremolo]) then begin chunk.effect := chunk.effect AND $0f0+ misc_cache[temp3] AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = ef_RetrigNote) then If (chunk.effect <> 0) then misc_cache[temp3] := chunk.effect else begin chunk.effect := misc_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = temp_ef_Arpeggio) then If (chunk.effect <> 0) then arpg_cache[temp3] := chunk.effect else begin chunk.effect := arpg_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, ef_FSlideUp,ef_FSlideUpFine, ef_TonePortamento]) then If (chunk.effect <> 0) then slide_cache[temp3] := chunk.effect else begin chunk.effect := slide_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = ef_Extended2) and (chunk.effect DIV 16 in [ef_ex2_FreqSlideDnXF,ef_ex2_FreqSlideUpXF]) then If (chunk.effect MOD 16 <> 0) then slide_cache[temp3] := chunk.effect MOD 16 else begin chunk.effect := chunk.effect AND $0f0+slide_cache[temp3] AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_TPortamVolSlide,ef_VibratoVolSlide, ef_VolSlide,ef_VolSlideFine]) and (temp2 <= patt_break) then begin If (chunk.effect <> 0) then volsld_cache[temp3] := chunk.effect else begin chunk.effect := volsld_cache[temp3];; put_chunk(patt,temp2,temp3,chunk); end; end; If (chunk.effect_def = ef_Extended2) and (chunk.effect DIV 16 in [ef_ex2_VolSlideDnXF,ef_ex2_VolSlideUpXF]) then If (chunk.effect MOD 16 <> 0) then Case chunk.effect DIV 16 of ef_ex2_VolSlideDnXF: begin volsld_cache[temp3] := chunk.effect MOD 16; xfvolsld_cache[temp3] := 0; end; ef_ex2_VolSlideUpXF: begin volsld_cache[temp3] := chunk.effect MOD 16*16; xfvolsld_cache[temp3] := 1; end; end; end; If (prev_cache[temp3].effect_def in [ef_Vibrato,ef_VibratoVolSlide]) and NOT (chunk.effect_def in [ef_Vibrato,ef_VibratoVolSlide]) then If (chunk.effect_def = 0) and (chunk.effect = 0) then begin chunk2 := chunk; chunk2.effect_def := ef_Extended; chunk2.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff; If NOT ((chunk2.effect_def = chunk2.effect_def2) and (chunk2.effect = chunk2.effect2)) then begin put_chunk(patt,temp2,temp3,chunk2); chunk := chunk2; end; end else If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then begin chunk2 := chunk; chunk2.effect_def2 := ef_Extended; chunk2.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff; If NOT ((chunk2.effect_def2 = chunk2.effect_def) and (chunk2.effect2 = chunk2.effect)) then begin put_chunk(patt,temp2,temp3,chunk2); chunk := chunk2; end; end; If (_1st_ins_load[temp3] and (chunk.instr_def <> 0)) or (forcevol_cache[temp3] <> 0) and (temp2 <= patt_break) and (chunk.instr_def <> 0) then If (chunk.effect_def2+chunk.effect2 = 0) then If NOT (chunk.effect_def in [ef_SetModulatorVol,ef_SetCarrierVol]) then begin chunk.effect_def2 := ef_Extended; chunk.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; put_chunk(patt,temp2,temp3,chunk); forcevol_cache[temp3] := 0; _1st_ins_load[temp3] := FALSE; end else begin chunk.effect_def2 := chunk.effect_def; chunk.effect2 := chunk.effect; chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; put_chunk(patt,temp2,temp3,chunk); forcevol_cache[temp3] := 0; _1st_ins_load[temp3] := FALSE; end; prev_cache[temp3].effect_def := chunk.effect_def; prev_cache[temp3].effect := chunk.effect; prev_cache[temp3].effect_def2 := chunk.effect_def2; prev_cache[temp3].effect2 := chunk.effect2; If is_4op_chan(temp3) and (temp3 in _4op_tracks_hi) then begin get_chunk(patt,temp2,SUCC(temp3),chunk3); If (chunk.instr_def = 0) and (chunk3.instr_def <> 0) then begin If (ins_cache[temp3] <> 0) then chunk.instr_def := ins_cache[temp3] else chunk.instr_def := chunk3.instr_def; put_chunk(patt,temp2,temp3,chunk); end; end; If (chunk.effect_def = temp_ef_Arpeggio) then begin chunk2 := chunk; chunk2.effect_def := ef_Arpeggio; put_chunk(patt,temp2,temp3,chunk2); end; If (chunk.effect_def in [ef_SetModulatorVol,ef_SetCarrierVol]) and (chunk.effect_def2 = ef_ForceInsVolume) then begin chunk2 := chunk; chunk2.effect_def := chunk.effect_def2; chunk2.effect := chunk.effect2; chunk2.effect_def2 := chunk.effect_def; chunk2.effect2 := chunk.effect; put_chunk(patt,temp2,temp3,chunk2); end; end; end; begin { fix_fmk_commands } FillChar(ins_cache,SizeOf(ins_cache),0); FillChar(_1st_ins_load,SizeOf(_1st_ins_load),TRUE); FillChar(_speed_table_fixed,SizeOf(_speed_table_fixed),FALSE); FillChar(xfvolsld_cache,SizeOf(volsld_cache),0); FillChar(volsld_cache,SizeOf(volsld_cache),0); FillChar(slide_cache,SizeOf(slide_cache),0); FillChar(misc_cache,SizeOf(misc_cache),0); FillChar(arpg_cache,SizeOf(arpg_cache),0); FillChar(forcevol_cache,SizeOf(forcevol_cache),0); patts := ''; order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; fix_single_pattern(patt); Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); For patt := 0 to PRED(patterns) do If NOT (Pos(CHR(patt),patts) <> 0) then fix_single_pattern(patt); end; procedure import_fin_instrument(inst: Byte; var data); begin With songdata.instr_data[inst] do begin fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[6]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[7]; fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 7; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 7; fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f; end; songdata.instr_data[inst].panning := 0; songdata.instr_data[inst].fine_tune := 0; end; procedure fmk_file_loader; type tFMK_HEADER = Record id: array[1..4] of Char; { FMK! } songname: array[1..28] of Char; { Song name (28) } composer: array[1..28] of Char; { Composer name (28) } bytef4: Byte; { Value 244 (f4h), just for check. } ftype: Byte; { File type {1=evolution 1, 2=evolution 2 } glob_var: Byte; { Global variables, bits : 0 = stereo, 1 = opl3, 2 = rhythm } { 3 = 4.8 db tremolo 4 = 14 cent vibrato. } base_spd: Byte; { Song basespeed, ticks / second. this version : fixed 50. } init_spd: Byte; { Song initial speed. } reserved: array[0..8] of Byte; { Reserved } ordnum: Byte; { Length of song (order). } insnum: Byte; { Number of instruments. } patnum: Byte; { Number of patterns. } trk_pan: array[1..5] of Byte; { Track stereo pan positions, bits 0-1, 2-3, 4-5, 6-7. } { value 0 = left 1 = both 2 = right, from track 1 to 18. } trk_set: array[1..20] of Byte; { Track initial settings, 255=unused, bits : } { 0-2, type value: 0 = normal 1=hihat 2=cymbal 3=tom tom 4=snare 5=bass } { 6 = 4op 7=unused } { 3-7, OPL-channel number (1-18), 21 = none. } { ### if ftype=2 --> trk_set: 1..18; type_value: 0 = normal 6 = 4op 7=unused } end; const id = 'FMK!'; const _conv_fmk_pan: array[0..2] of Byte = (1,0,2); type tFIN_DATA = Record dname: array[1..12] of Char; iname: array[1..27] of Char; idata: tFM_INST_DATA; end; var f: File; header: tFMK_HEADER; order_list: array[0..254] of Byte; paraptr_ins: array[1..99] of Word; paraptr_pat: array[0..63] of Longint; paraptr_msg: Word; insdata: tFIN_DATA; temp,temp2,fpos_bak: Longint; pat,row,chan, desc_rows: Byte; note,ins,vol,cmd,info: Byte; patlen,index: Word; dscbuf: array[0..PRED(20*24)] of Char; procedure import_fmk_event(pattern,line,channel,note,ins,vol,cmd,info: Byte); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); If (ins in [1..99]) then chunk.instr_def := ins; Case note of 254: chunk.note := BYTE_NULL; 255: chunk.note := 0; else If (note AND $0f in [1..12]) then chunk.note := 12*(note SHR 4)+(note AND $0f) end; If (vol <> BYTE_NULL) then begin chunk.effect_def2 := ef_ForceInsVolume; chunk.effect2 := 63-max(vol,63) end; Case CHR(cmd+ORD('A')-1) of { SET SPEED } 'A': If (info <> 0) then begin chunk.effect_def := ef_SetSpeed; chunk.effect := info; end; { JUMP TO ORDER } 'B': If (info <= 254) then begin chunk.effect_def := ef_PositionJump; chunk.effect := info; end; { CARRIER PARAM } 'C': Case info DIV 16 of 1: begin chunk.effect_def := ef_Extended3; chunk.effect := ef_ex3_SetMultipC*16+info MOD 16; end; 2: begin chunk.effect_def := ef_Extended3; chunk.effect := ef_ex3_SetKslC*16+(info MOD 16) AND 3; end; 3: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetAttckRateC*16+info MOD 16; end; 4: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetDecayRateC*16+info MOD 16; end; 5: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetSustnLevelC*16+info MOD 16; end; 6: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetRelRateC*16+info MOD 16; end; 7: begin chunk.effect_def := ef_SetWaveform; chunk.effect := info AND 7 SHL 4+$0f; end; 8: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetFeedback*16+info AND 7; end; end; { VOLUME SLIDE } 'D': { VOLUME SLIDE DOWN } Case info DIV 16 of { NORMAL } 0: If (info MOD 16 = 0) then chunk.effect_def := temp_ef_XFVSlide else begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_VolSlideDnXF*16+info MOD 16 end; { FINE } 15: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := info MOD 16; end; else { VOLUME SLIDE UP } Case info MOD 16 of { NORMAL } 0: If (info DIV 16 = 0) then chunk.effect_def := temp_ef_XFVSlide else begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_VolSlideUpXF*16+info DIV 16; end; { FINE } 15: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := info AND $0f0; end; end; end; { SLIDE DOWN } 'E': Case info DIV 16 of { NORMAL } 0..14: begin chunk.effect_def := ef_FSlideDown; chunk.effect := info; end; { FINE } 15: begin chunk.effect_def := ef_FSlideDownFine; chunk.effect := info AND $0f; end; end; { SLIDE UP } 'F': Case info DIV 16 of { NORMAL } 0..14: begin chunk.effect_def := ef_FSlideUp; chunk.effect := info; end; { FINE } 15: begin chunk.effect_def := ef_FSlideUpFine; chunk.effect := info AND $0f; end; end; { TONE PORTAMENTO } 'G': begin chunk.effect_def := ef_TonePortamento; chunk.effect := info; end; { VIBRATO } 'H': begin chunk.effect_def := ef_Vibrato; If (info <> 0) and (info DIV 16 = 0) then chunk.effect := $10+info AND $0f else If (info <> 0) and (info MOD 16 = 0) then chunk.effect := info AND $0f0+1 else chunk.effect := info; end; { RETRIG NOTE } 'I': begin chunk.effect_def := ef_RetrigNote; If (info <> 0) then chunk.effect := max(info*2,255); end; { ARPEGGIO } 'J': begin chunk.effect_def := temp_ef_Arpeggio; chunk.effect := info; end; { MODLATOR PARAM } 'M': Case info DIV 16 of 1: begin chunk.effect_def := ef_Extended3; chunk.effect := ef_ex3_SetMultipM*16+info MOD 16; end; 2: begin chunk.effect_def := ef_Extended3; chunk.effect := ef_ex3_SetKslM*16+(info MOD 16) AND 3; end; 3: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetAttckRateM*16+info MOD 16; end; 4: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetDecayRateM*16+info MOD 16; end; 5: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetSustnLevelM*16+info MOD 16; end; 6: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetRelRateM*16+info MOD 16; end; 7: begin chunk.effect_def := ef_SetWaveform; chunk.effect := $0f0+info AND 7; end; 8: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetFeedback*16+info AND 7; end; end; { SET VIBRATO/TREMOLO WAVEFORM } 'N': ; { BREAK PATTERN } 'P': If (info < 64) then begin chunk.effect_def := ef_PatternBreak; chunk.effect := Str2num(Num2str(info,16),10); end; { TREMOLO } 'R': begin chunk.effect_def := ef_Tremolo; If (info <> 0) and (info DIV 16 = 0) then chunk.effect := $10+info AND $0f else If (info <> 0) and (info MOD 16 = 0) then chunk.effect := info AND $0f0+1 else chunk.effect := info; end; { STEREO CONTROL } 'S': If (header.glob_var AND 1 = 1) then begin chunk.effect_def := ef_Extended; Case info of 1: chunk.effect := ef_ex_SetPanningPos*16+1; 2: chunk.effect := ef_ex_SetPanningPos*16+0; 3: chunk.effect := ef_ex_SetPanningPos*16+2; end; end; { MODULATOR VOLUME } 'T': begin chunk.effect_def := ef_SetModulatorVol; chunk.effect := info AND $3f; end; { CARRIER VOLUME } 'U': begin chunk.effect_def := ef_SetCarrierVol; chunk.effect := info AND $3f; end; end; If (chunk.effect_def = 0) and (chunk.effect <> 0) then chunk.effect := 0; put_chunk(pattern,line,channel,chunk); end; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id = id)) then begin CloseF(f); EXIT; end; load_flag := $7f; If (header.bytef4 <> $f4) or NOT (header.ftype in [1,2]) then begin CloseF(f); EXIT; end; If (header.ftype = 2) then begin SeekF(f,SizeOf(header)-2); If (IOresult <> 0) then begin CloseF(f); EXIT; end; end; If (header.ordnum <> 0) then begin BlockReadF(f,order_list,header.ordnum,temp); If (IOresult <> 0) or (temp <> header.ordnum) then begin CloseF(f); EXIT; end; end; BlockReadF(f,paraptr_msg,SizeOf(paraptr_msg),temp); If (IOresult <> 0) or (temp <> SizeOf(paraptr_msg)) then begin CloseF(f); EXIT; end; fpos_bak := FilePos(f); If (paraptr_msg <> 0) then begin SeekF(f,paraptr_msg); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,desc_rows,SizeOf(desc_rows),temp); If (IOresult <> 0) or (temp <> SizeOf(desc_rows)) then begin CloseF(f); EXIT; end; If (desc_rows <> 0) then begin BlockReadF(f,dscbuf,desc_rows*20,temp); If (IOresult <> 0) or (temp <> desc_rows*20) then begin CloseF(f); EXIT; end; end; end; SeekF(f,fpos_bak); If (IOresult <> 0) then begin CloseF(f); EXIT; end; If (header.insnum <> 0) then begin BlockReadF(f,paraptr_ins,header.insnum*2,temp); If (IOresult <> 0) or (temp <> header.insnum*2) then begin CloseF(f); EXIT; end; end; If (header.patnum <> 0) then begin BlockReadF(f,paraptr_pat,header.patnum*4,temp); If (IOresult <> 0) or (temp <> header.patnum*4) then begin CloseF(f); EXIT; end; end; init_songdata; load_flag := 0; If (header.init_spd <> 0) then speed := header.init_spd else speed := 1; If (header.base_spd <> 0) then tempo := header.base_spd else tempo := 50; songdata.tempo := tempo; songdata.speed := speed; songdata.songname := truncate_string(header.songname); songdata.composer := truncate_string(header.composer); songdata.common_flag := songdata.common_flag OR 1; songdata.common_flag := songdata.common_flag OR 2; songdata.common_flag := songdata.common_flag OR $80; For temp := 18 downto 1 do If NOT (header.trk_set[temp] AND 7 = 7) then BREAK; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := temp else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; For temp2 := 1 to temp do If (header.trk_set[temp2] AND 7 = 6) then Case temp2 of 1,2: songdata.flag_4op := songdata.flag_4op OR 1; 3,4: songdata.flag_4op := songdata.flag_4op OR 2; 5,6: songdata.flag_4op := songdata.flag_4op OR 4; 10,11: songdata.flag_4op := songdata.flag_4op OR 8; 12,13: songdata.flag_4op := songdata.flag_4op OR $10; 14,15: songdata.flag_4op := songdata.flag_4op OR $20; end; If (header.glob_var AND 1 = 1) then songdata.common_flag := songdata.common_flag OR $20; If (header.glob_var SHR 3 AND 1 = 1) then songdata.common_flag := songdata.common_flag OR 8; If (header.glob_var SHR 4 AND 1 = 1) then songdata.common_flag := songdata.common_flag OR $10; import_old_flags; If (header.glob_var AND 1 = 1) then begin Inc(songdata.lock_flags[1], _conv_fmk_pan[header.trk_pan[1] AND 3]); Inc(songdata.lock_flags[2], _conv_fmk_pan[header.trk_pan[1] SHR 2 AND 3]); Inc(songdata.lock_flags[3], _conv_fmk_pan[header.trk_pan[1] SHR 4 AND 3]); Inc(songdata.lock_flags[4], _conv_fmk_pan[header.trk_pan[1] SHR 6 AND 3]); Inc(songdata.lock_flags[5], _conv_fmk_pan[header.trk_pan[2] AND 3]); Inc(songdata.lock_flags[6], _conv_fmk_pan[header.trk_pan[2] SHR 2 AND 3]); Inc(songdata.lock_flags[7], _conv_fmk_pan[header.trk_pan[2] SHR 4 AND 3]); Inc(songdata.lock_flags[8], _conv_fmk_pan[header.trk_pan[2] SHR 6 AND 3]); Inc(songdata.lock_flags[9], _conv_fmk_pan[header.trk_pan[3] AND 3]); Inc(songdata.lock_flags[10],_conv_fmk_pan[header.trk_pan[3] SHR 2 AND 3]); Inc(songdata.lock_flags[11],_conv_fmk_pan[header.trk_pan[3] SHR 4 AND 3]); Inc(songdata.lock_flags[12],_conv_fmk_pan[header.trk_pan[3] SHR 6 AND 3]); Inc(songdata.lock_flags[13],_conv_fmk_pan[header.trk_pan[4] AND 3]); Inc(songdata.lock_flags[14],_conv_fmk_pan[header.trk_pan[4] SHR 2 AND 3]); Inc(songdata.lock_flags[15],_conv_fmk_pan[header.trk_pan[4] SHR 4 AND 3]); Inc(songdata.lock_flags[16],_conv_fmk_pan[header.trk_pan[4] SHR 6 AND 3]); Inc(songdata.lock_flags[17],_conv_fmk_pan[header.trk_pan[5] AND 3]); Inc(songdata.lock_flags[18],_conv_fmk_pan[header.trk_pan[5] SHR 2 AND 3]); end; For temp := 1 to max(header.ordnum,128) do Case order_list[temp-1] of 255: songdata.pattern_order[temp-1] := $80; else songdata.pattern_order[temp-1] := order_list[temp-1]; end; For temp := 1 to header.insnum do begin SeekF(f,paraptr_ins[temp]); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,insdata,SizeOf(insdata),temp2); If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then begin CloseF(f); EXIT; end; If (truncate_string(insdata.iname) <> '') then songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ Copy(truncate_string(insdata.iname),1,32) else songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ truncate_string(insdata.dname); import_fin_instrument(temp,insdata.idata); end; For pat := 0 to PRED(header.patnum) do begin SeekF(f,paraptr_pat[pat]); If (IOresult <> 0) then begin CloseF(f); EXIT; end; If (paraptr_pat[pat] = 0) then CONTINUE; BlockReadF(f,patlen,SizeOf(patlen),temp2); If (temp2 <> SizeOf(patlen)) then begin CloseF(f); EXIT; end; If (patlen = 0) then CONTINUE; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,patlen,temp2); index := 0; row := 0; Repeat If (buf1[index] <> 0) then begin note := BYTE_NULL; ins := 0; vol := BYTE_NULL; cmd := 0; info := 0; temp := buf1[index]; Inc(index); chan := SUCC(temp AND 31); If (temp OR $20 = temp) then begin note := buf1[index]; Inc(index); ins := buf1[index]; Inc(index); end; If (temp OR $40 = temp) then begin vol := buf1[index]; Inc(index); end; If (temp OR $80 = temp) then begin cmd := buf1[index]; Inc(index); info := buf1[index]; Inc(index); end; If (PRED(chan) in [1..18]) then import_fmk_event(pat,row,PRED(chan),note,ins,vol,cmd,info); end else begin Inc(row); Inc(index); end; until (row = 64); end; fix_fmk_commands(header.patnum); CloseF(f); songdata_title := NameOnly(songdata_source); load_flag := 13; end; procedure import_sat_instrument(inst: Byte; var data); begin With songdata.instr_data[inst] do begin fm_data.FEEDBACK_FM := pBYTE(@data)[0] AND $0f; fm_data.AM_VIB_EG_modulator := pBYTE(@data)[1]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[2]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[3]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[4]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[5]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[6]; fm_data.WAVEFORM_modulator := pBYTE(@data)[7] AND 3; fm_data.WAVEFORM_carrier := pBYTE(@data)[8] AND 3; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[9]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[10]; end; songdata.instr_data[inst].panning := 0; songdata.instr_data[inst].fine_tune := 0; end; function import_sat_instrument_name(var data; inst: Byte): String; var temp1: Word; temp2: Byte; temp3: String; begin temp1 := 0; temp2 := 0; temp3 := ''; While (temp1 < 496) do begin If (pBYTE(@data)[temp1] = BYTE(#16)) then Inc(temp2); Inc(temp1); If (temp2 = inst+1) then begin While (pBYTE(@data)[temp1] in [$20..$0ff]) and (Length(temp3) < 22) do begin temp3 := temp3+CHR(pBYTE(@data)[temp1]); Inc(temp1); end; BREAK; end; end; import_sat_instrument_name := temp3; end; procedure import_sa2_effect(effect,def1,def2: Byte; var out1,out2: Byte); forward; procedure sat_file_loader; type tHEADER = Record { version 1 } ident: array[1..4] of Char; { ident_string } vernm: Byte; { version_number (1) } instt: array[0..$1e] of { 31_instruments } array[0..$0a] of Byte; instn: array[0..495] of Byte; { 31_instrument_names } order: array[0..254] of Byte; { pattern_order } nopat: Word; { number of patterns } snlen: Byte; { song_length } rspos: Byte; { restart_position } calls: Word; { calls_per_second } end; type tHEADR2 = Record { version 6 } ident: array[1..4] of Char; { ident_string } vernm: Byte; { version_number (1) } instt: array[0..$1e] of { 31_instruments } array[0..$0e] of Byte; instn: array[0..495] of Byte; { 31_instrument_names } order: array[0..$7f] of Byte; { pattern_order } nopat: Word; { number of patterns } snlen: Byte; { song_length } rspos: Byte; { restart_position } calls: Word; { calls_per_second } arpgd: array[1..512] of Byte; { arpeggio_data } end; const id = 'SAdT'; var f: File; header: tHEADER; headr2: tHEADR2; SATver: Byte; temp,tmp2,tmp3,temp2,temp3, temp4,temp5: Longint; byte1,byte2,byte3,byte4,byte5,note_inc: Byte; procedure import_sat_event(pattern,line,channel, byte1,byte2,byte3,byte4,byte5: Byte); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); If (byte2 in [1..31]) then chunk.instr_def := byte2; If (byte1 in [1..12*8+1]) then chunk.note := byte1+note_inc; import_sa2_effect(byte3,byte4,byte5,chunk.effect_def,chunk.effect); If (chunk.effect_def = ef_Extended) and (chunk.effect = ef_ex_ExtendedCmd2*16) and (chunk.note = 0) then begin chunk.note := BYTE_NULL; chunk.effect_def := 0; chunk.effect := 0; end; put_chunk(pattern,line,channel,chunk); end; var absolute: Longint; function get_byte(var pos: Longint): Byte; begin If (pos = SizeOf(buf1)-5) then begin If NOT (absolute > SizeOf(buf1)-5) then Move(buf3,buf1,SizeOf(buf3)-5) else Move(buf4,buf1,SizeOf(buf4)-5); pos := 0; end; get_byte := buf1[pos]; Inc(pos); Inc(absolute); end; begin {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); EXIT; end; If NOT (header.vernm in [1,5,6]) then begin CloseF(f); EXIT; end; load_flag := $7f; SATver := header.vernm; If (SATver in [5,6]) then begin SeekF(f,0); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,headr2,SizeOf(headr2),temp); If (temp <> SizeOf(headr2)) then begin CloseF(f); EXIT; end; end; temp5 := (FileSize(f)-temp) DIV (64*9*5); FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1)-5,temp); If (IOresult <> 0) then begin CloseF(f); EXIT; end; tmp2 := WORD_NULL; If (temp = SizeOf(buf1)-5) then begin FillChar(buf3,SizeOf(buf3),0); BlockReadF(f,buf3,SizeOf(buf3)-5,tmp2); If (IOresult <> 0) then begin CloseF(f); EXIT; end; end; tmp3 := WORD_NULL; If (tmp2 = SizeOf(buf3)-5) then begin FillChar(buf4,SizeOf(buf4),0); BlockReadF(f,buf4,SizeOf(buf4)-5,tmp3); If (IOresult <> 0) then begin CloseF(f); EXIT; end; end; init_songdata; load_flag := 0; songdata.common_flag := songdata.common_flag OR 8; songdata.common_flag := songdata.common_flag OR $10; import_old_flags; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] OR 4 OR 8; If (SATver = 1) then begin speed := 6; If (header.calls < 255) then tempo := header.calls else tempo := 255; songdata.tempo := tempo; songdata.speed := speed; For temp := 0 to max(header.snlen-1,127) do If (temp < 128) and (header.order[temp] in [0..63]) then songdata.pattern_order[temp] := header.order[temp]; If (header.rspos < 128) and (SUCC(temp) < 128) then songdata.pattern_order[SUCC(temp)] := $80+header.rspos; temp5 := max(temp5,header.nopat); For temp := 0 to $1e do begin import_sat_instrument(temp+1,header.instt[temp]); songdata.instr_names[temp+1] := Copy(songdata.instr_names[temp+1],1,9)+ truncate_string(import_sat_instrument_name(header.instn,temp)); end; end else begin speed := 6; If (headr2.calls < 255) then tempo := headr2.calls else tempo := 255; songdata.tempo := tempo; songdata.speed := speed; For temp := 0 to headr2.snlen-1 do If (temp < 128) and (headr2.order[temp] in [0..63]) then songdata.pattern_order[temp] := headr2.order[temp]; If (headr2.rspos < 128) and (SUCC(temp) < 128) then songdata.pattern_order[SUCC(temp)] := $80+headr2.rspos; temp5 := max(temp5,headr2.nopat); For temp := 0 to $1e do begin import_sat_instrument(temp+1,headr2.instt[temp]); songdata.instr_names[temp+1] := Copy(songdata.instr_names[temp+1],1,9)+ truncate_string(import_sat_instrument_name(headr2.instn,temp)); end; end; temp := 0; absolute := 0; Case SATver of 1: note_inc := 24; 5: note_inc := 12; 6: note_inc := 0; end; For temp2 := 0 to temp5-1 do For temp3 := 0 to 63 do For temp4 := 1 to 9 do begin byte1 := get_byte(temp); byte2 := get_byte(temp); byte3 := get_byte(temp); byte4 := get_byte(temp); byte5 := get_byte(temp); import_sat_event(temp2,temp3,temp4,byte1,byte2,byte3,byte4,byte5); end; CloseF(f); songdata_title := NameOnly(songdata_source); load_flag := 14; end; function _sal(op1,op2: Word): Byte; var result: Byte; begin asm mov ax,op1 mov cx,op2 sal ax,cl mov result,al end; _sal := result; end; function _sar(op1,op2: Word): Byte; var result: Byte; begin asm mov ax,op1 mov cx,op2 sar ax,cl mov result,al end; _sar := result; end; procedure import_sa2_effect(effect,def1,def2: Byte; var out1,out2: Byte); begin Case effect of { NORMAL PLAY OR ARPEGGIO } $00: begin out1 := ef_Arpeggio; out2 := def1*16+def2; end; { SLIDE UP } $01: begin out1 := ef_FSlideUp; out2 := def1*16+def2; end; { SLIDE DOWN } $02: begin out1 := ef_FSlideDown; out2 := def1*16+def2; end; { TONE PORTAMENTO } $03: begin out1 := ef_TonePortamento; out2 := def1*16+def2; end; { VIBRATO } $04: begin out1 := ef_Vibrato; out2 := def1*16+def2; end; { TONE PORTAMENTO + VOLUME SLIDE } $05: If (def1+def2 <> 0) then If (def1 in [1..15]) then begin out1 := ef_TPortamVolSlide; out2 := min(_sar(def1,2),1)*16; end else begin out1 := ef_TPortamVolSlide; out2 := min(_sar(def2,2),1); end else begin out1 := ef_TPortamVolSlide; out2 := def1*16+def2; end; { VIBRATO + VOLUME SLIDE } $06: If (def1+def2 <> 0) then If (def1 in [1..15]) then begin out1 := ef_VibratoVolSlide; out2 := min(_sar(def1,2),1)*16; end else begin out1 := ef_VibratoVolSlide; out2 := min(_sar(def2,2),1); end else begin out1 := ef_VibratoVolSlide; out2 := def1*16+def2; end; { RELEASE SUSTAINING SOUND } $08: begin out1 := ef_Extended; out2 := ef_ex_ExtendedCmd2*16+0; end; { VOLUME SLIDE } $0a: If (def1+def2 <> 0) then If (def1 in [1..15]) then begin out1 := ef_VolSlide; out2 := min(_sar(def1,2),1)*16; end else begin out1 := ef_VolSlide; out2 := min(_sar(def2,2),1); end else begin out1 := ef_VolSlide; out2 := def1*16+def2; end; { POSITION JUMP } $0b: If (def1*16+def2 < 128) then begin out1 := ef_PositionJump; out2 := def1*16+def2; end; { SET VOLUME } $0c: begin out1 := ef_SetInsVolume; out2 := def1*16+def2; If (out2 > 63) then out2 := 63; end; { PATTERN BREAK } $0d: If (def1*16+def2 < 64) then begin out1 := ef_PatternBreak; out2 := def1*16+def2; end; { SET SPEED } $0f: If (def1*16+def2 < $20) then begin out1 := ef_SetSpeed; out2 := def1*16+def2; end else If (def1 < 16) and (def2 < 16) then begin out1 := ef_SetTempo; out2 := Round((def1*16+def2)/2.5); end; else begin out1 := 0; out2 := 0; end; end; end; procedure sa2_file_loader; type tHEADER = Record ident: array[1..4] of Char; { These bytes mark a song } vernm: Byte; { Version number (9) } instt: array[0..$1e] of { 31 instruments } array[0..$0e] of Byte; instn: array[0..495] of Byte; { 31_instrument_names } order: array[0..$7f] of Byte; { Pattern order } nopat: Word; { Number of patterns } snlen: Byte; { Length of song } rspos: Byte; { Restart position } snbpm: Word; { BPM } arpgd: array[1..512] of Byte; { Arpeggio data (list+commands) } ordr2: array[0..63] of { Track order } array[1..9] of Byte; chans: Word; { Active channels } end; const id = 'SAdT'; var f: File; header: tHEADER; temp,temp2,temp3,temp4,temp5: Longint; procedure import_sa2_event(pattern,line,channel, byte1,byte2,byte3: Byte); var chunk: tCHUNK; temp: Byte; begin FillChar(chunk,SizeOf(chunk),0); temp := (byte1 AND 1) SHL 4 +(byte2 SHR 4); If (temp in [1..31]) then chunk.instr_def := temp; If (byte1 SHR 1 in [1..12*8+1]) then chunk.note := (byte1 SHR 1); import_sa2_effect(byte2 AND $0f,byte3 SHR 4,byte3 AND $0f, chunk.effect_def,chunk.effect); If (chunk.effect_def = ef_Extended) and (chunk.effect = ef_ex_ExtendedCmd2*16) and (chunk.note = 0) then begin chunk.note := BYTE_NULL; chunk.effect_def := 0; chunk.effect := 0; end; put_chunk(pattern,line,channel,chunk); end; begin { sa2_file_loader } {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); EXIT; end; If NOT (header.vernm in [8,9]) then begin CloseF(f); EXIT; end; load_flag := $7f; If (header.vernm = 8) then begin SeekF(f,FilePos(f)-2); If (IOresult <> 0) then begin CloseF(f); EXIT; end; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1)-3,temp); If (IOresult <> 0) then begin CloseF(f); EXIT; end; init_songdata; load_flag := 0; songdata.common_flag := songdata.common_flag OR 8; songdata.common_flag := songdata.common_flag OR $10; import_old_flags; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] OR 4 OR 8; speed := 6; If (Round(header.snbpm/2.5) < 255) then tempo := Round(header.snbpm/2.5) else tempo := 255; songdata.tempo := tempo; songdata.speed := speed; temp2 := 0; temp3 := 0; temp4 := 1; Repeat While (header.ordr2[temp2][temp4] = 0) and (temp2 <= header.nopat-1) do begin Inc(temp4); If (temp4 > 9) then begin temp4 := 1; Inc(temp2); end; end; If (temp2 <= header.nopat-1) then begin temp5 := 64*3*(header.ordr2[temp2][temp4]-1)+temp3*3; import_sa2_event(temp2,temp3,temp4,buf1[temp5], buf1[temp5+1], buf1[temp5+2]); Inc(temp3); If (temp3 > $3f) then begin temp3 := 0; If (temp4 < 9) then Inc(temp4) else begin temp4 := 1; Inc(temp2); end; end; end; until (temp2 > header.nopat-1); For temp := 0 to header.snlen-1 do If (temp < 128) and (header.order[temp] in [0..63]) then songdata.pattern_order[temp] := header.order[temp]; If (header.rspos < 128) and (SUCC(temp) < 128) then songdata.pattern_order[SUCC(temp)] := $80+header.rspos; For temp := 0 to $1e do begin import_sat_instrument(temp+1,header.instt[temp]); songdata.instr_names[temp+1] := Copy(songdata.instr_names[temp+1],1,9)+ truncate_string(import_sat_instrument_name(header.instn,temp)); end; CloseF(f); songdata_title := NameOnly(songdata_source); load_flag := 15; end; adlibtracker2-2.4.23/adt2play/d.bat0000644000000000000000000000076613176573533015472 0ustar rootroot@echo off echo. echo ************************************ echo ** ** echo ** Deleting file garbage ** echo ** ** echo ************************************ echo. if not exist *.exe goto :no_exe_file del *.exe >nul :no_exe_file if not exist *.ppu goto :no_ppu_file del *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del *.o >nul :no_o_file if not exist !log goto :no_log_file del !log >nul :no_log_file adlibtracker2-2.4.23/adt2play/a2data.pas0000644000000000000000000062734213176573533016425 0ustar rootrootunit A2data; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const font8x8: array[0..511] of Dword = ( $0aa000000,$000000000,$0aa808080,$000808080,$0aaa0a0a0,$000a0a0a0,$0aaa8a8a8,$000a8a8a8, $0aaaaaaaa,$000aaaaaa,$0fe387c38,$07c387cfe,$07c381010,$07c387cfe,$03c180000,$00000183c, $0c3e7ffff,$0ffffe7c3,$042663c00,$0003c6642,$0bd99c3ff,$0ffc399bd,$07d0f070f,$078cccccc, $06666663c,$0187e183c,$0303f333f,$0e0f07030,$0637f637f,$0c0e66763,$0e73c5a99,$0995a3ce7, $0fef8e080,$00080e0f8,$0fe3e0e02,$000020e3e,$0187e3c18,$0183c7e18,$066666666,$000660066, $07bdbdb7f,$0001b1b1b,$06c38633e,$078cc386c,$000000000,$0007e7e7e,$0187e3c18,$0ff183c7e, $0187e3c18,$000181818,$018181818,$000183c7e,$0fe0c1800,$00000180c,$0fe603000,$000003060, $0c0c00000,$00000fec0,$0ff662400,$000002466,$07e3c1800,$00000ffff,$07effff00,$00000183c, $000000000,$000000000,$030787830,$000300030,$0006c6c6c,$000000000,$06cfe6c6c,$0006c6cfe, $078c07c30,$00030f80c,$018ccc600,$000c66630,$076386c38,$00076ccdc,$000c06060,$000000000, $060603018,$000183060,$018183060,$000603018,$0ff3c6600,$00000663c,$0fc303000,$000003030, $000000000,$060303000,$0fc000000,$000000000,$000000000,$000303000,$030180c06,$00080c060, $0decec67c,$0007ce6f6,$030307030,$000fc3030,$0380ccc78,$000fccc60,$0380ccc78,$00078cc0c, $0cc6c3c1c,$0001e0cfe,$00cf8c0fc,$00078cc0c,$0f8c06038,$00078cccc,$0180cccfc,$000303030, $078cccc78,$00078cccc,$07ccccc78,$00070180c,$000303000,$000303000,$000303000,$060303000, $0c0603018,$000183060,$000fc0000,$00000fc00,$00c183060,$000603018,$0180ccc78,$000300030, $0dedec67c,$00078c0de,$0cccc7830,$000ccccfc,$07c6666fc,$000fc6666,$0c0c0663c,$0003c66c0, $066666cf8,$000f86c66,$0786862fe,$000fe6268,$0786862fe,$000f06068,$0c0c0663c,$0003e66ce, $0fccccccc,$000cccccc,$030303078,$000783030,$00c0c0c1e,$00078cccc,$0786c66e6,$000e6666c, $0606060f0,$000fe6662,$0fefeeec6,$000c6c6d6,$0def6e6c6,$000c6c6ce,$0c6c66c38,$000386cc6, $07c6666fc,$000f06060,$0cccccc78,$0001c78dc,$07c6666fc,$000e6666c,$070e0cc78,$00078cc1c, $03030b4fc,$000783030,$0cccccccc,$000fccccc,$0cccccccc,$0003078cc,$0d6c6c6c6,$000c6eefe, $0386cc6c6,$000c66c38,$078cccccc,$000783030,$0188cc6fe,$000fe6632,$060606078,$000786060, $0183060c0,$00002060c,$018181878,$000781818,$0c66c3810,$000000000,$000000000,$0ff000000, $000183030,$000000000,$00c780000,$00076cc7c,$07c6060e0,$000dc6666,$0cc780000,$00078ccc0, $07c0c0c1c,$00076cccc,$0cc780000,$00078c0fc,$0f0606c38,$000f06060,$0cc760000,$0f80c7ccc, $0766c60e0,$000e66666,$030700030,$000783030,$00c0c000c,$078cccc0c,$06c6660e0,$000e66c78, $030303070,$000783030,$0fecc0000,$000c6d6fe,$0ccf80000,$000cccccc,$0cc780000,$00078cccc, $066dc0000,$0f0607c66,$0cc760000,$01e0c7ccc,$076dc0000,$000f06066,$0c07c0000,$000f80c78, $0307c3010,$000183430,$0cccc0000,$00076cccc,$0cccc0000,$0003078cc,$0d6c60000,$0006cfefe, $06cc60000,$000c66c38,$0cccc0000,$0f80c7ccc,$098fc0000,$000fc6430,$0e030301c,$0001c3030, $000181818,$000181818,$01c3030e0,$000e03030,$00000dc76,$000000000,$06c381000,$000fec6c6, $0ccc0cc78,$0780c1878,$0cc00cc00,$0007ecccc,$0cc78001c,$00078c0fc,$0063cc37e,$0003f663e, $00c7800cc,$0007ecc7c,$00c7800e0,$0007ecc7c,$00c783030,$0007ecc7c,$0c0780000,$0380c78c0, $0663cc37e,$0003c607e,$0cc7800cc,$00078c0fc,$0cc7800e0,$00078c0fc,$0307000cc,$000783030, $01838c67c,$0003c1818,$0307000e0,$000783030,$0c66c38c6,$000c6c6fe,$078003030,$000ccfccc, $060fc001c,$000fc6078,$00c7f0000,$0007fcc7f,$0fecc6c3e,$000cecccc,$07800cc78,$00078cccc, $07800cc00,$00078cccc,$07800e000,$00078cccc,$0cc00cc78,$0007ecccc,$0cc00e000,$0007ecccc, $0cc00cc00,$0f80c7ccc,$0663c18c3,$000183c66,$0cccc00cc,$00078cccc,$0c07e1818,$018187ec0, $0f0646c38,$000fce660,$0fc78cccc,$03030fc30,$0faccccf8,$0c7c6cfc6,$03c181b0e,$070d81818, $00c78001c,$0007ecc7c,$030700038,$000783030,$078001c00,$00078cccc,$0cc001c00,$0007ecccc, $0f800f800,$000cccccc,$0eccc00fc,$000ccdcfc,$03e6c6c3c,$000007e00,$0386c6c38,$000007c00, $060300030,$00078ccc0,$0fc000000,$00000c0c0,$0fc000000,$000000c0c,$0deccc6c3,$00fcc6633, $0dbccc6c3,$003cf6f37,$018001818,$000181818,$0cc663300,$000003366,$03366cc00,$00000cc66, $088228822,$088228822,$0aa55aa55,$0aa55aa55,$0eedb77db,$0eedb77db,$018181818,$018181818, $018181818,$0181818f8,$018f81818,$0181818f8,$036363636,$0363636f6,$000000000,$0363636fe, $018f80000,$0181818f8,$006f63636,$0363636f6,$036363636,$036363636,$006fe0000,$0363636f6, $006f63636,$0000000fe,$036363636,$0000000fe,$018f81818,$0000000f8,$000000000,$0181818f8, $018181818,$00000001f,$018181818,$0000000ff,$000000000,$0181818ff,$018181818,$01818181f, $000000000,$0000000ff,$018181818,$0181818ff,$0181f1818,$01818181f,$036363636,$036363637, $030373636,$00000003f,$0303f0000,$036363637,$000f73636,$0000000ff,$000ff0000,$0363636f7, $030373636,$036363637,$000ff0000,$0000000ff,$000f73636,$0363636f7,$000ff1818,$0000000ff, $036363636,$0000000ff,$000ff0000,$0181818ff,$000000000,$0363636ff,$036363636,$00000003f, $0181f1818,$00000001f,$0181f0000,$01818181f,$000000000,$03636363f,$036363636,$0363636ff, $018ff1818,$0181818ff,$018181818,$0000000f8,$000000000,$01818181f,$0ffffffff,$0ffffffff, $000000000,$0ffffffff,$0f0f0f0f0,$0f0f0f0f0,$00f0f0f0f,$00f0f0f0f,$0ffffffff,$000000000, $0dc760000,$00076dcc8,$0f8cc7800,$0c0c0f8cc,$0c0ccfc00,$000c0c0c0,$06c6cfe00,$0006c6c6c, $03060ccfc,$000fccc60,$0d87e0000,$00070d8d8,$066666600,$0c0607c66,$018dc7600,$000181818, $0cc7830fc,$0fc3078cc,$0fec66c38,$000386cc6,$0c6c66c38,$000ee6c6c,$07c18301c,$00078cccc, $0db7e0000,$000007edb,$0db7e0c06,$0c0607edb,$0f8c06038,$0003860c0,$0cccccc78,$000cccccc, $0fc00fc00,$00000fc00,$030fc3030,$000fc0030,$030183060,$000fc0060,$030603018,$000fc0018, $0181b1b0e,$018181818,$018181818,$070d8d818,$0fc003030,$000303000,$000dc7600,$00000dc76, $0386c6c38,$000000000,$018000000,$000000018,$000000000,$000000018,$00c0c0c0f,$01c3c6cec, $06c6c6c78,$00000006c,$060301870,$000000078,$03c3c0000,$000003c3c,$000000000,$000000000); const font8x16: array[0..1023] of Dword = ( $000000000,$000000000,$000000000,$000000000,$0817e0000,$0a58181a5,$07e818199,$000000000, $0ff7e0000,$0dbffffdb,$07effffe7,$000000000,$000000000,$0fefefe6c,$010387cfe,$000000000, $000000000,$0fe7c3810,$00010387c,$000000000,$018000000,$0e7e73c3c,$03c1818e7,$000000000, $018000000,$0ffff7e3c,$03c18187e,$000000000,$000000000,$03c180000,$00000183c,$000000000, $0ffffffff,$0c3e7ffff,$0ffffe7c3,$0ffffffff,$000000000,$042663c00,$0003c6642,$000000000, $0ffffffff,$0bd99c3ff,$0ffc399bd,$0ffffffff,$0061e0000,$0cc781a0e,$078cccccc,$000000000, $0663c0000,$03c666666,$018187e18,$000000000,$0333f0000,$03030303f,$0e0f07030,$000000000, $0637f0000,$06363637f,$0e6e76763,$0000000c0,$018000000,$0e73cdb18,$01818db3c,$000000000, $0e0c08000,$0f8fef8f0,$080c0e0f0,$000000000,$00e060200,$03efe3e1e,$002060e1e,$000000000, $03c180000,$01818187e,$000183c7e,$000000000,$066660000,$066666666,$066660066,$000000000, $0db7f0000,$01b7bdbdb,$01b1b1b1b,$000000000,$060c67c00,$0c6c66c38,$0c60c386c,$00000007c, $000000000,$000000000,$0fefefefe,$000000000,$03c180000,$01818187e,$07e183c7e,$000000000, $03c180000,$01818187e,$018181818,$000000000,$018180000,$018181818,$0183c7e18,$000000000, $000000000,$0fe0c1800,$00000180c,$000000000,$000000000,$0fe603000,$000003060,$000000000, $000000000,$0c0c00000,$00000fec0,$000000000,$000000000,$0fe6c2800,$00000286c,$000000000, $000000000,$07c383810,$000fefe7c,$000000000,$000000000,$07c7cfefe,$000103838,$000000000, $000000000,$000000000,$000000000,$000000000,$03c180000,$018183c3c,$018180018,$000000000, $066666600,$000000024,$000000000,$000000000,$06c000000,$06c6cfe6c,$06c6cfe6c,$000000000, $0c67c1818,$0067cc0c2,$07cc68606,$000001818,$000000000,$0180cc6c2,$086c66030,$000000000, $06c380000,$0dc76386c,$076cccccc,$000000000,$030303000,$000000060,$000000000,$000000000, $0180c0000,$030303030,$00c183030,$000000000,$018300000,$00c0c0c0c,$030180c0c,$000000000, $000000000,$0ff3c6600,$00000663c,$000000000,$000000000,$07e181800,$000001818,$000000000, $000000000,$000000000,$018181800,$000000030,$000000000,$0fe000000,$000000000,$000000000, $000000000,$000000000,$018180000,$000000000,$000000000,$0180c0602,$080c06030,$000000000, $0c67c0000,$0f6decec6,$07cc6c6e6,$000000000,$038180000,$018181878,$07e181818,$000000000, $0c67c0000,$030180c06,$0fec6c060,$000000000,$0c67c0000,$0063c0606,$07cc60606,$000000000, $01c0c0000,$0fecc6c3c,$01e0c0c0c,$000000000,$0c0fe0000,$006fcc0c0,$07cc60606,$000000000, $060380000,$0c6fcc0c0,$07cc6c6c6,$000000000,$0c6fe0000,$0180c0606,$030303030,$000000000, $0c67c0000,$0c67cc6c6,$07cc6c6c6,$000000000,$0c67c0000,$0067ec6c6,$0780c0606,$000000000, $000000000,$000001818,$000181800,$000000000,$000000000,$000001818,$030181800,$000000000, $006000000,$06030180c,$0060c1830,$000000000,$000000000,$000007e00,$00000007e,$000000000, $060000000,$0060c1830,$06030180c,$000000000,$0c67c0000,$018180cc6,$018180018,$000000000, $07c000000,$0dedec6c6,$07cc0dcde,$000000000,$038100000,$0fec6c66c,$0c6c6c6c6,$000000000, $066fc0000,$0667c6666,$0fc666666,$000000000,$0663c0000,$0c0c0c0c2,$03c66c2c0,$000000000, $06cf80000,$066666666,$0f86c6666,$000000000,$066fe0000,$068786862,$0fe666260,$000000000, $066fe0000,$068786862,$0f0606060,$000000000,$0663c0000,$0dec0c0c2,$03a66c6c6,$000000000, $0c6c60000,$0c6fec6c6,$0c6c6c6c6,$000000000,$0183c0000,$018181818,$03c181818,$000000000, $00c1e0000,$00c0c0c0c,$078cccccc,$000000000,$066e60000,$078786c66,$0e666666c,$000000000, $060f00000,$060606060,$0fe666260,$000000000,$0eec60000,$0c6d6fefe,$0c6c6c6c6,$000000000, $0e6c60000,$0cedefef6,$0c6c6c6c6,$000000000,$0c67c0000,$0c6c6c6c6,$07cc6c6c6,$000000000, $066fc0000,$0607c6666,$0f0606060,$000000000,$0c67c0000,$0c6c6c6c6,$07cded6c6,$000000e0c, $066fc0000,$06c7c6666,$0e6666666,$000000000,$0c67c0000,$00c3860c6,$07cc6c606,$000000000, $07e7e0000,$01818185a,$03c181818,$000000000,$0c6c60000,$0c6c6c6c6,$07cc6c6c6,$000000000, $0c6c60000,$0c6c6c6c6,$010386cc6,$000000000,$0c6c60000,$0d6d6c6c6,$06ceefed6,$000000000, $0c6c60000,$038387c6c,$0c6c66c7c,$000000000,$066660000,$0183c6666,$03c181818,$000000000, $0c6fe0000,$030180c86,$0fec6c260,$000000000,$0303c0000,$030303030,$03c303030,$000000000, $080000000,$03870e0c0,$002060e1c,$000000000,$00c3c0000,$00c0c0c0c,$03c0c0c0c,$000000000, $0c66c3810,$000000000,$000000000,$000000000,$000000000,$000000000,$000000000,$00000ff00, $000183030,$000000000,$000000000,$000000000,$000000000,$07c0c7800,$076cccccc,$000000000, $060e00000,$0666c7860,$07c666666,$000000000,$000000000,$0c0c67c00,$07cc6c0c0,$000000000, $00c1c0000,$0cc6c3c0c,$076cccccc,$000000000,$000000000,$0fec67c00,$07cc6c0c0,$000000000, $06c380000,$060f06064,$0f0606060,$000000000,$000000000,$0cccc7600,$07ccccccc,$00078cc0c, $060e00000,$066766c60,$0e6666666,$000000000,$018180000,$018183800,$03c181818,$000000000, $006060000,$006060e00,$006060606,$0003c6666,$060e00000,$0786c6660,$0e6666c78,$000000000, $018380000,$018181818,$03c181818,$000000000,$000000000,$0d6feec00,$0c6d6d6d6,$000000000, $000000000,$06666dc00,$066666666,$000000000,$000000000,$0c6c67c00,$07cc6c6c6,$000000000, $000000000,$06666dc00,$07c666666,$000f06060,$000000000,$0cccc7600,$07ccccccc,$0001e0c0c, $000000000,$06676dc00,$0f0606060,$000000000,$000000000,$060c67c00,$07cc60c38,$000000000, $030100000,$03030fc30,$01c363030,$000000000,$000000000,$0cccccc00,$076cccccc,$000000000, $000000000,$066666600,$0183c6666,$000000000,$000000000,$0d6c6c600,$06cfed6d6,$000000000, $000000000,$0386cc600,$0c66c3838,$000000000,$000000000,$0c6c6c600,$07ec6c6c6,$000f80c06, $000000000,$018ccfe00,$0fec66030,$000000000,$0180e0000,$018701818,$00e181818,$000000000, $018180000,$018001818,$018181818,$000000000,$018700000,$0180e1818,$070181818,$000000000, $0dc760000,$000000000,$000000000,$000000000,$000000000,$0c66c3810,$000fec6c6,$000000000, $0663c0000,$0c0c0c0c2,$00c3c66c2,$000007c06,$000cc0000,$0cccccc00,$076cccccc,$000000000, $030180c00,$0fec67c00,$07cc6c0c0,$000000000,$06c381000,$07c0c7800,$076cccccc,$000000000, $000cc0000,$07c0c7800,$076cccccc,$000000000,$018306000,$07c0c7800,$076cccccc,$000000000, $0386c3800,$07c0c7800,$076cccccc,$000000000,$000000000,$06060663c,$0060c3c66,$00000003c, $06c381000,$0fec67c00,$07cc6c0c0,$000000000,$000c60000,$0fec67c00,$07cc6c0c0,$000000000, $018306000,$0fec67c00,$07cc6c0c0,$000000000,$000660000,$018183800,$03c181818,$000000000, $0663c1800,$018183800,$03c181818,$000000000,$018306000,$018183800,$03c181818,$000000000, $01000c600,$0c6c66c38,$0c6c6c6fe,$000000000,$000386c38,$0c6c66c38,$0c6c6c6fe,$000000000, $000603018,$07c6066fe,$0fe666060,$000000000,$000000000,$03676cc00,$06ed8d87e,$000000000, $06c3e0000,$0ccfecccc,$0cecccccc,$000000000,$06c381000,$0c6c67c00,$07cc6c6c6,$000000000, $000c60000,$0c6c67c00,$07cc6c6c6,$000000000,$018306000,$0c6c67c00,$07cc6c6c6,$000000000, $0cc783000,$0cccccc00,$076cccccc,$000000000,$018306000,$0cccccc00,$076cccccc,$000000000, $000c60000,$0c6c6c600,$07ec6c6c6,$000780c06,$07c00c600,$0c6c6c6c6,$07cc6c6c6,$000000000, $0c600c600,$0c6c6c6c6,$07cc6c6c6,$000000000,$03c181800,$060606066,$018183c66,$000000000, $0646c3800,$06060f060,$0fce66060,$000000000,$066660000,$0187e183c,$01818187e,$000000000, $0ccccf800,$0deccc4f8,$0c6cccccc,$000000000,$0181b0e00,$0187e1818,$018181818,$0000070d8, $060301800,$07c0c7800,$076cccccc,$000000000,$030180c00,$018183800,$03c181818,$000000000, $060301800,$0c6c67c00,$07cc6c6c6,$000000000,$060301800,$0cccccc00,$076cccccc,$000000000, $0dc760000,$06666dc00,$066666666,$000000000,$0c600dc76,$0defef6e6,$0c6c6c6ce,$000000000, $06c6c3c00,$0007e003e,$000000000,$000000000,$06c6c3800,$0007c0038,$000000000,$000000000, $030300000,$060303000,$07cc6c6c0,$000000000,$000000000,$0c0fe0000,$000c0c0c0,$000000000, $000000000,$006fe0000,$000060606,$000000000,$0c2c0c000,$03018ccc6,$00c86dc60,$000003e18, $0c2c0c000,$03018ccc6,$03e9ece66,$000000606,$018180000,$018181800,$0183c3c3c,$000000000, $000000000,$0d86c3600,$00000366c,$000000000,$000000000,$0366cd800,$00000d86c,$000000000, $044114411,$044114411,$044114411,$044114411,$0aa55aa55,$0aa55aa55,$0aa55aa55,$0aa55aa55, $077dd77dd,$077dd77dd,$077dd77dd,$077dd77dd,$018181818,$018181818,$018181818,$018181818, $018181818,$0f8181818,$018181818,$018181818,$018181818,$0f818f818,$018181818,$018181818, $036363636,$0f6363636,$036363636,$036363636,$000000000,$0fe000000,$036363636,$036363636, $000000000,$0f818f800,$018181818,$018181818,$036363636,$0f606f636,$036363636,$036363636, $036363636,$036363636,$036363636,$036363636,$000000000,$0f606fe00,$036363636,$036363636, $036363636,$0fe06f636,$000000000,$000000000,$036363636,$0fe363636,$000000000,$000000000, $018181818,$0f818f818,$000000000,$000000000,$000000000,$0f8000000,$018181818,$018181818, $018181818,$01f181818,$000000000,$000000000,$018181818,$0ff181818,$000000000,$000000000, $000000000,$0ff000000,$018181818,$018181818,$018181818,$01f181818,$018181818,$018181818, $000000000,$0ff000000,$000000000,$000000000,$018181818,$0ff181818,$018181818,$018181818, $018181818,$01f181f18,$018181818,$018181818,$036363636,$037363636,$036363636,$036363636, $036363636,$03f303736,$000000000,$000000000,$000000000,$037303f00,$036363636,$036363636, $036363636,$0ff00f736,$000000000,$000000000,$000000000,$0f700ff00,$036363636,$036363636, $036363636,$037303736,$036363636,$036363636,$000000000,$0ff00ff00,$000000000,$000000000, $036363636,$0f700f736,$036363636,$036363636,$018181818,$0ff00ff18,$000000000,$000000000, $036363636,$0ff363636,$000000000,$000000000,$000000000,$0ff00ff00,$018181818,$018181818, $000000000,$0ff000000,$036363636,$036363636,$036363636,$03f363636,$000000000,$000000000, $018181818,$01f181f18,$000000000,$000000000,$000000000,$01f181f00,$018181818,$018181818, $000000000,$03f000000,$036363636,$036363636,$036363636,$0ff363636,$036363636,$036363636, $018181818,$0ff18ff18,$018181818,$018181818,$018181818,$0f8181818,$000000000,$000000000, $000000000,$01f000000,$018181818,$018181818,$0ffffffff,$0ffffffff,$0ffffffff,$0ffffffff, $000000000,$0ff000000,$0ffffffff,$0ffffffff,$0f0f0f0f0,$0f0f0f0f0,$0f0f0f0f0,$0f0f0f0f0, $00f0f0f0f,$00f0f0f0f,$00f0f0f0f,$00f0f0f0f,$0ffffffff,$000ffffff,$000000000,$000000000, $000000000,$0d8dc7600,$076dcd8d8,$000000000,$0cc780000,$0ccd8cccc,$0ccc6c6c6,$000000000, $0c6fe0000,$0c0c0c0c6,$0c0c0c0c0,$000000000,$000000000,$06c6c6cfe,$06c6c6c6c,$000000000, $0fe000000,$0183060c6,$0fec66030,$000000000,$000000000,$0d8d87e00,$070d8d8d8,$000000000, $000000000,$066666666,$060607c66,$0000000c0,$000000000,$01818dc76,$018181818,$000000000, $07e000000,$066663c18,$07e183c66,$000000000,$038000000,$0fec6c66c,$0386cc6c6,$000000000, $06c380000,$06cc6c6c6,$0ee6c6c6c,$000000000,$0301e0000,$0663e0c18,$03c666666,$000000000, $000000000,$0dbdb7e00,$000007edb,$000000000,$003000000,$0dbdb7e06,$0c0607ef3,$000000000, $0301c0000,$0607c6060,$01c306060,$000000000,$07c000000,$0c6c6c6c6,$0c6c6c6c6,$000000000, $000000000,$0fe0000fe,$000fe0000,$000000000,$000000000,$0187e1818,$0ff000018,$000000000, $030000000,$00c060c18,$07e003018,$000000000,$00c000000,$030603018,$07e000c18,$000000000, $01b0e0000,$01818181b,$018181818,$018181818,$018181818,$018181818,$070d8d8d8,$000000000, $000000000,$07e001818,$000181800,$000000000,$000000000,$000dc7600,$00000dc76,$000000000, $06c6c3800,$000000038,$000000000,$000000000,$000000000,$018000000,$000000018,$000000000, $000000000,$000000000,$000000018,$000000000,$00c0c0f00,$0ec0c0c0c,$01c3c6c6c,$000000000, $06c6cd800,$0006c6c6c,$000000000,$000000000,$030d87000,$000f8c860,$000000000,$000000000, $000000000,$07c7c7c7c,$0007c7c7c,$000000000,$000000000,$000000000,$000000000,$000000000); const picture_palette: array[0..191] of Dword = ( $000000000,$000003f1f,$002000001,$000020000,$000000200,$003000002,$000030000,$000000300, $004000003,$000040000,$000000400,$005000004,$000050000,$000000500,$006000005,$000060000, $000000600,$007000006,$000070000,$000000700,$008000007,$000080000,$000000800,$009000008, $000090000,$000000900,$00a000009,$0000a0000,$000000a00,$00b00000a,$0000b0000,$000000b00, $00c00000b,$0000c0000,$000000c00,$00d00000c,$0000d0000,$000000d00,$00e00000d,$0000e0000, $000000e00,$00f00000e,$0000f0000,$000000f00,$01000000f,$000100000,$000001000,$011000010, $000110000,$000001100,$012000011,$000120000,$000001200,$013000012,$000130000,$000001300, $014000013,$000140000,$000001400,$015000014,$000150000,$000001500,$016000015,$000160000, $000001600,$017000016,$000170000,$000001700,$018000017,$000180000,$000001800,$019000018, $000190000,$000001900,$01a000019,$0001a0000,$000001a00,$01b00001a,$0001b0000,$000001b00, $01c00001b,$0001c0000,$000001c00,$01d00001c,$0001d0000,$000001d00,$01e00001d,$0001e0000, $000001e00,$01f00001e,$0001f0000,$000001f00,$02000001f,$000200000,$000002000,$021000020, $000210000,$000002100,$022000021,$000220000,$000002200,$023000022,$000230000,$000002300, $024000023,$000240000,$000002400,$025000024,$000250000,$000002500,$026000025,$000260000, $000002600,$027000026,$000270000,$000002700,$028000027,$000280000,$000002800,$029000028, $000290000,$000002900,$02a000029,$0002a0000,$000002a00,$02b00002a,$0002b0000,$000002b00, $02c00002b,$0002c0000,$000002c00,$02d00002c,$0002d0000,$000002d00,$02e00002d,$0002e0000, $000002e00,$02f00002e,$0002f0000,$000002f00,$03000002f,$000300000,$000003000,$031000030, $000310000,$000003100,$032000031,$000320000,$000003200,$033000032,$000330000,$000003300, $034000033,$000340000,$000003400,$035000034,$000350000,$000003500,$036000035,$000360000, $000003600,$037000036,$000370000,$000003700,$038000037,$000380000,$000003800,$039000038, $000390000,$000003900,$03a000039,$0003a0000,$000003a00,$03b00003a,$0003b0000,$000003b00, $03c00003b,$0003c0000,$000003c00,$03d00003c,$0003d0000,$000003d00,$03e00003d,$0003e0000, $000003e00,$03f00003e,$0003f0000,$000003f00,$03020103f,$016322212,$02a1a3626,$03f2f1f3a); const picture_bitmap: array[0..15999] of Dword = ( $032384146,$041373231,$04d4d4c49,$04d4d4e4e,$04e4e4d4d,$04f50504f,$04b4c4d4e,$046494a4b, $042434344,$042424140,$046454544,$04a494847,$04d4c4b4b,$04e4e4e4d,$04f4f4f4e,$04f4f4f4f, $050505050,$050505050,$050505050,$050505050,$050505050,$04f504f4f,$04f4f4f4e,$04f4e4e4e, $04e4e4f4e,$04f4d4e4e,$04d4c5152,$04e4e4d4e,$0504f4c4d,$04d4d4c4e,$0504d4d4d,$04d4d4c50, $04d4d4e4d,$0504f4c4c,$04d4d4f50,$04e4d4d4d,$04d4d4e4e,$04e4e4e4e,$04e4e4e4e,$04e4e4e4e, $04e4e4e4e,$04f4f4e4f,$04f4f4f4f,$04f4f4f4f,$04f4f4e4f,$04f4f4f4f,$04e4e4e4f,$04e4e4e4e, $04e4e4e4e,$05a544e4e,$05d5d5d5c,$050575b5c,$04d4d4b4c,$03e43474b,$03c3b3b3b,$0413e3d3c, $04d4a4744,$056555350,$05b5a5958,$05b5b5c5b,$054565859,$050515253,$056525150,$04f575b5a, $04f4e4d4c,$050504f4f,$04c4a4b4e,$04b4e4f4e,$04a4a4a4a,$04a4a4b4a,$049494a4a,$048484949, $047474748,$04d4b4947,$04f4e4e4e,$04f504f4f,$042464b4e,$03e3e3e40,$03f3f3e3e,$046444241, $033374147,$0443a3432,$04f4e4e4b,$04f4f4f4f,$04f4f4e4f,$050505050,$04c4c4d4f,$0484a4b4c, $043454546,$043434140,$047464545,$04b4a4948,$04e4d4d4c,$0504f4f4e,$051505050,$051515151, $052525151,$051515252,$052515151,$052525151,$051515152,$050515151,$050505050,$050505050, $050505050,$04f4e4f50,$04e4d5252,$04f4f4f4f,$0524f4e4f,$04f4e4d51,$0524d4e4f,$04e4e4d52, $04e4f4f4e,$0504d4c4d,$04f515252,$04f4f4f4f,$04f4f4f4f,$0504f504f,$050505050,$050505050, $050505050,$050505050,$050505050,$050505050,$050505050,$050505050,$050505050,$04f4f4f50, $04f4f4f4f,$058524f4f,$05b5c5d5b,$04f535759,$04e4d4d4e,$042464a4d,$0423f3e3f,$04c484644, $05654524f,$05a595857,$05b5b5a5a,$057595a5a,$050525456,$0504f4f4f,$057535251,$0525a5d5c, $0504f4e4d,$051515150,$04d4b4d4f,$04d50504f,$04b4c4c4b,$04b4c4c4c,$04a4b4b4b,$0494a4a4a, $048484949,$04d4b4948,$051504f4f,$051515151,$043484d51,$03f3f3f41,$0403f3f3f,$045424141, $034384248,$0483f3834,$0504f4f4d,$050505050,$0504f4f4f,$051515150,$04c4c4e50,$0494b4c4c, $043464748,$044434140,$048464645,$04c4a4949,$04f4e4d4d,$05150504f,$052515151,$052525252, $052525252,$052525252,$052525252,$052525252,$052525252,$052525252,$052525252,$051515151, $051515151,$04f505151,$04e4f5453,$051515050,$0544f4f50,$0504f4f54,$0524e4f50,$04f4e4f54, $04f50504f,$04d4d4e4f,$053535250,$0504f5051,$051505050,$051515151,$051515151,$051515151, $051515151,$051515151,$051515152,$051515151,$051515151,$051515151,$051515151,$050505151, $050515151,$052515150,$054565755,$050505152,$04f4e4f50,$04b4e5050,$0504d4a49,$058565452, $05b5b5a59,$059595a5a,$055565758,$050515354,$04d4e4e4f,$04f4e4d4d,$056535251,$0555c5f5c, $051504f4f,$052525251,$04d4c4e51,$04f51514f,$04d4d4d4d,$04c4d4d4d,$04c4c4c4c,$04b4b4b4b, $0494a4a4a,$04e4b4949,$052515150,$052525252,$0454a5052,$03f3f4142,$0413f3f3f,$043424141, $0383c454a,$04c463f39,$051515150,$051515251,$050505050,$051525151,$04e4e5051,$04b4d4e4e, $044474849,$046444242,$049484746,$04c4b4a49,$050504f4e,$052515151,$053535353,$053535353, $054545453,$054545454,$054545454,$054545354,$053535353,$054545453,$053545353,$053535353, $052525353,$050525252,$04f525654,$052525251,$054505151,$051505155,$0524f5151,$050505255, $051515151,$04f505151,$05553514f,$051515456,$052525251,$053525252,$053525252,$053525253, $052525353,$053535352,$053535353,$053535353,$052535353,$053535353,$052535353,$052525252, $052525252,$052525251,$052535352,$053535252,$059575554,$0595b5c5b,$05b5a5958,$05c5c5c5c, $0585a5b5b,$053545557,$04f505051,$04f4f4f4f,$04f50504f,$04f4e4f4f,$056545251,$0585f605d, $052515051,$054535352,$04e4e5053,$051535351,$04e4e4e4e,$04e4e4e4e,$04d4d4e4d,$04c4c4c4d, $04b4b4b4c,$04f4c4a4a,$053535251,$054535353,$0474d5254,$041414243,$041414141,$042424141, $041434a4e,$0504d4843,$052525352,$053535353,$052525252,$053535352,$050515253,$04c4e5050, $04647484a,$047464344,$04a494847,$04e4c4c4a,$05151504f,$053535252,$054545454,$055555555, $055555555,$055555555,$055555555,$055555555,$055555555,$055555555,$055555555,$054545555, $054545454,$052535454,$051555754,$053535353,$054515253,$052515356,$052515353,$052535556, $053525352,$052525353,$055515152,$054565757,$054545353,$054545454,$054545454,$054545454, $054545454,$054545454,$054555454,$054545555,$054545454,$054545554,$055555454,$054545454, $054545454,$054545453,$055545454,$05e5c5956,$063626160,$061636464,$05d5e5f60,$058595a5c, $052535557,$04f4f5051,$04f4f4f4f,$05251504f,$055565553,$0504f5153,$057555452,$05c62625e, $053525053,$055555454,$04f4f5255,$052555452,$050504f50,$04f4f5050,$04f4f4f4f,$04e4e4e4e, $04c4d4d4e,$0504d4c4c,$054545453,$055545454,$0494f5455,$042424345,$041424141,$042424241, $04b4c4f52,$053514f4c,$054545454,$054545454,$053535354,$055545453,$053545555,$04e515252, $047484a4c,$049474445,$04b494948,$04f4d4d4b,$052525150,$055545453,$055555555,$056565656, $055555556,$056565656,$057575756,$057575656,$057575757,$057575757,$056565656,$056565757, $056565655,$053555555,$052575854,$054545554,$055525354,$054525659,$052535454,$057585756, $054545354,$054545454,$052535454,$059595754,$055545457,$055555555,$055555555,$056565655, $055555555,$056555555,$056565655,$056555656,$056565656,$056565656,$056565655,$055565556, $056565656,$059585756,$05e5c5b5a,$066656361,$066666666,$063656566,$0595a5c60,$051525355, $050505051,$050515050,$051515151,$059555251,$05c5e5d5c,$051515459,$058565453,$05f64635e, $054535256,$056565555,$050525456,$054565552,$051515051,$050515151,$050515050,$04f4f5050, $04e4e4f4f,$0514e4d4d,$055555454,$056565555,$04b525657,$043444446,$042424242,$043434342, $051525354,$055545352,$055555555,$055555656,$054545454,$056555554,$054565757,$051525353, $0484a4c4e,$04a484546,$04b4a4949,$04f4e4d4c,$053525151,$056555453,$056565656,$056565656, $056565656,$057575756,$058585857,$058585757,$058585858,$058585858,$057575858,$057575757, $057575757,$055565656,$053595954,$056565654,$055545555,$054535859,$053555555,$05b595753, $055545659,$056565556,$054565656,$05a585453,$056565959,$057565656,$057575656,$057575757, $057575657,$057575757,$057575757,$057575757,$057575757,$057575757,$057575757,$058575757, $05a5a5959,$06563605c,$067666565,$067686767,$066676768,$05e616365,$052535459,$051515151, $053535252,$052535353,$052525252,$05e585352,$05e606060,$05252565b,$058575553,$06266645d, $055535359,$058575756,$051535658,$056575553,$052525153,$052525252,$052525252,$050515151, $04f4f5050,$0514f4e4f,$056565554,$057575656,$04d535757,$043444548,$043434343,$043434343, $055565656,$056565656,$056575756,$056575756,$055555556,$058575656,$056575959,$053545555, $04a4d4f51,$04b484647,$04c4b4a4a,$0504f4e4d,$053535251,$056555554,$057575757,$057575757, $056565757,$059585757,$059595959,$059595959,$059595959,$059595a5a,$059595959,$058595959, $058585858,$057575757,$0555a5b57,$057575756,$055565657,$055555a5a,$056575757,$05b575455, $056595b5c,$057575757,$057575757,$056545557,$0595b5c5a,$057575757,$058585757,$058585858, $059595958,$059595959,$059595959,$059595959,$059595959,$0595a5a59,$05a595959,$0615f5d5c, $066666563,$06a696967,$06869696a,$065666667,$05e616364,$056595b5d,$053535355,$054535353, $05a5a5956,$054585a5b,$054545353,$05d585353,$05f5f5e5e,$05354595d,$059585754,$06567655d, $05655555d,$059595958,$053545859,$057585654,$053535355,$053545353,$053535353,$052525253, $050515152,$0524f4f50,$057575655,$058585757,$04f555858,$045454649,$043434344,$044444443, $058585858,$057575758,$057575857,$057575757,$057575757,$05b5a5958,$0585b5b5b,$056575757, $04a4e5153,$04c484546,$04d4c4b4b,$051504f4d,$054545252,$056565555,$058585857,$058585858, $057575758,$05b595958,$05a5b5b5b,$05b5a5a5a,$05b5a5a5b,$05b5b5b5b,$05a5a5a5a,$05a5a5a5a, $0595a5959,$059595959,$0575d5f5b,$058585957,$057575859,$056575b5b,$058585958,$057565758, $05c5e5d5b,$058585758,$059595959,$056575859,$05c5b5a58,$05858595c,$0595a5959,$05a5a5a59, $05a5a5a5a,$05a5a5a5a,$05b5a5a5a,$05b5a5a5b,$05b5b5b5b,$05e5d5c5b,$06663605f,$06b6a6967, $06b6b6c6b,$06a6a6a6b,$063646769,$05c5d5e61,$058595a5b,$057575758,$055555656,$056555555, $06364635d,$0565d6163,$055555554,$05b575454,$060605f5d,$054555b5e,$05b595755,$0686a665e, $058565761,$05a5a5a59,$05457595a,$059595754,$055555557,$055555555,$054545455,$053545454, $052525253,$052505151,$059585755,$05a595959,$052575959,$04646484c,$045444445,$045454545, $05a5a5a5a,$059595a5a,$059595959,$059595959,$05b5a5a59,$05e5d5c5b,$05c5d5e5e,$058595a5a, $0494d5155,$04b474546,$04d4d4c4c,$051504f4f,$055545353,$056555555,$058585857,$058585959, $058585858,$05c5b5a59,$05c5c5c5c,$05c5c5c5c,$05c5c5b5b,$05c5c5c5c,$05b5b5b5c,$05b5b5c5b, $05b5b5b5b,$05b5b5b5b,$0575e6160,$05a5a5a59,$058595a5a,$057595c5a,$05a5a5a5a,$057595a5a, $05e5d5a57,$059595b5e,$05a5a5a59,$0595a5a5a,$05d595757,$05a5d5e5f,$05b5b5b5a,$05c5b5b5b, $05c5c5c5c,$05c5c5c5c,$05c5c5c5c,$05d5d5d5c,$063615f5d,$06b696563,$06d6d6c6b,$06d6e6e6e, $0696b6c6d,$064656566,$05a5b5e61,$05959595a,$059595959,$0595b5b5a,$057575757,$058565656, $065666560,$0585f6263,$056565656,$05b565556,$06261615f,$055575d61,$05c5a5855,$06b6b675f, $059575a64,$05b5b5b5b,$056595b5c,$05b5a5755,$056565759,$056565656,$055565656,$055555555, $053545455,$053525253,$05a595856,$05b5b5a5a,$0555a5b5b,$04748494f,$046454647,$046464646, $05c5c5b5b,$05b5b5b5c,$05b5b5b5a,$05c5c5b5b,$05f5f5e5d,$06060605f,$05e5f5f5f,$0595a5b5c, $0484d5156,$04a454445,$04e4e4c4c,$05150504f,$054545353,$056555555,$059585858,$058595959, $059585858,$05d5b5a59,$05d5e5d5d,$05d5d5d5d,$05d5d5d5d,$05d5d5d5d,$05d5d5d5d,$05c5d5d5d, $05c5c5c5c,$0605c5c5c,$0595a6062,$05b5b5c5b,$0595b5c5b,$0585b5d5b,$05b5b5c5b,$05a5b5b5b, $05d59585a,$05b5e5f5f,$05b5b5a5a,$05b5b5b5b,$05958595a,$05f615f5d,$05d5c5c5c,$05d5d5d5d, $05e5d5d5d,$05d5d5d5e,$05e5d5d5d,$06462615f,$06e6d6b68,$06f6f6f6e,$06e6f6f6f,$0696a6c6d, $05f626567,$05c5c5c5d,$05a5a5b5b,$0595a5a5a,$0625e5a5a,$062666764,$05857575c,$057575757, $06464625d,$05a606264,$056575757,$05b565656,$065646260,$0575a6165,$05d5b5956,$06d6c665f, $059585d67,$05d5c5b5b,$0575b5d5d,$05c5a5856,$05757585b,$058585757,$057575757,$055565656, $054555555,$053535353,$05b5a5956,$05c5c5c5c,$0585c5d5d,$048494b51,$046474748,$046464646, $05f5e5d5d,$05e5e5e5f,$05f5f5f5e,$061605f5f,$064636362,$063636364,$060626262,$05a5b5c5e, $0484d5257,$048454445,$04e4e4d4d,$05251504f,$055545353,$057565655,$059595958,$059595959, $05a595959,$05e5c5b5a,$05e5f5e5e,$05e5e5f5f,$05e5f5e5e,$05e5e5e5e,$05e5e5e5e,$05d5e5f5e, $05d5d5e5e,$065605d5d,$05c5a5e62,$05d5d5d5c,$05b5d5d5d,$0595e5f5b,$05c5d5c5c,$05c5c5c5c, $05a5a5b5c,$06161605d,$05c5c5c5f,$05d5d5c5c,$05a5c5c5c,$062615d5a,$05e5d6062,$05e5f5e5e, $05f5f5e5e,$05f5f5f5f,$067646160,$0706e6d6b,$071717171,$06f707071,$0686a6c6e,$05f616365, $05d5d5d5e,$05d5d5d5d,$05b5c5c5c,$05a5b5b5c,$06c665c5b,$0666a6c6c,$059585960,$058585959, $06664625c,$05c626566,$058585858,$05b575758,$06a696661,$0595c6469,$05f5d5a57,$06f6d6660, $05a59606b,$05e5d5d5c,$0595d5f5f,$05d5b5857,$058585a5d,$059595959,$058585859,$057575858, $056565757,$054535455,$05d5c5a57,$05e5e5d5d,$05b5f5f5e,$0494a4d54,$048484949,$047474747, $061616060,$062616161,$063626262,$066656464,$067676767,$066666767,$064656566,$05b5d5f61, $0494e5358,$048464546,$04f4e4e4d,$05251504f,$055545452,$057565656,$05a5a5958,$05a5a5a5a, $05a5a5a5a,$05f5e5d5c,$060606060,$05f606060,$060606060,$0605f5f5f,$05f5f6060,$05f5f605f, $05f5f5f5f,$06466605f,$05e5c5a61,$05f5f5e5e,$05d5e5e5e,$05e61615b,$05e5e5d5c,$05e5e5e5e, $05c5d5d5d,$063615c5a,$05d5e6264,$05e5e5e5e,$05e5e5e5e,$0615d5b5d,$05e606564,$060606060, $062616060,$06a696865,$0726f696c,$073737372,$06f717272,$066686a6c,$060606264,$05e5e5f5f, $05f5f5f5e,$06362605f,$05d5d5f62,$05c5c5c5d,$069665e5b,$066666668,$05a595a62,$0595a5a5a, $06865625c,$05f666869,$05a59595a,$05b58595a,$071706a63,$05a5f686f,$0605e5a59,$0716e6661, $05a5b636e,$05f5e5e5d,$05b5f6060,$05e5c5959,$05a5a5c5e,$05a5a5a5a,$0595a5a5a,$059595959, $058585859,$055555657,$05e5d5b58,$05f5f5e5e,$05d60605f,$04a4c4f56,$0494a4a4a,$048484949, $064636362,$065646363,$066666565,$069696867,$06a6a6a6a,$06b6b6a6a,$0696a6b6b,$05e616467, $04d51555a,$04b49494a,$04f4e4e4e,$052515050,$055555453,$058575756,$05b5b5958,$05b5b5b5b, $05c5c5b5b,$061605f5d,$061616161,$061616161,$061616161,$061616161,$061616261,$061616161, $061616161,$064676561,$05f605c5e,$060606060,$05e5f5f60,$06363605c,$05f5e5f62,$05f5f5f5f, $05f5f5f5f,$0615c5c5e,$061656565,$06060605f,$060616161,$05d5e6060,$060656662,$067676664, $06e6b6968,$074747472,$073706c73,$06d707273,$065686a6c,$061616162,$060616161,$05f606060, $062606060,$06f6f6d68,$05e60676c,$05d5d5e5e,$066625c5c,$067666566,$05b5a5e65,$05a5b5b5b, $06966625c,$062686b6c,$05b5b5a5b,$05c5a5b5b,$075746f64,$05c636d74,$0605e5b5a,$0736e6661, $05b5d6871,$060605f5d,$05d606161,$05f5d5a5a,$05b5b5e60,$05c5b5b5b,$05b5b5b5c,$05b5b5b5b, $0595a5a5b,$056575858,$05f5e5c58,$060606060,$05e616160,$04c4d5259,$04a4a4b4b,$0494a4a4a, $066656564,$067666666,$069686867,$06d6d6c6a,$070706f6e,$072727171,$06d707172,$06064676b, $05154585c,$04b4b4c4e,$04d4c4c4c,$05252514f,$056555453,$058575757,$05b5b5959,$05c5b5b5b, $05e5e5d5c,$06261605f,$062636363,$063636262,$062636363,$062626262,$062626262,$062626262, $062626162,$063676964,$060615f5c,$061616161,$060606060,$064615c5e,$060626565,$06060605f, $061616061,$05d5f5f60,$067676560,$062616060,$062626262,$064646362,$06d6c6b65,$075757472, $076767575,$073757576,$06a676870,$063656769,$062626262,$062626262,$061616262,$061616161, $066606061,$07072726f,$05e646a6d,$05e5e5e5f,$065605c5d,$069686767,$05c5b6067,$05b5c5c5c, $06a66615c,$0656c6e6e,$05c5c5b5e,$05c5b5c5c,$076767064,$05d657076,$0615e5b5b,$0746d6563, $05d616d74,$06161605e,$05f616161,$0615e5b5b,$05c5c6062,$05d5d5c5c,$05c5c5c5d,$05b5c5c5c, $05a5b5b5b,$05858595a,$0605e5c59,$060616160,$060626160,$04d4e535b,$04b4b4c4c,$04a4a4a4b, $069696767,$06c6a6a6a,$06f6e6d6d,$075747371,$077767675,$077777777,$06f737576,$06164686c, $05456595d,$04a4b4f51,$04b4a4a4a,$05352514e,$056555454,$059585857,$05c5b5a59,$05d5c5c5c, $061605f5e,$063636361,$064646464,$065646464,$064646464,$064646464,$063636464,$063636463, $064636364,$05e666a6b,$06363625f,$062626262,$061626261,$05f5d5f61,$066686764,$062616162, $062626262,$061626262,$068645f5f,$065636063,$06b6a6866,$075726f6c,$078777776,$078787878, $072747577,$0686a6d6f,$063646466,$064636363,$063646364,$068656463,$065686969,$062626262, $065616262,$06e6e6e6c,$05f666c6e,$05f5f5f5f,$065605d5e,$06e6c6a69,$05d5d626a,$05d5d5d5d, $06f66605c,$06b727574,$05d5d5c62,$05c5c5c5d,$078766f62,$05f6a7478,$0625f5c5c,$0746c6564, $05e657176,$06261615f,$061636362,$0625e5c5d,$05d5f6264,$05f5e5e5e,$05e5e5e5e,$05d5d5e5e, $05b5c5d5d,$059595a5b,$0615f5c59,$062626161,$062636262,$04f51565d,$04c4c4d4e,$04c4c4c4c, $0706f6d6d,$074737271,$077767675,$07a7a7978,$07a7a7a7a,$079797979,$06d727578,$05f626569, $05556595c,$04d4f5254,$04a48494b,$05352504d,$056565554,$05a595858,$05d5c5b5b,$05e5d5d5d, $06361605f,$065646463,$065656565,$066666565,$065656566,$065656565,$064656565,$064656464, $069646465,$06062696c,$064646362,$063646464,$063636363,$060626363,$06a69645f,$06462636a, $064646363,$064646464,$069646164,$0746f6868,$079787776,$07b7a7a79,$0797a7a7a,$073767778, $067686a6e,$065656565,$066666566,$065656565,$064646465,$077726a64,$06d737677,$063636364, $062616363,$0706d6d6a,$060686f71,$060606160,$0655f5e60,$073726e6b,$05e5f656e,$05e5e5e5e, $07468615e,$070787a79,$05f5e5e65,$05d5d5e5e,$079736860,$0626d7679,$0625f5d5e,$0756b6564, $05f687478,$06363615f,$063666564,$0635f5e60,$05e616465,$060605f5f,$060606060,$05f5f5f5f, $05d5e5f5f,$05b5b5c5d,$062605d5a,$063636362,$064646464,$051535a61,$04e4e4e4f,$04d4d4d4e, $078777675,$07a7a7979,$07b7b7b7a,$07b7b7c7c,$0797a7a7b,$077787879,$0696d7275,$05e5e6165, $056575a5c,$04d505456,$04a48484a,$053514f4c,$057565554,$05b5a5a59,$05e5d5c5c,$0605f5f5e, $064636261,$066666565,$066676767,$067676766,$067676767,$067666667,$066666666,$065666566, $06d676565,$06360666b,$065656565,$064656565,$065656464,$063646465,$067636162,$06562696b, $066666565,$069676666,$072706f6c,$07c7b7874,$07c7c7d7c,$07a7b7c7c,$072747679,$0676a6c6d, $066666565,$066676666,$067676666,$066666566,$066656566,$078756d65,$06f747778,$064646366, $062626364,$0716f6d68,$0626a7172,$061616261,$065606061,$07776706a,$05f616971,$060606060, $07769615f,$0747b7c7c,$05f5f5f66,$05e5f5f5f,$0766d615e,$0656e7578,$0625f5e5f,$0756b6665, $0616b7679,$065646260,$066676666,$062605f62,$05f626666,$061616160,$061616161,$060606061, $05e5f6060,$05c5d5d5e,$062605d5b,$064646463,$065656565,$052555c63,$04f4f5051,$04e4e4e4e, $07d7d7d7d,$07d7d7d7d,$07c7c7c7d,$07a7b7c7c,$076777879,$075767676,$0686c6f73,$05d5e6063, $05455585b,$04a4d5153,$04a464546,$053504d4c,$058575554,$05d5c5b5a,$0605f5e5e,$062606060, $066656463,$068686767,$068686868,$068686868,$068686868,$068686868,$067676768,$067676767, $06d6e6767,$066646169,$067676666,$066666666,$066666666,$066666666,$063626565,$066646d6c, $06d6a6867,$07a76736f,$07d7d7d7c,$07e7e7e7e,$07b7d7e7e,$071737679,$06d6c696d,$067676665, $067686767,$069676867,$071726f6d,$06767686d,$066676667,$0726f6865,$06e737473,$065656467, $063636565,$072706d66,$0656d7374,$063646362,$065616162,$07c7b746a,$060636c76,$061626261, $076686160,$0797d7e7d,$06060616b,$05f606060,$073685e5d,$067717678,$063606061,$0756c6866, $0636e797b,$067666361,$068686867,$063606164,$061646767,$063626262,$062626263,$061626262, $060606161,$05d5e5f60,$063615e5c,$066666565,$067676766,$054585f66,$050515152,$04f4f4f4f, $07f7f7f80,$07d7e7e7e,$07a7a7b7c,$077797a7a,$077767576,$074767677,$0666a6e71,$0585a5d61, $050515356,$0494b4e50,$04e4a4646,$0534f4c4d,$05a585655,$05f5e5d5b,$061605f5f,$063626161, $068676564,$069696868,$069696969,$069696969,$069696969,$069696969,$069686969,$068686868, $06e706d69,$068676467,$068686868,$068686868,$067676768,$068686868,$068696868,$0716c706f, $07d7a7775,$0807f7f7e,$07f7f8080,$07d7d7e7e,$070757a7c,$06868696c,$06d6b6667,$068686768, $068686868,$075696868,$0777a7b7a,$068676d73,$067686868,$0706b6666,$06c727272,$066666567, $063646666,$074706b65,$068707777,$064656463,$065636364,$0807f796c,$061646f7b,$062626362, $06e646161,$07a7e7e7a,$06161636f,$05f616161,$070645d5e,$06a727676,$064616163,$0756c6968, $066727b7c,$068676462,$06a6a6969,$064616267,$063676867,$064636362,$063636364,$063636363, $061626262,$05e5f6061,$065625f5e,$068676766,$068686868,$0555a6268,$051525354,$050515151, $081828384,$07e7f7f80,$07b7a7b7c,$0797b7c7c,$07a797979,$06f737779,$06064676b,$055575a5c, $04f505152,$04a4c4e4f,$052504b48,$054504e4f,$05d5c5957,$06261605f,$064636262,$066666565, $06b6a6968,$06d6d6c6c,$06d6d6d6d,$06e6e6e6d,$06d6d6e6e,$06d6d6d6d,$06d6c6d6d,$06c6c6c6d, $06d72756f,$06c6c6a67,$06c6c6c6c,$06c6c6c6c,$06c6c6c6c,$0706e6d6c,$07f7c7874,$08482807f, $085858585,$084848484,$07c7f8282,$07473767a,$06c6c6e72,$06c6c6c6c,$075716b6c,$06b6c6c71, $06c6c6c6c,$0766d6b6c,$077777777,$06b6a7175,$06a6b6b6b,$0726b686a,$071747574,$06a6a696d, $067696a6a,$07a736d68,$06f777e7f,$068696867,$067666768,$085858070,$064677783,$065656665, $066616464,$07f828076,$064646976,$063656464,$071646161,$06f777a7a,$068646567,$0776f6e6c, $06b798180,$06c6a6765,$06e6e6d6d,$06664666b,$0676b6c69,$067676665,$067676767,$067676767, $065666666,$062636464,$068656261,$06c6c6b6a,$06c6c6c6c,$05a5f676c,$054555657,$053545454, $083858687,$080818182,$07d7d7d7e,$0787a7c7d,$076767676,$065696d73,$05e5f6062,$056595b5d, $04f505153,$04c4d4e4f,$053524e4b,$056535151,$0605e5c5a,$064646362,$067666565,$06a696968, $0706e6d6c,$071717070,$071717171,$072727171,$071717272,$071727272,$071717272,$071707071, $06b747878,$070706f6c,$070707170,$071727271,$074737271,$084807a75,$08a8a8988,$08a8a8a8a, $08688898a,$07b7e8184,$074727679,$06f6c7578,$070707070,$070707070,$084827a72,$0707a8083, $07070706f,$0726d6e6f,$07c7a7876,$06e6f777c,$06e706f6f,$0746d6b6d,$07a7b7978,$06e6c6d74, $06b6d6e6e,$082786f6b,$074808788,$06c6d6b6b,$06a696b6c,$08b8a8372,$0676d7e89,$069696968, $065646668,$085888578,$067676e7c,$067676768,$074656365,$0767d817e,$06a67696d,$07973716f, $072808684,$0706d6a69,$072717170,$069686b70,$06b6f6f6d,$06b6a6a68,$06b6b6b6b,$06b6b6b6b, $0696a696a,$067676868,$06c686565,$06f6f6f6d,$0706f6f6f,$05e656c70,$05758595b,$056575757, $085878889,$07e818284,$077787a7c,$06c6e7275,$06d6d6b6b,$06061656a,$05d5d5e5f,$05457595b, $04d4d4f51,$050504f4e,$054545351,$05b595654,$063615f5d,$067676665,$06a696868,$06e6d6c6b, $073727170,$075757474,$075757575,$076757575,$075767676,$076767575,$075757676,$079747574, $06f737a7e,$074747373,$076757574,$07b797776,$08987847f,$08f8f8e8b,$08f8f8f90,$088898c8e, $0797e8486,$073737576,$073727373,$07370797a,$074737374,$073747373,$0898d8b7d,$076828888, $073737371,$072707273,$0837f7d7a,$071737b83,$072737373,$077727070,$07e82807c,$072707178, $070717272,$08a7b6e6d,$07b898f8f,$06f706e70,$06c6d6f6f,$08e8a7d70,$06b76848c,$06c6c6c6b, $067686b6b,$08a8c8778,$06a6b7381,$06a6b6b6b,$074656668,$080868883,$06c6a6d75,$07b767472, $078888c87,$073716d6d,$075747473,$06c6c7074,$070737370,$06f6e6d6c,$06f6f6f6f,$06e6f6f6f, $06d6d6d6e,$06b6b6b6d,$06e6b696a,$073737271,$074737373,$0626a7174,$05a5b5d5e,$059595a5a, $07f828586,$074777a7c,$0696b6e71,$062636668,$065656362,$05a5c5e62,$054555659,$04a4d4f51, $04b494949,$058565350,$0595c5b59,$060605c59,$065636261,$069696867,$06d6b6b6a,$072716f6e, $077767573,$07a797878,$079797979,$07a797979,$07a7a7a7a,$07a7a797a,$0797a7a79,$080787a79, $078727b80,$07a7a7978,$07b7a7979,$0918d867e,$094949492,$092939394,$08c909192,$078828585, $076777777,$077767777,$078777778,$0797d8482,$077767677,$076777777,$0868a877d,$078828785, $076777674,$073737676,$08a87827c,$074767f8a,$076777676,$079747375,$0888d8981,$07673767f, $074757676,$093817171,$085939696,$073727174,$06f707272,$09089786e,$06f7d8a90,$06f6f6f6e, $0686b6e6e,$08e8f8976,$06e707b87,$06d6e6f6e,$072676a6c,$08b918f87,$06f6e727e,$07d797774, $07f8e9088,$075737072,$079787776,$06f707478,$075787773,$072727171,$072727272,$072727272, $071717172,$06e6f6f70,$0716d6c6e,$076767675,$078777676,$0676f7679,$05e5f6062,$05b5c5d5d, $070737779,$067696b6d,$062636465,$05d5f6061,$05a5a5b5c,$04e505357,$046484a4c,$043434445, $04a464543,$0605c5852,$068686662,$064666667,$067666564,$06d6c6b69,$0706f6e6d,$075747270, $07b7a7977,$07d7d7c7c,$07e7e7d7d,$07e7e7e7e,$07e7e7e7e,$07e7e7e7e,$07e7e7e7e,$0827c7e7e, $0817c7c83,$084838382,$08e8b8a87,$099999894,$093969798,$086888c90,$07c818485,$07a848378, $07b7b7a78,$07b7b7b7b,$08f857c7b,$08b919394,$07b7a7982,$0797a7b7b,$087858179,$07e878e8a, $07a7a7a78,$07577797a,$0918d857c,$0777d868f,$07a7b7a78,$07c777779,$095999387,$078767a8a, $078797979,$096827475,$08b969a9b,$077767477,$072737476,$09389756e,$073818e93,$072737371, $06a707272,$093938a74,$07174808c,$070717171,$072696e70,$09398978b,$071737785,$07e7c7976, $087939388,$078757377,$07c7b7a79,$07374797d,$07a7c7976,$076757475,$076767777,$076767676, $075757575,$072737374,$074707071,$07a7a7977,$07c7b7a7a,$06c757b7d,$061626366,$05f5f6061, $06466686a,$05f606162,$05d5d5d5e,$054585b5c,$04a4c4d50,$041424447,$03e3e3f40,$03f3e3e3e, $04c484542,$06b655f56,$087817870,$06d727b85,$06a69686a,$0706f6e6d,$072727171,$07a777573, $07f7e7d7c,$081818080,$082828281,$083828282,$082828383,$083838282,$083838383,$089848584, $098958e8d,$09a9a9999,$0999b9c9b,$092959697,$08487898c,$07f7f8082,$07f7e7e7e,$08188857d, $07e7f7e7d,$07f7f7f7e,$09b94807e,$092969599,$07e7c7d89,$07c7d7f7f,$08c87807b,$08590968f, $07e7e7d7c,$07a7b7d7e,$097948a80,$07b858c95,$07e7e7e7c,$07f7a7b7d,$09ea09d8f,$07b7a7f93, $07b7c7d7d,$08c7a7678,$08e979998,$07a79767d,$076767879,$093847171,$079869095,$075767775, $06d737576,$09c9a8d72,$0747a8a97,$073747474,$0716b7072,$09a9e9c8e,$074777f8d,$081807c78, $091999587,$07b78777f,$0807e7d7c,$076787e82,$07e7f7b78,$07a79777a,$07a7a7b7b,$07a7a7a7a, $079797979,$076767778,$077737475,$07e7e7d7b,$07f7f7f7e,$0717a8080,$06567686b,$062636465, $05b5d5f60,$056575758,$052525354,$0464c5152,$03c3d3f42,$03a38383a,$03b3a3a3a,$03f3d3d3b, $0524c4743,$07f746a5d,$098969089,$0808b9397,$06c6c6e74,$07271706e,$075747373,$07d7a7876, $08280807f,$083838282,$085858483,$085858585,$085858485,$086868685,$08f8c8986,$09d9c9a95, $0a1a19f9e,$09d9fa0a1,$08b90959a,$083858585,$082818182,$081828181,$081818181,$08f928a80, $0807f8587,$080808080,$093887e7f,$092949395,$0817d808a,$07f7f8080,$08d87807d,$08a949690, $080807e7f,$07c7d8080,$09e988b81,$0808c959d,$07f80807d,$07f7b7d7f,$0a3a4a394,$07c7b849b, $07c7d7e7e,$08478787b,$0949b9a93,$07b7a7882,$078797a7a,$094807075,$07f8d9499,$078787777, $071747677,$0a29d8b70,$07781949f,$074747575,$06e6d7173,$09d9f9a87,$07a848d96,$083827f7a, $0989d9587,$07d7a7a88,$083817f7e,$0787c8183,$081807c79,$07c7a797c,$07c7c7d7d,$07c7c7c7c, $07b7b7b7c,$078797a7a,$078757677,$080807f7c,$081818181,$0767e8282,$0686a6b6e,$065666767, $04e515355,$047484a4b,$045444446,$03c414545,$035353638,$036343334,$03a393838,$0423e3c3b, $0655a5047,$090897e71,$096979593,$094999996,$06e6f7586,$07271706e,$075747372,$07d7b7977, $08180807f,$083838282,$085848483,$085858585,$088878686,$0918d8b8a,$0a09d9a95,$0a0a1a1a1, $09d9c9d9f,$08a91979c,$082828386,$082838282,$083828182,$081808182,$084808080,$09a9b9b92, $07e849198,$07f7f8180,$08a7f7c7e,$091919091,$07f7c818a,$07e7f7f7f,$08c847d7c,$08c969791, $0807f7e81,$07c7e8081,$0a198887e,$07f8e9ca2,$07f807f7c,$07a7b7d7f,$0a0a29f8a,$07b7a8599, $07c7c7c7d,$07f74787b,$09598988f,$07b797985,$0787a7a7a,$0947c6f75,$08591989b,$078787779, $073757677,$0a29c8670,$0778699a2,$073747575,$0676b7072,$09c958573,$08594999c,$083817e7a, $09c9d9386,$07c797c8c,$08281807e,$0797d8283,$081807c78,$07c7a7a7e,$07c7c7d7d,$07c7c7c7c, $07a7b7b7b,$078797a7a,$077757778,$081807e7c,$081818181,$079808383,$06a6b6c70,$066676869, $041424546,$03b3c3d3e,$03d3a3a3a,$0393c3f3f,$035353435,$037353435,$03b3a3837,$04e46403d, $07d746659,$08b888380,$0898d8c8b,$09a968c82,$06f738294,$07373716f,$075747373,$07d7b7977, $08281807f,$084838282,$086858584,$08a888686,$098938f8c,$0a09e9c9b,$0a0a1a1a0,$0989e9fa0, $088889194,$082828588,$082828282,$083838282,$082828282,$080818181,$0857e7f80,$094939896, $07d869196,$07f7e8180,$0857c7c7e,$09296918d,$07e7b828a,$07e807f7f,$08b817a7c,$08e969994, $0807f7d83,$07c7e7f80,$0a39c887b,$07f91a1a4,$07f7f7d7c,$0797c7d7e,$09d9a8e7c,$07a7a8998, $07c7c7d7c,$07973787b,$09496968b,$07a797b89,$07879797a,$092797075,$08d9a9e9d,$07777777b, $072747577,$0a29b7f6e,$07c8c9ca2,$071727375,$0636a6f71,$09880675f,$0969ea09f,$082807d80, $09d9d9184,$07a787e92,$081807f7e,$0797e8382,$082807b78,$07c7a7a80,$07c7c7d7c,$07c7c7c7c, $07a7b7c7b,$0797a7a7a,$078767878,$081807e7b,$081818181,$07b818383,$06b6c6e73,$06869696a, $037383a3c,$037373736,$03d393836,$03f444543,$036363739,$039383737,$044413d3b,$0534e4a47, $0706c6258,$0827e7871,$083878684,$098897775,$0717d919a,$07372706f,$075747473,$07d7b7977, $08282807f,$084838382,$08c888785,$09a97938f,$0a0a09f9d,$09fa0a1a1,$0979a9c9d,$0858c9295, $081808a89,$082828283,$082818282,$089868382,$087918f8c,$08180807f,$07f7e7f81,$09191918c, $07d868f95,$0807e7f7e,$0817a7b7e,$093958f88,$07d7b848b,$07e7f7f7f,$08a7e797d,$0929d9d97, $07f7e7d85,$07d7e7f80,$0a49c8379,$08096a2a3,$07e7f7d7c,$0787c7d7e,$09a94867a,$07a7b8a97, $07c7c7d7c,$07474797b,$096999889,$079797e8d,$07979797a,$093777276,$094a0a3a1,$07676777f, $070747576,$09c8d716a,$08c959ea1,$071717480,$0666c6e70,$09369545c,$09da1a2a0,$082807d89, $09e9c8e84,$07a788195,$0807f7f7d,$0797f8281,$0827e7a78,$07c7a7b81,$07c7c7c7c,$07c7c7c7c, $07a7b7b7b,$0797a7a7a,$078777878,$081807e7b,$081828281,$07c818282,$06c6d7074,$069696b6b, $034353637,$037373635,$0463e3a38,$0474e4f4c,$03a38383e,$04543423e,$046464645,$047444445, $05754504b,$07d786d5d,$083858381,$0917a6f74,$0758b9a9c,$072727070,$075747473,$07d7b7977, $08181807f,$087848382,$09c99948e,$0a0a0a09e,$09d9e9fa0,$09095999c,$085888a8c,$07f818384, $080828b86,$082828382,$081828282,$09a988c81,$08f959799,$080807f7f,$07c7d7f80,$091918e84, $07e899495,$07e7e7e7e,$07f797c7e,$096928b85,$07d7d8790,$07f807f7f,$08a7b797d,$099a1a09b, $07f7e7d86,$07e7e7f7f,$09d8c7878,$083959c9f,$07d7e7c7c,$0777c7c7d,$096908174,$07a7d8a94, $07c7d7d7b,$07376797b,$09a9c9886,$079798192,$07879797a,$091737377,$096a2a3a1,$075757782, $06e727475,$086726468,$09a9c9d97,$070727f93,$06b6d6d6f,$08658505d,$09ca0a19d,$081807f8b, $09c998b83,$079778294,$07f7f7e7c,$07a7f8281,$0827d7a78,$07b797c81,$07c7c7c7c,$07c7c7c7c, $07b7b7b7c,$0797a7b7a,$077787978,$080807e7a,$081818181,$07d828282,$06e6f7176,$06a6b6c6d, $036353434,$038373737,$04b433c3a,$04d535552,$0423f3f44,$043464746,$03f3e3f41,$04342403f, $0514e4b46,$07b746655,$084848481,$088726c76,$07a939d9a,$072716f70,$074737373,$07d7b7876, $08181807e,$08c848382,$0a0a09f9b,$0999c9e9f,$08b8e9296,$084858789,$083848384,$080828383, $081878a84,$082838182,$080818281,$09493897f,$08b8d8f91,$0807f7d81,$07a7d8080,$0908f887f, $07e899395,$07e7f7e7c,$07e797d7f,$099958c85,$07d7e8a94,$07f80807f,$08a797a7d,$09fa3a3a0, $07e7c7d8c,$07d7e7e7f,$09481767a,$087979b9b,$07d7d7b7b,$0787c7d7d,$0958d7b71,$07a828f94, $07c7d7d7b,$074787a7b,$0a0a09882,$0787a8798,$077787878,$0856f7476,$097a0a29d,$074777e8a, $06d717274,$0615c6168,$0a1a19c81,$06f7590a0,$0676a6c6d,$06f504f5c,$0949a9b91,$08181838a, $095908682,$077767e8e,$080807e7b,$07b808181,$0817d7978,$07b797d82,$07c7c7c7c,$07c7c7c7c, $07c7c7c7c,$07a7a7b7b,$078797a79,$080807e7a,$080818181,$07e818180,$06f707177,$06c6c6d6e, $03a383736,$042403e3c,$0504c4744,$051575754,$03c3c3f47,$03c3d3d3d,$03d3c3c3c,$041403f3e, $04e4b4743,$079726152,$08383837f,$0806e6c79,$07c969d98,$071706f6f,$073727271,$07d7b7774, $08180807e,$08c838382,$0979ea09d,$0878a8e92,$084848586,$083838483,$082838383,$085838182, $08f90918d,$08181828c,$07f818282,$08e8b807e,$0888c8e8e,$07f7f7d81,$07a7c7e81,$0908c837b, $081899497,$07e7f7e7b,$07c7a7d7f,$09d978e81,$07c7f8d9b,$07f7f7f7f,$084787b7e,$09fa1a39d, $07d7b7b8e,$07c7d7e7e,$0907b757a,$089979b9a,$07d7c7a7b,$0797c7d7d,$0988b7771,$07c889599, $07c7c7c7b,$07479797a,$0a3a2997e,$0787d8e9d,$075777877,$06f6b7373,$09b9f998b,$075859297, $06d6f7073,$0535c676c,$0a3a1976a,$06e7a98a2,$065686b6c,$06051525d,$08f939284,$084838389, $088858383,$075757a84,$0807f7e7a,$07c808180,$0817c7878,$07b7a7e82,$07c7c7c7c,$07c7c7c7c, $07c7c7c7c,$07a7a7b7b,$078797a7a,$0807f7d7a,$080818180,$07f818180,$070717379,$06d6d6e70, $04c494745,$04d50504e,$04e4b4a4b,$0565a5955,$03b3b3f4c,$03b3b3b3b,$03c3c3c3b,$0413f3e3d, $04b484542,$0776f5c4f,$08483807c,$07a6c6c7c,$07d979d95,$0706f6e6f,$072717170,$07d7b7774, $08080807e,$08a838281,$08795a09c,$083838384,$082838383,$082828383,$082828282,$094858081, $0918e8e93,$0817f8791,$080808181,$08d887d7e,$090938e8e,$07f7f7c84,$07a7c7f7f,$0928b8179, $0838d9598,$07e7f7e7b,$0777a7d7f,$0a29c8e7e,$07c8194a1,$07e7e7e7d,$079787b7e,$09b9e9b8b, $07d7b7d8f,$07c7d7d7d,$08a76777a,$089959897,$07d7c7b7c,$07b7c7c7d,$097867274,$07e8e9b9e, $07b7c7b7a,$07377787b,$0a4a39779,$0778093a0,$074767776,$060686f71,$09e967f6c,$07d979f9f, $06d6e6f72,$04f5b686d,$0a2a08c57,$06c7e99a0,$06467696a,$05c51535e,$08b89887a,$084858288, $07d7c7f81,$07474797d,$0807f7d79,$07e828281,$0807b7879,$07a7a7f82,$07c7c7c7b,$07c7c7c7c, $07c7c7c7c,$07a7b7b7b,$078797a7a,$0807f7c79,$081808080,$080818180,$07272757b,$06f6f6f71, $051525454,$042474c4f,$048403d3f,$05c5e5b54,$03b3c4452,$03b3b3b3b,$03c3c3b3b,$0403f3e3d, $049464341,$0756b574d,$083827f7a,$0786d6f80,$07d969c94,$06f6e6d6e,$07271706f,$07c797673, $080807f7d,$089828281,$086949f9b,$083838383,$085848483,$081838686,$081828282,$08a817f81, $08c8d8c89,$0807e898d,$07f808080,$08a857c7d,$090938f8d,$07f7e7b84,$07c7d7f7f,$0968a7f79, $0858f979b,$07e7f7e7b,$0787c7e7e,$0a3a1947d,$07c849ca3,$07d7e7e7e,$079797b7d,$0989b9582, $07c7a7f90,$07c7c7c7d,$08675777b,$090969896,$07c7b7b80,$07b7c7c7c,$09b857176,$08095a1a3, $07a7b7a7a,$07275787a,$0a3a18d72,$0818b99a2,$074747578,$0626a6e71,$0a0855d5d,$08ea2a3a3, $06b6d6f72,$0515c6669,$09d987a50,$06b7d949b,$063656768,$05e56565d,$083808073,$07c7e7f83, $071777c7c,$072717372,$0807f7d78,$07f838381,$0807b7879,$0797b8082,$07c7c7c7b,$07c7c7c7c, $07c7c7c7c,$07a7b7b7b,$078787a7a,$0807f7b78,$081818080,$082828181,$07373777e,$071717172, $04044494c,$038393a3c,$0453c3838,$061615d54,$03b3e4a59,$03b3a3a3b,$03c3c3b3b,$03f3e3d3d, $047434141,$07366534c,$084827e79,$07f707483,$07b959d97,$06f6d6c6d,$072716f6f,$07b787673, $0807f7e7d,$087838281,$08596a099,$082828382,$093918e86,$0818b9294,$081828282,$0827d8080, $08b8f8e8a,$07f7e8a8d,$07e808080,$089827c7e,$09195908d,$07f7d7d87,$07c7d7f7f,$099887b7a, $086969fa0,$07e7e7d7c,$0797c7d7e,$0a19e8b7a,$07c8c9fa1,$07e7e7e7e,$071797b80,$09596907a, $07b7a808f,$07c7d7d7d,$082757a7b,$0969b9d97,$07c7b7c84,$0797b7b7b,$09f857076,$08399a3a4, $0797b7b7a,$071747778,$09d8f7468,$0999c9fa2,$074747587,$069706f71,$09e74555f,$094a2a3a3, $06a6c6d73,$0525d6568,$0928a6850,$069798a8f,$064656465,$067646363,$07a797871,$07a7b7c7d, $06770787a,$0726f6b65,$081807c76,$080838381,$07e7a777a,$0797d8282,$07c7c7c7b,$07c7c7c7c, $07c7c7c7d,$07a7b7b7c,$078787a7a,$0807e7a78,$081818181,$084838181,$073747980,$073727373, $033343537,$036363534,$0433a3737,$063625e53,$03c414e5d,$03b3b3a3a,$03c3c3c3b,$03e3e3d3c, $04442403f,$071625049,$085817c77,$08f7b7c85,$076909c9b,$06f6d6b6c,$07271706f,$07b787573, $0807f7e7d,$086838281,$0869aa097,$081828283,$09090918b,$0818c8c90,$081828280,$0827c7f80, $08b8f908c,$07e818b8c,$07f808080,$088807c7e,$09298938e,$07f7c808b,$07b7d7f7f,$09d87777a, $08799a2a3,$07d7d7b7d,$07b7b7d7d,$0a096817b,$07d909f9f,$07d7e7e7c,$06e787b7d,$094968e74, $07a7b8590,$07c7d7d7c,$07c747c7b,$0999f9e93,$07b7a7c89,$0787a7b7a,$09a7c6c75,$0889aa2a2, $0777a797c,$06e737576,$07f665d62,$0a3a3a29c,$071737d9b,$0686e6e6f,$0905d515d,$092a0a1a1, $0696b6c74,$0535d6366,$0857d6050,$066788181,$06e6d6a66,$07170716f,$0797a7774,$076777779, $05e656e74,$0716d645c,$081807c75,$081828282,$07d78777b,$0797e8382,$07c7c7c7b,$07d7c7c7c, $07c7c7c7d,$07a7b7b7c,$0787a7a7a,$0807d7978,$081818181,$084838281,$074767b81,$076747474, $030303132,$036353431,$03f393737,$064625c4f,$03c445360,$03b3b3a3a,$03c3c3c3b,$03f3e3d3d, $04341403f,$06e5d4d47,$085807a75,$09b8f8789,$06f84989e,$06f6d6b6b,$073727170,$07b787573, $0807f7e7c,$085828281,$08a9d9f94,$07e818183,$08e8d8b84,$0838a8a8e,$08181817f,$07f7d7f80, $08d8e8e89,$07d83898e,$080808080,$0867e7c80,$0979b968f,$07e7b818e,$07c7d7f7f,$09c81757b, $08c9ea2a2,$07d7c7a7c,$07b7b7d7c,$09f937d79,$07d929ea0,$07c7d7d7a,$070787b7c,$097998b70, $07a7c8a94,$07c7c7c7c,$076757c7b,$09ea3a191,$07a7a7f90,$077797a7a,$0886c6b75,$0959f9f96, $07679858e,$06e717374,$05e556069,$0a4a4a395,$06f7085a2,$0656a6c6d,$07b53525d,$08c969a97, $066696a74,$0575b6063,$07d776259,$06f767a7a,$075757370,$077757576,$076757677,$078767575, $05b647279,$0706b5f57,$0807f7a74,$082838281,$07c77777c,$079808482,$07c7c7b7a,$07c7c7c7c, $07b7b7c7c,$07a7b7b7b,$078797a7a,$0807d7978,$081818181,$084838282,$075777d82,$078757575, $02f2f2f30,$036353331,$03c383737,$063615a4a,$03d485862,$03b3a3a3b,$03c3c3c3b,$03f3e3d3d, $04341403f,$06c594c47,$087817a74,$09e9b938d,$06c778f9c,$06f6d6b6a,$073727170,$07a777573, $07f7e7d7c,$084828180,$08e9e9f90,$07e808182,$08e8d8a81,$084888c8e,$08080817e,$07c7d7f80, $095928c84,$07c848994,$08080807f,$0827a7c7f,$09e9f9e94,$07d7a8191,$07c7d7e7f,$08d78787b, $0909b9e9d,$07c7b7a7d,$07b7c7d7b,$09d8c7978,$07f929b9e,$07e7e7e7b,$0747a7b7d,$09c9a876f, $0797e8e99,$07c7c7c7b,$074777b7c,$0a1a4a38e,$079798296,$075787879,$06c5d6b73,$09fa09a81, $0747f9a9e,$0716f7273,$04d556571,$0a4a3a285,$06e708da1,$065696b6c,$06d50535e,$0878b8f8c, $062646576,$066666462,$077716867,$072757778,$075777572,$079767373,$0807c7677,$0877e8081, $05a657382,$06f675953,$07f7c7771,$08283817f,$07a76787e,$07a808280,$07c7c7b79,$07b7b7b7b, $07b7b7c7b,$07a7a7b7b,$079797a7a,$07f7c7978,$081818180,$084838282,$076797f84,$07c787776, $02f2f2f30,$036343331,$03b383737,$063615646,$03f4c5b63,$03b3b3a3c,$03d3c3c3b,$03f3e3e3d, $046444240,$06b594e49,$08c847c76,$09c9d9b94,$06b6e7f95,$06f6e6c6b,$072727271,$078767573, $07e7d7c7a,$084818080,$0929f9d8c,$07f808182,$08f8d897f,$0868a8e8e,$080807f7f,$07c7d7f80, $09d988e81,$07c868e9a,$07f80807e,$0827a7c7f,$0a0a0a299,$07c7b8399,$07c7d7d7e,$08677787b, $0919a9c98,$07c7b7b7f,$07b7c7b7b,$099867778,$08494999c,$07e7e7e7b,$0777a7b7d,$0a097826f, $07a8296a0,$07b7a7b7a,$06d76797a,$0a0a3a086,$0797d8a98,$074767778,$05b5e6b72,$0a3a0805b, $07490a3a4,$06e6f7172,$04a56646c,$0a1a19a6e,$06c708b9d,$063686a6a,$06953545c,$086848586, $06f6b6777,$073747271,$078737172,$072737376,$076757372,$07a7b7a77,$088867c77,$07f808384, $0535e6e7c,$06e65544e,$07f7c756f,$08382807f,$07875797f,$07b80817d,$07c7b7a78,$07b7b7b7b, $07b7b7b7b,$07a7b7b7b,$079797a7a,$07e7b7878,$081818180,$084838282,$0777a8084,$0807c7877, $02f2f3030,$036343230,$03a393737,$0625e5142,$043515e63,$03c3b3c3d,$03e3d3d3c,$042413f3e, $04f494643,$0796d6157,$097918981,$093999d9c,$0696a7084,$06f6d6c6a,$072727170,$076747373, $07d7c7a79,$08280807f,$097a09c89,$07e808183,$08e8c887f,$0888e8f8f,$080807f7e,$07c7e7f80, $0a19b8c7f,$07e85939e,$07f7f7f7e,$07f7a7c7e,$0a1a2a093,$07c7b869c,$07c7d7c7d,$07c71787a, $0939a9a92,$07c7b7a82,$07d7b7a7b,$09982777a,$08b999c9f,$07d7c7a7c,$079797b7c,$0a3977e6f, $07b869ca4,$07a7a7b79,$06a757879,$0a29a8e73,$08393989e,$074757777,$0646a7172,$0a49e6a5a, $07799a4a4,$06d6e6f71,$04d58656a,$098998b5d,$072768e96,$0656d6e70,$0685e5c5d,$07e7e807d, $078737076,$075777577,$072737273,$07b787574,$082807c7f,$0787d8180,$0817d7c7c,$06e737777, $050566170,$06c62504b,$07e7b746e,$083828180,$077767b81,$07c81807c,$07b7b7a79,$07b7b7b7b, $07b7b7a7a,$07a7a7a7a,$07879797a,$07e7a7878,$081808080,$083828281,$0777b8084,$0827e7a77, $030303031,$036343230,$03a393737,$0615a4c3e,$048586264,$03d3d3d3f,$042413f3e,$049474543, $0665d544d,$0857d756e,$09794928d,$07b899598,$067676970,$06f6c6b69,$072727170,$074727272, $07b7a7876,$081807f7d,$09ba09a87,$07f808187,$0918e877d,$08c939695,$080807e80,$07c7e7f7f, $0a29c8b7b,$07d8697a1,$07e7f7f7d,$07a7b7b7d,$09f9f9985,$07b7c8b9a,$07b7c7c7c,$077727a7a, $09498988d,$07d7c7b87,$07a7b7b7c,$0977c767b,$08f9ca0a0,$07b7b7a7d,$078787a7b,$0a394766f, $07c8a9da4,$078797a78,$066737678,$09c816a5c,$095a0a1a1,$073747578,$0646e7571,$0a4925859, $07d9ea3a4,$06c6d6e6e,$04d59656a,$08b8e7e55,$070728e8e,$06c6c6a6e,$06e6b6d6d,$079797976, $074737274,$070747372,$079777372,$0837f7e7a,$083857e8b,$07577767e,$06d6a6e72,$05c616567, $05056595d,$06a5f4c4a,$07d78726d,$08382817f,$077777c82,$07e83817c,$07b7a797a,$07a7a7a7b, $07b7b7a7a,$07a7a7a7a,$07879797a,$07d7a7778,$080808080,$082828181,$0787c8183,$082807c78, $030313131,$035343231,$039383837,$06057483d,$04e5d6464,$043414143,$0504b4744,$05f5c5855, $0726e6863,$0807c7875,$088878785,$06d7e888a,$066656769,$06c6b6a68,$07070706f,$073717070, $07a797776,$0807f7d7c,$09da09784,$07f81828a,$0998d827c,$0919c9f9e,$080807e83,$07c7e7f7f, $0a19a8376,$07d8b9da2,$07e7f8080,$0757b7b7e,$0a1a0947e,$07a7e929d,$07b7c7b7b,$076717a7c, $0959a9a8d,$07c7a7d8d,$0797b7c7c,$09278757a,$0969ea19f,$07a7b7a82,$07b797a7c,$096836971, $08b939e9f,$077777983,$068727477,$08b56565d,$0a2a4a4a3,$072737383,$0646b6e6f,$09e7b4f5a, $07c969d9f,$06d6c6c6c,$05865666c,$081847253,$06e738482,$078767674,$074767778,$075747877, $075767276,$078787873,$088837e7b,$085828887,$0787b7481,$064626770,$0615e5e61,$05b595d5e, $04d56595d,$06a5d4947,$07c77706d,$08381817f,$076777e83,$07f84817b,$07a797879,$07a7a7a7a, $07b7a7a7a,$07b7b7b7b,$07979797a,$07c797778,$08081807f,$082828181,$07a7e8283,$082807d79, $030313133,$036343231,$03a393837,$05e55473d,$055616563,$054504c4c,$065615c58,$06b6a6968, $06e6d6c6b,$06d6f6f6f,$079757370,$06c7f827e,$065656567,$06c6a6867,$07070706f,$073717070, $079787775,$0807e7d7b,$09f9f9283,$07f81818d,$09d8e7f7d,$0919ea2a2,$0807f7d85,$07c7d7f80, $09e917c77,$07e8c989c,$07f7f7f80,$0757a7b7d,$09f9f8c76,$07a83959c,$07b7b7b7a,$072757a7a, $0999d9d8c,$07c7a8093,$0787b7c7c,$08e757679,$09ca2a3a1,$0797a7a87,$07877797b,$0876d606f, $0a09fa29a,$076767f9c,$072727375,$0764e5f6a,$0a4a4a4a2,$06f70708e,$0636a6d6e,$09067505c, $0788b9295,$07a737271,$0656b6a76,$07d7e7363,$07678807f,$075787c7b,$07c777573,$075737579, $07c85837b,$08681837f,$07d7e7e80,$06f777f7b,$066616067,$05a5b5a62,$057565858,$058575b5b, $04e555855,$068594848,$07c766f6c,$08282807e,$076787e83,$08084817b,$07978787a,$079797979, $07b7b7a79,$07b7c7c7c,$07979797a,$07b787879,$08180807e,$083818181,$07a7f8383,$081807d79, $031313234,$037353332,$03e3c3b39,$05c544841,$060656661,$06663605e,$06a6a6a68,$061646769, $057575a5d,$054545656,$0756f6a60,$06e80807a,$064646566,$06b696865,$071706f6d,$074717171, $079797776,$07f7d7c7b,$09f9e8c81,$080818292,$09c8b7d7e,$0909fa3a2,$0807e7e84,$07c7d7f80, $099908179,$07e91999b,$07e7e7c7a,$076797b7c,$09c998572,$07b85969a,$07b7b7b7a,$06f777a7a, $09d9f9b82,$07b7c8696,$0797c7d7c,$0886d7578,$09ea4a4a2,$078787a8f,$074767677,$061565c6f, $0a3a3a185,$0757591a3,$074737374,$05e4c5d6b,$0a2a3a497,$06c6d6e90,$064696c6c,$08460545b, $07c848488,$078716c6c,$074747376,$07c797573,$077797b7d,$072737476,$0837f756f,$082828588, $07f837f7f,$0807e7a7f,$0646c6e75,$0615e5c5e,$05d575456,$0545c5b5b,$059565a55,$054585958, $04d54514f,$063534849,$07b746e6b,$08281807e,$077797f83,$081837f79,$07978777a,$079797979, $07d7c7a79,$07d7e7f7f,$0797a7b7b,$07b787879,$08281807e,$083828182,$07c818483,$0817f7c79, $033323436,$03b383534,$04b46423e,$05c58534f,$068696661,$067676868,$05c606366,$04a4d5257, $044444547,$04a474544,$0716b6558,$0707f7d77,$064636464,$06b696865,$071706f6d,$076727171, $07a7a7979,$07f7d7c7b,$09f9b8781,$080818396,$0917e7b7d,$09ba0a3a0,$07f7f7e8a,$07b7d7e7f, $096827779,$081949c9e,$07c7d7c7a,$077797b7c,$09f988072,$07b8a999d,$07a7a7b7b,$06d797a7a, $0a09f9679,$07b7c8a9a,$078797a7c,$0746c7577,$09fa4a298,$0767f8b97,$072757676,$05c61646f, $0a4a49a67,$073799da4,$06d707273,$0514e5e69,$09a9c9c86,$06b6c6e8c,$060666a6c,$07e5f5c5b, $07b817e80,$07c7a736f,$07b7b7a7b,$072747777,$079787373,$077787374,$0868b8280,$087868b81, $06d757b7c,$066706569,$05d5a5d62,$0565a5a59,$058575853,$05255595c,$05f585853,$053545358, $04e525153,$05f4d4749,$079726d6a,$08180807d,$0757a8183,$081827d77,$07877767b,$079787878, $086807c7b,$085898d8c,$07b7d7f81,$07a787879,$08282817e,$083828282,$07d818483,$0807e7b79, $039373738,$049443f3c,$05c59534f,$05d5e605f,$0696a6560,$054575c64,$046494d50,$041414244, $041414141,$047444342,$06f696153,$0737d7a75,$064636364,$06b6a6967,$072706f6d,$087787372, $07a7b808a,$07d7c7b7a,$09f978480,$07e7f8499,$0897b7a7e,$09a9ea09b,$07e7d7f8f,$07c7e7e7e, $09077757a,$084949b9a,$07c7d7b7a,$0797a7b7c,$0a1987c74,$07d909ca0,$07a7b7c7b,$0717a797a, $0a3a29273,$0797c919e,$077787879,$0606b7376,$0a09f8f79,$074919d9f,$072747574,$064697373, $0a4a48c5f,$07480a1a4,$06d6f7576,$04c505e68,$08d909076,$06b686f87,$06a6c6e6d,$077696668, $0787f7f7d,$07c7d7976,$075747a7a,$0746f7479,$0817e807c,$084888282,$07c7e8787,$06a6e777a, $0605f6766,$0585a635d,$056595e5c,$05b595657,$052555656,$052535757,$056545453,$054515259, $051555152,$05949464b,$078706c68,$081807f7d,$0757a8182,$081807c76,$07776767c,$079777777, $0988d817c,$0959b9e9d,$07e83888e,$07977797b,$08281807e,$082828282,$07e828383,$0807c7a79, $04a464444,$05b56534f,$06262605e,$05d5f6162,$0696b6660,$043464e5d,$03e3e3f41,$03e3e3e3e, $0403f3e3e,$046434140,$06e675e4f,$0777e7973,$066636365,$06d70716c,$073716f6d,$096817573, $07a7b8899,$07c7a7a79,$09e91817f,$07d7f859b,$0887e7c7c,$09c9f9f96,$07d7d8194,$07c7e7e7d, $08674767b,$08a949b97,$07d7d7c7c,$07a7a7c7c,$0a0927573,$081959ca0,$07a7a7a7b,$072787879, $0a4a08b6d,$0788197a0,$076767777,$055667174,$0a1895b54,$080a1a3a2,$072737473,$05f646f72, $0a3a0775b,$0868b9ea2,$06b7a8789,$04b526067,$08183886d,$0756b7481,$07b7b7979,$07a767679, $0777a7b7d,$078757476,$07a737b75,$07b7e837d,$082828382,$07a7b7c7b,$069727172,$05f5e5f68, $0535a605e,$059585455,$0525a5f5c,$05b5a5d55,$052545653,$04e4f5554,$05a514f51,$058545055, $052555254,$05547484f,$0766f6c67,$081807e7c,$0767c8283,$0827f7974,$07675777e,$07d787776, $0a19c8e84,$09ea1a2a2,$0848b9198,$078787a7e,$082817f7d,$082828182,$07f838382,$07e7a7879, $059585757,$05b5b5b5a,$05658595b,$05c5c5654,$06a6c6760,$03e424d5e,$03c3c3d3d,$03d3d3c3c, $0403f3e3e,$045434141,$06d675d4c,$07b7f7873,$06a646468,$072858c7c,$072706e6e,$098827573, $07a7c8f9c,$07b797978,$09c8b7f7d,$07d7f889c,$0827b7c7b,$09c9f9f91,$07e7d8396,$07d7d7d7d, $08573767b,$08a939a9b,$07c7d7b7e,$07a797b7c,$09f8c7173,$0879ca0a1,$0787a7a7c,$071767778, $0a0937664,$08e959ca2,$075757679,$0646c7173,$0a1735c63,$08ca4a4a4,$070727272,$058656d6f, $09a936250,$08990969a,$06f838788,$056575f65,$07c7f8367,$07c75777b,$07e7f7e7e,$07375787f, $075787471,$07d817a79,$081878182,$080848489,$06f74797a,$05f616967,$05f5c5b5b,$05c57585c, $05c59575d,$055555459,$0565a5657,$0595a5854,$053585952,$0535a5653,$055575050,$059565851, $054524f57,$052454750,$0756e6c65,$0817f7e7b,$0767d8383,$0837f7773,$074737880,$0847b7674, $0a3a0988c,$0a1a3a4a4,$0888f969c,$077787c81,$082807f7b,$082818182,$07f838382,$07d7a787a, $054585c5e,$0494b4f52,$043444648,$05c554843,$06e6d6660,$03e435063,$03b3b3b3c,$03d3c3c3b, $0403f3e3e,$046434140,$06d675c4b,$084897c73,$06c66646d,$07b949789,$071706e6e,$0917b7472, $0787c919b,$079787877,$097847e7b,$07e7f8b9d,$07b777b7d,$0989b9c89,$07d7d8795,$07c7d7d7d, $08174767a,$091969b99,$07c7b7c82,$0797a7c7c,$09f837076,$090a0a3a3,$07778797c,$070747777, $08d715b62,$0a0a1a09f,$073747388,$06d757173,$097646062,$093a3a3a4,$07b797773,$04e6d7d7f, $08d835342,$0808d8c8c,$07580817f,$06a6c6f71,$07b7d796f,$07c787b7d,$073757379,$07678797b, $0887f827d,$08b868185,$077858789,$064657477,$067656a63,$05e615c5a,$051575b5c,$055535454, $05a55575b,$055596057,$051525854,$05a565558,$05d59535b,$05458545b,$04f505050,$058515350, $052545757,$04e44474d,$0726c6b61,$081807e7a,$0767f8282,$0827d7672,$073737981,$0867e7674, $0a3a0998d,$0a0a2a3a3,$08990979c,$077787e83,$081807e7a,$082818181,$080828282,$07c79777b, $041474e51,$0393a3b3d,$03c3b3b3a,$05b50423d,$0706d665f,$03e455568,$03b3c3c3c,$03d3c3c3c, $0403f3e3e,$049444140,$06c665b4e,$08a8f7d72,$06f676673,$08298988b,$071706e6f,$084757271, $0777d9498,$077767676,$08f7f7c7a,$07d7e8e9d,$077777b7c,$09a9c9783,$07d7e8b97,$07c7c7d7d, $07c73787a,$0999e9c96,$07c7b7d88,$078797a7b,$09b787177,$096a0a3a1,$076777a82,$070737676, $069555761,$0a4a4a399,$072737697,$0686e7172,$0885a5c5f,$0939d9e9f,$0898b8b86,$04c697e86, $084774f3f,$077888582,$07b7d7e79,$0797a797a,$07a7a787a,$07a747576,$07d7a787a,$08a7c7e7f, $0808a9286,$0767f7a7e,$0676f6e6d,$058576463,$05d5f595d,$056535951,$04e57574f,$051545353, $0584e5558,$05355555c,$054545b53,$05a5a5253,$056575355,$059565156,$04f515359,$0504e4e4e, $054545552,$04b47494c,$0706b695e,$081807d78,$078808382,$0817c7471,$072737a81,$0847f7873, $0a09d958a,$09d9fa0a1,$0878d9398,$076797e82,$0807f7d78,$082818181,$080828282,$07c79787c, $0373a3d3f,$035353435,$03a3a3936,$0594b3f3b,$0726d645e,$03f485c6c,$03c3c3c3c,$03d3d3d3d, $0403f3f3e,$053474241,$06a665c58,$08d8e7b71,$06c676678,$08697917d,$0706f6d6f,$07b73706f, $077819794,$076757576,$0897d7b78,$07e7f929c,$077787c7d,$09b9e9580,$07c809097,$07c7c7d7d, $07672797a,$09ea19f92,$07b7b7d8f,$07678797a,$086666e75,$09c9fa098,$075758c99,$071727475, $06163656c,$0a4a4a38d,$071717ca0,$06b6e7072,$0744d515d,$091939495,$0797c8185,$0606b7678, $080746461,$076797c7e,$07c7f7c79,$078797c7b,$07e7b7073,$07e7c7777,$07e818782,$0877b7b83, $0656e8085,$05d60606b,$0585a5867,$054535e59,$057515158,$05156534f,$058555552,$052535554, $05a595655,$054545254,$052535455,$053545555,$05d535252,$058555458,$05153545f,$04f4f5251, $052525556,$04b484c52,$06e6a685c,$081807d77,$07a828482,$0807a7171,$070737b81,$0827e7871, $098958f87,$098999b9a,$084898e93,$0757a7e81,$0807e7c77,$081818181,$081828281,$07b78787d, $035373839,$034343434,$03a393836,$058473e3b,$0726c625e,$0414e636f,$03c3c3c3d,$03c3c3c3c, $03f3f3e3e,$0604a4341,$06b68646a,$08f8c7970,$06866687c,$08b94816e,$06d6d6c72,$076706e6e, $07786998f,$076757576,$0857d7a77,$07e84999b,$0757a7c7d,$09d9e927f,$07c82939a,$07b7b7c7d, $071757a7a,$09ea2a08d,$079798296,$074777979,$05e5b6b72,$0a1a09170,$0747999a1,$073717273, $05d606673,$0a2a3a17b,$07b7785a0,$0777f817d,$06646425c,$088848788,$06c666274,$073767472, $079737071,$07678797a,$078797676,$07d7c7274,$0898c797d,$0878f8884,$087858583,$06e686d7d, $066696071,$05357555f,$0585b5957,$05b565d55,$05051575d,$05d56534f,$054525555,$058575852, $052575758,$051565754,$055525556,$059585759,$0564c4f53,$05451565d,$054555352,$057545352, $0524f5456,$04d494c54,$06c696559,$081807d76,$07b828382,$07e776f71,$06f737c81,$0807b756f, $08e8c8984,$092939391,$08185898e,$0767a7e7f,$0807e7a76,$081818181,$081838281,$07a77787d, $035363738,$033333334,$03a393735,$057443d3a,$0716a615f,$044556871,$03c3c3b3d,$03d3c3c3c, $0403f3e3e,$0644c4341,$06b686c71,$0928b776f,$068666b83,$091947b6b,$06d6c6d75,$074706f6e, $0788c9987,$075747476,$0837c7976,$07d8d9e9a,$073797b7c,$0a09f8e7a,$07c86999d,$07a7b7c7c, $06e757778,$0a0a0997e,$07984909a,$074767777,$05c5d6b72,$0a3a07a59,$07488a2a3,$06f727274, $05a5d636a,$09c9d9466,$0898b8e99,$0737f8487,$06450485b,$0807f8186,$07a766e75,$07c7b797b, $074777779,$071707475,$0877e7774,$08a8d847c,$07d8b9085,$074808680,$074706e70,$0615d6066, $05b545e5a,$0535e5959,$056565557,$051505153,$0505a5b5e,$05352524f,$04c545b52,$05859584c, $053565452,$0565d5c57,$058525652,$055575359,$052565454,$051505458,$051565754,$05555554f, $054504f51,$04c494c54,$06b696357,$080807d74,$07c828281,$07c746e72,$06e737c80,$07f79726d, $085838281,$08d8e8d8a,$07e81858a,$0777c7e7d,$0807d7975,$081818181,$082838281,$07a77797e, $035363737,$034333334,$039383635,$054433c3a,$07068605f,$0475a6b72,$03c3b3c3e,$03d3d3c3c, $0403f3e3e,$05e494341,$06c676d70,$094897770,$068667089,$094947a6b,$06c6c6c79,$072706f6d, $07c93967e,$075757677,$0817a7775,$07e919f98,$073797a7c,$0a29d8772,$07d909fa1,$0797a7b7c, $067727577,$09f968166,$07f979c9d,$074757677,$0656e7371,$0a39b6c62,$07293a3a3,$074727173, $04c556a75,$090918656,$083848d8d,$071797d80,$06966676a,$07d7d7c79,$07b7b7478,$074787d7e, $0766f7178,$07e7f7b75,$0888b8781,$083888b90,$06f707e7e,$0686c6768,$05c5b606e,$05c5b5758, $0615a5a5e,$04e58544f,$062585454,$0585a5659,$04f555a5b,$050524b4e,$04f575354,$055555755, $054575952,$0605a545c,$05b575957,$054585b5a,$055594e55,$052505559,$051575553,$053515052, $051515152,$049494e51,$06a696153,$0807f7b71,$07d818180,$07a726d73,$06d757d7f,$07d776f6c, $07f7d7f7f,$0898a8884,$07c7d8085,$0797e807d,$07f7d7875,$081818180,$082838181,$079767a7f, $035363737,$034333233,$039373635,$052413b3a,$06f666160,$04c616f73,$03c3c3c3f,$03d3d3c3c, $041403f3e,$054474342,$06d676f6d,$094867670,$06766748c,$09691766a,$06c6c6d7f,$071706f6d, $07f959178,$074747577,$07d797674,$07f959f94,$075797a7c,$0a1997b6d,$08196a0a2,$07878797a, $064707376,$09a765a5a,$08da0a0a0,$072737475,$0616e7571,$09f8f6160,$07b97a1a1,$08687857f, $03e4c6f83,$082867f4f,$07d7b8681,$0777a7d7e,$076747577,$0787e7c79,$074777774,$0797b7b78, $08279767e,$08a8b8485,$086848788,$0666d7c83,$062636362,$054675857,$0575e5b5a,$0525b5557, $0635e5b55,$04f545454,$05b58534f,$0575e5554,$057585a5d,$054524e4b,$055545357,$0514f4f51, $057575751,$056545358,$054525653,$057545a57,$050555055,$052504e51,$050515857,$054514d53, $053575451,$046484f54,$069685e4d,$07e7d786f,$07e81807f,$0776f6d74,$06e777f7e,$07c756d6b, $07c7c7e7e,$0888a8781,$07c797c83,$07a7f807e,$07f7c7775,$081818180,$082828181,$078767b80, $035373737,$034333333,$039373535,$04e3f3b3a,$06e65625f,$053677274,$03c3c3d42,$03d3d3c3c, $045423f3e,$051474446,$06e6b756c,$094847771,$06666798d,$0968a7068,$06d6c6d83,$071706f6e, $07c8f8773,$073737577,$07a777573,$0839b9f8f,$077787a7b,$09b8c6d6b,$0929aa0a1,$076787883, $067717375,$08f646362,$098a2a2a1,$071727476,$05f686e70,$09b7b5659,$08c93999b,$07e84878b, $054576878,$07d83745a,$075747d7e,$07b7a7c7b,$0787a7b7a,$074767875,$07d797975,$083837e7b, $080808089,$082767a7e,$06567716f,$05a596263,$05a535654,$04e4b5458,$059595450,$0525b585c, $05c574f50,$0565a5354,$04f535852,$053595250,$054595753,$053525153,$053575757,$054555251, $05354545e,$053535254,$053585552,$05b595853,$051555259,$05558584f,$052515555,$058555853, $055595657,$0484a5457,$068685b4b,$07d7c756c,$07f817f7e,$0746c6d76,$06e78807d,$07a736c6b, $07e7d7e7e,$08c8d8983,$07d7c7f87,$07a80807f,$07f7b7675,$082818180,$082828281,$077777c81, $037373737,$034343434,$039373534,$04a3e3b3a,$06e64645e,$0596c7676,$03c3c3e46,$03d3d3d3c, $04a45403e,$04e47464a,$072717968,$095867873,$065687c8e,$093816b67,$06c6c6c83,$06f6f6e6d, $0757a7570,$073737475,$076747272,$0889d9d87,$07677797b,$0846f636c,$09e9fa09a,$075777891, $076737374,$07d60636a,$09da2a29f,$07573737e,$05e767d79,$098734749,$0858c8e92,$07c7e7f7d, $06a6e7275,$07d7b726a,$078777a7d,$07a777a79,$072787978,$07f797c77,$089868c87,$07e868582, $0797a7d7a,$05e606e71,$05d655562,$050595f5a,$05a545656,$052585457,$056615f58,$054575459, $05a575050,$05e5b5256,$053525356,$05351504f,$05352574e,$053545450,$05158514e,$059595550, $051595e58,$0595b5455,$053545152,$053515855,$052565355,$0585d5a54,$057555152,$052545859, $05a515355,$0474c5459,$069675748,$07d7a7268,$07f807f7e,$0726b6d78,$06f7a7f7b,$079716a6b, $0807e7e7d,$08e8e8a84,$08080838a,$07c818181,$07e797576,$081818180,$083838281,$076787e83, $037383737,$034343436,$039373635,$0473e3b3a,$06d64655c,$060727a77,$03c3d3f4a,$03d3d3d3c, $04946403e,$04c474748,$0797e7a62,$0968e7f79,$0676b808d,$089766a68,$06c6c6c7c,$06e6d6d6c, $073716e6d,$071727373,$075727070,$08b9e997e,$074747779,$0615c6670,$0a1a19f85,$07475819d, $071727373,$06d5e6067,$09b9e9f97,$089888388,$06077888b,$091695050,$07984848b,$07a7c7870, $076777777,$078767576,$07676777a,$07d7a7672,$07f7d807d,$0868c8680,$07e808a85,$0646d737c, $05f5c6667,$05b5a5a59,$05b56595b,$059595f58,$05c5f5b5b,$053575757,$0505a5d5e,$051545553, $0575b594e,$057534d55,$04d554e58,$0524a4c4e,$04d4e4b52,$04b515c57,$05651544c,$05259514a, $055575551,$054585a54,$056575452,$05c595355,$04f565954,$057585553,$051535957,$051545352, $05a555556,$0474e5358,$069645246,$07c797067,$081807f7e,$0716a6f7b,$0727c7f7a,$0776f696a, $0807f7e7c,$08a898682,$082838487,$07d818282,$07d787476,$08181807f,$084828281,$075797f84, $037373737,$036353436,$039373736,$0453e3b3a,$06b646559,$066777d78,$03d3e4250,$03d3d3d3d, $04845403e,$04a474647,$08684765a,$092948f88,$069708287,$0716b6969,$06b6a6a6e,$06c6b6c6c, $06f6d6b6c,$06f707171,$0726f6f6f,$0949f9679,$072737679,$05363666f,$0a2a19b72,$0737389a0, $06d6f7172,$05f565c66,$09094948a,$08088868a,$0686b6f76,$08b6d6464,$0777c808a,$07b7d7a74, $075777678,$074737575,$07b7c7577,$08187797a,$0868c8e82,$0777e8383,$06a69766c,$05b616367, $051555c5c,$054555552,$0585e5454,$0545d564f,$0535b5857,$053525157,$04f575655,$058575954, $0524d4f57,$0514d5055,$055535753,$054575952,$051504d51,$053535a57,$05850544f,$0585a575c, $052555851,$0575a5550,$057545251,$054535053,$052515451,$057505055,$04e505654,$053545451, $055595753,$048505756,$069604c44,$07c776d67,$082817f7e,$06e6a737f,$0747e7f78,$0756c696b, $080807e7b,$084838281,$083838484,$07e828282,$07b777378,$08181807f,$083838282,$0767a8184, $038383737,$036363637,$03a383737,$0443e3c3b,$067626254,$06a797e76,$03d3f4455,$03d3d3d3d, $044423f3e,$048464544,$0847c6951,$0848c8e8a,$06d798281,$06a6a6a6b,$06a6a6a69,$06a6a6a6b, $06d6c6a6b,$06d6e6f6e,$06f6d6c6c,$09a9f9576,$07072747e,$042516a76,$0a09f925d,$073738e9e, $07a7c7b77,$06648526b,$083858985,$0727c7382,$071706a65,$08774716f,$0767a7d85,$07d7a7775, $07675777b,$07f7d7d77,$07c7f8684,$071818281,$0757b837b,$0666b5f71,$0605f5b5e,$050525156, $058525757,$057555557,$052505450,$0544d4e54,$04c545659,$04c4d5852,$052575153,$057535e55, $04e4b4b5b,$0575d5350,$054575557,$05559585f,$05b58514b,$05c565352,$051515654,$0544d5056, $056524f50,$0605b5658,$05755575f,$050505252,$0595c5956,$057545354,$051515353,$0504f5253, $04f50524e,$0494f5352,$0685b4844,$07b756b67,$082817f7e,$06d6b7580,$0777f7f77,$0726a696c, $080807e7a,$082818181,$082828282,$080828282,$07a75737a,$08181807e,$083838282,$0767b8284, $0393c3d3e,$036373838,$03a393837,$0423e3d3c,$0615b5a4c,$06e7a7c72,$03e3f475a,$03d3d3d3d, $042413f3e,$047444342,$06e64554c,$07d7c7f7a,$07c82817f,$06b6b6d72,$06a6a696a,$06869696a, $06b6a6868,$06c6d6d6c,$06d6a6b6b,$09d9f9173,$06e717284,$04150646c,$09b98814d,$083778d98, $079858988,$06864656a,$07e7d8277,$07c787380,$077777778,$078757577,$075797878,$07d7b7470, $07b7d7b7d,$085878280,$0727a7e84,$0656c6a71,$06160635e,$059585b56,$058565457,$053535657, $059625754,$051575855,$05f5a5953,$052525258,$056626358,$04d4a4d50,$056565558,$051535654, $054525353,$05a5a565c,$057595a4e,$05054574e,$05c554f4d,$04f525d57,$050535859,$050484951, $0554f4e53,$0584f5058,$054525259,$058575b52,$06f6d5356,$056535457,$053544e55,$054545351, $0524e5051,$046505551,$067564543,$07a746968,$08281807d,$06c6d7881,$078807d75,$0716a696e, $081807e7a,$082818181,$082838282,$082838282,$07974747b,$082807f7d,$082828282,$0767d8283, $03f424547,$03838393b,$03b3a3938,$03f3e3d3c,$0574c4944,$0727c796b,$03d404a5e,$03d3d3d3d, $0403f3f3e,$046444241,$05c524e49,$07a76726d,$083837f7c,$06d6f777f,$06a6a696a,$06668696a, $069686665,$06a6b6b6b,$06b696869,$09e9e886e,$06d6f7089,$04156656b,$091907248,$0867d878d, $069737b80,$066696763,$07b7e7f75,$079787679,$077767678,$077757273,$07d7d7778,$07f847e7e, $081838181,$0787c7d7c,$06063696f,$0615d6564,$0595e574f,$053515358,$05a5a5e5c,$057504e5c, $04c57564f,$04d525a58,$057545253,$054515d5a,$05951595a,$04e51555d,$059525359,$056595555, $05952555a,$04f515c66,$04f515450,$0525a574f,$05753594e,$0505a5954,$04e565654,$056514f52, $053525054,$05655514d,$04f52515a,$0525a6e68,$07a735553,$04e535658,$054505451,$055555655, $054515253,$0494f5150,$065524645,$07a716767,$08281807e,$06b6e7a82,$07b807c73,$06f696a70, $081817f79,$081818182,$082828181,$083838282,$07773757d,$08281807d,$082828282,$0787e8283, $046484848,$0393b3e42,$03c3b3a39,$03f3e3e3d,$051464341,$0747b7565,$03e414d62,$03d3d3d3d, $03f3f3f3e,$046444140,$0564f4d49,$078747169,$0827f7d7b,$0737d8382,$06b6a6b6d,$065666769, $068666565,$0696a6a69,$069676768,$09e9c7f6c,$06b6e708d,$0455a656a,$08b8d6a46,$07a7d8485, $070717579,$06f6f7070,$077797a76,$076757476,$075727373,$07b817d77,$0828b817b,$077878a87, $06d797875,$062656565,$057595f65,$056535453,$054505955,$052565850,$04f555650,$056655e52, $05c555251,$050546054,$056505754,$055545856,$05759545b,$050555859,$04f4f5556,$058575150, $05a545558,$0575c5e59,$054595356,$05b544f50,$052534e53,$050575556,$055574c49,$052545b64, $050595952,$070575451,$057535362,$05a6f7c6b,$0786a5554,$052535660,$05456554e,$054505450, $04e535658,$04e505350,$0624e4547,$07a706667,$08281807e,$06a707d83,$07d7f7a70,$06e696a73, $081817f78,$080808181,$083828281,$082828282,$07672757e,$08181807c,$082828181,$0787f8383, $049494948,$03d414447,$03d3c3c3c,$0403f3e3d,$04d454241,$074776f5f,$03e425065,$03e3e3e3d, $03f3f3f3e,$047454241,$0524f4c49,$076726d61,$0817e7c78,$081858484,$06b6d6f78,$065646569, $066656465,$069686968,$069676768,$09e99786b,$06a6c7191,$0505e646a,$089876a54,$075797f82, $0767a7e7a,$075757575,$072727574,$07c7c7674,$07d7c7d7a,$08186827c,$075827f80,$0636e7576, $05e645f62,$054565e57,$05259595b,$056545452,$056575558,$04e525355,$05355595e,$0535b6155, $04d52534f,$0564a5150,$05d51525a,$052535054,$055515352,$053525657,$0594d4f5e,$05b52525e, $05c575353,$05c605b52,$0575a5450,$05c4b4d57,$05d484d5b,$0525a5b60,$0555a4f4c,$05e615f65, $050555a5e,$07b595e5c,$054585a76,$06c7c7e64,$07b625554,$056595368,$052535655,$0534f5051, $04f4e5154,$04c525451,$05e4b4247,$0786d6668,$082817f7d,$06a737f83,$07e7f786e,$06c686a75, $081807d77,$080818181,$083828281,$083838383,$07572777f,$081817f7b,$082828181,$0787f8283, $04a494846,$04346484a,$03e3d3e41,$0403f3f3f,$049444140,$073716859,$03f445367,$03e3e3e3e, $0403f3f3e,$048454341,$0514f4d4a,$0736e6555,$0827f7d79,$086858484,$06c707b85,$065666769, $065646464,$067666766,$069676767,$09e94736b,$0696c7294,$064696a68,$085847068,$07d7e8182, $0797b7c7c,$077747578,$075797776,$08687837b,$07f7d777b,$0767f827c,$060687170,$05d5e5d60, $05c545257,$056565759,$04a4d5352,$056635653,$053575951,$051555355,$056535b50,$0595f5850, $05b555a57,$059515452,$052505050,$0505b5857,$05e505254,$054545754,$05752504e,$05f555156, $057585b4f,$053545858,$057555451,$04c4b4d5e,$0584e5153,$051554d57,$05d525757,$07d7f7d71, $05765757a,$07d615454,$052576b7b,$07b7a795a,$0795d586d,$05357566f,$052515658,$052565450, $053545052,$04c4f5155,$059484549,$0756a6667,$082807f7c,$06b758183,$0817f766c,$06b686c78, $081807c74,$080818181,$083828181,$083838383,$074727980,$081817f7a,$081828282,$0797f8282, $04845413f,$047484949,$03f404345,$03f3f3f3f,$047423f3f,$0726e6455,$040455569,$03f3f3f3f, $0413f3f3f,$048454442,$0514f4d4a,$071645853,$0817f7b78,$085858583,$06c7a8586,$065666868, $064646464,$067656665,$067666767,$09e8c6e6a,$0656a7597,$061606366,$0827b7165,$0797c8080, $07c7a7878,$07e7b7c79,$07c7b807d,$0797f857e,$06b6e737d,$06060646c,$05d595f63,$05d5b565b, $05b5d585f,$058555755,$05f545153,$0555a4d57,$05a5f584d,$051555453,$058585951,$055555054, $05659555d,$0554e5752,$050515850,$055544e51,$056505154,$04f4c4d50,$0545b5b53,$050514b54, $0545e5055,$05a565a58,$053584f52,$0504a5358,$0524e5358,$050585f59,$074575a52,$0646a7578, $0637c7960,$079665352,$056697972,$069747754,$0765b6d7c,$051575c76,$054585756,$056565351, $05b585456,$050505353,$05346474c,$072676663,$081807e7b,$06c778183,$0827e746a,$069696f7b, $0817f7b72,$082828282,$083828282,$083838383,$072737b81,$081807e78,$081818181,$0797f8181, $0433f3c3b,$048494947,$042444647,$03d3d3e3f,$04a44403e,$0706c6154,$041475868,$03f3f3f3f, $0413f3f40,$048464442,$0524f4d4b,$063595653,$0807e7a70,$085858683,$06f848786,$065666767, $064646465,$066666666,$067666667,$09c846c68,$057637a99,$057524e50,$06d65605b,$07a777672, $0827f817a,$07e828483,$077787d80,$06d6e7278,$062606469,$0555e5e5f,$0555b5b64,$05b625855, $05752575b,$05152545e,$060555755,$05c544b53,$0515a545d,$04f595752,$057575851,$055545658, $048554d55,$05552544f,$052564e52,$0514d5159,$053575355,$051515257,$059665753,$04e504a4d, $056524953,$0505a6355,$05f5c5855,$04f525658,$051585656,$05c7b7158,$070545652,$055505373, $06a7b6150,$079695d56,$05b73755e,$05b747056,$067647a6b,$051535d78,$050535957,$056534f4e, $055545253,$050535252,$04e43454b,$07166635e,$0817f7d7a,$06e7a8282,$0837d7269,$0696a717e, $0817f7a71,$082828282,$083828282,$083838383,$071747c81,$0807f7c76,$081818180,$07a808181, $03d3b3a3a,$048484642,$045464647,$03e3d3e42,$0534d4541,$06d6a6056,$041495a68,$040404141, $041404041,$048464442,$0524f4d4b,$05a585554,$07e7a6d5f,$084838381,$075868584,$067676767, $064656466,$065656565,$065656565,$0997a6b66,$04e5d7f9b,$04a474245,$0655a534d,$0857e766e, $08480817d,$0707d7d80,$0636c6d72,$059576067,$05b595557,$055545861,$055565259,$058615b50, $054545357,$052545b55,$058545653,$05b585552,$0534f555d,$05b545e59,$04f52525c,$053545659, $04f595554,$04c5b554f,$051545a4d,$054505a55,$060544d54,$0524e5557,$0535b5b56,$05357564e, $0585a5358,$05a555052,$057565553,$07e745753,$054595f7d,$076837262,$062594f5a,$0575a5875, $0687b5f51,$0766d5c58,$0667b624f,$05e796a53,$073776e51,$055566579,$053575658,$059575050, $052535456,$052514f53,$04b43444b,$06f65635a,$0807f7c78,$0717d8382,$0827b7069,$06a6b7480, $0817f786f,$082828383,$082828282,$082828282,$070757d81,$07f7e7a74,$08181807f,$07d808081, $03b3b3a3a,$04644403d,$046464647,$040414547,$0574e4440,$06c6b5f57,$0424b5b66,$041414141, $042414141,$048464443,$0514f4d4b,$05a565553,$076695e5b,$08382817e,$07a878684,$067666767, $064646465,$064656564,$064646464,$094726967,$05262869d,$03d3b3941,$05c514941,$0807d6f65, $075717477,$062676671,$060596060,$05557575b,$059585855,$05754565a,$0525a5c53,$064645850, $058525557,$056505757,$0595b5958,$0575a5f58,$05153585a,$059565659,$052555257,$056574f4b, $04e515550,$054505254,$055515857,$057585353,$04f514e52,$0776a5353,$04c607c78,$051535c56, $0545a544e,$059565259,$053515456,$0827c5f55,$05b595a78,$0807d725f,$05d5d4f6d,$058545877, $05b7b796b,$075755854,$07379655b,$0677a655c,$07b6e5550,$054566d7a,$055555757,$056545352, $053555355,$04f515150,$04a46484b,$06c656257,$0807f7c77,$074808382,$081796e6a,$06a6c7881, $0817e776d,$082828383,$081818181,$081828181,$06f767e81,$07f7e7972,$081817f7f,$07f828180, $03b3b3b3b,$0423f3d3c,$048464644,$03f454c4d,$0564c423e,$06c695d56,$045505d66,$042424142, $042424242,$048464544,$0514e4d4b,$059575553,$0655f5d5a,$082807e74,$07e858484,$066666669, $063636365,$064646463,$065646464,$0906e6867,$053678f9d,$038373843,$04e46413b,$06f6c6056, $06061636a,$0585b5d5e,$057555658,$05656565a,$05a5b5757,$054535257,$04f535a55,$059545350, $05c5d5d54,$058555255,$052545761,$04e505153,$050575a52,$0525a675d,$05851545a,$04a555459, $04c555455,$054565154,$054504d53,$050564e53,$062756c5b,$07e79625b,$04b6f8380,$04d53534c, $057585b56,$04f4b5051,$058545353,$0774f5256,$058565074,$06b707552,$056595f78,$076707379, $05961797e,$07979585c,$07b767b78,$0727c5b6d,$074575158,$04d577178,$054535353,$04f4f4e4c, $056575550,$04f4f5153,$04846494e,$06a646054,$0817f7c75,$077828482,$07f776c6c,$06a6e7a81, $0807c756c,$080818181,$080807f80,$081818181,$070787f81,$07f7d7971,$081818080,$080828180, $03c3b3b3b,$03e3e3d3c,$04c46433f,$0474d5353,$051494142,$06a655952,$04a5a6267,$043434345, $043424243,$04a484745,$0524f4d4c,$059575554,$062605d5c,$0817f7b69,$081868483,$06868696c, $062636365,$064646261,$066646564,$08a6c6867,$0556c949d,$038373745,$0463f3c38,$0605b544d, $05a5c5762,$0565a5c5a,$05a595456,$054545556,$054595655,$056575355,$0545c5856,$04c525454, $05b565b56,$0534b4e5a,$053524f56,$05953514c,$058555f50,$053565959,$04f535253,$0525a5552, $059575956,$055534f52,$05e4c5358,$04d64746d,$06d838273,$07c725050,$05a7b8183,$05e62544f, $0545b5b55,$04b525351,$0524e5653,$06e505a4c,$057555876,$0546a775a,$052577675,$0686e7976, $0554b5864,$0757a5653,$07160636c,$077756177,$060555e60,$04f577576,$054544f52,$050535254, $057585154,$04c4e5251,$04647494d,$068645f51,$0817f7c74,$07a838382,$07d746b6d,$06a707b80, $07d7a726b,$0807f7f7f,$080808080,$081808080,$0717a8182,$07f7d7770,$081818180,$080828181, $03c3c3c3c,$03d3e3d3c,$04d443e3d,$052585c57,$04a46454a,$06962564d,$054636669,$044444547, $045434344,$04b494846,$0514f4e4c,$059575553,$064615e5c,$0807f7a68,$086868481,$06f757577, $063646569,$064636262,$067666564,$0836b6867,$05f77999c,$037383948,$0423e3a38,$05a54504b, $05a5b5859,$058555a60,$05455565c,$05354544f,$054565354,$04c535759,$0535b5b55,$05b5a5657, $05956555d,$05650545a,$0594e4f54,$0584f5752,$058524f56,$056505756,$05b5b5155,$054575d4f, $0605a544d,$067685a55,$06c4d4d5b,$048668285,$06d84826a,$083725053,$0657b8085,$054555358, $051564d51,$04d4b4b58,$056585954,$064555958,$04c505c7b,$053617a5b,$050647b65,$05553756b, $0584e504f,$0627c6452,$062585451,$07472747a,$055575954,$0505b635c,$057595251,$050525455, $054535355,$04d505653,$045464b4b,$067655e4f,$082807c72,$07c838382,$07a716a6f,$06a717c7f, $07c786f69,$0807f7e7e,$080808080,$082818080,$0737d8282,$07f7c7670,$081808080,$081828181, $03c3c3c3c,$03d3e3e3d,$04b413e3e,$05c636459,$046444751,$0675d514a,$05b646568,$04545464a, $045454545,$04c4a4947,$052504f4d,$05a585654,$06764615e,$081807869,$08f888582,$08d959693, $064666a7c,$063636363,$067666564,$07c6c6a67,$05f7e9b9a,$037373d49,$0413c3b39,$0564d4b46, $05859575a,$057565753,$04d555354,$051535050,$057545654,$05d585657,$058595a54,$055554f52, $05153515b,$05555514f,$058565556,$05b524f52,$05e565566,$05654515a,$05e55564e,$053585b54, $0505b5158,$08083806b,$05f55577b,$04a767f80,$0757e805d,$07f705454,$0747d7c77,$05a62505b, $04c58555b,$04e4d5155,$053555755,$0584e5f63,$04a4e6c7b,$071728061,$0637b7e77,$056677e65, $05252514e,$0637a6a52,$053525755,$0615a686a,$04e4f5356,$051565554,$05958514f,$04e4e5358, $050555752,$050505154,$0474b5150,$066665d4c,$0817f7b70,$07d828182,$0786f6a71,$06b737d7e, $07b766d68,$0807f7f7e,$080808080,$082828180,$0757e8282,$07e7b746f,$080808080,$081828180, $03d3c3c3b,$03e3e3e3e,$0483f3f3e,$060676356,$043424853,$061584e49,$059606163,$04746464b, $047464546,$04d4c4b49,$05352504f,$05c595754,$079736a61,$081827f77,$09c8e8683,$09d9f9f9f, $065677694,$064636363,$067676665,$0756c6a68,$05d849d96,$038383e4c,$03d3b3a3a,$0564e4942, $059595859,$05b5e5758,$053525053,$050525154,$05553514d,$0655c5856,$0524f5055,$04e505650, $04f555556,$05553554e,$052555c58,$05259555c,$05f56574f,$056534e54,$050555150,$07d7a6b58, $05a587087,$07f807c76,$05a565f7d,$05d7a837d,$07d807a5a,$080755654,$081876b78,$05351565d, $050565957,$0504c5056,$057585b62,$0535c515b,$056506e77,$078777c62,$075806d73,$052687d5c, $050505754,$057726454,$0564e5152,$059555657,$0524e505a,$054595356,$0534e4e50,$04d4d4f53, $04f50514e,$055514e4e,$045495654,$065655b4a,$07f7d786c,$07f828080,$0766c6a73,$06c767e7e, $07b746b68,$0807f7f7d,$080808080,$081818180,$0777f8282,$07d79726f,$08080807f,$081818180, $03d3c3c3b,$03e3e3e3e,$0483f3e3e,$05c5d5852,$044434b54,$05a534b48,$0575b5c5c,$04746464c, $049474647,$04f4d4c4a,$055545351,$05f5a5756,$095928870,$083858a91,$0a0978884,$0a0a19e9e, $06569819c,$064636364,$068676766,$06f6c6a6a,$068909e92,$037374456,$03e393939,$0524a4642, $053555a56,$055575654,$05456544f,$05155554f,$055544f57,$0504f5354,$052555851,$063545d59, $05651545c,$056525358,$052505252,$04f5a5852,$059555650,$05e515456,$0607a766e,$08481764e, $053547980,$07e7b826c,$053506b7f,$0577b8276,$08184724f,$080754f5f,$0807e617a,$0514e516e, $050555557,$04f4d534c,$04e514e4e,$05459574f,$056537774,$0575b796d,$07e685054,$0506b746a, $055505557,$050555c52,$057505354,$05a595d59,$057565556,$053565661,$04c4b4b4e,$04d535150, $050544f4c,$05c575152,$0444c5357,$064635546,$07e7b7469,$080817f7f,$0746b6b76,$06d797f7d, $07b736a68,$080807f7e,$080808080,$081818080,$079818282,$07c777070,$080807f7e,$081818180, $03e3d3c3c,$03f3f3e3e,$0493f3e3f,$05b5d5a55,$046465359,$0544f4b4a,$0575a5a57,$04746464d, $04a484747,$053504e4c,$0585a5d58,$0615b5958,$09b9c9780,$082817b91,$0a0988883,$0a1a2979a, $0666a889e,$064636263,$069686866,$06e6c6b6a,$070969d8d,$03737495c,$03e3a3837,$050494542, $0595c5c58,$050545559,$0535b574f,$04e4e5358,$057595050,$05c515254,$04e595558,$05751534d, $057555b53,$05450515d,$059525254,$059524d54,$06d676161,$0714c4e5e,$06d7e7d7e,$0857f7351, $051507f82,$084868373,$04f597b80,$06c7d816a,$083857c76,$081795365,$080775c7b,$055554e79, $055565258,$0534c5053,$064535251,$0545b526b,$04e5a7e72,$04e587b75,$07550524f,$04e5c616e, $057545c53,$058555a4e,$058545058,$04e545451,$052585452,$053525050,$04e4c5059,$05653584e, $052535253,$053505256,$0464a4d52,$0645f5147,$07d7a7166,$08181807f,$072696c78,$0707c817d, $07a706869,$08080807e,$080808081,$081818080,$07a818282,$07c766f71,$080807f7e,$081818180, $03e3d3c3c,$03f3f3f3e,$04b403f3f,$0595f5f59,$047485357,$052514e4b,$058595853,$04747464d, $04c4a4847,$06257514e,$072777c71,$0625d5d66,$0979e9982,$0837f7481,$0a0958683,$0a2a29fa0, $0676d8d9f,$065656564,$06b696766,$06c6c6c6b,$073989a81,$03638475c,$03c393737,$04f49433e, $059595957,$05453605c,$054565655,$051525455,$04f4f5253,$058555451,$0515d5854,$04d575852, $058555751,$04f545252,$058545d50,$0585f685b,$07f7f7d79,$06a564c6f,$07c817d7f,$081847256, $0526a807c,$0727f7f6a,$052667e7b,$0847d8065,$07d7c7e82,$082734f6d,$08274637d,$05b5b5d77, $054555553,$0514f5354,$068515355,$05d506682,$05b5d7a7c,$0555b7a74,$0564e5154,$056605257, $0534c4e4f,$05054534f,$059594d4c,$0575b5c50,$04e514f4e,$05552524c,$0504b5054,$055525a54, $05352575a,$052525354,$046494e52,$0635c4c44,$07e796f65,$08282807f,$071696f7b,$0727f827c, $0786e6869,$080807f7e,$07f7f8080,$081818080,$07c818281,$07a746e72,$080807f7e,$081818181, $03e3d3d3d,$03f3f403f,$0473f3f3f,$053565653,$04a4e5555,$05253514d,$057585651,$04848484c, $04d4b4a48,$07d675650,$088888786,$0625e6881,$09c9f997e,$085868993,$09e908784,$0a1a2a2a2, $0677293a0,$066656564,$06b6a6867,$06d6d6c6b,$075979072,$036394859,$03c393836,$04b49443f, $056525a54,$0584e5657,$05152515d,$058525353,$056535455,$056515051,$04f5b514e,$04d575750, $057564f4e,$067565454,$055535969,$057758075,$0807e817c,$0634f5379,$07e797b7f,$0837b6d68, $04f667e84,$05f7a8266,$060737e78,$0807f7c60,$081827d80,$0826d5279,$07c80807d,$05250697d, $061505353,$04c545456,$057534c52,$0807e7c79,$0545b677b,$056585f5a,$055555255,$051535751, $051495454,$04d515156,$054535152,$04e515851,$051565a51,$05951514e,$04e4d4b4f,$0514e5253, $051525d56,$051575554,$0484e5050,$063584a45,$07d796d64,$08382807f,$06e6a727e,$0757f807a, $0776c686a,$080807f7d,$07f7f8080,$08181807f,$07d818180,$079736e74,$081807f7d,$081818181, $03e3e3e3d,$04040403f,$0433e3f3f,$056504d4b,$053565a5c,$0575a5654,$05a5a5854,$04a4b4c52, $0504d4c4a,$082785c54,$07c73727a,$0615e7083,$09e9d9779,$08e989b9d,$09d8d8688,$09e9c9ea1, $069809a9f,$067656565,$06c6b6a68,$06d6d6d6d,$07895856e,$0363b4c58,$03a373636,$04a48413f, $054555653,$055545350,$054555256,$050535357,$055555955,$0595b5959,$052555658,$0504f5651, $04f52524e,$07c62584e,$05554787b,$057737f78,$07d7e817a,$05b506684,$08688817c,$07a846e71, $04c6d837f,$062828165,$05d7c8076,$07c81794c,$07e7c5f64,$08365527b,$07b807b82,$0595b797b, $056505151,$05151544d,$052545552,$06d786e55,$050565864,$04e4f5258,$053525153,$04d585b4f, $057545553,$050545757,$05a4f5856,$0534e5256,$05552514f,$0574f5054,$050555255,$050525454, $04f525754,$04e535250,$04a525551,$062554946,$07d776b64,$08382807e,$06c6b7580,$0777f7e76, $0756b686b,$080807f7d,$07f7f7f7f,$080808080,$07e818080,$079726e76,$081807f7e,$081818181, $03f3f3e3d,$041413f3f,$0403f3f40,$065564d47,$05c59626c,$05f666260,$05e5c5a59,$04e51565c, $0514f4e4d,$07a7f6456,$0615c5c63,$0605d646a,$095958f71,$0999a9795,$09e918791,$08783929e, $073919e97,$068676667,$06e6e6b69,$06d6e6f6e,$07a917c6d,$0333e4d57,$039353636,$04a47403d, $054535c51,$054545652,$051595552,$0534f5753,$05357534f,$05c5c5557,$04d535658,$053565452, $051544f50,$0795d5a56,$0586b7a7e,$057697f7f,$079767e77,$052576e82,$07f7e7c74,$072817478, $0556f8178,$05e7f8162,$06681836e,$07e817259,$07f745362,$07f6d6280,$072667385,$05d708280, $055524a54,$050525857,$057595850,$04d595a5b,$04e4e5658,$0544f5554,$04f51535c,$04f52504c, $052545252,$050525151,$05a505555,$04e51565b,$053535654,$05a535252,$0555d5453,$053505257, $054515455,$04f515655,$04b545751,$061544746,$07c756864,$08281807f,$06a6b7780,$0797f7c74, $07369686c,$0807f7f7c,$07f7f7f7f,$08080807f,$080818181,$077707078,$080807f7d,$081818181, $03f3f3e3d,$042414140,$03f3f4041,$074604e44,$05e5b6676,$0686e6d68,$05f606063,$0575c5e5f, $053515153,$07c846957,$05a595a5f,$05e5b5c5b,$0767a7765,$09a8f7d75,$09e918a99,$075778d9b, $07f9a9e90,$06a696869,$06f6f6d6b,$06e6e6f70,$07b8c736c,$03441515a,$038383735,$04b423e3b, $05550504e,$055525357,$05157544e,$05958595b,$04e56575b,$0505d5d64,$052585353,$0535b605c, $053525852,$060575558,$063798079,$050627a7d,$06f727e6f,$04d5c797e,$07b737b73,$073828082, $05d7d7f78,$072807c60,$07883867c,$07f827162,$080745a67,$07f6b6d81,$05b4e6082,$05878817b, $04e53574d,$0575c5c53,$05f585a58,$04d565f63,$057545454,$0565b5552,$04f4d5155,$04d505b5a, $055545152,$056625854,$0594d4d53,$04f585452,$054585250,$058585a53,$04e585750,$054555653, $051525453,$05251514e,$04b505051,$060514446,$07b736664,$08180807f,$0696c7981,$07b807b71, $07069686f,$07f7f7e79,$07f7f7f7f,$080808080,$081818181,$07670727b,$080807f7c,$081818181, $0403f3e3d,$042424141,$040414142,$071604b42,$067616571,$06c717471,$061636165,$063646361, $05655575d,$080876d59,$059585a62,$05d5b5b5a,$065656360,$092776b66,$09d8e8e9b,$0847e909c, $080999f9a,$06b6a696a,$0706f6e6c,$06e6f6f70,$07d876f6c,$036454e5b,$0383b3934,$047433f3c, $05355584c,$0564f5057,$054525458,$055524e52,$04d545254,$0555d5a50,$04f5b5a52,$051505959, $059535f5a,$04d554f5b,$06e797b71,$054638279,$06c777d72,$04b657f7f,$0727d7d6a,$072818381, $05c7d7d74,$080808262,$07f7f857f,$07b7f615d,$081694d62,$081696e82,$0595a657d,$05b7c8274, $0555c5351,$05b54534f,$05260525d,$053525556,$05b555152,$0524f4d4d,$052505357,$050565354, $04e504e4e,$05f5c5754,$053515458,$055524f59,$050505053,$063595352,$050515658,$051565752, $05655514e,$054555051,$04e4e4e52,$05e4d4447,$07a6f6565,$0807f7e7e,$0686e7a81,$07e80796f, $06e696a72,$07f7e7d77,$07f7f7f7f,$081808080,$081818181,$0756f737c,$080807f7c,$081818181, $0413f3f3e,$043434241,$041414242,$05e504542,$071696263,$06a6f7375,$05d57555e,$068666461, $05c5f6668,$0848a715d,$05b5a5c67,$05d5d5c5c,$06564625f,$094796b67,$099898c9b,$09a959b9f, $075919d9e,$06d6c6a6c,$07171706e,$06e6f6f70,$07b816b6b,$0394d535c,$037353534,$049443f3b, $055534f4c,$05a525158,$05357525d,$0564e5053,$04d555357,$0555f5651,$051575551,$052544d4d, $05b585557,$058585d58,$0807f7c5f,$051627f7d,$05a78786e,$050787c7a,$06c7d7a5f,$06d817f81, $0697e7f6d,$08084795d,$078817773,$07a7f5a6b,$082624d77,$07f6e7984,$05a535e77,$0535a635d, $04e545d58,$050564d50,$04b4f595f,$052505454,$059515559,$058534951,$055525450,$05555524f, $056555651,$065565156,$0534e525f,$052535053,$056565d56,$079725256,$04f565a63,$04e57544d, $05c514f4b,$05453525a,$04e4f5153,$05c4a4447,$0776d6566,$07f7e7d7c,$069707c81,$07f7f796d, $06c696a75,$07f7e7c75,$07f7f8080,$08181807f,$081818181,$0736e747d,$080807e7a,$081808080, $0413f3f3e,$044444342,$043434444,$04b464443,$06b615952,$05a61686c,$0544f4c4f,$06b67635d, $0686d6d6c,$089897064,$05f5e616e,$060616260,$06d716961,$09b8e766d,$08d858998,$09c9c9d99, $0707c929a,$06f6e6c6e,$07071716f,$06e6f6f70,$07779676a,$03c51555c,$037373534,$049483f3a, $05551504e,$056555354,$054575353,$0534f5354,$053555c53,$055545659,$05352595d,$050545a53, $05a575652,$05b5b524f,$07d7e704f,$05b657e7d,$056787d6f,$05d7b7a70,$0677f7b63,$074827d75, $06d838067,$07182815d,$0827e5a51,$0807b597c,$07c5b5a7b,$06657757e,$04c53515c,$0594c4e57, $053565d57,$053564e53,$0544f5950,$051575757,$05a5e6155,$05a4f5052,$059545751,$04f5b5251, $056565552,$0575b5351,$0594f4d52,$04b545552,$056707659,$076775b54,$0555c566b,$051555755, $05554534f,$052565555,$04b515754,$058464548,$0756a6465,$0807f7d7c,$069737f81,$0807e776b, $06a676b77,$07f7e7b73,$07f808080,$08181807f,$080818181,$0716e767e,$0807f7d78,$081808080, $041403f3f,$046454443,$045454646,$044444444,$0514c4745,$0494b4f53,$0504f4c4a,$06a655c53, $07472706e,$08f846d70,$06665697f,$064737f74,$08a8d7764,$099999289,$08583858e,$0878f8f89, $06f717681,$06f6f6e6e,$06f707070,$06c6d6f70,$079766669,$03f51545b,$037343333,$043443f39, $04f52534a,$057515653,$055585a56,$050545257,$050565855,$056545154,$056535460,$054575553, $0554c5250,$058535a57,$07f7c5c51,$0585c7c7a,$0707a7f71,$0747e7b7b,$072807655,$07a878067, $077817f5c,$071818261,$081775450,$07c716681,$058504e68,$0545d5a5a,$04f57594a,$053505755, $05050544c,$054515253,$04f504d50,$05855585a,$053595c55,$04f4f5558,$051575c52,$0514e5855, $053565861,$0545b504e,$04d4f4e4a,$0514f514f,$06a787b60,$07c7d6454,$054585170,$0584f5155, $05559555a,$056585352,$04f525d55,$05246454a,$073686563,$0807f7d7b,$06a768081,$07f7c736a, $069676d79,$07f7e7a71,$080808080,$081818080,$080818181,$06f6f787e,$07f7f7c76,$08180807f, $043424140,$047464544,$046474847,$044444546,$045444343,$049474545,$0504e4c4b,$064595250, $07874716c,$0907b6f79,$07e75818f,$0657e918e,$0968d7365,$08b959897,$083828486,$072868784, $06f706f6c,$06f6f6e6e,$06f70706f,$06b6d6f6f,$07c736568,$041505261,$037343335,$0413f3e39, $052574f46,$053545958,$056535659,$055575252,$055545e62,$056525258,$057595459,$05256574e, $05151545a,$059515254,$07c6d525b,$054587b7f,$07e7c7c6e,$07c7c7c78,$07b826d50,$07384805f, $07c817c53,$06e818060,$071615652,$057545e6e,$05754544e,$0595b4f62,$054515156,$051555759, $04b4f5751,$057566151,$04f4d4b52,$053575757,$05a4d4d56,$04d5a5d57,$05151514a,$055545956, $0645a5361,$0554f5c66,$0504d5156,$0574e5152,$07a7c7658,$07b786d66,$052505b76,$054504f51, $054525054,$057555351,$056535558,$05044464b,$071666662,$07f7f7d7a,$06d788081,$0807a7069, $068686f7b,$07f7d786f,$080818180,$081818180,$081818181,$06e70797f,$0807e7c75,$081818080, $043434241,$048474645,$047484948,$044454647,$044444343,$049484745,$04f4e4d4b,$05853504f, $078746e63,$0866f727a,$094919391,$064779095,$084786863,$06f798286,$08282827c,$074888885, $06f6e6d6b,$06f6e6e6e,$06f6f706f,$0696c6e6f,$07d6f6566,$044515567,$035343236,$0423f3d3a, $05555544c,$056575858,$05b5b5754,$053525557,$05752525a,$04c4e4e53,$05053524f,$05357504c, $04f50585c,$056524d4f,$0775c5057,$0525c7c7b,$079807b6f,$0807e7c73,$0807e6b66,$06c767360, $080847c52,$068707a69,$04b485056,$0575e5151,$0555c5c4c,$05356545a,$0555c4b52,$0525c5c53, $04f585752,$0555b524e,$054524d53,$0534c5457,$056515358,$0535a474c,$04e4d5151,$05457524f, $0807c6755,$0556c777e,$054555259,$056515359,$0787d6f52,$072737c7d,$051575c7b,$04d4e4e57, $04e54594e,$056555353,$051515354,$04e44474c,$06e65665f,$07f7d7d79,$06f7a8080,$07f796e69, $06869727d,$07f7c766d,$080818180,$08180807f,$081818181,$06e727b81,$0817f7b74,$081818181, $044434343,$049484746,$049494949,$045464749,$045444444,$049484745,$0504f4e4c,$054514f50, $078736659,$07068757a,$08f918e81,$063697c89,$06a676462,$06868686a,$083838277,$07a888785, $06e6d6c6b,$06f6e6e6e,$06e6f6f6f,$06a6b6c6e,$07e756969,$04754576c,$035333238,$03f3f3d39, $059534e45,$058525757,$053545f59,$052515251,$0505d5b57,$04f4e5753,$04f525757,$055545651, $05459595a,$052535550,$06e584d51,$05266817a,$061807f70,$07c83685a,$0847f6671,$052565368, $067736856,$050565053,$05650534d,$05d5c4f59,$056594e4a,$0525a4e5c,$05c59564e,$04d5c5d58, $055534f4f,$04f545253,$0535b5653,$053564f56,$055505056,$0565a5453,$06c665450,$056515168, $0687c7e62,$06b7f7166,$051585656,$05155534f,$0697c694e,$06c677a74,$04d55607b,$050525156, $05153544e,$054575551,$053524f52,$04b44474e,$06d66675d,$07f7c7b78,$0717d8080,$07e776c69, $06769747d,$07f7c756b,$080818180,$080808080,$081818181,$06e747e82,$0817f7a72,$081818181, $046454444,$04a484747,$04a4a4a4a,$046464849,$045454645,$049474646,$050514e4c,$054525050, $079736158,$06467787b,$073787469,$06263666c,$0726b6462,$06666666a,$084838171,$07e898785, $06e6e6d6b,$06e6e6e6e,$06d6e6e6e,$06b6b6d6d,$07c70766a,$04a585770,$03633323c,$0413f3a38, $05a504b45,$054515762,$055545353,$053524f52,$052565a5e,$059585152,$0514e5458,$05e535352, $050565e5d,$05c4f5157,$067535659,$04c6d817d,$05f7c8172,$07e77544b,$07b79687c,$0534e4a5a, $057515552,$056555853,$054505a54,$0524f4d56,$05050595e,$0595c5252,$05a525757,$0554e4c5b, $05a594e5d,$05957515a,$0555a5958,$057585256,$0554b4a50,$058554f4f,$082827657,$05d647a80, $04d628075,$07c7c5c56,$0504d5059,$06b636257,$06a7d6971,$0675f685b,$04c4f657b,$052585651, $051544f4e,$056585551,$056525357,$04a454950,$06b676a5b,$07f7d7b75,$0747e8080,$07c736a6a, $0676b767e,$07f7b7369,$080818180,$080808180,$082818281,$06e777f82,$0807d7871,$082828281, $047464646,$049494848,$04a4a4a4a,$04747494a,$046464646,$04a474646,$051514f4c,$056535252, $079715f5a,$0626b7a7b,$064646463,$063636364,$08b7c6663,$066666874,$08482816e,$083878786, $06d6e6d6e,$06e6e6e6e,$06d6d6d6d,$06b6b6c6c,$077677b72,$04b555974,$03734333d,$0423f3938, $053524c47,$0515a5c54,$052555553,$058595654,$04e555c5a,$055555555,$04f544f53,$057575351, $0545f6054,$06256514a,$063525252,$051787e7a,$0627f7b6a,$0725f514f,$0525a566c,$05d5a5652, $05d605254,$04c545759,$0555d555c,$05b5c4f4f,$04f4f5b5a,$055525854,$0564d4d55,$051515354, $054595b54,$0534e575a,$050515a5b,$0524c5850,$071756c5e,$04c535463,$06870846d,$04f72786a, $04f56726f,$07e795b53,$0766b5e64,$07e7c7c7c,$06e79657e,$068585251,$054586e7b,$05656574f, $04f514e51,$05652504f,$05052575c,$04a474c4d,$0696a7564,$0807f7b73,$0767f8080,$07b71696b, $0676e797f,$07f7a7168,$081818180,$081818181,$082828281,$070798082,$07f7c766f,$081818180, $048474747,$04a4a4949,$04b4b4b4b,$048484a4b,$046474747,$04b494746,$052514f4d,$059565352, $0786f5f5b,$0636f7b7c,$064636363,$063636464,$094836964,$068686c83,$083817c6b,$086878684, $06d6e6c72,$06e6e6d6d,$06d6d6d6d,$06f6d6d6c,$06d667380,$04d525e75,$035333441,$0413c3937, $04f504743,$04f585751,$053565650,$052575859,$054545655,$0514f5853,$050515354,$05a505159, $056565355,$04a4d4e54,$05c53574f,$0657a7b78,$05a737c6d,$05351555a,$055595054,$058595253, $051525158,$05c504e4f,$0595b5661,$0584a5055,$04d514e4f,$05a4b564e,$05b585657,$04d535951, $0505b524c,$04b485256,$075645751,$05c4b5970,$07f7a8180,$052527382,$0584f7275,$04c505156, $0515a5853,$0757d6a4e,$07d82735c,$0616b707c,$07775595d,$05a50525a,$0525a7476,$0534d5052, $052515758,$05a585752,$05a525258,$04e494f51,$0686f8479,$0807e7b71,$079808181,$07970696d, $0686f7b7f,$07f796f67,$082828281,$082828282,$082828282,$0727b8182,$07e7b746e,$08181807f, $04a494949,$04c4b4b4a,$04c4c4c4c,$0494a4b4c,$048484849,$04c4a4848,$052504f4d,$05a585554, $0796d5f5d,$065747e7c,$066666565,$065656565,$098846b66,$06a6a7591,$082807a6a,$088878483, $06d6d6b76,$06d6d6d6e,$06c6d6d6d,$07d6e6d6c,$067677181,$053566475,$033313543,$03f3a3634, $04e4b4343,$0575a5b51,$053535555,$054536364,$052525357,$0584e504d,$051505557,$053565353, $04c525254,$054545f59,$05a566157,$05b6b7670,$058575f55,$0524b5758,$04f504f4e,$0515b514d, $0504b5457,$053615d51,$056655c50,$04f4f5751,$0534e5750,$0564a5154,$0555c5852,$04e514c50, $04d4b4e4a,$06f575e5d,$084888074,$0784d6681,$05c526680,$05469826f,$06b596a7c,$05655686f, $055525957,$05e77826d,$05b625753,$057515a5e,$07a6e585a,$052515961,$0575b7673,$0504e5055, $0554f5355,$056555352,$05b575457,$04a474b53,$067758a7b,$0807d786e,$07c818081,$0786e686f, $068727d7f,$07f786d67,$083838382,$082828282,$082828282,$0747e8282,$07d79736e,$081807f7f, $04c4c4b4b,$04d4c4c4c,$04d4e4d4d,$04b4c4d4d,$04a4a4b4b,$04d4b4949,$05351504f,$05c5a5856, $0796b615e,$06a787f7e,$06c6a6968,$06665696c,$09a836c68,$06a6c8299,$08280776a,$086858383, $06e6d6c7b,$06d6e6d6e,$06b6c6e6d,$087766e6c,$0646a757d,$051576976,$033323743,$03e393534, $0504a4542,$056595a57,$059575550,$058575357,$050535352,$05b575051,$052565a55,$05b5a5754, $053575453,$057575956,$05151565b,$04f50504e,$0565b5651,$056535155,$04f545152,$0534e4f51, $04b526052,$04d4f5750,$05c524f4c,$0544e5b61,$0635e585f,$04951544f,$053534850,$0494a4b54, $06c4d5257,$0847e5f67,$0696d717a,$080584f5c,$055544f6f,$058737c55,$07f7c7680,$063787a76, $072525659,$05f63727c,$0544f4a4f,$05c565951,$07d664d50,$04e52505e,$0565a6d66,$052534f4f, $052555551,$055525353,$058595351,$048484b53,$067788871,$07f7c766b,$07d818180,$0776c6972, $06a757e7f,$07f776b67,$083838382,$082828282,$082828282,$0767f8282,$07d78726e,$0807f7f7e, $04e4e4d4d,$04e4e4e4f,$04f4f4e4e,$04d4e4e4e,$04d4d4d4d,$04f4d4c4c,$055535250,$05f5d5b58, $07b6b6461,$075828380,$086837e75,$0686c7d84,$0987e6b6a,$06b6e8a9b,$08280736a,$085858483, $06e6e6d7f,$06d6d6d6e,$06b6b6c6c,$08585706d,$05c6d797f,$052596f77,$032313947,$03f3a3533, $0534a4745,$04e515959,$0595b5450,$04e525959,$04f57544e,$05a554e50,$057535354,$04e4c5054, $052575855,$0595b5654,$054575658,$04e504c53,$0544f5354,$050524e54,$05e4e5156,$056545754, $04c495255,$053565f5b,$07c57535b,$052555c82,$058505d5e,$0595a4e4a,$05d554d54,$050665b56, $0815c5152,$0737b5574,$04e514f55,$06a535257,$053525260,$0566e8165,$0647c8177,$07871564c, $080694c5f,$05b5c506a,$058524c50,$05253515a,$07562524d,$04d53515c,$053555952,$052534f50, $056575554,$052565655,$0545c5957,$048494d4f,$06771745c,$07f7b7469,$07f818180,$0766b6b75, $06d79817f,$07d756a68,$082838281,$082828182,$082828282,$0777f8181,$07c77706e,$07f7f7f7e, $053535251,$04f505152,$051515050,$050515151,$050504f50,$0514f4f4f,$058565553,$063615e5b, $0836f6865,$0888c8a89,$09397958e,$06975868c,$094776c6b,$06c728f9c,$0827f6e6b,$085848483, $06c6d6f80,$06c6c6d6d,$06c6b6b6c,$082867c6d,$056677c82,$0535d7574,$033323d4a,$0403a3534, $0524a4845,$055585d56,$0585a5656,$050505356,$053555152,$051514f4f,$055585654,$057515058, $055555151,$04f55514d,$05053574d,$0514e5156,$05b4b5052,$05452515d,$0504d4c4e,$05854575c, $051595e57,$04e545b56,$07e6b5556,$0494d5d7f,$055515258,$056504f53,$07c5d5556,$06c836b60, $0846f5950,$075724d75,$04e505553,$0534d585d,$0654d5466,$051587d81,$0536a806b,$07d624c56, $0787b5462,$05e5b4f58,$0564f525e,$055535862,$05a5b5756,$051504e55,$053525356,$052535654, $057575356,$053565553,$055575550,$04c4c4f54,$067675b4e,$07f7a7167,$082828281,$074696d79, $06f7c827e,$07a716968,$08182817f,$082818181,$080828282,$0797f8180,$07b766f70,$07f7f7f7d, $063635f5b,$052545a60,$053535352,$053535353,$054555453,$054535253,$05c595856,$06c6f665f, $090847a6f,$08887888f,$09497968f,$0697a888f,$090736d6b,$06d79969d,$0807c6d6b,$084838281, $06c6b7284,$06b6b6b6c,$06d6b6b6b,$082838674,$0575b7a82,$04c607b71,$03433404c,$03c383534, $04e494342,$053555852,$054575255,$051515551,$04a515356,$055514f57,$056564f52,$0575a4a4d, $05158514d,$05b5f5a50,$053525153,$056545c4f,$05a525856,$059515558,$05c545a56,$07e71655c, $07b817d7d,$05d57526f,$07f784d52,$052524e75,$053504f4e,$0516c775f,$07e6e4948,$08381635a, $0807a5068,$07c605376,$06e5d5760,$0525e596e,$082694e54,$0494d6675,$04d657b58,$07f645556, $06a816462,$07d786f63,$0584f617f,$055515856,$05256555a,$0544f4e55,$057545551,$053535554, $052585751,$053525252,$051515655,$049494e53,$066615348,$07f7a7066,$083828180,$070686f7c, $0727e817b,$0766c6768,$08181807c,$081818181,$080818181,$07b808180,$07a746e72,$080807f7d, $080817d79,$0565b6b7a,$057575655,$056565757,$0585a5a58,$059585757,$064605e5b,$085877a6b, $09a989389,$084808593,$093959186,$06b7f8991,$08e726d6a,$06e809a9d,$07f786c6c,$085848482, $06c6b7685,$06b6a6b6c,$06e6b6b6b,$083848883,$0595a6a82,$04e657c69,$031404a4f,$03a373533, $04b434241,$053575655,$053525152,$051555856,$04a4f5153,$05a595651,$055555557,$051555452, $04d4e4f50,$050535659,$04f524f58,$04e565553,$0544e5956,$05c4d5751,$062534e5c,$082878281, $08383807f,$056576f80,$07f806050,$054564969,$05b585256,$066816d4a,$07082564d,$07c7d5e53, $0637e6f7f,$07d62697b,$083827c7e,$04b575879,$06d7f6b51,$052565454,$059787256,$079776052, $07e7e6957,$06970787d,$053566165,$0574f504f,$051524f53,$054524f4b,$04e525553,$05453565a, $050555454,$053535053,$0544f535b,$0494c4e58,$0655d4e48,$07e796e65,$083828180,$06d68717e, $0747f8078,$06f69676a,$0807f7c76,$081818080,$080808080,$07c818180,$079726e74,$080807f7d, $08a8e8f8f,$0595e6e81,$05b5c5b5a,$05a5a5b5b,$06164625d,$06a666260,$07c79756e,$0888a8781, $09a9a978d,$07f7e8694,$08e908d80,$06d7f868c,$08a706c69,$06e859b9c,$07f746a6c,$085858481, $06c6b7a85,$06a696a6b,$07b6c6a6a,$084828389,$0595c5d76,$04f69765e,$0313a464d,$03a363533, $04945423e,$054565353,$052585655,$053575554,$04c4e5252,$05357564d,$057514d55,$04f505a57, $0565b5251,$04b52514f,$04d535254,$051505255,$05b545c58,$0576c7873,$07e624b5b,$07f7e8382, $0807f837d,$05c627b7e,$07d81765b,$0504c5052,$0515c5256,$0826d534c,$062806670,$066745f57, $052778470,$07d536e7d,$06164687d,$05857565a,$0486e7e59,$052524d4f,$07d775655,$05f7b817c, $064625c56,$056595563,$052525452,$05b55524e,$055544f50,$0544f5255,$057545253,$051525355, $051565853,$053545659,$053515457,$04b4e5256,$064594c48,$07d776a64,$08281807f,$06b69737e, $0767f7e77,$06767676b,$07d79746e,$080807f7e,$080808080,$07f818181,$078716e76,$0807f7e7d, $07d858a8f,$05f606772,$064666461,$05f5d5f62,$07e7f7769,$07e7c7a7a,$081818180,$082828281, $0999a9689,$07b7e8995,$089867d77,$06f7d8185,$0846f6b68,$06f8a9d9b,$07f71696a,$086848380, $06a6b8086,$069696a69,$088736a69,$07e838384,$0595b5d62,$0556d6d57,$0323c474e,$039353333, $044423f3d,$05352514b,$050555150,$052575953,$051555d5b,$04f51544f,$05a5e504e,$04a56555a, $05654504e,$051575053,$050535553,$051505450,$07b5f585b,$068808180,$082795758,$084848583, $05c575470,$04f657d77,$0757f805f,$052575b62,$04f53605a,$0635b5b4c,$05372827e,$075714b4d, $0545c5e4a,$06e537472,$04e4d4c75,$04c5f5854,$04f537e6c,$06d6d665f,$06d595a55,$0535a646f, $04951554e,$052545c53,$054595651,$051576159,$05358565b,$05a555655,$057535357,$04f4f4f53, $05f565854,$052555653,$050515352,$04b515255,$062554a46,$07c746764,$081807f7e,$06969757f, $0787f7d74,$06666676c,$077706b67,$080807e7b,$081818180,$080828281,$076706f78,$07f7f7e7c, $06b6e767f,$06c686769,$07b7f7a72,$069696e74,$08e918b79,$07e7e8086,$07e7e7e7e,$07f7e7f7e, $097989488,$07a7d8995,$081766e71,$0717a7b81,$07b6c6a67,$071909d98,$07d6e6a6a,$086858381, $06a6e8287,$069686969,$087816e6a,$06c828485,$058595c5b,$05c706555,$0333d4853,$037333334, $04746413c,$059504d4b,$05a585152,$05859585b,$0504e505d,$04f525652,$05c58524f,$05754504f, $05255544f,$052524e4e,$059565252,$0595c5250,$07f806446,$06483817e,$075816748,$07c826f70, $058564b54,$05063826f,$0647d8571,$0594c4f5d,$051514c59,$0524e564f,$04964795e,$07d655152, $04f565154,$06c597e69,$05757557b,$052585250,$07b777c72,$06e777e80,$057555e53,$053585156, $04e4a4e54,$0555a5652,$04e595854,$051555e52,$04e505357,$04b4d5350,$0514e5050,$04f4e5252, $054575753,$054515251,$054545553,$04a555353,$061514847,$07b726664,$0807f7f7d,$0686b7780, $07a7f7b71,$06564676e,$06d686666,$0807f7b74,$081818080,$082828281,$0756f717a,$07f7f7e7b, $06d65666d,$0847f7a75,$09094928b,$06e6f7885,$091938e7d,$07c7d7f88,$07c7d7d7d,$07d7c7d7c, $096969185,$0777c8995,$0786b666d,$0757a7b80,$0746b6866,$077959d92,$07e6e6b6b,$085858382, $068718486,$069696868,$08488796b,$05e778586,$0575a5c5e,$061705d54,$035414752,$035323231, $04544413b,$053464846,$059505351,$0575a5457,$0545c5453,$0575c554e,$057555153,$05b56574d, $04d554f52,$058504d52,$059534b51,$050575553,$07c7d846d,$07c7d7f81,$0576a5f5a,$071837856, $056505551,$059597a7b,$0537b7b76,$058514e50,$054545155,$04c4d5258,$04e6a754c,$081605154, $04b5c5661,$0655d845f,$052536785,$052545352,$06b6e725d,$053565d61,$0524b4e4e,$05a565c54, $0594e5257,$05357595c,$04c4c5955,$04d4d5852,$0504f5754,$04e4c5052,$0514f5154,$051535450, $050525354,$055534f4e,$055565955,$04c505657,$0604f4749,$0796f6565,$0807f7e7c,$0676d7a81, $07c807a6e,$064646771,$067656564,$07f7d766d,$081818181,$082828181,$0746f737c,$07f7e7d7a, $078676367,$08d8a8782,$0949a9993,$070707a89,$093938c7c,$07b7c808c,$07b7c7c7b,$07b7a7b7b, $095948b7f,$0767d8993,$07062616d,$0797b7c7d,$06f6a6666,$07f9a9c8c,$082756d6c,$084838281, $066748686,$06a676768,$086868872,$060648086,$0585b5d5f,$059635554,$03d483e4b,$036353432, $03c3e3d3a,$04a41433d,$055524c48,$05654514c,$056525d54,$050555356,$04f4f5155,$056525250, $050525451,$04d4d4e56,$0584e4d52,$068514f4d,$082838284,$0827d717a,$0534e4e71,$067837e5d, $078525a55,$05c507481,$0476c8082,$0555a504e,$05e5c5150,$058545651,$0557a6a57,$081605c57, $04b57546a,$05f698062,$04f566a87,$0534e4c52,$051565055,$052585d51,$051525853,$057595151, $056525454,$0514d5256,$04a565853,$055585250,$04c535250,$04f4d4f4b,$0534e5150,$057575353, $04f585753,$056534e50,$059585760,$04f515356,$05d4c4649,$0796d6465,$0807f7e7d,$068707d82, $07e7f786c,$064646873,$066656565,$07f7c746a,$081818180,$082818181,$0726e757e,$07f7e7c78, $07868666e,$08d8a8782,$093999892,$073737b88,$093928b7b,$07b7c838f,$07b7b7b7b,$07a7a7a7b, $09290867b,$0747d8a93,$06c5e5f6d,$07b7b7a79,$06c686569,$0879c9b85,$082817170,$084838381, $064748486,$06c686766,$084838680,$061606f84,$05a5d5f5f,$03b4b5156,$0494f282f,$034333431, $037383736,$03e3c3837,$051544b41,$052554f4f,$04f4e5554,$053515452,$04d536252,$054545251, $051505258,$04e50524d,$0544c4a4b,$07f635554,$073847d84,$0816b5059,$04e535379,$055767f76, $07f725a5d,$06f4f6a7a,$05665827f,$0565f5856,$055505353,$05c595155,$05a836f56,$07853585b, $04c4f4d73,$0566e7b5a,$04e515a6a,$053575b4d,$04e4f4c53,$05257504e,$055545459,$053595656, $0514e4f53,$055575455,$052574b4e,$059574a4b,$04e575249,$05451544d,$04e4e4c51,$05351504c, $04e535454,$05a525053,$05a575457,$04f535454,$05949464a,$0776a6365,$0807f7e7d,$069737f82, $07e7e766b,$065666a75,$066666565,$07e7a7168,$08080807f,$081818181,$0716f767f,$07e7d7b77, $076696f7c,$08b888681,$090949490,$076777c86,$09491887b,$07b7c8590,$07b7b7b7b,$07a7a7b7b, $0908c837a,$0727b8892,$0685d616d,$07f7d7773,$06a67646e,$0919e9a80,$083857e75,$086858382, $0646d8185,$0796b6866,$085848286,$06061607b,$05b5e5f5f,$03b4d5157,$03e412d2e,$032323333, $032323031,$03b393432,$04e46443e,$058565354,$057535455,$053505555,$052575854,$04f5b5353, $057545054,$04e575350,$05e4b554e,$07b74545e,$054717e7f,$07e6c5056,$06858537b,$0616f7f81, $07f7d7c74,$07f586472,$04f567b82,$0655b5e5f,$053505f67,$052525358,$0667f5f4a,$06f514d4f, $050545477,$0575c5750,$05b55514a,$0515f5759,$051556053,$05c565754,$05252534e,$0575e6054, $04c505c5a,$0655e5951,$0545b4f4d,$050554e4e,$055515151,$052545353,$055554f4e,$052525451, $057545052,$052504e52,$056595151,$053544f52,$05547484c,$073676363,$0807f7e7c,$06b768081, $07f7d7369,$066676c78,$066656565,$07c776e67,$0807f7f7d,$081818181,$07070787f,$07e7d7b76, $0776d798a,$089878580,$0878c8e8c,$0787a7f81,$09591867b,$07b7d8891,$07b7a7a7a,$0797a7a7b, $0918c817a,$0727e8b91,$06b5e626f,$083817874,$069656373,$0989f9879,$083858882,$085858482, $066667984,$086726a68,$082868485,$06061616a,$05c5e5e5f,$03f4f5458,$04a3e2c2f,$02f303234, $02d2c2c2d,$03733312f,$04a443c3b,$0525a5554,$05a555457,$058515252,$054575159,$04d515357, $053534e52,$05a5c5b50,$05250544e,$07b7d7058,$0534e7780,$0827e5150,$0826e4c71,$0817f7d80, $0697d8185,$07d6f5354,$07f7f8384,$084857e7e,$0544f567a,$04e525956,$06a805a5a,$059505054, $05453565a,$05a535457,$06255514e,$05e535557,$0564e5159,$04f525755,$0504e5151,$053595351, $053575b5f,$05a585351,$058545558,$051524d57,$0544c5156,$050595b56,$04f51544c,$056545252, $054565352,$051525452,$055595a51,$051534f52,$05146484c,$071646460,$080807f7b,$06d798181, $07f7c7168,$06868707b,$066666767,$07c756b66,$0807f7e7d,$080818181,$06f727a7f,$07e7d7b75, $07d7a8493,$089878682,$07d838889,$07b7e7e7b,$0948f837b,$07a7f8a92,$07b7a7a7a,$0797a7a7b, $0908b807a,$073838d91,$06e60646e,$081807b78,$068646477,$09d9f9473,$082828791,$085848483, $06866697f,$086816d69,$074878686,$060616260,$05d5f5f60,$04550565a,$05b522631,$02c2e3035, $02c2b2b2b,$033302e2d,$0483e3c38,$04f515151,$05651545a,$0564e5055,$057535152,$04d525150, $053575153,$051555659,$050514f4e,$07c7e7b5a,$052525e7c,$0807a6a58,$086754f66,$07c7e7e7b, $053617278,$07f83704d,$07e817d83,$082837f7f,$04f4d4b6f,$0504a5858,$05d665a54,$05159534b, $0505d564e,$04d4f494f,$04e56584f,$04f545553,$055504c4e,$051535554,$055544e4d,$055594e55, $052515254,$052535b57,$058555458,$053525752,$04f4a545d,$05057514f,$053525b53,$051565054, $052555453,$050515653,$054575751,$04d505250,$04e46474b,$06e64645f,$081807f7a,$06f7b8181, $07f796f68,$06a6c747e,$067676869,$07b746b68,$07f7f7e7e,$080808080,$06f747c7f,$07f7d7a74, $083858e98,$084858684,$0777d8183,$07c7f7b76,$0918d8079,$07b818c91,$07a7a7a7a,$079797a7a, $08e887d79,$074848b8e,$06e62626c,$0827e7773,$06764657a,$09e9e8e6f,$083838693,$082838283, $069696672,$08588786b,$0647f8887,$061626362,$05f5f6060,$04b52565c,$05b4e2934,$02a2d2d3a, $02b2a292a,$0312e2c2b,$048403b37,$0564f4a4c,$053535256,$04f515751,$052515158,$04e544d50, $057525656,$05750575f,$04f5e584e,$07b7c7f65,$04f59536e,$07c7a7a54,$0806d5359,$064727f7f, $04b515053,$07f828367,$07f81817c,$07981857d,$050545259,$05351514b,$05e525755,$05b535454, $056544c58,$04d5e544e,$05d535250,$05b4d5152,$059565b58,$0555c524e,$051505152,$04d494c5d, $05658525b,$056545756,$05054564e,$050575150,$057504e4c,$05253524e,$0595c5152,$06052544e, $053554e55,$053575659,$053555d54,$04f555652,$04b46494e,$06c63645c,$081807e79,$0727e8181, $07e766c69,$06e747b80,$0696a6b6c,$07a726a69,$07f7e7e7d,$07f807f7f,$070767d80,$07f7d7973, $08386909a,$07b7f8283,$0767a7c7a,$078797474,$08e877b75,$07b838d90,$0797a7a7a,$078797979, $089817978,$07180868b,$071676568,$0837c7570,$06763687e,$09f9c866b,$084838592,$07a838384, $06b6a6967,$088878572,$0616c8488,$062626564,$060606161,$04c53595d,$062482a38,$02b2d2e44, $029292829,$02e2c2a2a,$045403832,$053524a46,$057524b52,$055515553,$04f555655,$051524e52, $058515454,$0575e595d,$04b565f56,$0767e7c6c,$05e545659,$0747a7c66,$083725754,$04f526483, $0524f4c51,$07a807d71,$07072727a,$0555b6465,$05c595f56,$059505658,$05e574f56,$0584b595c, $050545453,$049505454,$064574c5b,$04f504e56,$0484f5152,$07e827c61,$057595c6b,$04d515856, $051515254,$0544f5252,$055525249,$04a514d58,$0534f504e,$050545350,$04e555550,$05a525551, $050515255,$051565353,$053545b56,$056545557,$048464a51,$06a636356,$081807d77,$0747f8181, $07c736969,$07a7e8181,$06b707577,$079716a69,$07f7f7e7d,$08080807f,$070787f80,$07f7d7872, $08386929c,$0757a7f81,$072787974,$074706a6d,$08a827673,$07b848d8e,$078797979,$077777878, $0837a7676,$069777e84,$07f776964,$07c7a787a,$068636578,$09f997d6b,$084848694,$06b808484, $0706b6967,$089878880,$065637689,$062636364,$060606161,$04f555a5e,$04d372e3c,$02e2f3343, $02928292c,$02d2b2a29,$03f3b3833,$0554c453f,$0594f5057,$057504e57,$051575255,$054575453, $059515356,$0575f5356,$04e505654,$0747a7f74,$062515551,$05c7a7f7b,$08176595a,$0515c5a78, $050515153,$0626f7f71,$05f61494e,$0555b5755,$050545956,$0504d555d,$0535f5253,$056575658, $04c525253,$052474a4d,$0574f5659,$056555051,$05b545a6c,$0736d717d,$05c546e7f,$04f525050, $0534f514e,$0595b5555,$051504852,$0504a4d58,$055515253,$055595750,$0504d4f52,$04c515151, $05651504f,$055575759,$052525354,$05453524f,$047464850,$067646353,$0817f7c74,$076808181, $0776d676b,$086878680,$0757c8184,$0786f6a6d,$0807f7e7c,$081818080,$0727a8082,$07f7c7771, $08388959d,$0767a8082,$070757676,$0706a6367,$0857d7271,$07a848b8b,$076777777,$071727475, $0726d6f70,$05c646c73,$07d736962,$0696e737c,$06a666263,$09f997f6f,$085858999,$068738485, $0786d6b69,$088868689,$065676780,$061626263,$060616161,$050565b5e,$02d2d2f42,$02d2f3031, $027282a2c,$02b2a2928,$03f3c372f,$05a514744,$05752575d,$0554b5057,$050535157,$051525754, $05a594c52,$0504f4f50,$059525555,$06e7e7d72,$0775e5150,$0526d827d,$07c7b5e50,$05350556a, $0504e504b,$0524e5254,$0554c5458,$059535a56,$059575257,$050545a55,$0595a5250,$0515d5f52, $04c504e4e,$050535a54,$05063614c,$05e564e51,$075597083,$05e524b76,$051527b70,$056505454, $0554e5355,$054504d53,$04f4f4e52,$0554d4d53,$05657544e,$05556514f,$04f4f5251,$04c585151, $05a564f4c,$05d545352,$053575457,$04f525254,$048484b4e,$066656050,$0807f7c71,$079808080, $06f67676d,$08988867e,$07e848789,$0766e6c74,$081807f7c,$081818181,$0747c8182,$07f7c7771, $0848a979e,$07b7d8182,$06d727478,$06d6a6465,$081776f6f,$076818785,$06e707273,$06366696b, $0575d6361,$0524f5154,$064605d5a,$065636264,$0746e6b68,$0a19e917d,$085858a9b,$06a697c85, $085726d6a,$085868587,$06465646d,$063636463,$061616162,$051585c5f,$02c2e3246,$02f2b2929, $0272a2c2d,$02b292828,$0433c382e,$058574948,$055555a58,$04f515252,$05155564f,$054564d50, $058516257,$053505254,$052565750,$0767c7c6b,$07f7d6060,$0565a737b,$07e785756,$0534f555f, $0554d5853,$052554e4f,$05459575c,$05853514d,$057594c4b,$057545856,$04b4e5155,$054575d53, $05251535b,$050555355,$05f83694d,$059565859,$07a59747b,$050535068,$053535857,$057535252, $051555057,$056574d4c,$05d535253,$050574e52,$050524d4d,$053585553,$04f4f5651,$04d534f50, $052525452,$05353524c,$057545759,$04c525359,$048494c4d,$06567604e,$07e7e7b6f,$07a7f8080, $06b66676e,$08e88847b,$07f84898f,$0756d7078,$081807f7b,$081818181,$0767e8181,$07e7b7671, $0848d999e,$07c7f8080,$06a6d7077,$0696a6866,$0776d6a6c,$06b777d7c,$05a5f6366,$04d505356, $04c595f55,$0504c4a49,$068645e56,$06e6c6b6a,$0928b7e72,$0a1a19e98,$086858c9b,$06a686c80, $0887f6e6b,$075868686,$064646463,$063636463,$062616162,$052595d60,$02c2e354b,$02b28292a, $0292b2c2e,$02b292827,$0413e3830,$051504a46,$0585b5755,$04d50524f,$04f565d55,$05755514e, $058575b55,$05c5c5b52,$04e4e4d54,$07e7d7c58,$07f7f7f7c,$054515474,$067665955,$05a4d484d, $054515c5e,$055554d53,$056515651,$051544f53,$057514e58,$057585d4d,$04950544e,$06661595b, $057525157,$05353757c,$06a816054,$050586159,$078547777,$059555569,$057534f52,$04f515555, $053505253,$0514d494c,$057535353,$05a524c4f,$05a554a55,$05b555352,$052565953,$052515352, $053555151,$053544c50,$055545752,$050515153,$0484b5052,$0656b604c,$07e7c776b,$07d808080, $06d656771,$09a8d847d,$07d82919b,$0736c727a,$081807e7a,$081818080,$0777f8180,$07e7b7573, $0828f9b9e,$07b7e7c7b,$06b6c7076,$06872706b,$065606369,$056626969,$04a4b4e51,$047474848, $0494c4f4b,$056504c49,$0716d6860,$0827c7975,$09e9b9187,$09d9f9f9f,$084858996,$06b6a6773, $08587786d,$0657d8585,$065656565,$063636363,$062616262,$0535a5e60,$02d313c4e,$02728292a, $02a2b2d2c,$02d2a2827,$0433f3933,$052514e4a,$052525454,$04e565151,$056595457,$05a564d4f, $0535b5554,$050555a52,$0504a4b4c,$07e7a6750,$0737d7d79,$059565056,$05161544e,$05f584f4d, $056515253,$0505c5458,$051545757,$04b555557,$053515252,$05a5d544b,$0776d5e5c,$07e847c79, $0664f5060,$04e6a7e7f,$06d7d5e4b,$0424f5653,$079577a69,$054535573,$05255594f,$051555855, $052525c51,$05c5b5351,$057575450,$053565b5b,$05151575b,$058525851,$051545152,$059575056, $055564e52,$05a565052,$054555550,$052545255,$0484a4e51,$0676e5f4c,$07e7c7469,$07f818080, $06e656975,$09c8e827c,$07b80929d,$0716d757c,$0807f7d79,$080808080,$0797f8180,$07d7a7473, $07b909b9d,$07c7c776f,$06f6e7378,$068747771,$051535f67,$04a545652,$048474848,$046464747, $04a494847,$062544d4a,$083807b70,$086868686,$09a998f87,$08d909498,$07b868689,$06c6a6868, $085868571,$0656c8385,$066666767,$063636364,$061616263,$0555b5e61,$02f344351,$02728292b, $02a2c2e2b,$0312b2828,$04b463c36,$05657524e,$051555754,$051535556,$050545155,$051535755, $05d5e585a,$051594f53,$05e585050,$065595b66,$05b61636c,$05352525d,$052574e51,$05654524e, $05956534e,$04f535056,$04e504e54,$04c55594e,$054555351,$0545b4e50,$07d887f5e,$0626c6c73, $06252545b,$056788283,$0787a574f,$0736a5854,$078607d7d,$05a555678,$058695559,$04f4a4b53, $0505b6258,$05b565351,$057555556,$05657575b,$04e4e585a,$053525851,$04e555353,$053504f4f, $054505154,$056565153,$0565c5652,$052555555,$0474a4d4e,$069705e4a,$07f7c7268,$081818080, $06d656b77,$093857f7a,$0817e8a95,$0706e7982,$07f7e7d78,$081808080,$07a808181,$07c787475, $079929b9c,$07c7a7269,$07473777b,$06e737775,$0494f606b,$0474d4e4a,$047474747,$046464646, $04a484746,$0705f514d,$08686857e,$084858585,$08b8c8785,$085868788,$06d828686,$06e6b6867, $08485857c,$066647685,$065666666,$064636464,$062626363,$0575c6062,$033384953,$028282a2c, $02b2d2f2c,$038302929,$0514b413b,$0565c5953,$05a545151,$054555554,$050534f50,$04f4e4e53, $055555550,$0484d5152,$05c50534e,$050575564,$05254514b,$0544d5455,$054505459,$0505d5953, $05454534f,$04a524b57,$05455514b,$0505f5051,$050565e4a,$04d505556,$04e767d53,$05a58455b, $0674f5a62,$06a80647d,$08572524f,$07d848180,$0666c807a,$0544c5c7c,$063816251,$0554f4f5a, $058585a54,$04d4e5157,$05e575754,$054575455,$0554d4e55,$050595e4e,$050525454,$050504f4d, $054535251,$054535856,$056585155,$052515154,$0474b5156,$06b6f5949,$07e7a7066,$08181807f, $069666d7a,$0827f7f77,$08e8e8885,$06e6e7987,$07e7d7c76,$081807f7f,$07c808180,$07c777376, $07b939997,$07a776d67,$078767779,$078797a7a,$049516471,$046474848,$046464646,$049484746, $0504f4e4b,$072635753,$08585847e,$084858586,$087868584,$084858586,$067778484,$0776c6a69, $084848385,$06765667e,$065666666,$064656464,$063646464,$0595e6163,$0353f5054,$0282a2b2e, $02d2f3434,$03c362d2a,$051504940,$057535854,$050535150,$05654534d,$054534f55,$0545e5250, $04d55594e,$04f535c50,$04f4d5851,$0585f534f,$056515854,$0524a5b5b,$050535059,$0515e574f, $050514f50,$054574f52,$0724d5855,$0525b5169,$057505b52,$0594c584e,$05d797a56,$0565a5f5a, $06c4d5157,$0806e557b,$0866d4e66,$0595d6678,$052747552,$05157737d,$056787153,$0524d5459, $059564b54,$04f53504e,$05f59564e,$055545153,$055515555,$051525353,$05554514f,$050535051, $053555854,$052535a51,$053505051,$0574f5156,$0474b5459,$06d6c5647,$07c786e66,$08180807e, $065666f7c,$088857e71,$0969b978c,$06d6d7587,$07f7e7b75,$081807f7f,$07e818281,$07b767377, $08094958c,$0706f6769,$0796e6c6e,$080828280,$04a526576,$047474849,$04b4a4847,$05251504d, $057565654,$076695e59,$08485847f,$084858585,$085858584,$084848484,$069697c85,$083706b6a, $083858585,$06868646e,$066676767,$064656465,$063636465,$05b5d6062,$036455456,$0292a2b2f, $02f323638,$03e3c362d,$05a534d44,$056565b5b,$053595150,$052585a56,$056504d51,$051555551, $053535050,$053565550,$050545954,$05555554f,$050565d53,$05558595c,$058564d55,$04e5d5353, $056495154,$05350595c,$0856a5158,$056535a78,$05855535b,$054515951,$0607f6e52,$0616b6056, $075544f58,$07a565377,$081635478,$04d534f67,$05a7a7453,$072797f69,$04e6b8079,$04f505658, $052565054,$0545a564f,$05d5a5555,$04f524d50,$051565052,$054545450,$052505152,$0524e5050, $05b555554,$052535258,$052515255,$0524d4e50,$04a565858,$06e675149,$07d766b67,$081807f7f, $06567727e,$08c857769,$090999891,$06d6d717e,$07f7e7b74,$082818080,$080828282,$07b757379, $088969081,$06362626d,$0796a6462,$083868683,$04d566878,$04e4c4b4b,$05453514f,$05c5a5856, $06260605e,$07a716965,$084848380,$084858585,$084848484,$083848483,$06a676e7d,$0877d6d6b, $077878785,$068676764,$066666767,$066656666,$063646465,$05c5e6062,$0394d5857,$038262c30, $03537383d,$043403e36,$06159544b,$052566362,$0555d5850,$056535757,$05455555a,$053505555, $053575152,$04d514b52,$04849474d,$056535753,$051555052,$05c5f5255,$05b5a5247,$05859585f, $07a74665c,$05b737f7b,$0847f5a59,$052505c7e,$0575d5452,$04e535463,$07d806351,$07984817c, $0774f5262,$0807a6f7d,$0815e657e,$051504f71,$05f827056,$07b746354,$04f526573,$051515c59, $0554c5253,$0525b4f51,$055534e4e,$04e4d494d,$04d505053,$054535350,$052555553,$0514f5453, $055535052,$052515156,$056515051,$053515051,$0505c5a55,$06e604c48,$07c746968,$081807f7e, $06669747f,$07f766a65,$07b858784,$06d6c6d72,$0807e7a72,$082818181,$081828282,$07974747b, $08e978c79,$067666876,$0776d6a69,$082858481,$0555f6f7c,$057545252,$0605e5b59,$06a666462, $06f6e6f6d,$07f797471,$084838382,$083848584,$07f828383,$07076797b,$06b6a6869,$08586766d, $068818887,$067676766,$066666667,$065666666,$063646565,$05d5f6162,$03b4f5758,$049503730, $03e3d3c40,$04945413f,$063625f55,$055525e67,$05e525958,$05851555c,$0585c5455,$051555455, $05151574f,$05d4f4d4e,$04e4a4b51,$058505350,$050544f58,$05450514d,$06c61534b,$0526e7c75, $065827958,$0797e685c,$06d6b5f59,$0515f6181,$058525455,$05f5b5f57,$07e806354,$05d696772, $0785c5a56,$06c717880,$0755c7d74,$05b595f7b,$0607f6754,$05752525d,$0504c4d50,$04f4e5559, $0584f5352,$05a5e5353,$05c53494d,$051544c50,$04d535251,$052535554,$050505255,$0534f4f52, $056514f51,$0504e4f53,$0504d5353,$053515250,$04e53514f,$06e594846,$07a72686a,$081807f7e, $0666b7881,$06c676565,$06e71716f,$06d6c6c6d,$0807e7971,$081818180,$081828181,$07874757c, $095978773,$07a767684,$07774797c,$083838380,$05f68757e,$0635f5c5b,$06f6c6a67,$076737271, $07a7a7978,$0827f7b7a,$083848484,$07b7e8081,$06a6f7478,$068686868,$06c6b6a69,$085868370, $066718688,$068676768,$066676768,$065666565,$064646465,$05f606162,$03b51565a,$04658593d, $04c4d4945,$0524b4747,$0686d685e,$0565c636d,$059555754,$056555054,$05954534c,$04f555a59, $04f4d4e52,$050555e53,$05254544e,$058594c4e,$0545a524f,$0524c4f4f,$07b7b7257,$050627376, $050628563,$082685258,$0564c5a66,$04f4d727d,$0504f5953,$052505c51,$074815a4e,$04f4f5559, $07f61564e,$050584f6f,$06d6f7a5d,$051585a7c,$059635b54,$051555d53,$04c4c5051,$0504f5052, $05d575450,$059565056,$056525051,$0555a5255,$04951514e,$05253524d,$04f555351,$04d515653, $054545b50,$052504e52,$0554e5357,$055505556,$04f535353,$06b564647,$07a70686b,$082807f7e, $0686e7a81,$068676767,$06c6b6a69,$06d6c6b6b,$07f7d7870,$081818080,$081818180,$07873767d, $09995816d,$0908e8d93,$0767d8a90,$08283827e,$06b717a80,$0706d6a68,$079777673,$07d7c7b7b, $07f7f807f,$081807e7f,$0767a7e80,$06a6b6d71,$067676868,$06a6b6a68,$06f6c6a6a,$08586897d, $067657986,$068696868,$065666767,$064646465,$064636464,$060616263,$03d52575c,$04a485746, $0505a5c56,$063585350,$066706f69,$05452595e,$0594d4e53,$054524f4f,$0534e5354,$0504f5656, $04c524e52,$053595e4c,$04d4d5652,$052555152,$07a6b5f52,$051566b77,$055697f5b,$0454c5856, $054507664,$082614d57,$05c5c515f,$055527b79,$0555a5452,$0575f5653,$077705760,$0514f4c54, $08560565f,$0524f4b6b,$0536a6556,$053585862,$054505252,$04f515057,$0534b4b48,$05b575053, $054555b53,$04d4c5956,$054505455,$055504f4f,$04e4b4f59,$04e50524e,$052595452,$057585657, $05255554f,$052565853,$057555254,$052515054,$051525250,$067514549,$0796e686b,$082807f7e, $06a717c82,$068686869,$06b6a6a6a,$06d6c6c6b,$07f7d7770,$080807f7f,$081808080,$07773787f, $0978f7969,$092959698,$07074828d,$08383827b,$076797e81,$079777574,$07f7d7d7a,$08081807f, $07c7e8081,$07274767a,$068696b6e,$06a686767,$069696969,$06c6c6b6a,$0766f6d6d,$086858687, $068676a81,$068696968,$067686867,$064656565,$063636564,$060626262,$04154585e,$047464a3c, $05556524f,$06c62595a,$064767670,$05556575a,$057525757,$055524d52,$052535857,$04f525759, $05451514b,$05052554f,$04f4e4d53,$04f4d5250,$0687b7b60,$0566f7b71,$04e6a7c5a,$04a56615c, $053524d50,$07a7a614b,$04a505053,$0595c7c6b,$05956585d,$053505554,$07f6d4e5a,$0726b605f, $07960787c,$0545d4f57,$0524f5352,$05956535b,$05654595c,$052554e54,$05354544d,$05054514b, $052585556,$056525850,$053505958,$04f4a4c50,$0534a4e57,$054515459,$055544e58,$05c575154, $052535552,$054515458,$055565052,$052515151,$0484d4b51,$0624c4343,$0776c696c,$082807f7e, $06b747f82,$06969696a,$06b6a6a6a,$06e6d6c6c,$07f7d7973,$080807f7f,$081808080,$076747a80, $0897e6f65,$080868a8c,$069696f78,$083827f76,$07d7f8182,$07e7e7d7c,$08080807f,$07b7e8081, $06b6f7377,$067666769,$068696868,$06a6a6969,$06c6b6a6a,$0726f6e6c,$0867d7975,$085868687, $069696872,$068686869,$067676866,$064656766,$062636464,$05f606162,$046555960,$03f47463b, $0443f3b39,$063574b49,$05f6a736d,$0505e5d5a,$053545453,$058565352,$0555a5d58,$052505251, $05a514f4e,$0524a4f52,$05152514e,$050545b59,$04f5d7f71,$0607d6b52,$07e7e765d,$0667c7d81, $04f595254,$05a7b8363,$049595853,$057648063,$056565952,$057554d4f,$083624f5a,$081807b81, $058596878,$050575a56,$057585553,$055555551,$0504d5356,$054514e4e,$054534f4d,$057565053, $052525356,$05b5a5856,$04f535459,$04b505450,$050525854,$04f515957,$059514c4e,$051525354, $054515052,$052504e51,$04f55514f,$0474c4b4e,$041424548,$060483e3e,$0766b6b6f,$08282807d, $06d767f82,$06a6a6a6a,$06c6b6b6b,$0716e6e6c,$07f7e7c78,$080807f7f,$081808080,$075757b81, $0726b6563,$06a6e7274,$066656668,$082807b70,$080818282,$080808080,$0777a7d7e,$0696c7175, $066666768,$069686767,$069696a69,$06c6c6c6b,$072706f6d,$08c847a75,$096999692,$079848689, $069696968,$066676869,$067676767,$065656566,$063636465,$060606263,$051595b5e,$040474841, $039393735,$04d46413d,$0565f6357,$054515253,$053505255,$055555153,$059585150,$04e4b4e4d, $050504d4f,$05554514e,$050505a5a,$052535555,$05a4a7577,$06f7a5764,$07a807062,$07d7a676d, $067545b58,$0625e727d,$050594e51,$0536d7e5d,$0545c5c53,$054524f50,$06f57545a,$0565a6373, $057545254,$059555659,$054526668,$055545660,$0504c5c5e,$050574b52,$051514e51,$05d515454, $057525255,$05056575b,$04c505757,$052515951,$050595b54,$04f51584f,$0554f5151,$051525252, $04f4d4a52,$04a494d4d,$04a4a474b,$041424649,$03d3d4041,$05d443b3b,$0746c6c6e,$08281807d, $06f7a8182,$06b6b6b6c,$06c6c6c6c,$076716f6e,$07f7f7e7c,$080808080,$081808080,$074767d81, $065636262,$063656666,$064636363,$0807c7469,$07d7f8181,$07476787b,$0686a6d70,$067676666, $069696867,$06b6a6969,$06e6c6c6b,$078757370,$086837f7a,$09b958b87,$09b9f9f9d,$0697f868b, $068686967,$066676868,$067676666,$066666666,$065646565,$061616264,$056595c5f,$041474646, $037363434,$047423e39,$05959594f,$054545556,$0564f5055,$05156535b,$05a524e50,$059535956, $052515055,$05552534d,$0525a5756,$05e5b5451,$056537272,$0797a5d53,$058675c56,$07953534e, $07f656370,$056575c6f,$058585353,$057788057,$053575451,$05553534c,$0534f5961,$04e4f4e4e, $05c504e4e,$04f4e4c52,$05551515a,$04b4e5a58,$04f545251,$055575654,$04b4d5362,$05058544f, $053554d51,$0574e5056,$04f4c4b55,$05253534f,$051535551,$0514e544f,$04b4b5258,$0504d4d4d, $04a4c4e4c,$04546484c,$043474243,$03c3e3e3f,$039393b3c,$0543d3939,$0726b6e6c,$081807f7c, $0727d8382,$06c6c6c6d,$06e6d6c6d,$07c767170,$07f807f7f,$080808080,$081818080,$074777e81, $063626262,$063636363,$063636363,$077726a64,$06e727578,$06667686b,$067676767,$068686767, $06b6b6b69,$06f6d6c6c,$07b767170,$092918b83,$0888a8d90,$0938d8a89,$099a09d96,$06670858c, $068686969,$067676868,$068676666,$067676768,$066656666,$062626366,$05a5a5e60,$04249484c, $036353435,$0453f3b38,$059575349,$04f595855,$055555752,$056545358,$054505158,$055535150, $051505552,$05353554e,$0524d4f5a,$05a575d56,$05a6b7d70,$07a837358,$0544d5360,$077565353, $073775c7a,$05b4e5053,$058525a67,$052777459,$058555e58,$050565359,$062585c51,$050565559, $054504b48,$0504b4c52,$05350534c,$04f545955,$05255525a,$0534f4f57,$04a555b5a,$05553554f, $04f514f57,$056534f56,$05655514e,$04f4e4f4c,$053505051,$052504d51,$049494d50,$04d4e4949, $043464846,$041424141,$03c3d3d3d,$038383a3b,$037373738,$04f3c3938,$0716c6f6a,$0807f7e7a, $0747e8381,$06d6d6d6e,$0706e6d6d,$0807b7471,$080807f80,$081808080,$080808181,$074787e80, $063626262,$062626363,$064636363,$069676564,$067676869,$068676666,$069686868,$06b6a6969, $07672706d,$0807c7978,$08e888381,$09b9b9b97,$0898b939b,$08b898888,$0989f9b8f,$069687587, $068686869,$068676767,$067686767,$067676767,$066656666,$063636465,$05e5b5f61,$0434a4a51, $035343236,$0433f3b38,$057524c4a,$055575353,$051565a54,$058554e54,$04e51544f,$04e4c4d51, $0504c5453,$051505051,$04d4a4a54,$05b545151,$07b7e7059,$07c6d787f,$05b685c63,$07c554e51, $07a7e5a71,$0837c786b,$0504e6382,$056616058,$05b545a55,$0514e5050,$05650554f,$050515459, $05152554b,$04e545352,$058515d4d,$052626056,$0534d5250,$052505359,$050575e51,$0565e5655, $05152555b,$051525053,$04f4d5154,$04e4c4f52,$0504e5256,$0504e4b50,$047464a4e,$042434749, $03d3e3e40,$03a3c3d3c,$037383939,$036363637,$038373736,$04e3e3d3b,$0706e746c,$07f7e7d78, $076808281,$06e6e6e6f,$070706e6e,$0817f7972,$080808080,$080808080,$080808081,$074797f81, $063636362,$063636363,$066656464,$067666665,$068686767,$06a696868,$06c6b6a6a,$074706e6d, $0908b837a,$08d919393,$0948a8889,$09594989a,$0898e9a9b,$083848687,$09c9e9b8c,$06a6b6e88, $068686869,$067686868,$069686767,$067676868,$066666767,$063646466,$05c5b5f61,$0444a4d54, $035333139,$0413d3b37,$055534d49,$057595451,$053575856,$05b585455,$052535452,$05a544d5b, $04e4e5055,$04e525249,$04f51574b,$0534f5251,$06a634e51,$07d5c5f6f,$0787c5c67,$07e735966, $07c7a5f64,$069737d80,$04d4e505f,$052514f4c,$05350555b,$0554d574d,$04a525454,$0525a4c4c, $056554f4e,$0475b5e5d,$0544c5b55,$0555a5b5b,$055535356,$052565251,$0595b5859,$05d585652, $052514d54,$04e535355,$052575755,$05154524e,$04a525453,$044444649,$042414545,$03c3f4041, $038393a3b,$035373838,$035353536,$038373636,$03b3a3939,$05544423e,$06f707c76,$07e7d7b76, $079808281,$06e6e6e70,$072706f6f,$081817e77,$080808080,$080808080,$080808080,$0757b7f81, $065656464,$065656565,$067666666,$068686767,$06b6a6a69,$06e6d6c6b,$07673716f,$087827e7b, $09b9b988f,$0989c9c9c,$0928a898f,$08d8b8e93,$07e8b9996,$06e6f7278,$09c9b977f,$06b6d7d97, $06968686a,$068686869,$069686867,$068686868,$065666667,$063636465,$05c5c5f62,$0464b5159, $03434333c,$03f3b3b36,$0524d4644,$0545e5b51,$057565252,$04d4c5358,$05453504e,$0625a5054, $0474d4f54,$0514e5a56,$0575a584f,$055525b51,$056555752,$07e694c55,$07b694d5e,$06f7e7d7f, $067605457,$04c484c5e,$05055514c,$05c5a5150,$058575456,$051595351,$04e52554e,$04f565749, $053585853,$051595851,$05354494b,$051544d56,$05a585853,$05d504e4e,$05650525a,$059575252, $050524c4f,$04a554d52,$04e51554b,$049484b4d,$0424b4c4e,$040424341,$03c3c3d3e,$038393a3b, $036363637,$036363636,$037353535,$039383737,$03d3b3a3a,$075564842,$07075888c,$07f7d7b75, $07b818180,$06f6f6f71,$07471706f,$08081807b,$080808080,$080808080,$080807f7f,$0767c8080, $06a696868,$067696a6a,$069686767,$06c6a6a69,$0706e6d6c,$07e7a7673,$08685827f,$08d898887, $0979a9d97,$09d9c9796,$086878b95,$0807d8084,$06c849792,$06b696869,$0948b8474,$06b748f9a, $06868696a,$068696869,$068686868,$067676869,$065666768,$063646465,$05c5e5f61,$04b4e555d, $036353542,$03d3b3936,$053504741,$053535154,$046535653,$03133363c,$0463d3732,$0515d5652, $04f535255,$04f4d4e4c,$059585854,$05a5c5755,$06f775d56,$0757e6b62,$059535054,$0585d6b68, $050575a58,$05a575456,$05358555e,$05252524f,$052524d4e,$0494d5658,$05355574d,$04e555452, $04d4e5955,$04b555a4e,$04d4e4e50,$04e545650,$0564f6255,$0535a524c,$05e4e4a58,$0504f4f53, $04c515453,$04b514d49,$04e4d4d4c,$045454749,$03f3f4147,$03a3c3d3d,$03939393a,$036363737, $036363536,$035363736,$035343435,$038383736,$0443d3a39,$090765c4f,$0727e939a,$07f7d7b74, $07d838181,$06f6f6f73,$07972716f,$08081817f,$080808081,$07f7f7f80,$080807f7f,$0787e8180, $075747271,$06d717677,$06c6b6b6b,$072706f6d,$07f7b7875,$088868582,$088888887,$0908b8988, $093979d99,$09c9b9694,$073788193,$07b6d6c6e,$06c7f9594,$06b6a6a6a,$080736f6d,$06c7d9797, $06868696a,$069696969,$067676869,$066676768,$065666767,$063636364,$05c5f6061,$04c4e5560, $038383847,$03d3b3835,$059504641,$057555156,$033394c59,$039383736,$032323638,$051574b37, $05452545b,$056534e4b,$05a49474f,$058514e54,$07f6f4e5b,$05a727f82,$04e4f4d4d,$052605255, $04d4e5454,$04d4e595a,$057565353,$0504d5759,$0524f5356,$0524e5752,$058595556,$05b4c5653, $053575055,$05e565e5a,$0564b5b59,$056594e52,$053534e55,$05055524f,$059585451,$04e4c4a51, $04d504f4d,$04746484b,$043464b45,$03d3c3e42,$03a3b3e3e,$037373939,$036363637,$037363637, $036363636,$034353536,$033323333,$0413e3a35,$052454042,$096826d60,$07586999e,$0807e7c77, $07e838281,$06f6f6f74,$07e757170,$0807f8081,$080808181,$07f7f7f80,$080807f7f,$0797f8281, $08e8c8987,$077848d8e,$078767473,$0807f7e7a,$086858482,$088888787,$089878788,$08e8b8a89, $0989b9e97,$09b9f9c98,$0686a728c,$0836f6b68,$06b779096,$06a6a6a6a,$07a716e6c,$06c7d9694, $06968696b,$06b6b6b6b,$06666686a,$067676867,$066666767,$063646465,$05c5f6161,$04b4d5662, $034353a4a,$03d3b3735,$0534b4741,$054565759,$03e38374a,$042434242,$0393e4142,$052563f30, $051535859,$056564e53,$0574b4856,$0534e4e54,$06052515c,$04d4f5e68,$0555a5853,$059575655, $049545248,$0534f5a55,$058545355,$054575856,$056535754,$05554564a,$052574a4d,$05451484f, $04d505353,$056585752,$04d4b5b56,$05253585a,$0505a5651,$0504d4e53,$051565256,$04b515450, $047464b4d,$03e414146,$03c3e3f3e,$038393b3c,$036373839,$037383736,$036363736,$038373736, $035363737,$033343434,$032303132,$0514d4739,$0584d4c50,$096817165,$07b8c9c9e,$081807f7d, $07f838281,$0706f6f75,$0807a7371,$07f7f7f81,$080808080,$07f7f7f80,$081807f7f,$07a808282, $09c9b9b9a,$089959a9c,$086858282,$085868686,$086868685,$087888787,$086868787,$081808083, $0a0a09d8f,$099a0a1a0,$0696a6e84,$08c746c6a,$06b708495,$06d6b6a6a,$08073706e,$06c758f96, $06b6a6a6a,$07474716d,$068686a6f,$067686868,$066666667,$063646565,$05d606161,$04c4a535c, $034323e4b,$03e3b3736,$04b4a4441,$04e5b5653,$046423c3a,$046474747,$041464645,$0523a333c, $055535051,$04b4c4e4c,$0564f4c4e,$0534f5754,$054515455,$0545e4d4d,$05b535555,$05655504f, $052555759,$056595753,$05354594c,$052535153,$050535857,$0585a5655,$0534c4b51,$0575a4e50, $05459504f,$0554f534e,$0595f604e,$0524e5352,$04f5f5158,$05453504e,$04d4c4e52,$0434a5045, $041434a45,$03a3b3b3f,$03839393b,$036373838,$036363737,$036373837,$034353636,$038373635, $035393838,$032343433,$0342f2f30,$055574f3b,$059515355,$0937f7165,$083939f9e,$080808182, $07e828180,$0706f6f75,$0817e7771,$0807f7f81,$080818181,$07f7f7f7f,$08181807f,$07c818282, $09c9c9d9d,$0939c9e9c,$08888888b,$086868788,$085858585,$081838485,$074787c7f,$0716d6e70, $0a0a09b87,$0949fa1a0,$069696d79,$094826f6b,$06b6f7890,$07c726b6a,$0948a8585,$06c798c98, $0726b6a6b,$094948f85,$0696a6c82,$067686868,$066666767,$063646565,$05d606163,$05466635c, $03533424b,$03e3a3636,$04f4a4642,$041535451,$04846453e,$04a47484b,$044474745,$040303c43, $0535a4e4f,$04d50524c,$052544d51,$04c545756,$05b525551,$0595b514f,$0534f4e4e,$053585652, $04f555658,$05657514e,$05c595558,$05651515d,$05a515f53,$05756555b,$055574e5a,$05758534e, $048555052,$04f53524c,$05653534d,$050575458,$04b4c4a4b,$0484b4a49,$042464946,$03c3e3e41, $03c3d3c3d,$03738393a,$037373737,$037383737,$038373838,$035343637,$034343436,$03e393333, $03d49443e,$033373b3c,$036302f30,$05d5e513b,$05853585b,$08e797064,$08998a09d,$07f808082, $07b80817f,$071706f72,$081807b73,$080808080,$080818181,$080808080,$081818180,$07d828282, $093949697,$0979d9b95,$08786888d,$085868686,$07c7f8284,$06f72767a,$068696a6c,$06e6a6867, $09b9d9881,$0939c9b99,$0696a6d79,$09890776c,$06c707689,$0867c6c6b,$098999895,$06b6f7b8d, $0856e6c6c,$09e9e9c97,$0696c7292,$068686868,$066676767,$064646666,$05e606263,$059777c62, $03435484d,$03d3a3737,$04d49433e,$03d4d6055,$048474745,$046454749,$045454644,$0353b4245, $0514f4f4e,$05456534e,$053534e52,$04f56524e,$059515651,$050505556,$04d505451,$04f5a5559, $053535351,$05a504b49,$0585b5561,$0504f5953,$054565952,$065595253,$050545457,$054555750, $04d534c4b,$054535252,$05150534b,$04d574d52,$046484c49,$043474643,$03c3d3e3f,$03a3b3c3b, $037383738,$037363737,$037363737,$037363636,$038383938,$032333537,$036373433,$04d403132, $04b56534e,$0363c4448,$036302f32,$065644f3b,$057546166,$085706c62,$08c9aa09a,$07f808082, $0757d807f,$073717070,$081817f79,$081808180,$082818181,$081818181,$082818281,$07d828282, $08c8c8c8c,$0999d978f,$08384888f,$07b7d8082,$06c6e7276,$067686869,$067676767,$06c696767, $08c99937b,$096978e83,$06b6b7285,$09c998971,$074848b93,$077706c6d,$0848b8e88,$06b6c6c75, $0836e6b6b,$09e9b948f,$0696b7796,$067686868,$066676868,$064646666,$05e5f6264,$0576e6d5c, $0363b4c4d,$03b393a39,$04b47453f,$04247524e,$048474748,$044454648,$044454543,$035414446, $0544f5043,$055535056,$054595157,$0534d5052,$0514f5855,$0544e4b52,$05253574c,$05154535b, $04d505750,$056524c4a,$052546256,$0525b504c,$0564f5852,$054595f5a,$052525c5b,$052565050, $0504d4f4a,$04e4f4b53,$04b49514b,$042454852,$040424748,$03c3e3c40,$0393a3a3a,$036373838, $037363637,$037383838,$035353536,$034333435,$03b393937,$03a363439,$04346423d,$0533f3639, $0565e5f5b,$03a414b50,$036313134,$069664d3c,$05756656b,$07d6a6760,$08b9a9f97,$080818082, $071787e7f,$076727170,$08181807d,$081818181,$083828181,$081828282,$082828281,$07e828382, $088898888,$09a9c958b,$07579818e,$06a6c6f72,$067676868,$067686768,$067676767,$06b686767, $083958d75,$094887974,$06c6d7f91,$09c9b9177,$07d8f979a,$06c6c6b71,$06e707270,$06a6b6d6d, $06f6c6b6a,$09b887773,$06a6c7a98,$068686969,$067676768,$064656667,$05e606364,$054655f59, $0343e4c4f,$03c393a38,$04b45433f,$04547504d,$048484849,$045464748,$046464544,$03c444645, $055524d41,$052525254,$056575453,$06d5a5255,$059504d51,$0524e4e54,$0504d514e,$055504f51, $0514f5e52,$0514e514d,$056565a55,$052565358,$053565c5d,$05258584f,$0584d5652,$059505058, $0575e4f5a,$046514f54,$047484a49,$04040413f,$03c3c3e40,$03737393c,$037363737,$037373737, $038373838,$035373838,$034343435,$033333334,$04d43423a,$04f493f4d,$050535251,$0553f3d46, $05b636562,$03c454d54,$036323237,$06a664c3a,$055566369,$07668655e,$08b999d91,$081818082, $070737b80,$07a747271,$081818280,$081818282,$082828181,$082828383,$082828282,$07e828282, $080828384,$0999a9084,$06b6e778c,$067676769,$067686767,$067676767,$068686767,$06a686768, $084928370,$086766f70,$06c708790,$090928b74,$0717c858b,$06b6a6a6c,$06d6c6d6c,$06c6c6e6d, $06d6d6c6d,$094786f6d,$06a6c8099,$068696a6a,$067676768,$065656766,$05d606364,$054635959, $0363f4a4c,$03d3a3936,$045403f41,$047474e4c,$048484949,$045454546,$045454645,$041444545, $056504c3f,$0525c5a57,$05a5a5254,$0645c535a,$05354534e,$0534e5154,$0514e4c4f,$052584e57, $04f59524e,$05758534e,$055585857,$052505452,$061574f53,$051565454,$05d564e4a,$052535357, $04e564d55,$042434748,$03d423d3d,$03a3b3d3d,$03738383a,$036363737,$037373737,$035353636, $038373737,$034363838,$03c393635,$0373e423f,$05a555244,$05957515a,$055575758,$05741444f, $0606b6f6a,$03f485055,$035333539,$065624a38,$055565f63,$07168655d,$0929c9b8b,$081818185, $07071777f,$07f787371,$082828281,$081818282,$082828181,$082828383,$082828282,$07e828282, $072737577,$09a998977,$06a6c778e,$066676768,$067676766,$067676867,$068686867,$069676868, $0858e7c6d,$0736d6c70,$06b6e7f7e,$07377756d,$06c6d6e70,$06c6c6b6b,$06f6e6d6d,$0706f6f6f, $06a6c7071,$08e726d6c,$06b6d889a,$069696a6a,$066676768,$065656666,$05e606263,$057645758, $035424b4d,$03b3a3935,$044413f40,$04747504c,$047474848,$045444647,$046444545,$041444445, $053544e40,$050505555,$05a524b4c,$04d535855,$051565552,$056524f55,$04c515152,$052515753, $051545854,$053494d4c,$051555b57,$058525154,$05058564f,$04f505b59,$05b534948,$0464e4a4a, $0423e4347,$03c3e413f,$03b3a393a,$03636363b,$037363737,$037373738,$036363636,$034333535, $038383634,$0343b413a,$04c49433a,$03d494e4e,$060605a46,$05a5a595d,$056575859,$059444952, $06470726d,$0414a5257,$03234383c,$0605e4c36,$055565b5d,$06d68655c,$0989e9983,$082838389, $07071777f,$0817c7471,$082828282,$082828282,$082828281,$082828283,$082828182,$07e828282, $06b6a6b6b,$09b968371,$0696c7a91,$067676768,$068686767,$068686968,$068686867,$068676868, $07e83736a,$06b696a6d,$068696d6d,$06a696969,$06c6b6b6a,$06f6f6d6d,$073727170,$0867e7773, $06c7c888b,$07f6e6d6c,$06b6f8c97,$06869696a,$066676768,$064656666,$05d616363,$05d665659, $035454d4d,$03a383635,$046433e3d,$0484c4f4c,$049474747,$045454648,$048464545,$042454545, $04e525246,$058555552,$05d5a4f52,$04d555e55,$057544e4c,$056504f58,$05553585b,$04f4d675f, $04c4d514f,$04e515453,$04c545d4e,$04e4f5350,$047525153,$04a52504e,$044464847,$040434241, $03b3d3c3e,$03838393a,$037363738,$035373636,$037363737,$036373838,$033353535,$036353433, $043423936,$03e4e5849,$0514f4b41,$0414c5152,$068675d44,$05b5b5c64,$05657585a,$05a434b53, $0626c6f6d,$0454d5557,$033363d41,$05e5e543f,$055575b5c,$06b68645b,$09b9f967c,$08383858d, $070717880,$0827f7770,$082828282,$081828282,$081818181,$082818282,$082828182,$080828282, $06a696a6b,$09a927d6f,$0696e7e94,$067676767,$069686867,$06a6a6a6a,$068696a6a,$067686868, $06f706a68,$06968696a,$068686a6a,$068686868,$06f6c6b69,$079747271,$084837f7c,$099958b86, $070859198,$0746d6c6b,$06b739191,$068696869,$066676768,$064656666,$05e626363,$06265565a, $037464c4f,$03a383634,$044433f3d,$0494e5049,$047474747,$046464646,$046464646,$043454445, $04e52554b,$056525254,$055524e54,$0524f4d54,$0514c5150,$053555554,$05851565a,$04f495750, $051515053,$04e545952,$05d5f5b50,$04f4c4c5d,$04844484f,$04249494e,$03e404345,$039393c3d, $03838383a,$036363637,$036363637,$035353536,$036353535,$035373838,$038353333,$04946423c, $05551474a,$04a5a5f59,$0504b4545,$0434f5252,$074736441,$05b5a616e,$05657595a,$059414c53, $05d666b6b,$04a505757,$038394247,$067665f4c,$055565b61,$06b69645b,$09d9f947a,$084848691, $06f717a83,$0827f7870,$081828282,$080818182,$081808080,$082818181,$082828282,$081828382, $06a69696a,$0998d786d,$06a6e8196,$068676768,$06c6a6867,$07673706e,$0696d7377,$068686868, $06b696767,$06969696b,$068686969,$06a696868,$07c746e6b,$0938c8581,$08b949896,$095938d8b, $074838b93,$0706c6c69,$06b79968c,$06869696a,$066676768,$064666666,$060626463,$06561565b, $03b484b51,$039373536,$04343413d,$04a4e4c45,$047474949,$046464746,$045454545,$048464545, $05253574e,$0534f5452,$054565452,$058515258,$0514c5251,$057575a54,$05855555a,$052515a55, $05658524c,$050595a50,$04f4e4b4e,$0494c4651,$041404241,$03e3e3f42,$039393b3e,$036373738, $037383736,$037373838,$035353637,$033343435,$037333333,$0403d3b3a,$04a453f38,$05251504e, $05f534e53,$0505e6362,$04f48464b,$0464f5252,$074756641,$05c5a616f,$057585a5c,$058444c55, $0585a6264,$04d535959,$03e3e464a,$071736c56,$056555c66,$06a69645b,$09f9f9277,$084858995, $06f727d83,$0817e756f,$082828282,$080818182,$081818180,$082818181,$082828282,$081828383, $069696969,$09788746c,$06a708597,$068686768,$077716a68,$08d89847e,$06c77888e,$06969696a, $06a696868,$06a6b6b6b,$06a6a6a6a,$06e6c6b6a,$090877570,$096959492,$087919597,$08f8e8a85, $0767d848e,$06f6c6b68,$06c819889,$068696a6b,$067676768,$065656667,$060626364,$0665e585b, $03f494c53,$039383634,$045413f3e,$04c4e4b48,$04646494a,$045454746,$044444445,$04c474745, $04d50544f,$0524f5953,$050575254,$05a52534f,$057504e53,$0545a5354,$051575152,$05959564f, $05c514e49,$0484d4e52,$04644454c,$040414043,$03a3c3c3d,$038393a3a,$036363638,$036373737, $036363536,$0363c3c37,$033343536,$031323333,$042323233,$0504c494a,$054535049,$054535454, $066535154,$04f61696b,$04c46494c,$048505252,$06f706140,$05d5a5d6a,$0595b5d5d,$0564a4c55, $05651585e,$04f555b5b,$04945494c,$06d716b5a,$0585b6267,$06c6c655c,$0a09f9175,$085858b99, $06e747f84,$0807b726e,$082818182,$081818282,$081818080,$081818181,$082828281,$081828282, $069696969,$09582716b,$06a728898,$069686768,$08e83716a,$097989794,$06c778a94,$06c6b6b6b, $06b6b6b6c,$07172706e,$071706f6f,$0817d7975,$0908f8a85,$088888c8f,$0878d8e8e,$08b898681, $0777b7e88,$06e6c6a68,$06e889984,$068696a6b,$067676869,$065666668,$05f636364,$0685b595c, $040484b58,$039373533,$042403e3d,$055504f48,$04847454e,$045454546,$045444444,$0514b4746, $04d525450,$055545152,$051535353,$04e4d5252,$05351504e,$055575259,$05352504f,$0524d5353, $045444c4b,$04643484b,$041403d41,$03a3c3b3c,$037383838,$037363738,$037363738,$036363737, $033333434,$0373a3a35,$033313336,$042383735,$04636404e,$05a5b5956,$057575451,$054545455, $072555354,$0516c787b,$04a47494a,$046505252,$06c6c5f40,$05d5a5a63,$05b5d5e5e,$05c504a52, $056535e63,$051575c5b,$0524d4c4e,$06767655c,$05c656968,$06d6e675e,$0a09e8f73,$085868d9b, $06f768185,$07e786f6d,$082818180,$081818282,$081808080,$081818181,$081818181,$081828282, $069696968,$0927d6f6a,$06a748b98,$069686768,$0998e786c,$08f95999c,$06f717d89,$07372706e, $075717273,$08989847c,$086858486,$086888a89,$0747c8184,$06861676e,$0888f9086,$08783817e, $07a828187,$06d6b696a,$07390987e,$0696a6a6c,$068686868,$065666667,$061646464,$06b59595e, $0434a4c5d,$039373336,$040413e3b,$05c504a45,$048474955,$046464647,$046464545,$059574b47, $05a565356,$053545256,$05b5c534f,$04e4b4d54,$05353504a,$053515050,$056534c4f,$044494d50, $03f3f4749,$03c3d3d3e,$03b3d393a,$035363838,$036363737,$037373737,$035363837,$034343435, $031323332,$03d3c3933,$03b363c40,$0473e3f3e,$0463a5763,$063646259,$057565456,$054545556, $072525254,$0546d7678,$04a48494a,$046515451,$05d635d47,$05e5d5a57,$05d5e5f5e,$06a594a53, $053596c74,$052585b5a,$055504e4f,$06766655e,$0636e6f69,$06e6f6961,$0a19d8c72,$08687919d, $06f788285,$07d766d6d,$081818180,$081818182,$081808081,$081818181,$081818080,$081818181, $068686868,$08e786c69,$06b778f98,$069686768,$09b91796c,$07a818e9a,$075737478,$087847e78, $085848687,$093958f87,$07d899193,$0656c767a,$04f555b61,$051494a4c,$0888b8774,$0837f7f7f, $07b7f8084,$06c6b686d,$08099977a,$0696b6a6c,$068686868,$066666767,$061646565,$067565a5e, $0444d4f60,$038363436,$0413f3d3b,$0574e4b44,$0484c5056,$046474647,$04a474646,$055535658, $05d595057,$050575056,$05253514d,$056534e52,$04d4f4f50,$04a4d4d4b,$0464b4a4c,$041414243, $03c3c3f40,$038393b3c,$035353636,$036363636,$035353636,$037363634,$034363738,$033333334, $03a313233,$04f4e4a3c,$0423d4952,$043434544,$03f3e4f51,$06f716d5c,$05857545e,$054555657, $06c4d4d53,$055697071,$04a4a4b4d,$048505853,$058615c4f,$05e5d5951,$05c5e5f5e,$06c584b55, $0515a6b76,$053585a57,$055515050,$06c6b685d,$0676f6f6d,$0706f6a64,$0a09b8870,$08588949f, $06f7a8385,$07b746c6c,$08080807f,$080818180,$081808080,$081818181,$080808080,$081808080, $068686867,$08a756b68,$06c7b9297,$069686768,$09a8e776c,$073748296,$088827d79,$09a99948e, $0848b9399,$093938b82,$05d718a94,$051535658,$049535855,$0484e594a,$088877f61,$07b797b7f, $07a787a7c,$06c6b6872,$0889c9677,$06a6a6b6d,$068686969,$066666768,$061656665,$05f555a5e, $0444d4d62,$037343338,$03e3c3a3a,$0524d4e41,$050535554,$047484749,$05c544b47,$05256555c, $053585455,$050545252,$0554f514f,$0544f5458,$04b4c4c51,$044434347,$03f41464a,$03b3a3b3d, $03837383a,$036363638,$036353635,$034353535,$033333334,$038363432,$033373838,$037373632, $049323738,$05d5d5048,$04743545d,$045444546,$03d424344,$0787c7a61,$059575464,$054565758, $0684c4551,$05561686c,$04c4d4d50,$04a4e5a54,$0646c6758,$05d5b5754,$05b5d5e5d,$061514a57, $04f596168,$053585854,$053515251,$06e6e685c,$0676b6b6d,$071716c66,$09e96816f,$08487949d, $0717d8484,$079716b6c,$0807f7f7d,$081818180,$080808080,$081818181,$080808080,$081808080, $068686766,$087726b68,$06e809496,$069686869,$0998a746b,$075728195,$0928d8a83,$09f9f9d97, $0858c959c,$093918a83,$050638593,$05a646256,$05571786d,$0465b6a4f,$088877d59,$072737680, $077747772,$06b6b6774,$0909d9173,$069686a71,$068686969,$066666768,$062636365,$058565a5d, $045484154,$03736333b,$03e3d3b3a,$0534d4741,$055565655,$04f4f4d4f,$053575553,$05452534d, $053525356,$04f545157,$04a4b4e51,$0474a4d4a,$044454444,$03d3e4044,$0383a3b3b,$035363838, $035363536,$036363535,$035353637,$032333434,$032313334,$03d373131,$03c4c413d,$03e403f3a, $04a363a3c,$067624d4d,$047475f67,$044454748,$03b414545,$073767860,$05a575463,$05657595a, $0604f4450,$057555861,$04e4f4e54,$04b515b54,$068777560,$05c5a5555,$05b5c5c5c,$0594d4c57, $0505a5f60,$053575652,$055525251,$06e6f6a5f,$067686a6d,$074726d67,$0968b7670,$085868f97, $0737f8685,$0766e6b6c,$080807f7d,$080818180,$0807f7f80,$081808181,$080808080,$081808080, $068686665,$083706a68,$070859795,$06968686a,$09685716c,$076728296,$0928c8781,$09d9e9c98, $0858d959a,$0908d8680,$04d63858f,$069766f5e,$063797978,$045616a4f,$089857953,$06a6e7382, $07672706b,$06c6a6776,$0969d8d70,$068696a75,$068686868,$065666768,$061636364,$04f565a5e, $04642313d,$03835333d,$03e3e3a39,$0514d4541,$054565756,$055585351,$0514f4f53,$0594f4f54, $04c515254,$0464e524a,$04746434a,$042444443,$03e3d3e3d,$039383a3b,$036373838,$035363537, $034343435,$035343333,$035373736,$032323233,$032323233,$051413534,$04659514f,$042444441, $03c3c3e40,$075694b44,$0484c6b75,$046474949,$036414545,$06c71725c,$05b59555c,$0575a5b5b, $06052484a,$05a525661,$04f515057,$049535a52,$0626c6c5c,$05a585255,$0595b5b5a,$0564a4e56, $0525e625f,$054565550,$056525251,$06d6d6c64,$063676b6d,$076736d66,$082776d71,$088888888, $078838888,$0726a6a6d,$0807f7e7b,$080808080,$0807f7e7e,$080808080,$08080807f,$081808080, $069686665,$07e6f6a69,$073899792,$06968696a,$094806f6b,$072728597,$0908b857e,$096979694, $0858b9195,$08e8a827f,$04865858e,$069725a4c,$06a746f72,$04663674e,$08885754d,$066697482, $0746a6866,$06c686a7a,$09a9c896f,$068686a7d,$068676768,$065666767,$062636465,$050575b5f, $0483f2d40,$03934333d,$03f3c3b3a,$050484541,$052545456,$0554f5351,$04f535150,$04c4c504e, $049515454,$041444547,$03e3d4042,$03a45403d,$03a393a3a,$035363737,$035343434,$034353536, $031323334,$033323232,$039383736,$035343134,$034373636,$05842473b,$04f60605e,$043454543, $03e3f3f40,$07b70483f,$04a52737b,$0484a4b4b,$037424747,$05f686b59,$05c5a5757,$0555b5d5d, $06f624e44,$059526472,$050515058,$047545850,$060646354,$058565057,$0595a5959,$054484f56, $055616461,$05557544e,$059535251,$0706f6e68,$05f666f70,$078746e65,$0716c6b72,$08a88867e, $082888b8a,$06e696b75,$07f7e7c77,$07f7f7f7f,$0807f7e7e,$07f7f7f80,$07f7f7f7f,$080807f7f, $069696867,$0796d6a69,$0768c978e,$06969696b,$0937d6f6b,$071768c99,$08d89847b,$08f8f8f8e, $083868a8e,$08d887f7f,$0486a868d,$05f705f48,$06e70706c,$04966614e,$08685724a,$064677383, $06e626162,$06b686f7c,$09c9b836f,$067686c86,$066676767,$065666767,$062646565,$051585c61, $0493b3043,$03834353f,$0403c3a39,$04f474445,$050535455,$0504e4d52,$04b514d4e,$046474e4a, $044444248,$03d3f4044,$0393b3b3d,$0383b3838,$036363637,$034353535,$036353535,$033343436, $031313132,$0312f3030,$0483f3e3c,$03d3e3947,$0373b3c3e,$0583f4d41,$05a696565,$044464745, $03f404142,$074693e3a,$04a546f74,$04b4d4c4c,$04343494a,$0515b5f54,$05c5a5753,$0565c5e5e, $079684f45,$057516276,$04f4f5158,$04854564f,$06364614f,$058544f5c,$058585958,$053475157, $058636562,$05657534e,$059535252,$0746e6964,$0656b7375,$079766f69,$06e6a6b73,$08c89867d, $0888c8d8d,$06b686d7c,$07f7e7b74,$07f7f7f7f,$07f7f7f7f,$07f7f7f7f,$07e7e7f7f,$0807f7f7e, $06a6a6869,$0746c6a69,$0788e9588,$06969696c,$0917a6e6b,$0727c919a,$08987837a,$0888b8a89, $07d7f8285,$08c877e7d,$04c70878d,$053676b50,$0706b7165,$0546b5850,$086836a48,$061687785, $06c60615f,$06a68717b,$09d987c6d,$068696e8b,$067676868,$066676767,$064656666,$0545a5e62, $04a363448,$037343743,$03f3c3a39,$04c484442,$04c53544f,$04b494c4a,$04848484b,$047424347, $03d3c3d49,$039393a3e,$036373737,$035353636,$035343435,$033333434,$037373534,$033333437, $031313132,$0312f302f,$058505049,$042423e55,$03c3e4142,$05944413d,$068757370,$046484846, $03f414244,$0756a3b39,$04c506772,$04f4f4e4e,$04b3f484e,$0515d615a,$05c5b5751,$0575b5d5d, $0685f4a49,$0524f5c66,$0514f5258,$04a54544f,$06668604d,$057525160,$058585858,$051495257, $05a626762,$05555514f,$055525152,$07970635c,$06c737e7e,$07a77716d,$06f686971,$08f8c877f, $0888d8f90,$06866707f,$07f7e7b73,$07f7f7f7f,$07f80807f,$08080807f,$07e7e7f80,$080807f7e, $06a6b6b6d,$0706b6969,$07c919381,$06b6a6a6e,$08e79706d,$07b85979a,$084848380,$082888785, $0787b7f80,$08d857c79,$05175888d,$0545e6c55,$07173735d,$057644f50,$089836648,$0646a7888, $06e666662,$06a677679,$09c93756d,$0696b7190,$067686868,$067676767,$066686967,$0565c6163, $04a32394c,$037333a45,$0413c3b3a,$04746433f,$04a4c4a4b,$044464946,$041414141,$03c3e3d3f, $037383a3a,$036363737,$035363535,$035363536,$033333434,$031323232,$03a383532,$034353b3a, $036373837,$040353033,$062605c49,$04345445a,$03f3f4143,$05a3f3d3f,$069757776,$0494a4948, $041434546,$06c654338,$04e4e5763,$05251504f,$0563d4750,$0576d756c,$05b59564e,$057595b5c, $0635b464c,$04f505c62,$053515357,$04b545251,$068695f49,$055505362,$057585858,$0504a5357, $05f646964,$055545053,$055535152,$080746659,$06f7a8889,$07878716e,$07067666e,$08f8e8a81, $0888d8f8f,$06a667381,$07f7f7d76,$080807f7f,$07f808080,$080808080,$07e7e7f80,$080807f7f, $06a6e7075,$06e6a6a69,$08293907c,$0706d6c70,$08e7e7673,$089919c9b,$081828588,$07e818181, $075777c7d,$08c847b77,$0567a898d,$0646b6a51,$063716957,$0474a4447,$087806547,$06d6d7987, $06f6d706d,$06a687a77,$09d8d716d,$06a6b7795,$067686869,$069696767,$06f766c6a,$0585e646a, $047303c4e,$036323c46,$03d3b3b39,$04342413e,$042454345,$03d3d4143,$0383a3c3c,$036383838, $035353636,$035363534,$037373535,$034353637,$031313233,$0302c2b31,$0484d3c29,$03d434c47, $03a3d3f3f,$03b393639,$069686043,$045464a63,$03f414244,$054363c3e,$0656f7071,$04b4b4b4a, $04347494a,$0605e503f,$04f4a4854,$05252514f,$0543f4a51,$0576b776a,$05a58534d,$057595b5b, $06256444f,$04d576264,$054515455,$04e545152,$067685c48,$0554f5763,$057585757,$0514c5456, $07077756b,$05453525d,$058555152,$08875655c,$06e798b90,$07878726f,$07165656e,$08c8d8a82, $0898c8d8d,$06d677584,$0807f7d78,$080808080,$07f808080,$07f808080,$07f7f7f7f,$080808080, $06d747c83,$06c69696a,$087948d78,$07e777175,$091898481,$08b959d9b,$07f818386,$07a797a7c, $06f707377,$08b817874,$05d7e898c,$057615a4b,$0474e4b48,$045434141,$0867b6049,$06d6a7a88, $077787370,$069687679,$09d89706d,$06a6c7d99,$068686969,$06b6b6968,$09097836d,$05a6a7a81, $047304251,$036343f4b,$0383a3b38,$03f3d3c3b,$03c3d3e40,$0393a3b3b,$036363738,$035363636, $034353636,$033333333,$037353233,$034353637,$033323133,$03f484933,$058574c4a,$041485a59, $03e414143,$03c393b3c,$075756544,$04745516f,$041424546,$054303d3f,$05d6c7070,$04c4c4b4a, $03f484c4d,$068675b44,$04e4a4c61,$052525150,$04d414c51,$05861645c,$05957524d,$057595a5a, $062514350,$04d5d6769,$054505452,$050545053,$065665947,$0534e5962,$057565656,$0554e5456, $0818d8471,$053535a6a,$05d595152,$08371615f,$06f758188,$079787471,$06c636470,$08b8b887e, $08a8b8b8b,$06e667485,$081807d78,$080808081,$080808080,$07f808080,$07f7f7f7f,$081807f80, $073818d93,$06b696a6c,$08d948773,$08882797c,$08f8a8888,$08c989e9a,$07c7e8085,$076737377, $0686a7074,$0867b716a,$06381878a,$044454649,$04b484644,$0605c5750,$086837769,$066667581, $06f6b6868,$06b69686b,$09d86716e,$06b6c849c,$06a69696a,$07c746d6b,$09fa09a88,$05e85979d, $040344654,$03536414d,$038393a37,$03938393a,$037383a3b,$035363738,$035363535,$035363635, $034333535,$031313133,$038323031,$04046433c,$03d3c3a37,$03e535139,$05c555654,$043516262, $03f424344,$03c3b3c3d,$072746645,$04845536e,$043454748,$053353e42,$04e586465,$04d4d4c4a, $03d484c4d,$071756647,$04e494e66,$052525150,$049444e51,$05b5e5f59,$05856504f,$058595a59, $05f4b4452,$04f606868,$052515450,$052535155,$065665648,$052516064,$056565655,$05c505356, $081918a78,$05356646f,$0615b5253,$07c746461,$07070757a,$07b797875,$066616573,$08b8b8578, $08c8e8d8c,$06d646f83,$0817f7d77,$080808081,$080808080,$080808080,$07f7e7e7f,$080807f80, $07a8e999e,$06b6a6a6d,$093938170,$087878384,$08c888686,$08c989d97,$075777a81,$06f6d6c71, $062676b6f,$08071665e,$0687f8586,$0524d4c50,$06b65615a,$07c7b7873,$0787d7d7c,$065696e71, $06864625f,$0716e6c6a,$09e917d76,$06b6e899d,$06b6a696a,$09b968b79,$0a1a3a29f,$05c79909c, $0383a4b55,$036384349,$0373c3a37,$035363836,$034363636,$035353535,$035353535,$036373736, $032333434,$031303132,$049303131,$052565a58,$041424443,$0333a3b3f,$061555848,$0435c6c6b, $040434445,$0373b3c3d,$06e6e6436,$04846526a,$047474949,$056443e45,$044505e5f,$04d4c4c4a, $03e494d4e,$06a6b6044,$04d475062,$052525150,$046464f50,$05f616158,$057554e51,$058595958, $05d484753,$052626869,$05251544f,$052525355,$0786e564a,$0525c777e,$055555554,$05d505354, $077848073,$05359696e,$0635b5253,$07b776c66,$075737478,$07d7b7b7a,$060616877,$08f8c8370, $08c919090,$06c636a7d,$0807e7c76,$080808080,$080808180,$080808080,$07e7e7f7f,$07f7f7f7f, $080949ea2,$06b6a6b70,$097927d6e,$086888a8f,$088858585,$087979b92,$071717177,$06967686d, $0656d6c6b,$07b6b5e5c,$078838684,$0706b666a,$079797875,$074777879,$06164686d,$070716f69, $06b6b6a68,$08d7e6f6d,$09f9e9994,$06c6e8b9c,$06e6a6a6a,$0a19f9b8b,$0a0a3a3a2,$05c63708f, $037404e56,$0353a484c,$036393836,$035353433,$034353636,$033343434,$033323333,$036373736, $032323335,$039373433,$04e30343a,$0595a585e,$044444647,$03b3c3f42,$071574c3a,$045657576, $042444546,$0383c3d3f,$06a6c6235,$048475060,$0474a4b4a,$0694e3943,$0435d6f70,$04e4c4c49, $0434a4d4e,$068645a40,$04d465565,$05352514f,$043495052,$061656455,$056544c54,$057585958, $05b474a55,$056636769,$05152544e,$052515457,$08c76584c,$057678091,$054545453,$057515353, $06f777064,$0525c6869,$0655b5352,$07e7a716a,$07e7c7c7e,$07e7c7e80,$05f616a79,$08f8a7f6a, $088909090,$069626678,$07f7e7a75,$081818080,$07f808181,$080808080,$07e7e7f7f,$07e7f7e7e, $085979fa2,$06a6a6c72,$099907a6e,$085878c95,$07c7a7c81,$08798988b,$06f706c70,$06765666a, $06874726a,$075675f5d,$081868582,$07274767a,$065696d70,$05d5f6062,$05658595a,$0776f645d, $06c6c6b6d,$09b92796e,$09b9d9e9d,$06b6d8294,$06c6a6a6a,$0a09c9680,$09ea2a2a2,$05d646784, $037444f57,$0343f4f4c,$0363c3835,$036363433,$033353636,$032323233,$031303131,$03d3d3c36, $039393a41,$0403d3837,$04b34383f,$05f625f5d,$04546464b,$03d3d3f43,$072573c3a,$047657073, $045454647,$0373d3f41,$05b615941,$04948474e,$0474a4b4a,$073543843,$0445e747b,$04e4d4b47, $0464a4c4e,$0645e553f,$04c475762,$05452524f,$0424c5153,$062646151,$056534c58,$058585958, $05e464e56,$05f6a6c6e,$05153534f,$052525757,$08b755b50,$0606d768a,$054535354,$057515353, $070766c63,$052606b6c,$0675a5352,$0857e736d,$087878687,$07e7d8084,$060626e7c,$08c877a66, $0878d8e8d,$067626778,$07f7d7971,$081818180,$07f808181,$08080807f,$07e7f7f7f,$07e7e7d7d, $086969da0,$069686a72,$0998d776c,$082878d97,$0726e7079,$08a989583,$06f706b71,$0696b6b6a, $0656e716e,$06b5f5c60,$070787a78,$05e616569,$058595b5c,$058585858,$052555757,$07b726256, $06c6b6a6f,$09794826e,$0848c9397,$06a6c7178,$06a6a6969,$09285796d,$09da0a09c,$05d636785, $039475158,$035445449,$0363a3634,$037373534,$034353636,$031313133,$0322f2f30,$04d52523a, $043434951,$0413d3c41,$048363a41,$069716b64,$04647474e,$03c3d3f44,$06d50323b,$046616c6d, $046474747,$03d3e4244,$059625c4f,$04947434a,$047494a4a,$0654e3a44,$0485d656a,$04e4d4b45, $0474b4d4e,$0665f513e,$04a495e68,$055535250,$0434f5254,$061655f4d,$055514e5c,$058585958, $061475056,$07186867a,$051525256,$052545d5a,$076655651,$0666d727c,$054535256,$055505253, $073756861,$055656e6f,$067585352,$08780746f,$08a8a8a89,$07f818487,$06165727d,$08a837465, $0858a8b8b,$064626979,$0807d786e,$083838481,$080808183,$080807f7f,$07d7e8080,$07e7e7e7e, $08190979a,$06766676f,$09889756a,$07d868d98,$06f6c6c71,$08c98927d,$073716a73,$070737573, $06b6e7171,$0685d5864,$05d63686b,$059595a5a,$057575859,$058585757,$053555758,$07f776556, $06b6a6a74,$07f7d746c,$06e71767c,$0696b6d6e,$068696969,$0736d6b69,$099999384,$05e626581, $03d4c545a,$036454c40,$033353433,$036363533,$034363736,$030323333,$0332c2b2d,$05b5a563d, $04a49515c,$0413f3f49,$041353c41,$06f747569,$046474654,$03d3e4245,$06850303b,$048596268, $047484847,$0403c4344,$06a716e5f,$048474252,$0484a4a49,$061493d45,$04d616566,$04d4c4944, $0474b4d4e,$068624d3e,$0494c626a,$055545350,$045505355,$061655e48,$0554f515f,$057575757, $0644c5054,$076909582,$052525563,$05259625d,$06f635a51,$0686a6d75,$05352515a,$053505253, $07272655e,$058686e6e,$066585452,$0867f7570,$08b8b8a89,$08185888a,$06367757f,$08e877465, $08386878a,$063636a79,$0827e776c,$088878786,$080828487,$080807f7f,$07e7e8080,$0807f7e7e, $07a868d90,$06667686e,$0998b776b,$074838f9a,$06c6b6a6b,$08e978c76,$0736d6975,$072737676, $0666d7171,$05b59565e,$058595a5b,$058575858,$056565758,$057575756,$055565758,$0817a6a58, $06b6a6b79,$06e6d6c6b,$06d6d6e6e,$0696d6e6e,$067686969,$06c6b6967,$0817d726d,$061626571, $0414e565c,$03a474d3d,$031333433,$0413b3331,$03b4d4f43,$033373a3b,$02d2b2a2d,$066605935, $04b4d5a66,$042424147,$037363d41,$06c707365,$047474655,$03f414446,$05c4f393c,$04446505d, $047484847,$0413d4445,$068757460,$048464254,$0484a4a49,$05c433f45,$052626361,$04d4b4843, $0484c4d4e,$069624841,$04953696c,$055545250,$048515355,$06a6d6247,$0534e5969,$055555655, $063515153,$07182897a,$053525a6b,$0535f655d,$070645b52,$06d6e6d74,$05251525f,$050505353, $06f70645b,$05f6c6c6a,$066585553,$087807771,$08b8a8a89,$083898b8a,$0656b7981,$097927b68, $08182858e,$063646d7b,$08681786a,$089888888,$082858889,$080808080,$07f7f8080,$08181807f, $0747c8082,$06466696d,$0998e7c6c,$06d7d8f9a,$06c6a6a6a,$090948472,$070696979,$0696b6e71, $060636667,$05757585b,$058585757,$058585858,$057575758,$058585858,$059585859,$0837e705c, $06b6b6c7d,$06f6c6b6b,$07a767371,$06c747e7e,$068686869,$06a6a6968,$0696b6b6a,$061636568, $04550585e,$0393e443c,$030313437,$0514b3431,$04556554e,$03a3f4243,$02f2c2d31,$071685533, $044456272,$042454745,$033373e41,$0676c6e5f,$047474550,$042434647,$06054453c,$04442515d, $048484747,$03f3f4445,$062645f56,$048444359,$048494949,$05b404146,$057676965,$04d4c4743, $04a4d4e4e,$0655d4644,$0495a6b6a,$05554524e,$04a525455,$086806d4a,$05052677d,$054545453, $05b4f5053,$06b757769,$05253606b,$05665685c,$073635952,$07173757a,$052525465,$050515453, $073766b5b,$066706c6c,$0665a5757,$088827972,$089878889,$084898c8b,$06a6f7c82,$09b998771, $081828592,$06366707d,$087847969,$085848486,$084878987,$080808081,$080808080,$081808080, $06a6f7274,$05f5f6366,$0988d7e6a,$06b788e9a,$06a696a6a,$093917d6e,$068686c80,$065666767, $065676665,$058595d61,$058585858,$058585858,$058585858,$05c5b5a59,$05d5b5b5c,$083817661, $06b6b6e7f,$07d6f6c6a,$098949089,$0708a9899,$06768696b,$06a696968,$06a6b6b6a,$063656668, $049525a5e,$0393b3c3e,$02d2f3236,$0594f342e,$04b5a5654,$042454747,$03735363b,$076725636, $0494b6977,$043464849,$039383e41,$05a63665d,$04747464b,$041444647,$0736d4e39,$043405b6d, $047484747,$03d414446,$064615c51,$04743465d,$0484a4a49,$0553d4347,$05b686a65,$04d4c4745, $04b4d4f4e,$0695b4447,$04b626b6c,$05352514d,$04b505353,$08c897051,$0505d6b76,$054535351, $05f505053,$06c787868,$05255666c,$0596a6a5b,$077655552,$076797a7c,$053525669,$051535454, $078796f5b,$069727070,$0655c5a5a,$087817a73,$086858688,$083858787,$074747e82,$09e9e9787, $081828694,$06367737e,$086847a6a,$0817f7f82,$086888683,$07f808082,$07f7f7f7f,$07f7f7f7f, $05e616365,$05a595a5b,$0968a7c67,$06d7b919a,$06a68696a,$0968e786d,$06c6e758a,$0686a6d6c, $065676767,$0595c6063,$058585858,$05a595959,$05b5b5a5a,$05f5e5d5c,$061606060,$082817864, $06c6b7281,$08f746e6c,$09e9d9c9a,$076949d9e,$068696a6c,$0736b6a69,$06e747f7c,$07767686a, $04f55647d,$040434346,$02e30353b,$06050362e,$04f626363,$042434547,$03c3c3d3f,$0746f4e3d, $0484b656f,$045474748,$0493b4043,$04a576059,$047474643,$042444748,$0756b4c39,$042435c6e, $048484846,$03b424446,$064615c4e,$047434960,$0494a4a49,$04e3d4547,$061676961,$04d4b464c, $04b4e4e4e,$0745c4148,$0526b7677,$05252504d,$04c4f5152,$07b766852,$05364696e,$053535251, $05f505053,$0717d7967,$052596b70,$05f6e6b5a,$077635353,$0787b7b7e,$054545c6f,$053565756, $076756c5a,$0626b6e71,$0655d5b59,$0837f7b74,$083828384,$083838383,$0877b8082,$09fa09f97, $081828695,$06469767f,$083837c6b,$07f7c7b7e,$087888481,$07f7f8083,$07e7f7f7f,$07e7e7e7e, $057585a5b,$057555656,$094887762,$06f82959a,$06868696a,$0988b746b,$0797a8594,$06b72797a, $065676868,$05b5e6264,$05a5a5959,$05d5c5c5b,$05e5e5d5d,$06362605f,$064646464,$082817767, $06c6b7581,$08a726e6c,$092939495,$07a989d98,$0696a6a6c,$08e786c69,$08d949998,$0866b6c7b, $051567493,$04648494c,$032343940,$065483732,$04e676e6f,$046464644,$03f3f3f43,$0706e4e3c, $048495e6c,$046484848,$0533f3f44,$0505d635c,$048474543,$043454748,$05f58443b,$03f4a5d60, $048484845,$03c434547,$069665f4a,$047434f63,$049494a49,$0473f4647,$06365675a,$04d494550, $04b4d4d4d,$07f5b4349,$0626e7d83,$052514e4f,$04d4e5152,$074675c51,$05967666b,$053535351, $05c505153,$075807a65,$0535f7072,$066736b59,$076625356,$0797c7e7f,$058566477,$057595a59, $067686157,$05c5e6062,$066605f5d,$07f7e7c74,$087868381,$084868789,$08f7d7b80,$09c9f9e9a, $082828592,$0656c7981,$083837b6c,$0817f7c7e,$0898a8581,$07e7f8084,$07d7e7e7e,$07d7e7e7d, $054555657,$055545555,$09084715d,$070869699,$066666769,$097867068,$08f90959a,$06f808d90, $065676769,$05d606264,$05d5c5c5c,$05f5f5e5d,$06060605f,$065636261,$066666666,$082807368, $06c6d7981,$0766e6d6b,$07475777a,$080979580,$06868696c,$099907469,$09a999495,$08f7b8695, $052597d97,$04a4c4e51,$03a3b4145,$068483d3b,$054697172,$047484a49,$03e404245,$06768543a, $04848515f,$045474848,$05f3f3d44,$054717870,$04746433e,$042454747,$05d543e3d,$03e4f5f5f, $047474745,$03e444547,$069675f45,$046435466,$04a4a4a48,$043404547,$06567675a,$04b484556, $04c4d4c4b,$07c604848,$06c6c737d,$052504c58,$04d505252,$073646052,$05d696c6f,$053525250, $0574f5253,$074807c66,$055657170,$06b736959,$07763555b,$07d808481,$05a586579,$05b5b5b5a, $05e5c5b59,$061605e5e,$06c666362,$08181817a,$089888784,$082888a8a,$083706c76,$090949490, $08181838a,$0656e7b80,$084827868,$089888482,$0898d8b89,$07d7d7f83,$07d7d7d7d,$07d7c7d7d, $052525354,$053525252,$0887b6a58,$06f859494,$064646567,$0917e6c66,$094969797,$06c7f8d92, $064656667,$05e606162,$05e5e5d5d,$0605f5f5f,$061616060,$064636362,$066666665,$0807d6f69, $06b6d7b81,$06d6c6d6c,$06c6a6a6b,$08494866f,$06666676b,$091937868,$08e83767b,$099959592, $0525d8397,$0494c4f4f,$041424447,$063484141,$051626c70,$047474746,$03e424446,$05b5a4f40, $04643424c,$045464747,$05a3d3e43,$05465726d,$04645423e,$042444646,$05a523b3e,$040535d5c, $046464643,$03f434546,$068665b41,$045445966,$048494847,$042414547,$0706c6c63,$049464862, $04a4b4a4a,$064554b48,$069666e74,$0504f4d5e,$04d505151,$0725f5e50,$0626c6f73,$052525051, $0544e5152,$0747c796a,$0586b7370,$070736658,$0715e565e,$070767d7a,$05a585b68,$05b5c5c5b, $0605f5f5e,$066646261,$0897d726b,$081878f8f,$08c8a8885,$0828a8d8e,$06a626271,$07e7b7b75, $07e7e7e7f,$0636f7b7e,$0847f7264,$094918c86,$0878e9294,$07a7a7b80,$07a7a7a7b,$07a7a7a7a, $051515152,$051515151,$07c6d6054,$06f85908d,$062626365,$085736763,$0888c8e8c,$067727e84, $062636365,$05f606161,$0605f5f5f,$060606060,$06161605f,$064636262,$066656665,$07e796c69, $06c707e80,$07372706d,$06766666e,$087907b69,$06565666c,$088907566,$06e69696d,$095918275, $054628894,$04b4b4c51,$04346484a,$05e474142,$04c5c6667,$046474646,$03e424346,$060615845, $045414056,$044464645,$0503a3f42,$0555c5c59,$04644403f,$041454646,$05b4d383f,$042576161, $046464541,$03f434646,$06260553d,$042465d63,$048484645,$042424446,$07c7b7463,$04746556d, $04a4b4a49,$05f534949,$067697270,$04f4e5163,$04d4f5050,$071575a4d,$0666e6f75,$051514f53, $0524e5050,$07277756a,$05c70706e,$073726357,$060555763,$05b5e6363,$05b5a595a,$05d5d5c5c, $06966625f,$0827b756f,$095928c87,$07c899496,$08e8c8882,$0858c8f90,$05f5e6477,$072686361, $07b7a7978,$0626e787b,$082796960,$095938c87,$0838a9194,$07878797d,$077787879,$078787877, $0504f4f50,$050505050,$071625751,$06e848d85,$060606163,$072686161,$071757877,$064666b6e, $061626263,$060606060,$0605f5f60,$060605f60,$0605f5f5f,$063626261,$067666564,$0857b6d69, $0767b8689,$08588867f,$06463677b,$08a8b7266,$062636472,$08b8b7164,$063636574,$08b7b6863, $05565868e,$04c4d4e51,$044474a4b,$059463f42,$0464e595e,$046464645,$03d414245,$06d706249, $04340415c,$044454544,$04b393f41,$0595d5b58,$045433f43,$041444645,$0594a3840,$043575e60, $04545443f,$040434546,$0665f503a,$0414a6066,$047474644,$049414346,$06e74715f,$0464a6169, $04a4b4a49,$05f544749,$0686b7169,$04f4c5464,$04d4f504f,$07059594d,$0666c6e76,$051514f56, $0504f5051,$06e727166,$05c706e6b,$074705f56,$059585966,$05d5d5c5a,$05d5d5d5d,$068635f5e, $085817a70,$0908f8d89,$092929292,$074808d90,$08a89857e,$084898b8a,$05c5d677a,$07168605c, $077777674,$0606c7678,$07e72625d,$08e8b8784,$07e84898d,$07676777a,$076767776,$076767676, $04e4e4e4e,$04f4f4f4f,$06a5c534f,$070848a7f,$05e5e5f62,$063605e5e,$066666666,$064656767, $05f606162,$060606060,$0605f6060,$05f5f5f60,$05f5f5f5f,$062616160,$06c6a6865,$08e887b70, $07f7f878d,$0848a8984,$062606b7b,$08a856c64,$061616478,$08c846962,$061616c84,$070636060, $0545d727b,$04b4c4e50,$045474a4b,$0554b4143,$041465259,$044454544,$03c414244,$063675a46, $0423e4557,$043444444,$047383f40,$05c5c5b59,$043423d48,$041444544,$05744393f,$047595d5e, $04544433e,$03f434445,$070684d3b,$043546c74,$046464543,$046414346,$067675d57,$046506363, $04a4a4a49,$05e544648,$06c6b6f65,$04e4c5969,$04e504f4e,$0705e564b,$068686b74,$051514f5d, $04e505152,$0676c6c5e,$0565d6163,$0746c5c57,$05e5d5c69,$060615e5e,$068646260,$0847e776f, $08f8e8d89,$08c8e8f8f,$08184878a,$06b6c797e,$08383817a,$080838583,$05a5c6878,$0726c625b, $075757473,$05e697375,$0776b5f5b,$08483827e,$0797d8183,$074747476,$074757574,$074747474, $04d4d4d4d,$04e4e4d4d,$06358504e,$070828476,$05b5c5d61,$05e5d5c5b,$069676462,$06d6f6f6c, $05e5f6066,$05f5f5f5e,$05f5f5f5f,$05f5f6060,$05f5e5e5e,$06462605f,$07e7b766d,$08c8c8881, $078787f88,$07a7e7c77,$0605e6a73,$0897f6762,$05f60637a,$082726260,$05e607382,$05e5d5d5d, $053575a5e,$04a4b4c50,$045464849,$05e54464a,$03e4f5f60,$044444443,$03b3f4143,$05b585140, $03f3c4956,$043434343,$042393f40,$05b5d5c56,$0433f3c4c,$041444443,$0533f3a3f,$04d5b5a57, $04443413e,$041434344,$07a6c4f3d,$04d606b75,$046454441,$046424546,$066645a57,$04759605d, $04b4b4a49,$05d504649,$06b6e7062,$04e4c5e68,$04f504f4f,$06f5f504b,$069646870,$051515063, $04f525352,$056575852,$058565555,$073695b59,$0635f5e6c,$077736d67,$0827f7b79,$08b8b8986, $087898b8b,$0757b8083,$063676b70,$0635b5f61,$07e7d7b74,$07b7d7e7e,$0595a6575,$0706f665c, $073737271,$05b646f73,$071675d5a,$07c7c7b78,$07476797b,$072727273,$073737272,$072727272, $04c4c4c4c,$04c4c4c4c,$05e544e4c,$072807f6f,$05a5b5d61,$05f5b5a5a,$079746d65,$07a7e7f7d, $05e5f616e,$05e5e5e5d,$0605f5e5e,$05f5f6161,$0605f5f5f,$06e686462,$08483827a,$085878785, $06f727982,$06b6c6969,$05e5d686b,$086776360,$05d5f667e,$066615f5e,$05c5d6269,$05b5b5b5b, $05155585a,$04a4a4b4f,$044454748,$068584547,$03d50646b,$043434341,$03c3f4142,$058534c3c, $03e3b4c55,$042424242,$03d3b3f3f,$05a5d5c53,$0423e3d4f,$041434343,$0533c3c3f,$0535e5d5c, $042423f41,$03f424343,$0716a5443,$056656270,$046454443,$048424546,$0665f595b,$0495d615f, $04a4a4a48,$05a4c4749,$0686d6d5f,$04d4f6266,$04f4f4f4e,$06f634d4c,$06864666c,$052515061, $052535353,$056555353,$05b5a5857,$072675c5b,$07c776f70,$089888581,$088888888,$080838687, $06e75797c,$05b5e6267,$05858595a,$05a565758,$07978756b,$075777979,$059585f6d,$06e6d6960, $07071716f,$0585d676f,$06e685f5a,$075757371,$071727274,$071707070,$071717071,$070707071, $04a4a4a4a,$04b4b4a4a,$059504c4b,$0747f7a68,$0595a5c62,$0625c5a59,$082817c70,$0767d8182, $05e5e606a,$05f5f5f5e,$06361605e,$063646766,$06e6b6866,$07b787572,$07a7c7d7d,$081817c79, $0696e777c,$0605f5b60,$05b5d6867,$08371605d,$05c5e6a80,$05c5c5c5c,$05b5c5d5c,$05b5a5a5b, $051545b5c,$048494b4e,$044444647,$05e514242,$03d4e5860,$04242423f,$03c3f4042,$054504939, $03d3d4e54,$042424240,$03a3b3e3f,$05a5a5a50,$0403d3e52,$041424242,$0563a3c3e,$05d636564, $042413f48,$03f424242,$060584d42,$059605e67,$046464346,$044444646,$068615a56,$04d60605f, $04a4a4a48,$05849474a,$0656a6b5f,$04d536265,$04f50504f,$0675e4c4d,$0585b6065,$052525053, $055545453,$058565656,$0635e5a58,$07c77716a,$08787847f,$086878887,$0797d8084,$064696f74, $0585c5e60,$055555657,$054555555,$054545454,$073726d60,$06d717373,$05b565863,$06d6c6a64, $06d6e6e6e,$058585f69,$06c69625b,$0706f6e6d,$06f6f6e6f,$06f6f6e6e,$06f6f6f6f,$06d6d6e6e, $048494949,$04a4a4a49,$0554d4a4a,$0767d7663,$059595b64,$0645b5958,$07f828076,$0686e747a, $0605f5f61,$064646462,$0706b6664,$072737676,$077777674,$070737577,$05c61666b,$07b76645b, $0666c7479,$05955555e,$0585c6764,$07e6a5d5b,$05b5d6f7f,$05b59595a,$06868625c,$0625b5c62, $050577073,$047484b4d,$043434446,$0544d4141,$03e4f5657,$04141403d,$03b3e4041,$0554f4537, $03c3f5055,$04141413f,$0393b3e3f,$05955544b,$03f3c4254,$03f414141,$0543f3c3d,$0606e7265, $043414355,$041434343,$05a584d3f,$05b5b5e65,$04646424a,$043444646,$068615952,$052605f5f, $04a4a4a47,$05647474a,$062686a63,$04d586561,$050515150,$0514e4c4e,$0504f4f50,$054535352, $055555454,$0615c5857,$07c766e66,$084848380,$083848585,$0747a7e81,$05d61666d,$05556575a, $054555555,$053535354,$052535353,$052525252,$06b685f55,$060666a6c,$05f575557,$06c6a6966, $0696c6c6c,$058565961,$06a68655e,$06c6c6c6b,$06c6c6c6c,$06c6c6c6c,$06c6c6c6c,$06a6a6a6b, $048484848,$049494848,$0524a4848,$0777b715f,$057595b66,$0625a5857,$0767e7e74,$06262636a, $06b666362,$071727270,$0726e6e6f,$075777878,$0676a6e71,$054595d63,$04546484d,$072675046, $0656b7274,$05552565f,$0565d655f,$07a655b59,$0595c717e,$05a585858,$07c7b7664,$075656978, $05057727b,$046484a4d,$042424446,$0524b3f41,$03f4f5455,$041413f3c,$03c3e3f41,$0534e4137, $03b425154,$041413f3e,$0393c3d3f,$05a5c5848,$03e3d4856,$03f40403f,$055423c3d,$05c656961, $04340495b,$043434343,$057594b40,$05c5e6165,$046454250,$042454646,$06860564e,$058605d5f, $04a4a4947,$05347494a,$061666964,$04d55635f,$051515150,$051515050,$053535252,$055535354, $0625e5a56,$079756f69,$081817f7c,$080818181,$072777b7e,$05b60666c,$054545658,$053535354, $052535353,$052525252,$051535353,$051515151,$05d585350,$054595d5e,$063595453,$06a696967, $063696a6a,$05a56565a,$068676662,$06a6b6969,$069696969,$068686969,$068696969,$068686868, $046464646,$048484747,$04f484747,$075766b5a,$056575b68,$05f585655,$06c797a70,$068635d5f, $077736f6c,$075797a7a,$068646a70,$069737471,$04a4d525b,$043444546,$048454141,$06c5d4644, $0626a706f,$05350535b,$0545c605a,$075605957,$0585e737c,$05a575657,$07c7c7a6e,$07a787a7d, $050536676,$046484a4d,$041424445,$050483e40,$0434f5153,$0403f3e3a,$03c3e3f40,$0534c3e39, $03a465253,$03f3f3e3d,$03b3c3d3e,$067635b44,$03d425161,$03f403f3f,$04d423c3d,$0565a5e54, $043414e59,$043424243,$052554840,$05e5e6262,$046454355,$043464646,$068625249,$05d5f5a5f, $04c4b4949,$04e484a4b,$06062625e,$04e4d5059,$051515050,$052525151,$056545352,$069635d59, $07977746f,$07d7d7c7b,$0797a7c7c,$06f6e7176,$0595e6970,$053545657,$051515253,$052515151, $051525252,$054525151,$053565957,$04f4f5051,$05151504f,$051515151,$0645e5652,$068686766, $05b646767,$05e575455,$066666563,$068686767,$067666667,$066656666,$066666666,$066666666, $045454545,$046464646,$04d474646,$074736657,$056575c69,$05c565455,$06874756a,$06c665c5b, $07874716f,$073777979,$06160686f,$05e6d6f6b,$03e3f4049,$04f4b403c,$05a564949,$068564551, $0616a6f6d,$055505259,$0545b5d59,$0705b5654,$056617579,$060565556,$06f6e7573,$070797a78, $04f525662,$046484b4d,$041414345,$04e463e41,$047515253,$03f3f3d3a,$03c3d3f3f,$04f463b39, $03a484f4f,$03e3e3d3b,$0413b3d3e,$071675d4a,$03d4b5864,$03f403f3f,$050413c3e,$0555a5c51, $043415257,$043424142,$051524540,$05e5d615f,$046454659,$043464646,$066655546,$0605e575e, $04c4c494a,$048494b4c,$066604f4a,$050504f5a,$051515050,$059565352,$06d68625e,$079787471, $07a7a7a7a,$071747779,$06165696d,$05e55585c,$053566267,$051515252,$050505050,$053515150, $050515253,$061565250,$05e686d6a,$04e4f5155,$04f4e4e4e,$0504f4f4f,$063615952,$066666564, $0555d6365,$0605a5453,$064636362,$065656564,$063636364,$063636363,$063636363,$064646464, $044444444,$045454444,$04b464545,$073706355,$055565e6b,$058545354,$067727164,$067615959, $0726f6c6a,$06d717373,$05b586169,$05c696b66,$047453d45,$05b59473e,$057504a55,$0634e4456, $05f686c6a,$058514f56,$0535b5c5a,$069575452,$055647475,$063545454,$05c5b6a72,$06173756b, $050515356,$046484c54,$03f404245,$04e4a403f,$048505251,$03e3e3c3a,$03b3c3e3e,$052463a39, $03e4c5655,$03d3d3c3a,$03f3a3d3d,$0655c574d,$03f51585a,$03f403f3e,$04f3f3d3f,$0575d5a4f, $042445357,$043424242,$0544c4241,$05c5c6160,$045434a59,$045464646,$063635543,$0575c5c5e, $04c4b4947,$04c4b4b4c,$0645d4f4e,$05150525d,$0615c5853,$0716d6a66,$077767573,$076777777, $06c717375,$0575b6066,$050515253,$0564f5050,$051566062,$050505150,$0504f4f4f,$05d595451, $051555c5e,$06f615451,$06c727473,$04d4f5663,$04d4d4c4d,$04f4d4d4d,$062615d54,$063646362, $052565e62,$0605c5552,$062616161,$061626262,$060606061,$060606061,$061616160,$062626261, $043434343,$044444443,$04b464444,$0716d6256,$05459616c,$055525252,$068706d60,$0635d5659, $06b696765,$0666a6b6b,$056535860,$05c656761,$0514b3c46,$054584843,$052444856,$05c464254, $05c666966,$058504b50,$0545c5c5b,$063545250,$054647271,$060535253,$05858656e,$060717263, $05b565858,$047494d5b,$040414446,$04f514d43,$0494d504f,$03d3c3b3b,$03b3c3d3e,$057483939, $045516162,$03d3d3b3b,$03b3b3c3d,$05a534c47,$043525154,$040403f3d,$04c3d3e3f,$0575c574d, $040495658,$043434243,$056494041,$0595a5e5c,$045434f5b,$047474747,$058594f44,$0464a4f53, $04c4b4a48,$04e4c4b4c,$064584e4e,$0655f5a61,$074726f6b,$075757575,$072737475,$064696d70, $053585c60,$04d4d4e4f,$04d4d4d4d,$0524d4d4d,$051575f5d,$051515151,$0504f4e50,$06f6c6457, $054616c6f,$0726b5b53,$06f6e6f72,$04d52606d,$04c4c4c4d,$0514d4c4c,$0605f5e58,$061616160, $05253595f,$0615f5a54,$05f606061,$05f5f5f5f,$05f5e5e5e,$05e5e5f5f,$05f5f5f5f,$060605f5f, $041414141,$042424242,$04b454342,$06e6a6358,$0565c646c,$053515253,$0686e695b,$05e59545a, $063646361,$05d616363,$0534f5258,$05c63645d,$04f433a47,$052554446,$054474b55,$057413c4c, $05b636462,$0584f4a50,$0545a5a5a,$05c524f4e,$053636e6c,$057525051,$05c5f6a69,$06c717168, $06a656968,$05053545e,$046494d4f,$04f535147,$04d4d4e4d,$03c3b393f,$03a3b3c3d,$057493d39, $04d515b65,$03c3c3a3e,$03a3b3c3d,$059524e47,$047524f4f,$040403f3c,$0463c3e3f,$0585c564a, $03f4a5658,$044444342,$057493f42,$055565c5a,$04643525a,$047484747,$047454344,$04a4a4847, $04b4b4a4b,$0524d4c4c,$06b676058,$071716e6c,$072727272,$06c6f7172,$05d62666a,$04e505458, $04b4b4c4c,$04a4a4a4a,$04b4b4b4b,$04e4c4b4a,$0555b5e58,$0565a5a57,$0504f4f51,$071706b5e, $05b677071,$06f6e6359,$0685f5f68,$04d54656d,$04b4b4b4b,$0544e4b4b,$05d5d5d5b,$05e5e5e5e, $05c58565a,$06465635f,$05d5e5f61,$05d5d5d5d,$05c5c5c5d,$05d5c5c5d,$05d5d5d5d,$05d5d5d5d, $03f3f3f3f,$040403f3f,$049434241,$06b655f55,$05a5f656b,$052515255,$0686b6558,$05b57545d, $05e5e5d5c,$0575a5d5d,$0504c4e53,$05c626159,$04a3b394b,$051514147,$0514c4d52,$0513d3942, $05b61605d,$0564f4e53,$053555758,$055504e4d,$053656c66,$0534f4e4f,$06a6a6b64,$06c6d6e6c, $06966646b,$054585d64,$0474a4e51,$04c504b45,$051545552,$03b3a3944,$03a3b3b3b,$052493e39, $04e4e5559,$03c3c3b43,$0393b3c3c,$0584d4c44,$04a535351,$03e3f3e3c,$0423d3d3f,$0585b5549, $03f4e5656,$044444442,$057454143,$05556585a,$047434a53,$047474747,$04a474445,$04a4b4a4a, $0504e4b49,$0665d5853,$06f6f6e6b,$06f6f6f6f,$06a6c6d6e,$0555c6267,$04c4d4f52,$04949494a, $048494949,$049484848,$049494949,$04b4a4a49,$064635f55,$0666a6a67,$05150535c,$06f6b655a, $063696e6f,$06c6c6661,$063575661,$04c56666b,$04a494a4b,$0564f4b4a,$05b5b5a5a,$0595b5b5b, $067645d57,$0696b6a69,$05b5c5f65,$05b5b5a5b,$05a5a5a5b,$05b5a5b5b,$05b5b5b5b,$05b5b5b5b, $03e3e3e3e,$03e3e3e3e,$04642413f,$067605a51,$05b5e6468,$052525558,$068686256,$05a5a5960, $058585758,$052565959,$04b484b50,$05b5f5d54,$04838384c,$04f4b3e48,$04f4d4f50,$04e3c3e45, $0595d5c5a,$051505153,$052525352,$0514d4b4b,$055656961,$04f4d4c4d,$06767665c,$061646566, $06059545d,$05255585c,$0484b4d50,$04b484844,$0595e5c56,$03a393d4a,$0393a3b3a,$049433c39, $04e4b5051,$03c3c3b48,$03a3b3c3c,$05548463e,$04c525151,$03e3e3d3d,$03e3d3f3f,$056585046, $041525453,$044444342,$04f414244,$045494c51,$046464443,$047474746,$048474747,$0514d4a4a, $064625e57,$06b6a6966,$06b6b6b6b,$06567686a,$055595e62,$0484a4c4f,$048484848,$047474748, $047474746,$047474747,$047474747,$04a484848,$06a696454,$06a6b6a6b,$056555d67,$06a645f59, $062676b6c,$06a696460,$0665d5b63,$04c566569,$04848484a,$057504a49,$058585858,$054585959, $069676259,$06a6a6a69,$0595b6167,$059595959,$058585858,$058585858,$059595958,$058595959, $03d3d3d3d,$03d3d3d3d,$044403f3e,$0625b544c,$05a5c6265,$054555759,$066655f57,$0585b5d62, $054525254,$04d525555,$04745464a,$0595c5950,$04436394d,$050463c48,$04d464b51,$0483a3e48, $055595855,$0504e4f4f,$051505051,$04e4b4a4a,$05664655b,$04b4a4a4c,$055585750,$04e4f5154, $059584f4d,$051535557,$0494c4d50,$051454347,$052605f55,$03a39444b,$0393a3a3a,$047443938, $04d4e514e,$03c3b3c49,$0393b3c3c,$05247443b,$04e514f50,$03f3e3d40,$03d3d3f3f,$053544e45, $042535251,$044444442,$041414344,$045444442,$045474646,$046464746,$0504b4746,$064605a55, $067686766,$066666767,$061646565,$04f515a5f,$048494a4c,$046464747,$046464646,$045454645, $045464545,$046454545,$046464646,$049474646,$068686456,$067656466,$05b5c6368,$065605d5c, $060666868,$065625c5a,$067656465,$04c566367,$047474748,$055504948,$056565656,$04f535656, $064636057,$066656464,$0575a6066,$057575757,$056565757,$056565656,$056565656,$056565656, $03c3c3b3b,$03d3d3d3c,$0403e3d3d,$05c534c45,$0575a5f61,$056555556,$063615c58,$054575a60, $0504f4e50,$0494e5151,$044414245,$05859554b,$03e353c4f,$0463c3843,$03b393e46,$046393739, $051555551,$04c4a4849,$04b4e5250,$04c4a4847,$056616257,$04848484a,$049494949,$049494949, $05557534a,$051525354,$04a4c5053,$050454548,$04c5b5c53,$0393a484a,$0393a3a39,$045423838, $04d4d504a,$03b3a3e4a,$0393b3c3c,$051484239,$051514f4f,$03f3e3c44,$03c3e3f3f,$050514e46, $03f494e50,$043444341,$044444344,$046464645,$045454545,$04b484645,$0605d5851,$063636362, $05f626363,$05356595c,$051505353,$047495558,$046464747,$044454546,$044444444,$044444444, $044444444,$044444444,$044444444,$047464545,$064646153,$0635f5d60,$0575a6164,$05e585656, $060636362,$05d565056,$064646261,$04a566164,$046464647,$0524e4847,$054545453,$04b4d5254, $05858564f,$0625c5757,$055595f63,$055545454,$053545555,$053535353,$054545353,$053545454, $03b3b3b3b,$03c3c3b3b,$03d3c3c3c,$0584d4641,$054585e5f,$055545352,$0615f5956,$052555a5f, $04f4e4d4f,$0484c4e4f,$042414245,$056575148,$038363f51,$036343439,$036353435,$04b423c39, $04c515352,$044434346,$046464846,$04c4a4948,$057616156,$04747484a,$047474847,$048474747, $05454544d,$054535354,$04c4e575c,$04b48474a,$04b52524c,$0393d4847,$03a3a3a3a,$046413839, $04d4c5048,$03b3a414b,$03b3c3c3b,$0514a433a,$053535050,$03f3f3c48,$03c3f4040,$04446453f, $0413f3f41,$044444343,$044444444,$047464644,$0504e4b48,$05e5b5753,$061616160,$0595b5e60, $04c515557,$047464749,$04b464647,$046495355,$046464646,$044444546,$044444444,$043434344, $043434343,$043434343,$044434343,$046454444,$064635e4f,$063605f62,$04f535d62,$0524c4b4d, $061615e59,$0514c4e59,$0615f5d59,$04a576163,$046464647,$0514d4747,$054545453,$04a4b5054, $04b4d4c4a,$05e554c4a,$055595f61,$053535353,$052525353,$052525252,$053525252,$052525353, $03b3b3b3b,$03c3b3b3b,$03c3b3b3c,$05349423e,$050565d5c,$054535250,$0605c5755,$04f53595e, $04d4d4d4e,$047494a4c,$042434547,$055544e45,$03638424f,$038363536,$0423f3d3b,$04b494644, $049494a4b,$043424748,$048474645,$0534f4d4a,$05860615c,$04747474a,$046474848,$04a484747, $053535352,$058535353,$04c515c5e,$048454549,$04a4e4d47,$039414a4a,$03a3a3a3a,$0453f383a, $04c4c5048,$03c3a444b,$03c3d3d3c,$0504b413b,$053535150,$0403f3d4a,$03f404141,$041413f3f, $044434342,$044444444,$048464645,$05755534e,$0605f5e5b,$05e606161,$054585a5c,$046484c50, $044444445,$046454444,$048454646,$04a4c5452,$05250504f,$044454a52,$043434343,$043424343, $043434343,$043434343,$043434343,$046444443,$063625b4c,$063636363,$0484b5760,$04a494747, $05f5c544d,$04c4a4e5a,$05f5d5a53,$04a565f61,$046464647,$0524c4747,$055555555,$04e4e5355, $0484c4e4f,$05b504847,$0545a5f60,$053535353,$051525253,$052525251,$052525252,$051525252, $03b3b3b3b,$03b3b3b3b,$03b3b3c3b,$04e463f3c,$04c555b59,$052504e4b,$05e595453,$04a4d565d, $04a4b4c4c,$04a484849,$04344484c,$053514a44,$03e3f464f,$04241403f,$043434343,$042434444, $046423f40,$045464b48,$049474746,$05d5c5953,$0555d5f5f,$049474749,$047474949,$04f494848, $052525253,$058535252,$043515d5e,$03f3b3e40,$04e4f4a45,$039454b4d,$03b3b3b3b,$0453d393a, $0494d5048,$03d3c484a,$03e3e3d3e,$04f4b3e3c,$0484b4c4e,$0403f3d41,$041424141,$043434342, $045444444,$0504c4946,$059575753,$06060605e,$05e5f6060,$04f55595c,$044454649,$043434444, $043434343,$045444343,$047474847,$058505550,$05f5f5f5e,$04446555e,$043434343,$042434243, $043424242,$043434343,$043434343,$045444443,$062615849,$062626263,$0484a535f,$049484847, $05e594e4a,$04d494d59,$060605e58,$049535d60,$047464647,$0574f4948,$058585a5b,$058575859, $04a515659,$0584d4746,$054595e5e,$052515152,$051515252,$051515151,$051515051,$050515151, $03a3a3a3a,$03b3b3b3a,$03a3b3b3b,$04a423d3b,$04a545954,$04b494746,$05b534d4b,$0474a555b, $0494b4b4a,$04b484748,$04444464c,$04f4c4542,$043454a4e,$03f414243,$03c3c3d3e,$03c3c3c3c, $0413d3a3c,$045474c47,$04a464645,$05d5d5b56,$04b545a5c,$0524b4848,$04c4f5253,$05351504d, $051515151,$056545251,$03f505c5c,$03d3a3d3e,$04d4e4743,$03b474d4c,$03b3b3b3b,$0453b3a3b, $04b4d4f4b,$03e3e4949,$03e3f3e3f,$044423b3d,$03e3e3f42,$04141403f,$042424141,$044434342, $0514c4846,$05e5d5b56,$05f5f5f5f,$05c5e5f5f,$04d545759,$045464749,$042434343,$043434343, $042424242,$04f4a4543,$04f575855,$05a52544e,$060605f5e,$04348585f,$042434343,$042424242, $043424242,$043434443,$043434343,$045444443,$0615e5447,$060606061,$0474a555e,$04d4d4b47, $05c5b534d,$04d484a55,$05f5f5d58,$0484d575d,$049474647,$05d574f4b,$0585b5e5e,$05b5a5958, $04b54585b,$054494545,$053595d5c,$050505051,$050505050,$05050504f,$050504f50,$050505050, $03a3a3a3a,$03a3a3a3a,$03a3a3b3b,$047413c3a,$04b555851,$045444445,$0584f4845,$0464a555b, $04c4d4c49,$04b49494a,$044474749,$04846413f,$03e404447,$03c3c3d3d,$03b3b3b3b,$03b3b3b3b, $0413b393a,$045494d48,$048454545,$054565751,$0494a4e51,$053524c49,$054535353,$051525455, $050505150,$04e505151,$041505b59,$03b3a3c3e,$04d4d4844,$03d4a4f4d,$03d3d3c3b,$04745403d, $04c4c4d4c,$03e3e4948,$03f3f3f3f,$03f3e3e3e,$04142413f,$041414141,$045434342,$053504c48, $05e5c5a57,$05e5e5e5e,$05a5c5d5e,$04c515558,$042434547,$043434242,$043424242,$043434343, $042424243,$05c595145,$0585e5f5e,$04f52534e,$05f5e5954,$0444a5a5f,$042434343,$042424242, $043434342,$043434343,$044434343,$044444444,$05f5c5046,$05d5c5c5f,$0484e595d,$05959544b, $0595c5b58,$049474850,$059595650,$0484c5358,$0514d4a49,$05e5c5955,$055595c5e,$05a595654, $04c53575a,$051474445,$053595c5a,$04f4f4f50,$04f4f4f50,$04f4f4f4f,$04f4f4f4f,$05050504f, $03a3a3a3a,$03b3a3a3a,$03a3a3b3b,$0453f3b3a,$04c55574e,$044444446,$0554c4645,$0454a5559, $04e4d4c48,$04c4c4c4c,$0484c4b4b,$040414041,$03c3c3d3e,$03b3b3b3b,$03b3a3a3b,$03b3b3b3a, $0413b393a,$0454b4e49,$045444444,$0494a4a48,$04c494848,$054535350,$052515456,$050515353, $050505050,$046485050,$042525a54,$03a3b3c3e,$04f4d4842,$0424d5051,$03e3d3d3c,$0433f413d, $04748494c,$03e3c4044,$041404140,$042424241,$042424241,$049454242,$05754514d,$05d5c5b59, $05c5d5d5d,$0585a5b5c,$0484c5054,$042424445,$041414142,$042424140,$045434242,$050514f4a, $042424348,$05b595446,$0585e5e5e,$04951514c,$05e5a4c47,$0454f5c5e,$042424243,$042424242, $043424242,$043434343,$045444443,$044444545,$05d594c45,$05751535c,$04b555b5b,$05c5a554b, $052595b5c,$04847474a,$0504e4c49,$04f505454,$058555251,$05c5b5a59,$05255595c,$058565251, $04c515457,$04d454345,$053595b57,$04f4f4f50,$04f4f4f4f,$04e4e4e4f,$04f4f4f4e,$04f4f4f4f, $03a3a3a3b,$03a3a3a3a,$0393a3a3a,$0433e3b39,$04f57564c,$043434447,$052494544,$0454c5658, $04d4c4a46,$04a4b4b4b,$043494848,$03b3b3c3e,$03b3b3b3b,$03a3b3b3b,$03a3a3a3a,$03a3a3a3a, $0443b3a3a,$0454c4e4a,$044444444,$047474645,$0534c4948,$056545454,$050525556,$050525352, $04f504f50,$044424b4f,$04354594f,$03a3b3d3e,$0514f4942,$0464e5052,$03f3e3e3d,$03c3b3d3e, $03d3d3f42,$041413f3d,$042424241,$042424242,$049474543,$05956524c,$05c5c5c5b,$05b5b5c5c, $05254585a,$046494c50,$042424243,$041414242,$040414041,$041414040,$0554b4242,$05b5c5b59, $042454e57,$0504a4743,$0595d5d5b,$04c504e4b,$05c554948,$04a575d5d,$042424244,$042424242, $043434343,$044434343,$046454444,$044464848,$05b564945,$04c494f59,$04c565854,$057544d48, $04a505457,$04b494848,$0514e4b4c,$056565756,$054555656,$059565252,$050545759,$05552504f, $04a4f5254,$04a444244,$054595954,$04e4e4e50,$04e4e4e4e,$04e4e4e4e,$04e4e4e4e,$04e4e4f4f, $03a3b3c3e,$03a393a39,$0393a3a3a,$0413c3a39,$05156544a,$042424348,$04e464443,$0454e5656, $047484644,$043444445,$03e414242,$03a3a3a3b,$03a3a3a3a,$03a3a3a3a,$039393939,$03a3a3939, $0463d3b3a,$0454c4e4c,$043434343,$04f4b4644,$054535251,$054545253,$054555455,$04f515353, $04f4f4e4e,$04441434c,$04554564a,$03b3c3d3f,$04f4d4a42,$04a4f4f50,$03f3f3f3e,$03e3e3e3f, $042413f3f,$042424242,$045434343,$04d494847,$058575552,$05b5a5a59,$057595a5a,$04d4f5255, $04243464a,$0403f4041,$0403f3f3f,$03f3f3f40,$03f3f3f3f,$03f3f3f3f,$05a534340,$05a5a5b5b, $0434c585b,$048434241,$05a5c5c57,$04f4e4a4e,$0574e4a4e,$0505a5b5a,$042434345,$042424242, $043424242,$045434343,$0524f4b48,$0464f5453,$0574f4644,$046464d56,$049504f49,$04e4c4947, $04a4a4c4e,$053514f4c,$056545454,$052545656,$044484c50,$0524a4241,$04f535555,$0514f4d4d, $04a4e5051,$047424144,$054585751,$04e4e4e50,$04d4d4d4d,$04d4d4e4d,$04d4d4d4d,$04d4d4d4d, $03a3c4245,$039393939,$03939393a,$0403b3939,$052565247,$042424349,$04a444242,$047505653, $043434344,$042424242,$03e404141,$03a3a3a3b,$03a3a3a3a,$03a3a3a3a,$03939393a,$03c3b3a3a, $0473e3c3c,$0474c4d4c,$043424243,$057544c45,$057585858,$054535254,$054535254,$04f525354, $04d4e4e4e,$042414045,$047555446,$03c3d3e3f,$04e4d493f,$04f504e4e,$040414246,$042403f3f, $042424242,$049474543,$0534f4e4c,$059585756,$059595959,$055565758,$0474b4f52,$041414244, $03f3f3f40,$03f3f3f3f,$03f3f3f3e,$03f3f3f3f,$03f3f3f3f,$03f3f3e3e,$05a524340,$0514f5359, $045545a59,$045424141,$05a5a5a53,$04e494956,$04b4c4f50,$0555a5850,$042434348,$042424242, $042424242,$04b444343,$059595753,$049545959,$050484444,$044444851,$047484645,$053524e49, $050505253,$055555350,$04f525456,$043474a4c,$036383c40,$04b413a38,$04e525352,$04e4c4b4b, $04b4d4e4e,$045424146,$05558554d,$04d4e4e50,$04d4c4d4d,$04c4c4d4d,$04c4c4c4c,$04c4c4c4c, $03b3e464a,$03939393a,$039393939,$03e3a3939,$052554f45,$041414349,$048434241,$04a535652, $046464646,$041424345,$03e3f4041,$0393a3a3c,$03a3a3a39,$03a3a3a3a,$03a3a3a3a,$03d3c3c3b, $0463f3e3d,$0474c4c4b,$042424242,$057555045,$053555657,$053525252,$0524f4d50,$04e505254, $0454a4c4c,$04141403f,$04b565245,$03c3d3f41,$04e4d4a3f,$05151514e,$04143484f,$042424141, $04c494644,$057545250,$059585858,$057585959,$051535556,$04447494c,$03f404142,$03f404141, $03e3e3f3f,$03e3e3e3e,$03f3e3e3e,$03f3e3e3f,$03e3e3e3e,$03f3f3e3e,$059504240,$04e474855, $045535958,$043414141,$05857554c,$047444f58,$0494f4f4c,$056595448,$042434349,$042424242, $043424242,$050444343,$058585857,$047515657,$046434243,$043434447,$04e4c4743,$059585753, $04f525558,$05453514d,$03e434c53,$03637393b,$03a373939,$048424441,$04d51514f,$04a49494a, $04a4c4b4b,$043414247,$05657534a,$04d4d4e51,$04c4c4c4c,$04b4c4c4c,$04b4b4b4b,$04b4b4b4b, $03b3f474c,$038383939,$038393938,$03c393838,$052534c42,$03f41434a,$04641403f,$050555550, $04e4d4c4c,$04042464b,$03e3e3f3f,$0393a3a3c,$03a3a3a39,$03a3a3a3a,$03b3b3a3a,$03e3d3c3c, $0453f3e3e,$0484c4c4a,$041414141,$0514f4943,$04e4c4d50,$051515150,$054504e4f,$047494e52, $03e404344,$0403f3f3f,$04f554f43,$03d3d3e41,$04d4c4a3f,$04d4d4d4d,$0464a4c4d,$04d494645, $057555350,$058585757,$056575858,$04a515555,$041434647,$03f3f3f3f,$03f3f3e3e,$03f3f3f3f, $03e3e3f3f,$03e3d3d3e,$03e3d3d3d,$03e3e3e3e,$03e3e3e3e,$03f3f3e3e,$0574d413f,$056525257, $0424e5758,$041404041,$0524a4743,$043465357,$04a4e4b44,$05558554a,$042424349,$042424141, $042414141,$04c434242,$050525352,$043464a4e,$043424142,$042444646,$053504c44,$058585755, $04c505457,$051514e4b,$03337454f,$039343534,$03e414643,$045464844,$04e50504d,$04847484a, $0494a4948,$0413f4146,$055565147,$04b4c4d51,$04b4b4b4b,$04a4a4a4a,$04a4a4a4a,$04a4a4a49, $03b40484c,$038383839,$038383838,$03b383737,$052524a41,$03f3f434b,$044403f3f,$05556544d, $053545454,$040424a50,$03e3e3e3f,$03a3a3b3c,$03a3a3a3a,$03b3b3a3a,$03c3b3b3b,$03e3d3d3c, $0433f3e3e,$0484b4b49,$0403f4041,$045434240,$04b454243,$05251504d,$051545353,$03e3f434c, $03f3e3e3e,$03f3f3e3e,$04f534b41,$03d3d3e41,$04b4a463e,$04d4c4c4c,$04e4e4d4d,$056555350, $057575756,$054555656,$04f505153,$0464c4f4f,$03f404142,$03e3e3e3e,$0423f3e3e,$04c494744, $03e3e4148,$03d3d3d3e,$03d3d3d3d,$03e3e3e3e,$03e3e3e3e,$03f3f3e3e,$0564b403f,$058585858, $041475458,$041404041,$04d434241,$043475456,$050514e46,$052565753,$041424246,$041414141, $041414141,$044424241,$045464747,$043434344,$044424141,$043484f4d,$0504e4a44,$057575552, $04c4f5356,$0504f4c4a,$03335444e,$03d393f3b,$03d454847,$04246463d,$04e4f4e4b,$04847474a, $0494a4949,$0403f4146,$055544e45,$04a4b4d51,$04a4a4a4a,$049494a4a,$049494949,$04a494949, $03b41494c,$038383839,$038383838,$03a383737,$05250483f,$03e3f434b,$0423f3e3e,$05656524a, $053555556,$03f42484f,$03d3e3e3f,$03b3b3c3d,$03b3b3b3b,$03b3b3b3b,$03c3b3b3b,$03e3d3d3c, $0423f3e3e,$0494a4a48,$03f3f4042,$03f3f3f3f,$049423f3f,$050504e4b,$0484f5151,$03e3f3e40, $03e3e3e3e,$03f3f3e3e,$04a4f453f,$03d3d3d3f,$04b49423d,$0504e4d4c,$054535251,$056565655, $052535555,$04d4e4f50,$04c4c4c4c,$04b4d4c4c,$03e404246,$03e3d3e3e,$0504b423e,$055555452, $03e404b53,$03d3d3d3e,$03d3d3d3d,$03e3e3d3e,$03e3e3e3d,$03f3f3f3e,$05548403f,$057575757, $042465257,$041404041,$04f454241,$044475255,$05655544d,$04c545656,$041414244,$041414141, $041414141,$043434242,$042424243,$04a494342,$045424246,$0464f5350,$04d4b4742,$05352504e, $04a4d5153,$04f4e4a49,$03235434d,$03d3e443d,$03e454546,$03e43453d,$04d4e4d48,$04846474a, $048494949,$03f3e4246,$054534c43,$0494a4c51,$049494949,$049494949,$049494949,$049494949, $03c42494c,$038383839,$038383838,$03a383737,$0514f473e,$03e3f434c,$0413f3e3e,$055545048, $052545555,$03e40444c,$03d3d3e3e,$03b3b3c3d,$03b3b3b3b,$03b3b3b3b,$03b3b3b3b,$03d3d3d3c, $0413e3d3d,$0484a4947,$03f3f4043,$03d3d3e3e,$047413e3e,$04f4e4c4a,$03e484e4f,$03e3e3e3d, $03e3e3e3e,$03e3e3e3e,$04548413f,$03d3d3d3e,$04c49433e,$05452514e,$055555555,$052535455, $04b4d4e50,$04b4b4b4b,$04b4b4b4b,$04a4a4a4a,$03e3f454a,$03d3d3d3d,$05452483e,$055555554, $03e425054,$03d3d3d3d,$03d3d3c3c,$03d3d3d3d,$03e3d3d3d,$03f413f3e,$053463f3e,$056555656, $0414a5356,$042413f40,$052494342,$043455054,$05555534b,$0454e5456,$041414142,$041414141, $042414141,$046434242,$041414346,$04f4c4341,$04541434b,$048515350,$04b494541,$04f4e4d4b, $0494b4f50,$04e4d4949,$03135434c,$03c3f4339,$03f444446,$03b3e453e,$04c4d4c46,$04745464a, $047484849,$03e3e4246,$053524b42,$049494c50,$048484949,$048484848,$048484848,$048484848); implementation end. adlibtracker2-2.4.23/adt2play/a2fileio.pas0000644000000000000000000000373413176573533016754 0ustar rootrootunit A2fileIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const _debug_str_: String = ''; const GENERIC_IO_BUFFER_SIZE = 1500*1024; // 1.5 MB I/O Buffer type pGENERIC_IO_BUFFER = ^tGENERIC_IO_BUFFER; tGENERIC_IO_BUFFER = array[0..PRED(GENERIC_IO_BUFFER_SIZE)] of Byte; var buf1: tGENERIC_IO_BUFFER; buf2: tGENERIC_IO_BUFFER; buf3: array[WORD] of Byte; buf4: array[WORD] of Byte; const adjust_tracks: Boolean = TRUE; accurate_conv: Boolean = TRUE; fix_c_note_bug: Boolean = TRUE; var songdata_source: String; songdata_title: String; load_flag: Byte; procedure a2m_file_loader; procedure a2t_file_loader; procedure amd_file_loader; procedure cff_file_loader; procedure dfm_file_loader; procedure mtk_file_loader; procedure rad_file_loader; procedure s3m_file_loader; procedure fmk_file_loader; procedure sat_file_loader; procedure sa2_file_loader; procedure hsc_file_loader; procedure ResetF(var f: File); procedure BlockReadF(var f: File; var data; size: Longint; var bytes_read: Longint); procedure SeekF(var f: File; fpos: Longint); procedure CloseF(var f: File); implementation uses DOS, A2player,A2depack, StringIO,ParserIO; {$i iloaders.inc} procedure ResetF(var f: File); var fattr: Word; begin _debug_str_:= 'ADT2SYS.PAS:ResetF_RW'; GetFAttr(f,fattr); If (fattr AND ReadOnly = ReadOnly) then FileMode := 0; {$i-} Reset(f,1); {$i+} end; procedure BlockReadF(var f: File; var data; size: Longint; var bytes_read: Longint); begin _debug_str_:= 'ADT2SYS.PAS:BlockReadF'; {$i-} BlockRead(f,data,size,bytes_read); {$i+} If (IOresult <> 0) then bytes_read := 0; end; procedure SeekF(var f: File; fpos: Longint); begin _debug_str_:= 'ADT2SYS.PAS:SeekF'; {$i-} Seek(f,fpos); {$i+} end; procedure CloseF(var f: File); begin _debug_str_:= 'ADT2SYS.PAS:CloseF'; {$i-} Close(f); {$i+} If (IOresult <> 0) then ; end; end. adlibtracker2-2.4.23/adt2play/stringio.pas0000644000000000000000000002057713176573533017124 0ustar rootrootunit StringIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface function byte2hex(value: Byte): String; function byte2dec(value: Byte): String; function Capitalize(str: String): String; function Upper(str: String): String; function Lower(str: String): String; function ExpStrL(str: String; size: Byte; chr: Char): String; function ExpStrR(str: String; size: Byte; chr: Char): String; function DietStr(str: String; size: Byte): String; function CutStr(str: String): String; function FilterStr(str: String; chr0,chr1: Char): String; function Num2str(num: Longint; base: Byte): String; function Str2num(str: String; base: Byte): Longint; function PathOnly(path: String): String; function NameOnly(path: String): String; function BaseNameOnly(path: String): String; function ExtOnly(path: String): String; implementation uses DOS; function byte2hex(value: Byte): String; const data: array[0..15] of char = '0123456789ABCDEF'; begin asm mov edi,@RESULT lea ebx,[data] mov al,2 stosb mov al,value xor ah,ah mov cl,16 div cl xlat stosb mov al,ah xlat stosb end; end; function byte2dec(value: Byte): String; const data: array[0..9] of char = '0123456789'; begin asm mov edi,@RESULT lea ebx,[data] mov al,value xor ah,ah mov cl,100 div cl mov ch,ah xchg ah,al or ah,ah jz @@1 mov al,3 stosb xchg ah,al xlat stosb mov al,ch jmp @@2 @@1: mov al,2 stosb mov al,value @@2: xor ah,ah mov cl,10 div cl xlat stosb mov al,ah xlat stosb end; end; function Capitalize(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@4 mov al,[esi] inc esi cmp al,'a' jb @@0 cmp al,'z' ja @@0 sub al,20h @@0: mov [edi],al inc edi @@1: mov ah,al mov al,[esi] inc esi cmp ah,' ' jnz @@2 cmp al,'a' jb @@2 cmp al,'z' ja @@2 sub al,20h jmp @@3 @@2: cmp al,'A' jb @@3 cmp al,'Z' ja @@3 add al,20h @@3: mov [edi],al inc edi loop @@1 @@4: end; end; function Upper(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@3 @@1: mov al,[esi] inc esi cmp al,'a' jb @@2 cmp al,'z' ja @@2 sub al,20h @@2: mov [edi],al inc edi loop @@1 @@3: end; end; function Lower(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@3 @@1: mov al,[esi] inc esi cmp al,'A' jb @@2 cmp al,'Z' ja @@2 add al,20h @@2: mov [edi],al inc edi loop @@1 @@3: end; end; function ExpStrL(str: String; size: Byte; chr: Char): String; begin asm lea esi,[str] mov edi,@RESULT cld xor ecx,ecx lodsb cmp al,size jge @@1 mov ah,al mov al,size stosb mov al,ah mov cl,size sub cl,al mov al,chr rep stosb mov cl,ah rep movsb jmp @@2 @@1: stosb mov cl,al rep movsb @@2: end; end; function ExpStrR(str: String; size: Byte; chr: Char): String; begin asm lea esi,[str] mov edi,@RESULT cld xor ecx,ecx lodsb cmp al,size jge @@1 mov ah,al mov al,size stosb mov cl,ah rep movsb mov al,ah mov cl,size sub cl,al mov al,chr rep stosb jmp @@2 @@1: stosb mov cl,al rep movsb @@2: end; end; function DietStr(str: String; size: Byte): String; begin If (Length(str) <= size) then begin DietStr := str; EXIT; end; Repeat Delete(str,size DIV 2,1) until (Length(str)+3 = size); Insert('...',str,size DIV 2); DietStr := str end; function CutStr(str: String): String; begin While (str[0] <> #0) and (str[1] in [#00,#32]) do Delete(str,1,1); While (str[0] <> #0) and (str[Length(str)] in [#00,#32]) do Delete(str,Length(str),1); CutStr := str; end; function FilterStr(str: String; chr0,chr1: Char): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@3 @@1: mov al,[esi] inc esi cmp al,chr0 jnz @@2 mov al,chr1 @@2: mov [edi],al inc edi loop @@1 @@3: end; end; function Num2str(num: Longint; base: Byte): String; const hexa: array[0..PRED(16)+32] of Char = '0123456789ABCDEF'+ #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0; begin asm xor eax,eax xor edx,edx xor edi,edi xor esi,esi mov eax,num xor ebx,ebx mov bl,base cmp bl,2 jb @@3 cmp bl,16 ja @@3 mov edi,32 @@1: dec edi xor edx,edx div ebx mov esi,edx mov dl,byte ptr [hexa+esi] mov byte ptr [hexa+edi+16],dl and eax,eax jnz @@1 mov esi,edi mov ecx,32 sub ecx,edi mov edi,@RESULT mov al,cl stosb @@2: mov al,byte ptr [hexa+esi+16] stosb inc esi loop @@2 jmp @@4 @@3: mov edi,@RESULT xor al,al stosb @@4: end; end; const digits: array[0..35] of Char = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; function Digit2index(digit: Char): Byte; var index: Byte; begin digit := UpCase(digit); index := 15; While (index > 0) and (digit <> digits[index]) do Dec(index); Digit2index := Index; end; function position_value(position,base: Byte): Longint; var value: Longint; index: Byte; begin value := 1; For index := 2 to position do value := value*base; position_value := value; end; function Str2num(str: String; base: Byte): Longint; var value: Longint; index: Byte; begin value := 0; For index := 1 to Length(str) do Inc(value,Digit2index(str[index])* position_value(Length(str)-index+1,base)); Str2num := value; end; var dir: DirStr; name: NameStr; ext: ExtStr; function PathOnly(path: String): String; begin FSplit(path,dir,name,ext); PathOnly := dir; end; function NameOnly(path: String): String; begin If (Pos('\',path) <> 0) then begin FSplit(path,dir,name,ext); NameOnly := name+ext; end else NameOnly := path; end; function BaseNameOnly(path: String): String; begin FSplit(path,dir,name,ext); BaseNameOnly := name; end; function ExtOnly(path: String): String; begin FSplit(path,dir,name,ext); Delete(ext,1,1); ExtOnly := Lower(ext); end; end. adlibtracker2-2.4.23/adt2play/a2depack.pas0000644000000000000000000010557313176573533016740 0ustar rootrootunit A2depack; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface // Compression algorithm: RDC // Algorithm developed by Ed Ross function RDC_decompress(var source,dest; size: Word): Word; // Compression algorithm: LZSS // Algorithm developed by Lempel-Ziv-Storer-Szymanski function LZSS_decompress(var source,dest; size: Word): Word; // Compression algorithm: LZW // Algorithm developed by Lempel-Ziv-Welch function LZW_decompress(var source,dest): Word; // Compression algorithm: SixPack // Algorithm developed by Philip G. Gage function SIXPACK_decompress(var source,dest; size: Word): Word; // Compression algorithm: aPack // Algorithm developed by Joergen Ibsen function APACK_decompress(var source,dest): Dword; // Compression algorithm: LZH // Algorithm developed by Haruhiko Okomura & Haruyasu Yoshizaki function LZH_decompress(var source,dest; size: Dword): Dword; implementation uses A2fileIO; const WORKMEM_SIZE = 64*1024; var work_mem: array[0..PRED(WORKMEM_SIZE)] of Byte; ibufCount,ibufSize: Word; input_size,output_size: Word; input_ptr,output_ptr,work_ptr: Pointer; var ibuf_idx,ibuf_end,obuf_idx,obuf_src: Pointer; ctrl_bits,ctrl_mask, command,count,offs: Word; procedure RDC_decode; begin asm mov ctrl_mask,0 mov eax,input_ptr mov ibuf_end,eax xor eax,eax mov ax,input_size add ibuf_end,eax mov eax,input_ptr mov ibuf_idx,eax mov eax,output_ptr mov obuf_idx,eax @@1: xor ecx,ecx mov eax,ibuf_idx cmp eax,ibuf_end jnb @@7 mov ax,ctrl_mask shr ax,1 mov ctrl_mask,ax or ax,ax jnz @@2 mov esi,ibuf_idx lodsw mov ctrl_bits,ax add ibuf_idx,2 mov ctrl_mask,8000h @@2: mov ax,ctrl_bits and ax,ctrl_mask or ax,ax jnz @@3 mov esi,ibuf_idx mov edi,obuf_idx movsb inc ibuf_idx inc obuf_idx jmp @@1 @@3: xor ah,ah mov esi,ibuf_idx lodsb shr ax,4 and ax,0fh mov command,ax xor ah,ah mov esi,ibuf_idx lodsb and ax,0fh mov count,ax inc ibuf_idx cmp command,0 jnz @@4 add count,3 mov edi,obuf_idx mov cx,count mov esi,ibuf_idx lodsb rep stosb inc ibuf_idx mov cx,count add obuf_idx,ecx jmp @@1 @@4: cmp command,1 jnz @@5 xor ah,ah mov esi,ibuf_idx lodsb shl ax,4 add count,ax inc ibuf_idx add count,19 mov edi,obuf_idx mov cx,count mov esi,ibuf_idx lodsb rep stosb inc ibuf_idx mov cx,count add obuf_idx,ecx jmp @@1 @@5: cmp command,2 jnz @@6 mov ax,count add ax,3 mov offs,ax xor ah,ah mov esi,ibuf_idx lodsb shl ax,4 add offs,ax inc ibuf_idx xor ah,ah mov esi,ibuf_idx lodsb mov count,ax inc ibuf_idx add count,16 mov eax,obuf_idx mov cx,offs sub eax,ecx mov obuf_src,eax mov esi,eax mov edi,obuf_idx mov cx,count rep movsb mov cx,count add obuf_idx,ecx jmp @@1 @@6: mov ax,count add ax,3 mov offs,ax xor ah,ah mov esi,ibuf_idx lodsb shl ax,4 add offs,ax inc ibuf_idx mov eax,obuf_idx mov cx,offs sub eax,ecx mov obuf_src,eax mov esi,eax mov edi,obuf_idx mov cx,command rep movsb mov cx,command add obuf_idx,ecx jmp @@1 @@7: mov eax,obuf_idx sub eax,output_ptr mov output_size,ax end; end; function RDC_decompress(var source,dest; size: Word): Word; begin input_ptr := @source; output_ptr := @dest; input_size := size; RDC_decode; RDC_decompress := output_size; end; const N = 4096; F = 18; T = 2; procedure GetChar; assembler; asm push ebx mov bx,ibufCount cmp bx,ibufSize jb @@1 jmp @@2 @@1: push edi mov edi,input_ptr mov al,byte ptr [edi+ebx] pop edi inc ebx mov ibufCount,bx pop ebx clc jmp @@3 @@2: pop ebx stc @@3: end; procedure PutChar; assembler; asm push ebx mov bx,output_size push edi mov edi,output_ptr mov byte ptr [edi+ebx],al pop edi inc ebx mov output_size,bx pop ebx end; procedure LZSS_decode; begin asm mov ibufCount,0 mov ax,input_size mov ibufSize,ax mov output_size,0 xor ebx,ebx xor edx,edx mov edi,N-F @@1: shr dx,1 or dh,dh jnz @@2 call GetChar jc @@5 mov dh,0ffh mov dl,al @@2: test dx,1 jz @@3 call GetChar jc @@5 push esi mov esi,work_ptr add esi,edi mov byte ptr [esi],al pop esi inc edi and edi,N-1 call PutChar jmp @@1 @@3: call GetChar jc @@5 mov ch,al call GetChar jc @@5 mov bh,al mov cl,4 shr bh,cl mov bl,ch mov cl,al and cl,0fh add cl,T inc cl @@4: and ebx,N-1 push esi mov esi,work_ptr mov al,byte ptr [esi+ebx] add esi,edi mov byte ptr [esi],al pop esi inc edi and edi,N-1 call PutChar inc ebx dec cl jnz @@4 jmp @@1 @@5: end; end; function LZSS_decompress(var source,dest; size: Word): Word; begin input_ptr := @source; output_ptr := @dest; work_ptr := @work_mem; input_size := size; FillChar(work_ptr^,WORKMEM_SIZE,0); LZSS_decode; LZSS_decompress := output_size; end; var le76,le77: Byte; le6a,le6c,le6e,le70,le72,le74,le78, le7a_0,le7a_2,le7a_4,le7a_6,le7a_8,le82a,le82b: Word; procedure NextCode; assembler; asm mov bx,le82a mov ax,le82b add bx,le78 adc ax,0 xchg bx,le82a xchg ax,le82b mov cx,bx and cx,7 shr ax,1 rcr bx,1 shr ax,1 rcr bx,1 shr ax,1 rcr bx,1 mov esi,input_ptr mov ax,[ebx+esi] mov dl,[ebx+esi+2] or cx,cx jz @@2 @@1: shr dl,1 rcr ax,1 loop @@1 @@2: mov bx,le78 sub bx,9 shl bx,1 and ax,[ebx+le7a_0] end; function LZW_decode: Word; var result: Word; begin asm xor eax,eax xor ebx,ebx xor ecx,ecx mov le72,0 mov le78,9 mov le70,102h mov le74,200h mov edi,output_ptr xor eax,eax mov le6a,ax mov le6c,ax mov le6e,ax mov le76,al mov le77,al mov le82a,ax mov le82b,ax mov le7a_0,1ffh mov le7a_2,3ffh mov le7a_4,7ffh mov le7a_6,0fffh mov le7a_8,1fffh @@1: call NextCode cmp ax,101h jnz @@2 jmp @@9 @@2: cmp ax,100h jnz @@3 mov le78,9 mov le74,200h mov le70,102h call NextCode mov le6a,ax mov le6c,ax mov le77,al mov le76,al mov al,le77 mov byte ptr [edi],al inc edi jmp @@1 @@3: mov le6a,ax mov le6e,ax cmp ax,le70 jb @@4 mov ax,le6c mov le6a,ax mov al,le76 push eax inc le72 @@4: cmp le6a,0ffh jbe @@5 mov esi,work_ptr mov bx,le6a shl bx,1 add bx,le6a mov al,[ebx+esi+2] push eax inc le72 mov ax,[ebx+esi] mov le6a,ax jmp @@4 @@5: mov ax,le6a mov le76,al mov le77,al push eax inc le72 xor ecx,ecx mov cx,le72 jecxz @@7 @@6: pop eax mov byte ptr [edi],al inc edi loop @@6 @@7: mov le72,0 push esi mov bx,le70 shl bx,1 add bx,le70 mov esi,work_ptr mov al,le77 mov [ebx+esi+2],al mov ax,le6c mov [ebx+esi],ax inc le70 pop esi mov ax,le6e mov le6c,ax mov bx,le70 cmp bx,le74 jl @@8 cmp le78,14 jz @@8 inc le78 shl le74,1 @@8: jmp @@1 @@9: mov output_size,ax mov result,ax end; LZW_decode := result; end; function LZW_decompress(var source,dest): Word; begin input_ptr := @source; output_ptr := @dest; work_ptr := @work_mem; LZW_decode; LZW_decompress := output_size; end; const MAXFREQ = 2000; MINCOPY = 3; MAXCOPY = 255; COPYRANGES = 6; TERMINATE = 256; FIRSTCODE = 257; ROOT = 1; CODESPERRANGE = MAXCOPY-MINCOPY+1; MAXCHAR = FIRSTCODE+COPYRANGES*CODESPERRANGE-1; SUCCMAX = MAXCHAR+1; TWICEMAX = 2*MAXCHAR+1; MAXBUF = PRED(64*1024); MAXDISTANCE = 21389; MAXSIZE = 21389+MAXCOPY; const BitValue: array[1..14] of Word = (1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192); CopyBits: array[0..PRED(COPYRANGES)] of Word = (4,6,8,10,12,14); CopyMin: array[0..PRED(COPYRANGES)] of Word = (0,16,80,336,1360,5456); var leftC,rghtC: array[0..MAXCHAR] of Word; dad,frq: array[0..TWICEMAX] of Word; index,ibitCount,ibitBuffer,obufCount: Word; procedure InitTree; begin asm xor edi,edi mov di,2 mov bx,2 mov cx,1 @@1: xor dx,dx mov ax,di div bx push edi shl di,1 mov word ptr dad[edi],ax mov word ptr frq[edi],cx pop edi inc di cmp di,TWICEMAX jbe @@1 mov di,1 @@2: xor dx,dx mov ax,di mul bx push edi shl di,1 mov word ptr leftC[edi],ax inc ax mov word ptr rghtC[edi],ax pop edi inc di cmp di,MAXCHAR jbe @@2 end; end; procedure UpdateFreq(a,b: Word); begin asm xor ecx,ecx xor edi,edi @@1: mov di,a shl di,1 mov bx,word ptr frq[edi] mov di,b shl di,1 add bx,word ptr frq[edi] mov di,a shl di,1 mov dx,word ptr dad[edi] mov di,dx shl di,1 mov word ptr frq[edi],bx mov a,dx cmp a,ROOT jz @@3 mov di,a shl di,1 mov di,word ptr dad[edi] mov ax,di shl di,1 mov bx,word ptr leftC[edi] cmp a,bx jnz @@2 mov di,ax shl di,1 mov bx,word ptr rghtC[edi] mov b,bx jmp @@3 @@2: mov di,ax shl di,1 mov bx,word ptr leftC[edi] mov b,bx @@3: cmp a,ROOT jnz @@1 mov bx,MAXFREQ mov di,ROOT shl di,1 cmp word ptr frq[edi],bx jnz @@5 lea esi,[frq] lea edi,[frq] mov cx,TWICEMAX movsw @@4: lodsw shr ax,1 stosw loop @@4 @@5: end; end; procedure UpdateModel(code: Word); begin asm xor ecx,ecx xor edi,edi mov bx,code add bx,SUCCMAX mov di,bx shl di,1 mov ax,di mov cx,word ptr frq[edi] inc cx mov word ptr frq[edi],cx mov di,ax mov cx,ROOT cmp word ptr dad[edi],cx jz @@10 mov dx,word ptr dad[edi] push edi lea edi,[leftC] mov cx,dx shl cx,1 add edi,ecx mov si,word ptr [edi] pop edi cmp si,bx jnz @@1 mov di,dx shl di,1 mov si,word ptr rghtC[edi] @@1: push ebx push edx push ebx push esi call UpdateFreq pop edx pop ebx @@2: xor edi,edi mov di,dx shl di,1 mov ax,word ptr dad[edi] mov di,ax shl di,1 mov cx,di cmp word ptr leftC[edi],dx jnz @@3 mov di,cx mov si,word ptr rghtC[edi] jmp @@4 @@3: mov si,word ptr leftC[edi] @@4: xor edi,edi mov di,bx shl di,1 push eax mov ax,word ptr frq[edi] mov di,si shl di,1 mov cx,ax pop eax cmp cx,word ptr frq[edi] jbe @@9 mov di,ax shl di,1 mov cx,di cmp word ptr leftC[edi],dx jnz @@5 mov di,cx mov word ptr rghtC[edi],bx jmp @@6 @@5: xor edi,edi mov di,cx mov word ptr leftC[edi],bx @@6: lea edi,[leftC] xor ecx,ecx mov cx,dx shl cx,1 add edi,ecx cmp word ptr [edi],bx jnz @@7 mov word ptr [edi],si xor edi,edi mov di,cx mov cx,word ptr rghtC[edi] jmp @@8 @@7: xor edi,edi mov di,cx mov word ptr rghtC[edi],si mov cx,word ptr leftC[edi] @@8: xor edi,edi mov di,si shl di,1 mov word ptr dad[edi],dx mov di,bx shl di,1 mov word ptr dad[edi],ax push esi push esi push ecx call UpdateFreq pop ebx @@9: xor edi,edi mov di,bx shl di,1 mov bx,word ptr dad[edi] mov di,bx shl di,1 mov dx,word ptr dad[edi] cmp dx,ROOT jnz @@2 @@10: end; end; function InputCode(bits: Word): Word; var result: Word; begin asm xor bx,bx xor ecx,ecx mov cx,1 @@1: cmp ibitCount,0 jnz @@3 cmp ibufCount,MAXBUF jnz @@2 mov ax,input_size mov ibufCount,0 @@2: mov edi,input_ptr xor edx,edx mov dx,ibufCount shl dx,1 add edi,edx mov ax,[edi] mov ibitBuffer,ax inc ibufCount mov ibitCount,15 jmp @@4 @@3: dec ibitCount @@4: cmp ibitBuffer,7fffh jbe @@5 xor edi,edi mov di,cx dec di shl di,1 mov ax,word ptr BitValue[edi] or bx,ax @@5: shl ibitBuffer,1 inc cx cmp cx,bits jbe @@1 mov ax,bx mov result,ax end; InputCode := result; end; function Uncompress: Word; var result: Word; begin asm xor eax,eax xor ebx,ebx mov bx,1 mov dx,ibitCount mov cx,ibitBuffer mov ax,ibufCount @@1: or dx,dx jnz @@3 cmp ax,MAXBUF jnz @@2 mov ax,input_size xor ax,ax @@2: shl ax,1 mov edi,input_ptr add edi,eax shr ax,1 mov cx,[edi] inc ax mov dx,15 jmp @@4 @@3: dec dx @@4: cmp cx,7fffh jbe @@5 mov edi,ebx shl edi,1 mov bx,word ptr rghtC[edi] jmp @@6 @@5: mov edi,ebx shl edi,1 mov bx,word ptr leftC[edi] @@6: shl cx,1 cmp bx,MAXCHAR jle @@1 sub bx,SUCCMAX mov ibitCount,dx mov ibitBuffer,cx mov ibufCount,ax push ebx push ebx call UpdateModel pop eax mov result,ax end; Uncompress := result; end; procedure SIXPACK_decode; begin asm mov ibitCount,0 mov ibitBuffer,0 mov obufCount,0 mov ibufCount,0 xor ebx,ebx xor ecx,ecx mov count,0 call InitTree call Uncompress @@1: cmp ax,TERMINATE jz @@10 cmp ax,256 jae @@3 mov edi,output_ptr push ebx mov bx,obufCount add edi,ebx pop ebx stosb inc obufCount mov bx,MAXBUF cmp obufCount,bx jnz @@2 mov output_size,bx mov obufCount,0 @@2: mov edi,work_ptr push ebx mov bx,count add edi,ebx pop ebx stosb inc count cmp count,MAXSIZE jnz @@9 mov count,0 jmp @@9 @@3: sub ax,FIRSTCODE mov cx,ax xor dx,dx mov bx,CODESPERRANGE div bx mov index,ax xor dx,dx mul bx mov bx,cx add bx,MINCOPY sub bx,ax mov si,bx xor edi,edi mov di,index shl di,1 mov bx,word ptr CopyBits[edi] push ebx call InputCode add ax,si xor edi,edi mov di,index shl di,1 add ax,word ptr CopyMin[edi] mov bx,count mov dx,bx sub dx,ax mov cx,dx cmp count,ax jae @@4 add cx,MAXSIZE @@4: xor dx,dx @@5: mov edi,work_ptr add edi,ecx mov al,byte ptr [edi] mov edi,output_ptr push ebx mov bx,obufCount add edi,ebx pop ebx mov byte ptr [edi],al inc obufCount mov ax,MAXBUF cmp obufCount,ax jnz @@6 mov output_size,ax mov obufCount,0 @@6: mov edi,work_ptr push edi add edi,ecx mov al,byte ptr [edi] pop edi add edi,ebx mov byte ptr [edi],al inc bx cmp bx,MAXSIZE jnz @@7 xor bx,bx @@7: inc cx cmp cx,MAXSIZE jnz @@8 xor cx,cx @@8: inc dx cmp dx,si jb @@5 mov ax,si add count,ax cmp count,MAXSIZE jb @@9 sub count,MAXSIZE @@9: call Uncompress jmp @@1 @@10: mov bx,obufCount mov output_size,bx end; end; function SIXPACK_decompress(var source,dest; size: Word): Word; begin input_ptr := @source; output_ptr := @dest; work_ptr := @work_mem; input_size := size; SIXPACK_decode; SIXPACK_decompress := output_size; end; function APACK_decompress(var source,dest): Dword; var temp,result: Dword; begin asm mov esi,[source] mov edi,[dest] cld mov dl,80h @@1: movsb @@2: add dl,dl jnz @@3 mov dl,[esi] inc esi adc dl,dl @@3: jnc @@1 xor ecx,ecx add dl,dl jnz @@4 mov dl,[esi] inc esi adc dl,dl @@4: jnc @@8 xor eax,eax add dl,dl jnz @@5 mov dl,[esi] inc esi adc dl,dl @@5: jnc @@15 inc ecx mov al,10h @@6: add dl,dl jnz @@7 mov dl,[esi] inc esi adc dl,dl @@7: adc al,al jnc @@6 jnz @@24 stosb jmp @@2 @@8: inc ecx @@9: add dl,dl jnz @@10 mov dl,[esi] inc esi adc dl,dl @@10: adc ecx,ecx add dl,dl jnz @@11 mov dl,[esi] inc esi adc dl,dl @@11: jc @@9 dec ecx loop @@16 xor ecx,ecx inc ecx @@12: add dl,dl jnz @@13 mov dl,[esi] inc esi adc dl,dl @@13: adc ecx,ecx add dl,dl jnz @@14 mov dl,[esi] inc esi adc dl,dl @@14: jc @@12 jmp @@23 @@15: lodsb shr eax,1 jz @@25 adc ecx,ecx jmp @@20 @@16: xchg eax,ecx dec eax shl eax,8 lodsb xor ecx,ecx inc ecx @@17: add dl,dl jnz @@18 mov dl,[esi] inc esi adc dl,dl @@18: adc ecx,ecx add dl,dl jnz @@19 mov dl,[esi] inc esi adc dl,dl @@19: jc @@17 cmp eax,32000 jae @@20 cmp ah,5 jae @@21 cmp eax,7fh ja @@22 @@20: inc ecx @@21: inc ecx @@22: xchg eax,temp @@23: mov eax,temp @@24: push esi mov esi,edi sub esi,eax rep movsb pop esi jmp @@2 @@25: sub edi,[dest] mov result,edi end; APACK_decompress := result; end; const { DEFAULT COMPRESSION: dictionary 8kb } DIC_SIZE_DEF = 1 SHL 13; { ULTRA COMPRESSION: dictionary 16kb } DIC_SIZE_MAX = 1 SHL 14; const MATCH_BIT = 8; MAX_MATCH = 1 SHL MATCH_BIT; THRESHOLD = 2; PBIT = 14; TBIT = 15; CBIT = 16; DIC_BIT = 14; CODE_BIT = 16; NC = 255 + MAX_MATCH + 2 - THRESHOLD; NP = DIC_BIT + 1; NT = CODE_BIT + 3; MAX_HASH_VAL = 3 * (1 SHL DIC_BIT) + ((1 SHL DIC_BIT) SHR 9 + 1) * 255; PERC_FLAG = 32768; const DIC_SIZE: Word = DIC_SIZE_DEF; type pWORD = ^tWORD; tWORD = array[0..PRED((1 SHL DIC_BIT))] of Integer; pBYTE = ^tBYTE; tBYTE = array[0..PRED(2*(1 SHL DIC_BIT))] of Byte; var l_tree,r_tree: array[0..2*(NC-1)] of Word; p_table: array[0..255] of Word; p_len: array[0..PRED(NT)] of Byte; c_table: array[0..4095] of Word; c_len: array[0..PRED(NC)] of Byte; var dec_counter: Integer; bit_buf,sbit_buf,bit_count,block_size,dec_ptr: Word; input_buffer,output_buffer: pGENERIC_IO_BUFFER; input_buffer_idx,output_buffer_idx: Dword; size_unpacked,input_buffer_size: Dword; function ReadDataBlock(ptr: Pointer; size: Word): Word; var result: Word; begin If (input_buffer_size-input_buffer_idx >= size) then result := size else result := input_buffer_size-input_buffer_idx; Move(input_buffer^[input_buffer_idx],ptr^,result); Inc(input_buffer_idx,result); ReadDataBlock := result; end; procedure WriteDataBlock(ptr: Pointer; size: Word); begin Move(ptr^,output_buffer^[output_buffer_idx],size); Inc(output_buffer_idx,size); end; procedure FillBitBuffer(bits: Integer); begin bit_buf := (bit_buf SHL bits); While (bits > bit_count) do begin Dec(bits,bit_count); bit_buf := bit_buf OR (sbit_buf SHL bits); If (input_buffer_idx <= input_buffer_size) then begin sbit_buf := input_buffer^[input_buffer_idx]; Inc(input_buffer_idx); end else sbit_buf := 0; bit_count := 8; end; Dec(bit_count,bits); bit_buf := bit_buf OR (sbit_buf SHR bit_count); end; function GetBits(bits: Integer): Word; begin GetBits := bit_buf SHR (16-bits); FillBitBuffer(bits); end; procedure PutBits(bits: Integer; xbits: Word); begin If (bits < bit_count) then begin Dec(bit_count,bits); sbit_buf := sbit_buf OR (xbits SHL bit_count); end else begin Dec(bits,bit_count); output_buffer^[output_buffer_idx] := sbit_buf OR (xbits SHR bits); Inc(output_buffer_idx); If (bits < 8) then begin bit_count := 8-bits; sbit_buf := xbits SHL bit_count; end else begin output_buffer^[output_buffer_idx] := xbits SHR (bits-8); Inc(output_buffer_idx); bit_count := 16-bits; sbit_buf := xbits SHL bit_count; end; end; end; procedure MakeTable(n_char: Integer; bit_len: pBYTE; bits: Integer; table: pWORD); var count,weight: array[1..16] of Word; start: array[1..17] of Word; idx,idx2,len,chr,j_bits,avail,next_c,mask: Integer; ptr: pWORD; begin FillChar(count,SizeOf(count),0); FillChar(weight,SizeOf(weight),0); FillChar(start,SizeOf(start),0); For idx := 0 to PRED(n_char) do Inc(count[bit_len^[idx]]); start[1] := 0; For idx := 1 to 16 do start[SUCC(idx)] := start[idx]+(count[idx] SHL (16-idx)); j_bits := 16-bits; For idx := 1 to bits do begin start[idx] := start[idx] SHR j_bits; weight[idx] := 1 SHL (bits-idx); end; idx := SUCC(bits); While (idx <= 16) do begin weight[idx] := 1 SHL (16-idx); Inc(idx); end; idx := start[SUCC(bits)] SHR j_bits; If (idx <> 0) then begin idx2 := 1 SHL bits; If (idx <> idx2) then begin FillWord(table^[idx],idx2-idx,0); idx := idx2; end; end; avail := n_char; mask := 1 SHL (15-bits); For chr := 0 to PRED(n_char) do begin len := bit_len^[chr]; If (len = 0) then CONTINUE; idx2 := start[len]; next_c := idx2+weight[len]; If (len <= bits) then For idx := idx2 to PRED(next_c) do table^[idx] := chr else begin ptr := Addr(table^[WORD(idx2) SHR j_bits]); idx := len-bits; While (idx <> 0) do begin If (ptr^[0] = 0) then begin r_tree[avail] := 0; l_tree[avail] := 0; ptr^[0] := avail; Inc(avail); end; If (idx2 AND mask <> 0) then ptr := Addr(r_tree[ptr^[0]]) else ptr := Addr(l_tree[ptr^[0]]); idx2 := idx2 SHL 1; Dec(idx); end; ptr^[0] := chr; end; start[len] := next_c; end; end; procedure ReadPtrLen(n_char,n_bit,i_bit: Integer); var idx,chr,bits: Integer; mask: Word; begin bits := GetBits(n_bit); If (bits = 0) then begin chr := GetBits(n_bit); FillChar(p_len,SizeOf(p_len),0); FillWord(p_table,SizeOf(p_table) DIV 2,chr); end else begin idx := 0; While (idx < bits) do begin chr := bit_buf SHR (16-3); If (chr = 7) then begin mask := 1 SHL (16-4); While (mask AND bit_buf <> 0) do begin mask := mask SHR 1; Inc(chr); end; end; If (chr < 7) then FillBitBuffer(3) else FillBitBuffer(chr-3); p_len[idx] := chr; Inc(idx); If (idx = i_bit) then begin chr := PRED(GetBits(2)); While (chr >= 0) do begin p_len[idx] := 0; Inc(idx); Dec(chr); end; end; end; If (idx < n_char) then begin FillWord(p_len[idx],n_char-idx,0); idx := n_char; end; MakeTable(n_char,@p_len,8,@p_table); end; end; procedure ReadCharLen; var idx,chr,bits: Integer; mask: Word; begin bits := GetBits(CBIT); If (bits = 0) then begin chr := GetBits(CBIT); FillChar(c_len,SizeOf(c_len),0); FillWord(c_table,SizeOf(c_table) DIV 2,chr); end else begin idx := 0; While (idx < bits) do begin chr := p_table[bit_buf SHR (16-8)]; If (chr >= NT) then begin mask := 1 SHL (16-9); Repeat If (bit_buf AND mask <> 0) then chr := r_tree[chr] else chr := l_tree[chr]; mask := mask SHR 1; until (chr < NT); end; FillBitBuffer(p_len[chr]); If (chr <= 2) then begin If (chr = 1) then chr := 2+GetBits(4) else If (chr = 2) then chr := 19+GetBits(CBIT); While (chr >= 0) do begin c_len[idx] := 0; Inc(idx); Dec(chr); end; end else begin c_len[idx] := chr-2; Inc(idx); end; end; While (idx < NC) do begin c_len[idx] := 0; Inc(idx); end; MakeTable(NC,@c_len,12,@c_table); end; end; function DecodeChar: Word; var chr,mask: Word; begin If (block_size = 0) then begin block_size := GetBits(16); ReadPtrLen(NT,TBIT,3); ReadCharLen; ReadPtrLen(NP,PBIT,-1); end; Dec(block_size); chr := c_table[bit_buf SHR (16-12)]; If (chr >= NC) then begin mask := 1 SHL (16-13); Repeat If (bit_buf AND mask <> 0) then chr := r_tree[chr] else chr := l_tree[chr]; mask := mask SHR 1; until (chr < NC); end; FillBitBuffer(c_len[chr]); DecodeChar := chr; end; function DecodePtr: Word; var ptr,mask: Word; begin ptr := p_table[bit_buf SHR (16-8)]; If (ptr >= NP) then begin mask := 1 SHL (16-9); Repeat If (bit_buf AND mask <> 0) then ptr := r_tree[ptr] else ptr := l_tree[ptr]; mask := mask SHR 1; until (ptr < NP); end; FillBitBuffer(p_len[ptr]); If (ptr <> 0) then begin Dec(ptr); ptr := (1 SHL ptr)+GetBits(ptr); end; DecodePtr := ptr; end; procedure DecodeBuffer(count: Word; buffer: pBYTE); var idx,idx2: Word; begin idx2 := 0; Dec(dec_counter); While (dec_counter >= 0) do begin buffer^[idx2] := buffer^[dec_ptr]; dec_ptr := SUCC(dec_ptr) AND PRED(DIC_SIZE); Inc(idx2); If (idx2 = count) then EXIT; Dec(dec_counter); end; Repeat idx := DecodeChar; If (idx <= 255) then begin buffer^[idx2] := idx; Inc(idx2); If (idx2 = count) then EXIT; end else begin dec_counter := idx-(256-THRESHOLD); dec_ptr := (idx2-DecodePtr-1) AND PRED(DIC_SIZE); Dec(dec_counter); While (dec_counter >= 0) do begin buffer^[idx2] := buffer^[dec_ptr]; dec_ptr := SUCC(dec_ptr) AND PRED(DIC_SIZE); Inc(idx2); If (idx2 = count) then EXIT; Dec(dec_counter); end; end; until FALSE; end; function LZH_decompress(var source,dest; size: Dword): Dword; var ptr: pBYTE; size_temp: Dword; ultra_compression_flag: Boolean; begin LZH_decompress := 0; input_buffer := Addr(source); input_buffer_idx := 0; ultra_compression_flag := BOOLEAN(input_buffer^[input_buffer_idx]); Inc(input_buffer_idx); input_buffer_size := size; output_buffer := Addr(dest); output_buffer_idx := 0; Move(input_buffer^[input_buffer_idx],size_unpacked,SizeOf(size_unpacked)); Inc(input_buffer_idx,SizeOf(size_unpacked)); size := size_unpacked; If ultra_compression_flag then DIC_SIZE := DIC_SIZE_MAX else DIC_SIZE := DIC_SIZE_DEF; GetMem(ptr,DIC_SIZE); bit_buf := 0; sbit_buf := 0; bit_count := 0; FillBitBuffer(16); block_size := 0; dec_counter := 0; While (size > 0) do begin If (size > DIC_SIZE) then size_temp := DIC_SIZE else size_temp := size; DecodeBuffer(size_temp,ptr); WriteDataBlock(ptr,size_temp); Dec(size,size_temp); end; FreeMem(ptr,DIC_SIZE); LZH_decompress := size_unpacked; end; end. adlibtracker2-2.4.23/adt2play/a2player.pas0000644000000000000000000050200113176573533016770 0ustar rootrootunit A2player; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const ___UNIT_DATA_START___: Dword = 0; const MAX_IRQ_FREQ = 1000; timer_poll_proc_ptr: Pointer = NIL; timer_initialized: Boolean = FALSE; {$i typconst.inc} const opl3port: Word = $388; error_code: Integer = 0; current_order: Byte = 0; current_pattern: Byte = 0; current_line: Byte = 0; tempo: Byte = 50; speed: Byte = 6; macro_speedup: Word = 1; max_patterns: Byte = 128; fast_forward: Boolean = FALSE; overall_volume: Byte = 63; global_volume: Byte = 63; fade_out_volume: Byte = 63; const song_timer: Word = 0; song_timer_tenths: Word = 0; ticklooper: Longint = 0; macro_ticklooper: Longint = 0; timer_ticklooper: Longint = 0; timer_200hz_counter: Longint = 0; timer_50hz_counter: Longint = 0; timer_20hz_counter: Longint = 0; timer_200hz_flag: Boolean = FALSE; timer_50hz_flag: Boolean = FALSE; timer_20hz_flag: Boolean = FALSE; var timer_temp: Word; ticks,tick0,tickD, tickXF: Longint; limit_exceeded: Boolean; var time_playing: Real; pattdata: ^tPATTERN_DATA; songdata: tFIXED_SONGDATA; old_songdata: tOLD_FIXED_SONGDATA; old_hash_buffer: tOLD_VARIABLE_DATA1; hash_buffer: tOLD_VARIABLE_DATA2; const irq_freq: Word = 50; timer_fix: Boolean = TRUE; pattern_break: Boolean = FALSE; pattern_break_loop: Boolean = FALSE; pattern_break_docmd: Boolean = FALSE; pattern_break_oldord: Byte = BYTE_NULL; pattern_delay: Boolean = FALSE; next_line: Byte = 0; play_status: tPLAY_STATUS = isStopped; replay_forbidden: Boolean = TRUE; force_macro_keyon: Boolean = FALSE; type tDECAY_BAR = Record dir: Integer; lvl,max_lvl: Real; end; var decay_bar: array[1..96] of tDECAY_BAR; procedure start_playing; procedure set_overall_volume(level: Byte); procedure stop_playing; procedure init_old_songdata; procedure init_songdata; procedure init_timer_proc; procedure done_timer_proc; procedure get_chunk(pattern,line,chan: Byte; var chunk: tCHUNK); procedure put_chunk(pattern,line,chan: Byte; chunk: tCHUNK); procedure count_order(var entries: Byte); procedure timer_poll_proc; procedure opl2out_proc(reg,data: Word); procedure opl3out_proc(reg,data: Word); procedure opl3exp_proc(data: Word); procedure DisableTimerIRQ_proc; procedure EnableTimerIRQ_proc; function calc_following_order(order: Byte): Integer; function is_4op_chan(chan: Byte): Boolean; function min(value: Longint; minimum: Longint): Longint; function max(value: Longint; maximum: Longint): Longint; function asciiz_string(str: String): String; type tOPLOUT_proc = procedure(reg,data: Word); tOPLEXP_proc = procedure(data: Word); const opl2out: tOPLOUT_proc = opl2out_proc; opl3out: tOPLOUT_proc = opl3out_proc; opl3exp: tOPLEXP_proc = opl3exp_proc; DisableTimerIRQ: procedure = DisableTimerIRQ_proc; EnableTimerIRQ: procedure = EnableTimerIRQ_proc; const ___UNIT_DATA_END___: Dword = 0; implementation uses DOS,GO32,ISS_TIM, A2fileIO; const ___IRQ_DATA_START___: Dword = 0; procedure ___IRQ_CODE_START___; begin end; const keyoff_flag = $080; fixed_note_flag = $090; pattern_loop_flag = $0e0; pattern_break_flag = $0f0; const MACRO_NOTE_RETRIG_FLAG = $80; MACRO_ENVELOPE_RESTART_FLAG = $40; MACRO_ZERO_FREQ_FLAG = $20; const def_vibtrem_speed_factor: Byte = 1; def_vibtrem_table_size: Byte = 32; def_vibtrem_table: array[0..255] of Byte = ( 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24); var vibtrem_speed_factor: Byte; vibtrem_table_size: Byte; vibtrem_table: array[0..255] of Byte; type tVIBRATO_TREMOLO_TABLE = array[1..20] of Record pos: Byte; dir: Byte; speed: Byte; depth: Byte; fine: Boolean; end; var vibr_table: tVIBRATO_TREMOLO_TABLE; vibr_table2: tVIBRATO_TREMOLO_TABLE; trem_table: tVIBRATO_TREMOLO_TABLE; trem_table2: tVIBRATO_TREMOLO_TABLE; var fmpar_table: array[1..20] of tFM_PARAMETER_TABLE; volume_lock: array[1..20] of Boolean; vol4op_lock: array[1..20] of Boolean; volume_table: array[1..20] of Word; vscale_table: array[1..20] of Word; peak_lock: array[1..20] of Boolean; pan_lock: array[1..20] of Boolean; event_table: array[1..20] of tCHUNK; voice_table: array[1..20] of Byte; modulator_vol: array[1..20] of Byte; carrier_vol: array[1..20] of Byte; freq_table: array[1..20] of Word; zero_fq_table: array[1..20] of Word; effect_table: array[1..20] of Word; effect_table2: array[1..20] of Word; fslide_table: array[1..20] of Byte; fslide_table2: array[1..20] of Byte; glfsld_table: array[1..20] of Word; glfsld_table2: array[1..20] of Word; porta_table: array[1..20] of Record freq: Word; speed: Byte; end; porta_table2: array[1..20] of Record freq: Word; speed: Byte; end; portaFK_table: array[1..20] of Boolean; arpgg_table: array[1..20] of Record state,note,add1,add2: Byte; end; arpgg_table2: array[1..20] of Record state,note,add1,add2: Byte; end; retrig_table: array[1..20] of Byte; retrig_table2: array[1..20] of Byte; tremor_table: array[1..20] of Record pos: Integer; volume: Word; end; tremor_table2: array[1..20] of Record pos: Integer; volume: Word; end; panning_table: array[1..20] of Byte; last_effect: array[1..20] of Word; last_effect2: array[1..20] of Word; volslide_type: array[1..20] of Byte; event_new: array[1..20] of Boolean; notedel_table: array[1..20] of Byte; notecut_table: array[1..20] of Byte; ftune_table: array[1..20] of Shortint; keyoff_loop: array[1..20] of Boolean; macro_table: array[1..20] of Record fmreg_pos,arpg_pos,vib_pos: Word; fmreg_count,fmreg_duration,arpg_count, vib_count,vib_delay: Byte; vib_paused: Boolean; fmreg_table,arpg_table,vib_table: Byte; arpg_note: Byte; vib_freq: Word; end; loopbck_table: array[1..20] of Byte; loop_table: array[1..20,0..255] of Byte; misc_register: Byte; const current_tremolo_depth: Byte = 0; current_vibrato_depth: Byte = 0; var speed_update,lockvol,panlock,lockVP: Boolean; tremolo_depth,vibrato_depth: Byte; volume_scaling,percussion_mode: Boolean; last_order: Byte; reset_chan: array[1..20] of Boolean; var _opl_regs_cache: array[WORD] of Word; procedure opl2out_proc(reg,data: Word); begin If (_opl_regs_cache[reg] <> data) then _opl_regs_cache[reg] := data else EXIT; asm mov ax,reg mov dx,word ptr [opl3port] or ah,ah jz @@1 add dx,2 @@1: out dx,al mov ecx,6 @@2: in al,dx loop @@2 inc dl mov ax,data out dx,al dec dl mov ecx,36 @@3: in al,dx loop @@3 end; end; procedure opl3out_proc(reg,data: Word); begin If (_opl_regs_cache[reg] <> data) then _opl_regs_cache[reg] := data else EXIT; asm mov ax,reg mov dx,word ptr [opl3port] or ah,ah jz @@1 add dx,2 @@1: out dx,al inc dl mov ax,data out dx,al dec dl mov ecx,26 @@2: in al,dx loop @@2 end; end; procedure opl3exp_proc(data: Word); begin if (_opl_regs_cache[(data AND $ff) OR $100] <> data SHR 8) then _opl_regs_cache[(data AND $ff) OR $100] := data SHR 8 else EXIT; asm mov ax,data mov dx,word ptr [opl3port] add dx,2 out dx,al mov ecx,6 @@1: in al,dx loop @@1 inc dl mov al,ah out dx,al mov ecx,36 @@2: in al,dx loop @@2 end; end; const FreqStart = $156; FreqEnd = $2ae; FreqRange = FreqEnd-FreqStart; function nFreq(note: Byte): Word; const Fnum: array[0..11] of Word = ( $157,$16b,$181,$198,$1b0,$1ca,$1e5,$202,$220,$241,$263,$287); var result: Word; begin asm xor ebx,ebx mov al,[note] xor ah,ah cmp ax,12*8 jae @@1 push eax mov bl,12 div bl mov bl,ah xor bh,bh shl bx,1 pop eax mov cl,12 div cl xor ah,ah shl ax,10 add ax,word ptr [Fnum+ebx] jmp @@2 @@1: mov ax,7 shl ax,10 add ax,FreqEnd @@2: mov result,ax end; nFreq := result; end; function calc_freq_shift_up(freq,shift: Word): Word; var result: Word; begin asm mov cx,freq mov ax,shift mov bx,cx and bx,0000001111111111b mov dx,cx and dx,0001110000000000b add bx,ax and cx,1110000000000000b shr dx,10 cmp bx,FreqEnd jb @@2 cmp dx,7 jnz @@1 mov bx,FreqEnd jmp @@2 @@1: sub bx,FreqRange inc dx @@2: mov ax,cx shl dx,10 add ax,dx add ax,bx mov result,ax end; calc_freq_shift_up := result; end; function calc_freq_shift_down(freq,shift: Word): Word; var result: Word; begin asm mov cx,freq mov ax,shift mov bx,cx and bx,0000001111111111b mov dx,cx and dx,0001110000000000b sub bx,ax and cx,1110000000000000b shr dx,10 cmp bx,FreqStart ja @@2 or dx,dx jnz @@1 mov bx,FreqStart jmp @@2 @@1: add bx,FreqRange dec dx @@2: mov ax,cx shl dx,10 add ax,dx add ax,bx mov result,ax end; calc_freq_shift_down := result; end; function calc_vibtrem_shift(chan: Byte; var table_data): Word; var pos,dir,depth: Byte; result: Word; begin pos := tVIBRATO_TREMOLO_TABLE(table_data)[chan].pos; depth := tVIBRATO_TREMOLO_TABLE(table_data)[chan].depth; asm xor ebx,ebx mov al,depth xor ah,ah mov bl,pos xor bh,bh mov dh,bl mov cl,byte ptr [vibtrem_table_size] dec cl and bl,cl mov dl,byte ptr [vibtrem_table+ebx] mul dl rol ax,1 xchg ah,al and ah,1 mov dir,1 mov dl,byte ptr [vibtrem_table_size] test dh,dl jne @@1 mov dir,0 @@1: mov result,ax end; tVIBRATO_TREMOLO_TABLE(table_data)[chan].dir := dir; calc_vibtrem_shift := result; end; procedure change_freq(chan: Byte; freq: Word); begin If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin freq_table[SUCC(chan)] := freq_table[chan]; chan := SUCC(chan); end; asm xor ebx,ebx mov bl,chan dec ebx shl ebx,1 mov ax,freq and ax,1fffh mov dx,word ptr [freq_table+ebx] and dx,NOT 1fffh add ax,dx mov word ptr [freq_table+ebx],ax xor edx,edx mov dx,word ptr [_chan_n+ebx] add dx,0a0h push edx xor edx,edx mov dl,al push edx mov dx,word ptr [_chan_n+ebx] add dx,0b0h push edx xor edx,edx mov dl,ah push edx call opl3out call opl3out @@1: end; If is_4op_chan(chan) then freq_table[PRED(chan)] := freq_table[chan]; end; function ins_parameter(ins,param: Byte): Byte; var result: Byte; begin asm xor ebx,ebx lea esi,[songdata.instr_data] mov bl,ins dec ebx mov eax,INSTRUMENT_SIZE mul ebx add esi,eax mov bl,param add esi,ebx lodsb mov result,al end; ins_parameter := result; end; function is_chan_adsr_data_empty(chan: Byte): Boolean; begin is_chan_adsr_data_empty := (fmpar_table[chan].adsrw_car.attck = 0) and (fmpar_table[chan].adsrw_mod.attck = 0) and (fmpar_table[chan].adsrw_car.dec = 0) and (fmpar_table[chan].adsrw_mod.dec = 0) and (fmpar_table[chan].adsrw_car.sustn = 0) and (fmpar_table[chan].adsrw_mod.sustn = 0) and (fmpar_table[chan].adsrw_car.rel = 0) and (fmpar_table[chan].adsrw_mod.rel = 0); end; function is_ins_adsr_data_empty(ins: Byte): Boolean; begin is_ins_adsr_data_empty := (ins_parameter(ins,5) SHR 4 = 0) and (ins_parameter(ins,4) SHR 4 = 0) and (ins_parameter(ins,5) AND $0f = 0) and (ins_parameter(ins,4) AND $0f = 0) and (ins_parameter(ins,7) SHR 4 = 0) and (ins_parameter(ins,6) SHR 4 = 0) and (ins_parameter(ins,7) AND $0f = 0) and (ins_parameter(ins,6) AND $0f = 0); end; function is_data_empty(var buf; size: Longint): Boolean; var result: Boolean; begin asm xor edx,edx mov eax,size cmp eax,16 jb @@3 mov ecx,4 div ecx mov ecx,eax jecxz @@1 mov edi,[buf] xor eax,eax repz scasd jnz @@2 mov ecx,edx jecxz @@1 repz scasb jnz @@2 @@1: mov result,TRUE jmp @@6 @@2: mov result,FALSE jmp @@6 @@3: mov ecx,size jecxz @@4 mov edi,[buf] xor eax,eax repz scasb jnz @@5 @@4: mov result,TRUE jmp @@6 @@5: mov result,FALSE @@6: end; is_data_empty := result; end; function min(value: Longint; minimum: Longint): Longint; begin If (value > minimum) then min := value else min := minimum; end; function max(value: Longint; maximum: Longint): Longint; begin If (value < maximum) then max := value else max := maximum; end; function asciiz_string(str: String): String; begin If (Pos(#0,str) <> 0) then asciiz_string := Copy(str,1,Pos(#0,str)-1) else asciiz_string := ''; end; function concw(lo,hi: Byte): Word; begin concw := lo+(hi SHL 8); end; procedure synchronize_song_timer; begin song_timer := TRUNC(time_playing); song_timer_tenths := TRUNC(time_playing*100) MOD 100; timer_temp := song_timer_tenths; end; procedure change_frequency(chan: Byte; freq: Word); begin macro_table[chan].vib_paused := TRUE; change_freq(chan,freq); If is_4op_chan(chan) then If (chan in _4op_tracks_hi) then begin macro_table[SUCC(chan)].vib_count := 1; macro_table[SUCC(chan)].vib_pos := 0; macro_table[SUCC(chan)].vib_freq := freq; macro_table[SUCC(chan)].vib_paused := FALSE; end else begin macro_table[PRED(chan)].vib_count := 1; macro_table[PRED(chan)].vib_pos := 0; macro_table[PRED(chan)].vib_freq := freq; macro_table[PRED(chan)].vib_paused := FALSE; end; macro_table[chan].vib_count := 1; macro_table[chan].vib_pos := 0; macro_table[chan].vib_freq := freq; macro_table[chan].vib_paused := FALSE; end; function _macro_speedup: Word; begin If (macro_speedup > 0) then _macro_speedup := macro_speedup else _macro_speedup := macro_speedup+1; end; procedure TimerSetup(Hz: Longint); forward; procedure update_timer(Hz: Longint); begin _debug_str_ := 'A2PLAYER.PAS:update_timer'; If (Hz = 0) then begin TimerSetup(18); EXIT end else tempo := Hz; If (tempo = 18) and timer_fix then IRQ_freq := TRUNC((tempo+0.2)*20) else IRQ_freq := 250; While (IRQ_freq MOD (tempo*_macro_speedup) <> 0) do Inc(IRQ_freq); If (IRQ_freq > MAX_IRQ_FREQ) then IRQ_freq := MAX_IRQ_FREQ; TimerSetup(IRQ_freq); end; procedure key_on(chan: Byte); begin If NOT (is_4op_chan(chan) and (chan in _4op_tracks_hi)) then opl3out($0b0+_chan_n[chan],0) else opl3out($0b0+_chan_n[SUCC(chan)],0); end; procedure key_off(chan: Byte); begin freq_table[chan] := LO(freq_table[chan])+ (HI(freq_table[chan]) AND NOT $20) SHL 8; change_freq(chan,freq_table[chan]); event_table[chan].note := event_table[chan].note OR keyoff_flag; end; procedure release_sustaining_sound(chan: Byte); begin opl3out(_instr[02]+_chan_m[chan],63); opl3out(_instr[03]+_chan_c[chan],63); FillChar(fmpar_table[chan].adsrw_car, SizeOf(fmpar_table[chan].adsrw_car),0); FillChar(fmpar_table[chan].adsrw_mod, SizeOf(fmpar_table[chan].adsrw_mod),0); key_on(chan); opl3out(_instr[04]+_chan_m[chan],BYTE_NULL); opl3out(_instr[05]+_chan_c[chan],BYTE_NULL); opl3out(_instr[06]+_chan_m[chan],BYTE_NULL); opl3out(_instr[07]+_chan_c[chan],BYTE_NULL); key_off(chan); event_table[chan].instr_def := 0; reset_chan[chan] := TRUE; end; function scale_volume(volume,scale_factor: Byte): Byte; begin scale_volume := 63-Round((63-volume)/63* (63-scale_factor)); end; function _4op_data_flag(chan: Byte): Dword; var _4op_conn: Byte; _4op_mode: Boolean; _4op_ch1,_4op_ch2: Byte; _4op_ins1,_4op_ins2: Byte; begin _4op_mode := FALSE; If is_4op_chan(chan) then begin _4op_mode := TRUE; If (chan in _4op_tracks_hi) then begin _4op_ch1 := chan; _4op_ch2 := SUCC(chan); end else begin _4op_ch1 := PRED(chan); _4op_ch2 := chan; end; _4op_ins1 := event_table[_4op_ch1].instr_def; If (_4op_ins1 = 0) then _4op_ins1 := voice_table[_4op_ch1]; _4op_ins2 := event_table[_4op_ch2].instr_def; If (_4op_ins2 = 0) then _4op_ins2 := voice_table[_4op_ch2]; If (_4op_ins1 <> 0) and (_4op_ins2 <> 0) then begin _4op_mode := TRUE; _4op_conn := (pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[_instr_data_ofs[11]] AND 1) SHL 1 + (pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[_instr_data_ofs[11]] AND 1); end; end; {------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---} { BIT |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0 } {------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---} { DATA |..|..|..|..|..|F7|F6|F5|F4|F3|F2|F1|F0|E7|E6|E5|E4|E3|E2|E1|E0|D3|D2|D1|D0|C3|C2|C1|C0|B1|B0|A0 } {------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---} _4op_data_flag := ORD(_4op_mode) + {1-bit: A0} (_4op_conn AND 3) SHL 1 + {2-bit: B1-B0} (_4op_ch1 AND 15) SHL 3 + {4-bit: C3-C0} (_4op_ch2 AND 15) SHL 7 + {4-bit: D3-D0} _4op_ins1 SHL 11 + {8-bit: E7-E0} _4op_ins2 SHL 19; {8-bit: F7-F0} end; function _4op_vol_valid_chan(chan: Byte): Boolean; var _4op_flag: Dword; begin _4op_flag := _4op_data_flag(chan); _4op_vol_valid_chan := BOOLEAN(_4op_flag AND 1) and vol4op_lock[chan] and (BYTE(_4op_flag SHR 11) <> 0) and (BYTE(_4op_flag SHR 19) <> 0); end; procedure set_ins_volume(modulator,carrier,chan: Byte); var temp: Byte; begin If (modulator <> BYTE_NULL) then begin temp := modulator; If volume_scaling then If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator); If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then opl3out(_instr[02]+_chan_m[chan], scale_volume(scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+LO(vscale_table[chan])) else opl3out(_instr[02]+_chan_m[chan], temp+LO(vscale_table[chan])); volume_table[chan] := concw(temp,HI(volume_table[chan])); If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then modulator_vol[chan] := 63-scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)) else modulator_vol[chan] := 63-modulator; end; If (carrier <> BYTE_NULL) then begin temp := carrier; If volume_scaling then carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier); opl3out(_instr[03]+_chan_c[chan], scale_volume(scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+HI(vscale_table[chan])); volume_table[chan] := concw(LO(volume_table[chan]),temp); carrier_vol[chan] := 63-scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)); end; end; procedure set_ins_volume_4op(volume,chan: Byte); var _4op_flag: Dword; _4op_conn: Byte; _4op_ch1,_4op_ch2: Byte; procedure set_volume(modulator,carrier,chan: Byte); var temp: Byte; begin If (modulator <> BYTE_NULL) then begin temp := modulator; modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator); opl3out(_instr[02]+_chan_m[chan], scale_volume(scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+LO(vscale_table[chan])); volume_table[chan] := concw(temp,HI(volume_table[chan])); modulator_vol[chan] := 63-scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)) end; If (carrier <> BYTE_NULL) then begin temp := carrier; carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier); opl3out(_instr[03]+_chan_c[chan], scale_volume(scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+HI(vscale_table[chan])); volume_table[chan] := concw(LO(volume_table[chan]),temp); carrier_vol[chan] := 63-scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)); end; end; begin _4op_flag := _4op_data_flag(chan); _4op_conn := (_4op_flag SHR 1) AND 3; _4op_ch1 := (_4op_flag SHR 3) AND 15; _4op_ch2 := (_4op_flag SHR 7) AND 15; If _4op_vol_valid_chan(chan) then Case _4op_conn of // FM/FM 0: If (volume = BYTE_NULL) then set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1) else set_volume(BYTE_NULL,volume,_4op_ch1); // FM/AM 1: If (volume = BYTE_NULL) then begin set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1); set_volume(LO(volume_table[_4op_ch2]),BYTE_NULL,_4op_ch2); end else begin set_volume(BYTE_NULL,volume,_4op_ch1); set_volume(volume,BYTE_NULL,_4op_ch2); end; // AM/FM 2: If (volume = BYTE_NULL) then begin set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1); set_volume(BYTE_NULL,HI(volume_table[_4op_ch2]),_4op_ch2); end else begin set_volume(BYTE_NULL,volume,_4op_ch1); set_volume(BYTE_NULL,volume,_4op_ch2); end; // AM/AM 3: If (volume = BYTE_NULL) then begin set_volume(LO(volume_table[_4op_ch1]),HI(volume_table[_4op_ch1]),_4op_ch1); set_volume(LO(volume_table[_4op_ch2]),BYTE_NULL,_4op_ch2); end else begin set_volume(volume,volume,_4op_ch1); set_volume(volume,BYTE_NULL,_4op_ch2); end; end; end; procedure reset_ins_volume(chan: Byte); begin If NOT volume_scaling then set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f, ins_parameter(voice_table[chan],3) AND $3f,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,0,chan) else set_ins_volume(0,0,chan); end; procedure set_global_volume; var chan: Byte; begin For chan := 1 to songdata.nm_tracks do If _4op_vol_valid_chan(chan) then set_ins_volume_4op(BYTE_NULL,chan) else If NOT ((carrier_vol[chan] = 0) and (modulator_vol[chan] = 0)) then If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(BYTE_NULL,HI(volume_table[chan]),chan) else set_ins_volume(LO(volume_table[chan]),HI(volume_table[chan]),chan); end; procedure set_overall_volume(level: Byte); begin overall_volume := max(level,63); set_global_volume; end; procedure init_macro_table(chan,note,ins: Byte; freq: Word); begin macro_table[chan].fmreg_count := 1; macro_table[chan].fmreg_pos := 0; macro_table[chan].fmreg_duration := 0; macro_table[chan].fmreg_table := ins; macro_table[chan].arpg_count := 1; macro_table[chan].arpg_pos := 0; macro_table[chan].arpg_table := songdata.instr_macros[ins].arpeggio_table; macro_table[chan].arpg_note := note; macro_table[chan].vib_count := 1; macro_table[chan].vib_paused := FALSE; macro_table[chan].vib_pos := 0; macro_table[chan].vib_table := songdata.instr_macros[ins].vibrato_table; macro_table[chan].vib_freq := freq; macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; zero_fq_table[chan] := 0; end; procedure set_ins_data(ins,chan: Byte); var old_ins: Byte; begin If (ins <> event_table[chan].instr_def) or reset_chan[chan] then begin opl3out(_instr[02]+_chan_m[chan],63); opl3out(_instr[03]+_chan_c[chan],63); If NOT pan_lock[chan] then panning_table[chan] := ins_parameter(ins,11) else panning_table[chan] := songdata.lock_flags[chan] AND 3; opl3out(_instr[00]+_chan_m[chan],ins_parameter(ins,0)); opl3out(_instr[01]+_chan_c[chan],ins_parameter(ins,1)); opl3out(_instr[04]+_chan_m[chan],ins_parameter(ins,4)); opl3out(_instr[05]+_chan_c[chan],ins_parameter(ins,5)); opl3out(_instr[06]+_chan_m[chan],ins_parameter(ins,6)); opl3out(_instr[07]+_chan_c[chan],ins_parameter(ins,7)); opl3out(_instr[08]+_chan_m[chan],ins_parameter(ins,8)); opl3out(_instr[09]+_chan_c[chan],ins_parameter(ins,9)); opl3out(_instr[10]+_chan_n[chan],ins_parameter(ins,10) OR _panning[panning_table[chan]]); fmpar_table[chan].connect := ins_parameter(ins,10) AND 1; fmpar_table[chan].feedb := ins_parameter(ins,10) SHR 1 AND 7; fmpar_table[chan].multipM := ins_parameter(ins,0) AND $0f; fmpar_table[chan].kslM := ins_parameter(ins,2) SHR 6; fmpar_table[chan].tremM := ins_parameter(ins,0) SHR 7; fmpar_table[chan].vibrM := ins_parameter(ins,0) SHR 6 AND 1; fmpar_table[chan].ksrM := ins_parameter(ins,0) SHR 4 AND 1; fmpar_table[chan].sustM := ins_parameter(ins,0) SHR 5 AND 1; fmpar_table[chan].multipC := ins_parameter(ins,1) AND $0f; fmpar_table[chan].kslC := ins_parameter(ins,3) SHR 6; fmpar_table[chan].tremC := ins_parameter(ins,1) SHR 7; fmpar_table[chan].vibrC := ins_parameter(ins,1) SHR 6 AND 1; fmpar_table[chan].ksrC := ins_parameter(ins,1) SHR 4 AND 1; fmpar_table[chan].sustC := ins_parameter(ins,1) SHR 5 AND 1; fmpar_table[chan].adsrw_car.attck := ins_parameter(ins,5) SHR 4; fmpar_table[chan].adsrw_mod.attck := ins_parameter(ins,4) SHR 4; fmpar_table[chan].adsrw_car.dec := ins_parameter(ins,5) AND $0f; fmpar_table[chan].adsrw_mod.dec := ins_parameter(ins,4) AND $0f; fmpar_table[chan].adsrw_car.sustn := ins_parameter(ins,7) SHR 4; fmpar_table[chan].adsrw_mod.sustn := ins_parameter(ins,6) SHR 4; fmpar_table[chan].adsrw_car.rel := ins_parameter(ins,7) AND $0f; fmpar_table[chan].adsrw_mod.rel := ins_parameter(ins,6) AND $0f; fmpar_table[chan].adsrw_car.wform := ins_parameter(ins,9) AND $07; fmpar_table[chan].adsrw_mod.wform := ins_parameter(ins,8) AND $07; If NOT reset_chan[chan] then keyoff_loop[chan] := FALSE; If reset_chan[chan] then begin voice_table[chan] := ins; reset_ins_volume(chan); reset_chan[chan] := FALSE; end; If (event_table[chan].note AND $7f in [1..12*8+1]) then init_macro_table(chan,event_table[chan].note AND $7f,ins,freq_table[chan]) else init_macro_table(chan,0,ins,freq_table[chan]); end; vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6, fmpar_table[chan].kslC SHL 6); voice_table[chan] := ins; old_ins := event_table[chan].instr_def; event_table[chan].instr_def := ins; If NOT volume_lock[chan] or (ins <> old_ins) then reset_ins_volume(chan); end; procedure update_modulator_adsrw(chan: Byte); begin opl3out(_instr[04]+_chan_m[chan], fmpar_table[chan].adsrw_mod.attck SHL 4+ fmpar_table[chan].adsrw_mod.dec); opl3out(_instr[06]+_chan_m[chan], fmpar_table[chan].adsrw_mod.sustn SHL 4+ fmpar_table[chan].adsrw_mod.rel); opl3out(_instr[08]+_chan_m[chan], fmpar_table[chan].adsrw_mod.wform); end; procedure update_carrier_adsrw(chan: Byte); begin opl3out(_instr[05]+_chan_c[chan], fmpar_table[chan].adsrw_car.attck SHL 4+ fmpar_table[chan].adsrw_car.dec); opl3out(_instr[07]+_chan_c[chan], fmpar_table[chan].adsrw_car.sustn SHL 4+ fmpar_table[chan].adsrw_car.rel); opl3out(_instr[09]+_chan_c[chan], fmpar_table[chan].adsrw_car.wform); end; procedure update_fmpar(chan: Byte); begin opl3out(_instr[00]+_chan_m[chan],fmpar_table[chan].multipM+ fmpar_table[chan].ksrM SHL 4+ fmpar_table[chan].sustM SHL 5+ fmpar_table[chan].vibrM SHL 6+ fmpar_table[chan].tremM SHL 7); opl3out(_instr[01]+_chan_c[chan],fmpar_table[chan].multipC+ fmpar_table[chan].ksrC SHL 4+ fmpar_table[chan].sustC SHL 5+ fmpar_table[chan].vibrC SHL 6+ fmpar_table[chan].tremC SHL 7); opl3out(_instr[10]+_chan_n[chan],(fmpar_table[chan].connect+ fmpar_table[chan].feedb SHL 1) OR _panning[panning_table[chan]]); vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6, fmpar_table[chan].kslC SHL 6); set_ins_volume(LO(volume_table[chan]), HI(volume_table[chan]),chan); end; function is_4op_chan(chan: Byte): Boolean; var result: Boolean; begin asm mov al,byte ptr [songdata.flag_4op] mov ah,chan test al,1 jz @@1 cmp ah,1 jb @@1 cmp ah,2 ja @@1 mov result,TRUE jmp @@7 @@1: test al,2 jz @@2 cmp ah,3 jb @@2 cmp ah,4 ja @@2 mov result,TRUE jmp @@7 @@2: test al,4 jz @@3 cmp ah,5 jb @@3 cmp ah,6 ja @@3 mov result,TRUE jmp @@7 @@3: test al,8 jz @@4 cmp ah,10 jb @@4 cmp ah,11 ja @@4 mov result,TRUE jmp @@7 @@4: test al,10h jz @@5 cmp ah,12 jb @@5 cmp ah,13 ja @@5 mov result,TRUE jmp @@7 @@5: test al,20h jz @@6 cmp ah,14 jb @@6 cmp ah,15 ja @@6 mov result,TRUE jmp @@7 @@6: mov result,FALSE @@7: end; is_4op_chan := result; end; procedure output_note(note,ins,chan: Byte; restart_macro,restart_adsr: Boolean); var pos: Byte; freq: Word; begin If (note = 0) and (ftune_table[chan] = 0) then EXIT; If NOT (note in [1..12*8+1]) then freq := freq_table[chan] else begin freq := nFreq(note-1)+SHORTINT(ins_parameter(ins,12)); If restart_adsr then key_on(chan); freq_table[chan] := concw(LO(freq_table[chan]), HI(freq_table[chan]) OR $20); pos := Round(25/(12*8+1)*note); If (decay_bar[pos].lvl <> 0) then If (pos > 1) and (decay_bar[pos-1].dir <> 1) then Dec(pos) else If (pos < 25) and (decay_bar[pos+1].lvl <> 1) then Inc(pos); If is_4op_chan(chan) then begin decay_bar[pos].dir := 1; If (ins_parameter(voice_table[chan],10) AND 1 = 0) then decay_bar[pos].max_lvl := (carrier_vol[PRED(chan)]+carrier_vol[chan]) DIV 2 else decay_bar[pos].max_lvl := (carrier_vol[PRED(chan)]+modulator_vol[PRED(chan)]+ carrier_vol[chan]+modulator_vol[chan]) DIV 4; end else begin decay_bar[pos].dir := 1; If (ins_parameter(voice_table[chan],10) AND 1 = 0) then decay_bar[pos].max_lvl := carrier_vol[chan] else decay_bar[pos].max_lvl := (carrier_vol[chan]+modulator_vol[chan]) DIV 2; end; end; If (ftune_table[chan] = -127) then ftune_table[chan] := 0; freq := freq+ftune_table[chan]; change_frequency(chan,freq); If (note <> 0) then begin event_table[chan].note := note; If is_4op_chan(chan) then event_table[PRED(chan)].note := note; If restart_macro then With event_table[chan] do If NOT (((effect_def = ef_Extended) and (effect DIV 16 = ef_ex_ExtendedCmd2) and (effect MOD 16 = ef_ex_cmd2_NoRestart)) or ((effect_def2 = ef_Extended) and (effect2 DIV 16 = ef_ex_ExtendedCmd2) and (effect2 MOD 16 = ef_ex_cmd2_NoRestart))) then init_macro_table(chan,note,ins,freq) else macro_table[chan].arpg_note := note; end; end; procedure generate_custom_vibrato(value: Byte); const vibtab_size: array[0..15] of Byte = ( 16,16,16,16,32,32,32,32,64,64,64,64,128,128,128,128); var mul_r: Real; mul_b: Byte; idx,idx2: Byte; function min0(value: Longint): Longint; begin If (value >= 0) then min0 := value else min0 := 0; end; begin Case value of // set default speed table 0: begin vibtrem_table_size := def_vibtrem_table_size; Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table)); end; // set custom speed table (fixed size = 32) 1..239: begin vibtrem_table_size := def_vibtrem_table_size; mul_r := value/16; For idx2 := 0 to 7 do begin vibtrem_table[idx2*32] := 0; For idx := 1 to 16 do vibtrem_table[idx2*32+idx] := ROUND(idx*mul_r); For idx := 17 to 31 do vibtrem_table[idx2*32+idx] := ROUND((32-idx)*mul_r); end; end; // set custom speed table (speed factor = 1-4) 240..255: begin vibtrem_speed_factor := SUCC((value-240) MOD 4); vibtrem_table_size := 2*vibtab_size[value-240]; mul_b := 256 DIV (vibtab_size[value-240]); For idx2 := 0 to PRED(128 DIV vibtab_size[value-240]) do begin vibtrem_table[2*vibtab_size[value-240]*idx2] := 0; For idx := 1 to vibtab_size[value-240] do vibtrem_table[2*vibtab_size[value-240]*idx2+idx] := min0(idx*mul_b-1); For idx := vibtab_size[value-240]+1 to 2*vibtab_size[value-240]-1 do vibtrem_table[2*vibtab_size[value-240]*idx2+idx] := min0((2*vibtab_size[value-240]-idx)*mul_b-1); end; end; end; end; procedure update_fine_effects(chan: Byte); forward; procedure play_line; var chan,idx: Byte; event: array[1..20] of tCHUNK; eLo,eHi,eLo2,eHi2: array[1..20] of Byte; tporta_flag: Boolean; function no_loop(current_chan,current_line: Byte): Boolean; var result: Boolean; chan: Byte; begin result := TRUE; For chan := 1 to PRED(current_chan) do If (loop_table[chan][current_line] <> 0) and (loop_table[chan][current_line] <> BYTE_NULL) then begin result := FALSE; BREAK; end; no_loop := result; end; begin _debug_str_ := 'A2PLAYER.PAS:play_line'; If (current_line = 0) and (current_order = calc_following_order(0)) then time_playing := 0; If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and (current_order <> last_order) then begin FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); last_order := current_order; end; For chan := 1 to songdata.nm_tracks do begin event[chan] := pattdata^[current_pattern DIV 8][current_pattern MOD 8] [chan][current_line]; If (effect_table[chan] <> 0) then last_effect[chan] := effect_table[chan]; If (glfsld_table[chan] <> 0) then effect_table[chan] := glfsld_table[chan] else effect_table[chan] := effect_table[chan] AND $0ff00; If (effect_table2[chan] <> 0) then last_effect2[chan] := effect_table2[chan]; If (glfsld_table2[chan] <> 0) then effect_table2[chan] := glfsld_table2[chan] else effect_table2[chan] := effect_table2[chan] AND $0ff00; ftune_table[chan] := 0; If (event[chan].note = BYTE_NULL) then event[chan].note := event_table[chan].note OR keyoff_flag else If (event[chan].note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then event[chan].note := event[chan].note-fixed_note_flag; If (event[chan].note <> 0) or (event[chan].effect_def <> 0) or (event[chan].effect_def2 <> 0) or ((event[chan].effect_def = 0) and (event[chan].effect <> 0)) or ((event[chan].effect_def2 = 0) and (event[chan].effect2 <> 0)) then event_new[chan] := TRUE else event_new[chan] := FALSE; If (event[chan].note <> 0) or (event[chan].instr_def <> 0) or (event[chan].effect_def+event[chan].effect <> 0) or (event[chan].effect_def2+event[chan].effect2 <> 0) then begin event_table[chan].effect_def := event[chan].effect_def; event_table[chan].effect := event[chan].effect; event_table[chan].effect_def2 := event[chan].effect_def2; event_table[chan].effect2 := event[chan].effect2; end; If (event[chan].instr_def <> 0) then If NOT is_data_empty(songdata.instr_data[event[chan].instr_def], INSTRUMENT_SIZE) then set_ins_data(event[chan].instr_def,chan) else begin release_sustaining_sound(chan); set_ins_data(event[chan].instr_def,chan); end; If NOT (event[chan].effect_def in [ef_Vibrato,ef_ExtraFineVibrato, ef_VibratoVolSlide,ef_VibratoVSlideFine]) then FillChar(vibr_table[chan],SizeOf(vibr_table[chan]),0); If NOT (event[chan].effect_def2 in [ef_Vibrato,ef_ExtraFineVibrato, ef_VibratoVolSlide,ef_VibratoVSlideFine]) then FillChar(vibr_table2[chan],SizeOf(vibr_table2[chan]),0); If NOT (event[chan].effect_def in [ef_RetrigNote,ef_MultiRetrigNote]) then FillChar(retrig_table[chan],SizeOf(retrig_table[chan]),0); If NOT (event[chan].effect_def2 in [ef_RetrigNote,ef_MultiRetrigNote]) then FillChar(retrig_table2[chan],SizeOf(retrig_table2[chan]),0); If NOT (event[chan].effect_def in [ef_Tremolo,ef_ExtraFineTremolo]) then FillChar(trem_table[chan],SizeOf(trem_table[chan]),0); If NOT (event[chan].effect_def2 in [ef_Tremolo,ef_ExtraFineTremolo]) then FillChar(trem_table2[chan],SizeOf(trem_table2[chan]),0); If NOT (((event[chan].effect_def = ef_Arpeggio) and (event[chan].effect <> 0)) or (event[chan].effect_def = ef_ExtraFineArpeggio)) and (arpgg_table[chan].note <> 0) and (arpgg_table[chan].state <> 1) then begin arpgg_table[chan].state := 1; change_frequency(chan,nFreq(arpgg_table[chan].note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end else If NOT (((event[chan].effect_def2 = ef_Arpeggio) and (event[chan].effect2 <> 0)) or (event[chan].effect_def2 = ef_ExtraFineArpeggio)) and (arpgg_table2[chan].note <> 0) and (arpgg_table2[chan].state <> 1) then begin arpgg_table2[chan].state := 1; change_frequency(chan,nFreq(arpgg_table2[chan].note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end; end; For chan := 1 to songdata.nm_tracks do begin If event_new[chan] and is_4op_chan(chan) then If (chan in _4op_tracks_hi) then event_new[SUCC(chan)] := TRUE else event_new[PRED(chan)] := TRUE; If (tremor_table[chan].pos <> 0) and (event[chan].effect_def <> ef_Tremor) then begin tremor_table[chan].pos := 0; set_ins_volume(LO(tremor_table[chan].volume), HI(tremor_table[chan].volume),chan); end; If (tremor_table2[chan].pos <> 0) and (event[chan].effect_def2 <> ef_Tremor) then begin tremor_table2[chan].pos := 0; set_ins_volume(LO(tremor_table2[chan].volume), HI(tremor_table2[chan].volume),chan); end; eLo[chan] := LO(last_effect[chan]); eHi[chan] := HI(last_effect[chan]); eLo2[chan] := LO(last_effect2[chan]); eHi2[chan] := HI(last_effect2[chan]); end; For chan := 1 to songdata.nm_tracks do Case event[chan].effect_def of ef_Arpeggio, ef_ExtraFineArpeggio, ef_ArpggVSlide, ef_ArpggVSlideFine: If (event[chan].effect_def <> ef_Arpeggio) or (event[chan].effect <> 0) then begin Case event[chan].effect_def of ef_Arpeggio: effect_table[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect); ef_ExtraFineArpeggio: effect_table[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect); ef_ArpggVSlide, ef_ArpggVSlideFine: If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := effect_table[chan] AND $0ff00; end; If (event[chan].note AND $7f in [1..12*8+1]) then begin arpgg_table[chan].state := 0; arpgg_table[chan].note := event[chan].note AND $7f; If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then begin arpgg_table[chan].add1 := event[chan].effect DIV 16; arpgg_table[chan].add2 := event[chan].effect MOD 16; end; end else If (event[chan].note = 0) and (event_table[chan].note AND $7f in [1..12*8+1]) then begin If NOT (eLo[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio, ef_ArpggVSlide,ef_ArpggVSlideFine]) then arpgg_table[chan].state := 0; arpgg_table[chan].note := event_table[chan].note AND $7f; If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then begin arpgg_table[chan].add1 := event[chan].effect DIV 16; arpgg_table[chan].add2 := event[chan].effect MOD 16; end; end else effect_table[chan] := 0; end; ef_FSlideUp, ef_FSlideDown, ef_FSlideUpFine, ef_FSlideDownFine: begin effect_table[chan] := concw(event[chan].effect_def,event[chan].effect); fslide_table[chan] := event[chan].effect; end; ef_GlobalFSlideUp, ef_GlobalFSlideDown: begin If (event[chan].effect_def = ef_GlobalFSlideUp) then begin If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, event[chan].effect) else If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then effect_table[chan] := concw(ef_FSlideUpFine,event[chan].effect) else effect_table[chan] := concw(ef_FSlideUp,event[chan].effect); end else begin If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, event[chan].effect) else If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then effect_table[chan] := concw(ef_FSlideDownFine,event[chan].effect) else effect_table[chan] := concw(ef_FSlideDown,event[chan].effect); end; For idx := chan to songdata.nm_tracks do begin fslide_table[idx] := event[chan].effect; glfsld_table[idx] := effect_table[chan]; end; end; ef_FSlideUpVSlide, ef_FSlUpVSlF, ef_FSlideDownVSlide, ef_FSlDownVSlF, ef_FSlUpFineVSlide, ef_FSlUpFineVSlF, ef_FSlDownFineVSlide, ef_FSlDownFineVSlF: If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide, ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF, ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := effect_table[chan] AND $0ff00; ef_TonePortamento: If (event[chan].note in [1..12*8+1]) then begin If (event[chan].effect <> 0) then effect_table[chan] := concw(ef_TonePortamento,event[chan].effect) else If (eLo[chan] = ef_TonePortamento) and (eHi[chan] <> 0) then effect_table[chan] := concw(ef_TonePortamento,eHi[chan]) else effect_table[chan] := ef_TonePortamento; porta_table[chan].speed := HI(effect_table[chan]); porta_table[chan].freq := nFreq(event[chan].note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12)); end else If (eLo[chan] = ef_TonePortamento) then begin If (event[chan].effect <> 0) then effect_table[chan] := concw(ef_TonePortamento,event[chan].effect) else If (eLo[chan] = ef_TonePortamento) and (eHi[chan] <> 0) then effect_table[chan] := concw(ef_TonePortamento,eHi[chan]) else effect_table[chan] := ef_TonePortamento; porta_table[chan].speed := HI(effect_table[chan]); end; ef_TPortamVolSlide, ef_TPortamVSlideFine: If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := effect_table[chan] AND $0ff00; ef_Vibrato, ef_ExtraFineVibrato: begin If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := event[chan].effect_def; If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then vibr_table[chan].fine := TRUE; vibr_table[chan].speed := HI(effect_table[chan]) DIV 16; vibr_table[chan].depth := HI(effect_table[chan]) MOD 16; end; ef_Tremolo, ef_ExtraFineTremolo: begin If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := event[chan].effect_def; If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then trem_table[chan].fine := TRUE; trem_table[chan].speed := HI(effect_table[chan]) DIV 16; trem_table[chan].depth := HI(effect_table[chan]) MOD 16; end; ef_VibratoVolSlide, ef_VibratoVSlideFine: begin If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and (HI(effect_table[chan]) <> 0) then effect_table[chan] := concw(event[chan].effect_def,HI(effect_table[chan])) else effect_table[chan] := effect_table[chan] AND $0ff00; If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then vibr_table[chan].fine := TRUE; end; ef_SetCarrierVol: set_ins_volume(BYTE_NULL,63-event[chan].effect,chan); ef_SetModulatorVol: set_ins_volume(63-event[chan].effect,BYTE_NULL,chan); ef_SetInsVolume: If _4op_vol_valid_chan(chan) then set_ins_volume_4op(63-event[chan].effect,chan) else If percussion_mode and (chan in [17..20]) then set_ins_volume(63-event[chan].effect,BYTE_NULL,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(BYTE_NULL,63-event[chan].effect,chan) else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan); ef_ForceInsVolume: If percussion_mode and (chan in [17..20]) then set_ins_volume(63-event[chan].effect,BYTE_NULL,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect),63-event[chan].effect,chan) else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan); ef_PositionJump: If no_loop(chan,current_line) then begin pattern_break := TRUE; next_line := pattern_break_flag+chan; end; ef_PatternBreak: If no_loop(chan,current_line) then begin pattern_break := TRUE; next_line := max(event[chan].effect,PRED(songdata.patt_len)); end; ef_SetSpeed: speed := event[chan].effect; ef_SetTempo: update_timer(event[chan].effect); ef_SetWaveform: begin If (event[chan].effect DIV 16 in [0..7]) then begin fmpar_table[chan].adsrw_car.wform := event[chan].effect DIV 16; update_carrier_adsrw(chan); end; If (event[chan].effect MOD 16 in [0..7]) then begin fmpar_table[chan].adsrw_mod.wform := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; end; ef_VolSlide: effect_table[chan] := concw(ef_VolSlide,event[chan].effect); ef_VolSlideFine: effect_table[chan] := concw(ef_VolSlideFine,event[chan].effect); ef_RetrigNote: If (event[chan].effect <> 0) then begin If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then retrig_table[chan] := 1; effect_table[chan] := concw(ef_RetrigNote,event[chan].effect); end; ef_SetGlobalVolume: begin global_volume := event[chan].effect; set_global_volume; end; ef_MultiRetrigNote: If (event[chan].effect DIV 16 <> 0) then begin If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then retrig_table[chan] := 1; effect_table[chan] := concw(ef_MultiRetrigNote,event[chan].effect); end; ef_Tremor: If (event[chan].effect DIV 16 <> 0) and (event[chan].effect MOD 16 <> 0) then begin If (eLo[chan] <> ef_Tremor) then begin tremor_table[chan].pos := 0; tremor_table[chan].volume := volume_table[chan]; end; effect_table[chan] := concw(ef_Tremor,event[chan].effect); end; ef_Extended: Case (event[chan].effect DIV 16) of ef_ex_SetTremDepth: Case (event[chan].effect MOD 16) of 0: begin opl3out(_instr[11],misc_register AND $07f); current_tremolo_depth := 0; end; 1: begin opl3out(_instr[11],misc_register OR $080); current_tremolo_depth := 1; end; end; ef_ex_SetVibDepth: Case (event[chan].effect MOD 16) of 0: begin opl3out(_instr[11],misc_register AND $0bf); current_vibrato_depth := 0; end; 1: begin opl3out(_instr[11],misc_register OR $040); current_vibrato_depth := 1; end; end; ef_ex_SetAttckRateM: begin fmpar_table[chan].adsrw_mod.attck := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetDecayRateM: begin fmpar_table[chan].adsrw_mod.dec := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetSustnLevelM: begin fmpar_table[chan].adsrw_mod.sustn := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetRelRateM: begin fmpar_table[chan].adsrw_mod.rel := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetAttckRateC: begin fmpar_table[chan].adsrw_car.attck := event[chan].effect MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetDecayRateC: begin fmpar_table[chan].adsrw_car.dec := event[chan].effect MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetSustnLevelC: begin fmpar_table[chan].adsrw_car.sustn := event[chan].effect MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetRelRateC: begin fmpar_table[chan].adsrw_car.rel := event[chan].effect MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetFeedback: begin fmpar_table[chan].feedb := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex_SetPanningPos: begin panning_table[chan] := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex_PatternLoop, ef_ex_PatternLoopRec: If (event[chan].effect MOD 16 = 0) then loopbck_table[chan] := current_line else If (loopbck_table[chan] <> BYTE_NULL) then begin If (loop_table[chan][current_line] = BYTE_NULL) then loop_table[chan][current_line] := event[chan].effect MOD 16; If (loop_table[chan][current_line] <> 0) then begin pattern_break := TRUE; next_line := pattern_loop_flag+chan; end else If (event[chan].effect DIV 16 = ef_ex_PatternLoopRec) then loop_table[chan][current_line] := BYTE_NULL; end; ef_ex_ExtendedCmd: Case (event[chan].effect MOD 16) of ef_ex_cmd_MKOffLoopDi: keyoff_loop[chan] := FALSE; ef_ex_cmd_MKOffLoopEn: keyoff_loop[chan] := TRUE; ef_ex_cmd_TPortaFKdis: portaFK_table[chan] := FALSE; ef_ex_cmd_TPortaFKenb: portaFK_table[chan] := TRUE; ef_ex_cmd_RestartEnv: begin key_on(chan); change_freq(chan,freq_table[chan]); end; ef_ex_cmd_4opVlockOff: If is_4op_chan(chan) then begin vol4op_lock[chan] := FALSE; If (chan in _4op_tracks_hi) then vol4op_lock[SUCC(chan)] := FALSE else vol4op_lock[PRED(chan)] := FALSE; end; ef_ex_cmd_4opVlockOn: If is_4op_chan(chan) then begin vol4op_lock[chan] := TRUE; If (chan in _4op_tracks_hi) then vol4op_lock[SUCC(chan)] := TRUE else vol4op_lock[PRED(chan)] := TRUE; end; end; ef_ex_ExtendedCmd2: Case (event[chan].effect MOD 16) of ef_ex_cmd2_RSS: release_sustaining_sound(chan); ef_ex_cmd2_ResetVol: reset_ins_volume(chan); ef_ex_cmd2_LockVol: volume_lock [chan] := TRUE; ef_ex_cmd2_UnlockVol: volume_lock [chan] := FALSE; ef_ex_cmd2_LockVP: peak_lock [chan] := TRUE; ef_ex_cmd2_UnlockVP: peak_lock [chan] := FALSE; ef_ex_cmd2_VSlide_def: volslide_type[chan] := 0; ef_ex_cmd2_LockPan: pan_lock [chan] := TRUE; ef_ex_cmd2_UnlockPan: pan_lock [chan] := FALSE; ef_ex_cmd2_VibrOff: change_frequency(chan,freq_table[chan]); ef_ex_cmd2_TremOff: If is_4op_chan(chan) then set_ins_volume_4op(BYTE_NULL,chan) else set_ins_volume(LO(volume_table[chan]), HI(volume_table[chan]),chan); ef_ex_cmd2_VSlide_car: If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ ef_ex_cmd2_VSlide_mod) then volslide_type[chan] := 3 else volslide_type[chan] := 1; ef_ex_cmd2_VSlide_mod: If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ ef_ex_cmd2_VSlide_car) then volslide_type[chan] := 3 else volslide_type[chan] := 2; end; end; ef_Extended2: Case (event[chan].effect DIV 16) of ef_ex2_PatDelayFrame, ef_ex2_PatDelayRow: begin pattern_delay := TRUE; If (event[chan].effect DIV 16 = ef_ex2_PatDelayFrame) then tickD := (event[chan].effect MOD 16) else tickD := speed*(event[chan].effect MOD 16); end; ef_ex2_NoteDelay: begin effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0); notedel_table[chan] := event[chan].effect MOD 16; end; ef_ex2_NoteCut: begin effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0); notecut_table[chan] := event[chan].effect MOD 16; end; ef_ex2_FineTuneUp: Inc(ftune_table[chan],event[chan].effect MOD 16); ef_ex2_FineTuneDown: Dec(ftune_table[chan],event[chan].effect MOD 16); ef_ex2_GlVolSlideUp: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp, event[chan].effect MOD 16); ef_ex2_GlVolSlideDn: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn, event[chan].effect MOD 16); ef_ex2_GlVolSlideUpF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF, event[chan].effect MOD 16); ef_ex2_GlVolSlideDnF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF, event[chan].effect MOD 16); ef_ex2_GlVolSldUpXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF, event[chan].effect MOD 16); ef_ex2_GlVolSldDnXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF, event[chan].effect MOD 16); ef_ex2_VolSlideUpXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF, event[chan].effect MOD 16); ef_ex2_VolSlideDnXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF, event[chan].effect MOD 16); ef_ex2_FreqSlideUpXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, event[chan].effect MOD 16); ef_ex2_FreqSlideDnXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, event[chan].effect MOD 16); end; ef_Extended3: Case (event[chan].effect DIV 16) of ef_ex3_SetConnection: begin fmpar_table[chan].connect := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetMultipM: begin fmpar_table[chan].multipM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetKslM: begin fmpar_table[chan].kslM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetTremoloM: begin fmpar_table[chan].tremM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetVibratoM: begin fmpar_table[chan].vibrM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetKsrM: begin fmpar_table[chan].ksrM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetSustainM: begin fmpar_table[chan].sustM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetMultipC: begin fmpar_table[chan].multipC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetKslC: begin fmpar_table[chan].kslC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetTremoloC: begin fmpar_table[chan].tremC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetVibratoC: begin fmpar_table[chan].vibrC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetKsrC: begin fmpar_table[chan].ksrC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetSustainC: begin fmpar_table[chan].sustC := event[chan].effect MOD 16; update_fmpar(chan); end; end; end; For chan := 1 to songdata.nm_tracks do Case event[chan].effect_def2 of ef_Arpeggio, ef_ExtraFineArpeggio, ef_ArpggVSlide, ef_ArpggVSlideFine: If (event[chan].effect_def2 <> ef_Arpeggio) or (event[chan].effect2 <> 0) then begin Case event[chan].effect_def2 of ef_Arpeggio: effect_table2[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect2); ef_ExtraFineArpeggio: effect_table2[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect2); ef_ArpggVSlide, ef_ArpggVSlideFine: If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := effect_table2[chan] AND $0ff00; end; If (event[chan].note AND $7f in [1..12*8+1]) then begin arpgg_table2[chan].state := 0; arpgg_table2[chan].note := event[chan].note AND $7f; If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then begin arpgg_table2[chan].add1 := event[chan].effect2 DIV 16; arpgg_table2[chan].add2 := event[chan].effect2 MOD 16; end; end else If (event[chan].note = 0) and (event_table[chan].note AND $7f in [1..12*8+1]) then begin If NOT (eLo2[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio, ef_ArpggVSlide,ef_ArpggVSlideFine]) then arpgg_table2[chan].state := 0; arpgg_table2[chan].note := event_table[chan].note AND $7f; If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then begin arpgg_table2[chan].add1 := event[chan].effect2 DIV 16; arpgg_table2[chan].add2 := event[chan].effect2 MOD 16; end; end else effect_table2[chan] := 0; end; ef_FSlideUp, ef_FSlideDown, ef_FSlideUpFine, ef_FSlideDownFine: begin effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2); fslide_table2[chan] := event[chan].effect2; end; ef_GlobalFSlideUp, ef_GlobalFSlideDown: begin If (event[chan].effect_def2 = ef_GlobalFSlideUp) then begin If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, event[chan].effect2) else If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then effect_table2[chan] := concw(ef_FSlideUpFine,event[chan].effect2) else effect_table2[chan] := concw(ef_FSlideUp,event[chan].effect2); end else begin If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, event[chan].effect2) else If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then effect_table2[chan] := concw(ef_FSlideDownFine,event[chan].effect2) else effect_table2[chan] := concw(ef_FSlideDown,event[chan].effect2); end; For idx := chan to songdata.nm_tracks do begin fslide_table2[idx] := event[chan].effect2; glfsld_table2[idx] := effect_table2[chan]; end; end; ef_FSlideUpVSlide, ef_FSlUpVSlF, ef_FSlideDownVSlide, ef_FSlDownVSlF, ef_FSlUpFineVSlide, ef_FSlUpFineVSlF, ef_FSlDownFineVSlide, ef_FSlDownFineVSlF: If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide, ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF, ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := effect_table2[chan] AND $0ff00; ef_TonePortamento: If (event[chan].note in [1..12*8+1]) then begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2) else If (eLo2[chan] = ef_TonePortamento) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan]) else effect_table2[chan] := ef_TonePortamento; porta_table2[chan].speed := HI(effect_table2[chan]); porta_table2[chan].freq := nFreq(event[chan].note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12)); end else If (eLo2[chan] = ef_TonePortamento) then begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2) else If (eLo2[chan] = ef_TonePortamento) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan]) else effect_table2[chan] := ef_TonePortamento; porta_table2[chan].speed := HI(effect_table2[chan]); end; ef_TPortamVolSlide, ef_TPortamVSlideFine: If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := effect_table2[chan] AND $0ff00; ef_Vibrato, ef_ExtraFineVibrato: begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := event[chan].effect_def2; If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then vibr_table2[chan].fine := TRUE; vibr_table2[chan].speed := HI(effect_table2[chan]) DIV 16; vibr_table2[chan].depth := HI(effect_table2[chan]) MOD 16; end; ef_Tremolo, ef_ExtraFineTremolo: begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := event[chan].effect_def2; If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then trem_table2[chan].fine := TRUE; trem_table2[chan].speed := HI(effect_table2[chan]) DIV 16; trem_table2[chan].depth := HI(effect_table2[chan]) MOD 16; end; ef_VibratoVolSlide, ef_VibratoVSlideFine: begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and (HI(effect_table2[chan]) <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,HI(effect_table2[chan])) else effect_table2[chan] := effect_table2[chan] AND $0ff00; If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then vibr_table2[chan].fine := TRUE; end; ef_SetCarrierVol: set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan); ef_SetModulatorVol: set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan); ef_SetInsVolume: If _4op_vol_valid_chan(chan) then set_ins_volume_4op(63-event[chan].effect2,chan) else If percussion_mode and (chan in [17..20]) then set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan) else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan); ef_ForceInsVolume: If percussion_mode and (chan in [17..20]) then set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect2),63-event[chan].effect2,chan) else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan); ef_PositionJump: If no_loop(chan,current_line) then begin pattern_break := TRUE; next_line := pattern_break_flag+chan; end; ef_PatternBreak: If no_loop(chan,current_line) then begin pattern_break := TRUE; next_line := max(event[chan].effect2,PRED(songdata.patt_len)); end; ef_SetSpeed: speed := event[chan].effect2; ef_SetTempo: update_timer(event[chan].effect2); ef_SetWaveform: begin If (event[chan].effect2 DIV 16 in [0..7]) then begin fmpar_table[chan].adsrw_car.wform := event[chan].effect2 DIV 16; update_carrier_adsrw(chan); end; If (event[chan].effect2 MOD 16 in [0..7]) then begin fmpar_table[chan].adsrw_mod.wform := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; end; ef_VolSlide: effect_table2[chan] := concw(ef_VolSlide,event[chan].effect2); ef_VolSlideFine: effect_table2[chan] := concw(ef_VolSlideFine,event[chan].effect2); ef_RetrigNote: If (event[chan].effect2 <> 0) then begin If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then retrig_table2[chan] := 1; effect_table2[chan] := concw(ef_RetrigNote,event[chan].effect2); end; ef_SetGlobalVolume: begin global_volume := event[chan].effect2; set_global_volume; end; ef_MultiRetrigNote: If (event[chan].effect2 DIV 16 <> 0) then begin If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then retrig_table2[chan] := 1; effect_table2[chan] := concw(ef_MultiRetrigNote,event[chan].effect2); end; ef_Tremor: If (event[chan].effect2 DIV 16 <> 0) and (event[chan].effect2 MOD 16 <> 0) then begin If (eLo2[chan] <> ef_Tremor) then begin tremor_table2[chan].pos := 0; tremor_table2[chan].volume := volume_table[chan]; end; effect_table2[chan] := concw(ef_Tremor,event[chan].effect2); end; ef_Extended: Case (event[chan].effect2 DIV 16) of ef_ex_SetTremDepth: Case (event[chan].effect2 MOD 16) of 0: begin opl3out(_instr[11],misc_register AND $07f); current_tremolo_depth := 0; end; 1: begin opl3out(_instr[11],misc_register OR $080); current_tremolo_depth := 1; end; end; ef_ex_SetVibDepth: Case (event[chan].effect2 MOD 16) of 0: begin opl3out(_instr[11],misc_register AND $0bf); current_vibrato_depth := 0; end; 1: begin opl3out(_instr[11],misc_register OR $040); current_vibrato_depth := 1; end; end; ef_ex_SetAttckRateM: begin fmpar_table[chan].adsrw_mod.attck := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetDecayRateM: begin fmpar_table[chan].adsrw_mod.dec := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetSustnLevelM: begin fmpar_table[chan].adsrw_mod.sustn := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetRelRateM: begin fmpar_table[chan].adsrw_mod.rel := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetAttckRateC: begin fmpar_table[chan].adsrw_car.attck := event[chan].effect2 MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetDecayRateC: begin fmpar_table[chan].adsrw_car.dec := event[chan].effect2 MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetSustnLevelC: begin fmpar_table[chan].adsrw_car.sustn := event[chan].effect2 MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetRelRateC: begin fmpar_table[chan].adsrw_car.rel := event[chan].effect2 MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetFeedback: begin fmpar_table[chan].feedb := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex_SetPanningPos: begin panning_table[chan] := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex_PatternLoop, ef_ex_PatternLoopRec: If (event[chan].effect2 MOD 16 = 0) then loopbck_table[chan] := current_line else If (loopbck_table[chan] <> BYTE_NULL) then begin If (loop_table[chan][current_line] = BYTE_NULL) then loop_table[chan][current_line] := event[chan].effect2 MOD 16; If (loop_table[chan][current_line] <> 0) then begin pattern_break := TRUE; next_line := pattern_loop_flag+chan; end else If (event[chan].effect2 DIV 16 = ef_ex_PatternLoopRec) then loop_table[chan][current_line] := BYTE_NULL; end; ef_ex_ExtendedCmd: Case (event[chan].effect2 MOD 16) of ef_ex_cmd_MKOffLoopDi: keyoff_loop[chan] := FALSE; ef_ex_cmd_MKOffLoopEn: keyoff_loop[chan] := TRUE; ef_ex_cmd_TPortaFKdis: portaFK_table[chan] := FALSE; ef_ex_cmd_TPortaFKenb: portaFK_table[chan] := TRUE; ef_ex_cmd_RestartEnv: begin key_on(chan); change_freq(chan,freq_table[chan]); end; ef_ex_cmd_4opVlockOff: If is_4op_chan(chan) then begin vol4op_lock[chan] := FALSE; If (chan in _4op_tracks_hi) then vol4op_lock[SUCC(chan)] := FALSE else vol4op_lock[PRED(chan)] := FALSE; end; ef_ex_cmd_4opVlockOn: If is_4op_chan(chan) then begin vol4op_lock[chan] := TRUE; If (chan in _4op_tracks_hi) then vol4op_lock[SUCC(chan)] := TRUE else vol4op_lock[PRED(chan)] := TRUE; end; end; ef_ex_ExtendedCmd2: Case (event[chan].effect2 MOD 16) of ef_ex_cmd2_RSS: release_sustaining_sound(chan); ef_ex_cmd2_ResetVol: reset_ins_volume(chan); ef_ex_cmd2_LockVol: volume_lock [chan] := TRUE; ef_ex_cmd2_UnlockVol: volume_lock [chan] := FALSE; ef_ex_cmd2_LockVP: peak_lock [chan] := TRUE; ef_ex_cmd2_UnlockVP: peak_lock [chan] := FALSE; ef_ex_cmd2_VSlide_def: volslide_type[chan] := 0; ef_ex_cmd2_LockPan: pan_lock [chan] := TRUE; ef_ex_cmd2_UnlockPan: pan_lock [chan] := FALSE; ef_ex_cmd2_VibrOff: change_frequency(chan,freq_table[chan]); ef_ex_cmd2_TremOff: If _4op_vol_valid_chan(chan) then set_ins_volume_4op(BYTE_NULL,chan) else set_ins_volume(LO(volume_table[chan]), HI(volume_table[chan]),chan); ef_ex_cmd2_VSlide_car: If NOT ((event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ ef_ex_cmd2_VSlide_mod)) then volslide_type[chan] := 1; ef_ex_cmd2_VSlide_mod: If NOT ((event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ ef_ex_cmd2_VSlide_car)) then volslide_type[chan] := 2; end; end; ef_Extended2: Case (event[chan].effect2 DIV 16) of ef_ex2_PatDelayFrame, ef_ex2_PatDelayRow: begin pattern_delay := TRUE; If (event[chan].effect2 DIV 16 = ef_ex2_PatDelayFrame) then tickD := (event[chan].effect2 MOD 16) else tickD := speed*(event[chan].effect2 MOD 16); end; ef_ex2_NoteDelay: begin effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0); notedel_table[chan] := event[chan].effect2 MOD 16; end; ef_ex2_NoteCut: begin effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0); notecut_table[chan] := event[chan].effect2 MOD 16; end; ef_ex2_FineTuneUp: Inc(ftune_table[chan],event[chan].effect2 MOD 16); ef_ex2_FineTuneDown: Dec(ftune_table[chan],event[chan].effect2 MOD 16); ef_ex2_GlVolSlideUp: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp, event[chan].effect2 MOD 16); ef_ex2_GlVolSlideDn: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn, event[chan].effect2 MOD 16); ef_ex2_GlVolSlideUpF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF, event[chan].effect2 MOD 16); ef_ex2_GlVolSlideDnF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF, event[chan].effect2 MOD 16); ef_ex2_GlVolSldUpXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF, event[chan].effect2 MOD 16); ef_ex2_GlVolSldDnXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF, event[chan].effect2 MOD 16); ef_ex2_VolSlideUpXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF, event[chan].effect2 MOD 16); ef_ex2_VolSlideDnXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF, event[chan].effect2 MOD 16); ef_ex2_FreqSlideUpXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, event[chan].effect2 MOD 16); ef_ex2_FreqSlideDnXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, event[chan].effect2 MOD 16); end; ef_Extended3: Case (event[chan].effect2 DIV 16) of ef_ex3_SetConnection: begin fmpar_table[chan].connect := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetMultipM: begin fmpar_table[chan].multipM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetKslM: begin fmpar_table[chan].kslM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetTremoloM: begin fmpar_table[chan].tremM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetVibratoM: begin fmpar_table[chan].vibrM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetKsrM: begin fmpar_table[chan].ksrM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetSustainM: begin fmpar_table[chan].sustM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetMultipC: begin fmpar_table[chan].multipC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetKslC: begin fmpar_table[chan].kslC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetTremoloC: begin fmpar_table[chan].tremC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetVibratoC: begin fmpar_table[chan].vibrC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetKsrC: begin fmpar_table[chan].ksrC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetSustainC: begin fmpar_table[chan].sustC := event[chan].effect2 MOD 16; update_fmpar(chan); end; end; end; For chan := 1 to songdata.nm_tracks do begin tporta_flag := (event[chan].effect_def in [ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine]) or (event[chan].effect_def2 in [ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine]); If (event[chan].effect_def+event[chan].effect = 0) then If (glfsld_table[chan] = 0) then effect_table[chan] := 0 else begin event_table[chan].effect_def := event[chan].effect_def; event_table[chan].effect := event[chan].effect; end; If (event[chan].effect_def2+event[chan].effect2 = 0) then If (glfsld_table2[chan] = 0) then effect_table2[chan] := 0 else begin event_table[chan].effect_def2 := event[chan].effect_def2; event_table[chan].effect2 := event[chan].effect2; end; If (event[chan].note = event[chan].note OR keyoff_flag) then key_off(chan) else If NOT (LO(effect_table[chan]) in [ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine, ef_extended2+ef_fix2+ef_ex2_NoteDelay]) and NOT (LO(effect_table2[chan]) in [ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine, ef_extended2+ef_fix2+ef_ex2_NoteDelay]) then If NOT (((event[chan].effect_def2 = ef_SwapArpeggio) or (event[chan].effect_def2 = ef_SwapVibrato)) and (event[chan].effect_def = ef_Extended) and (event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart)) and NOT (((event[chan].effect_def = ef_SwapArpeggio) or (event[chan].effect_def = ef_SwapVibrato)) and (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart)) then output_note(event[chan].note,voice_table[chan],chan,TRUE,TRUE) else output_note(event[chan].note,voice_table[chan],chan,TRUE,FALSE) else If (event[chan].note <> 0) and tporta_flag and (event_table[chan].note = event_table[chan].note OR keyoff_flag) then output_note(event_table[chan].note AND NOT keyoff_flag,voice_table[chan],chan,FALSE,TRUE) else If (event[chan].note <> 0) then If portaFK_table[chan] and tporta_flag then output_note(event[chan].note,event[chan].instr_def,chan,FALSE,TRUE) else event_table[chan].note := event[chan].note; Case event[chan].effect_def of ef_SwapArpeggio: begin If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart) then begin If (macro_table[chan].arpg_pos > songdata.macro_table[event[chan].effect].arpeggio.length) then macro_table[chan].arpg_pos := songdata.macro_table[event[chan].effect].arpeggio.length; macro_table[chan].arpg_table := event[chan].effect; end else begin macro_table[chan].arpg_count := 1; macro_table[chan].arpg_pos := 0; macro_table[chan].arpg_table := event[chan].effect; macro_table[chan].arpg_note := event_table[chan].note; end; end; ef_SwapVibrato: begin If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart) then begin If (macro_table[chan].vib_table > songdata.macro_table[event[chan].effect].vibrato.length) then macro_table[chan].vib_pos := songdata.macro_table[event[chan].effect].vibrato.length; macro_table[chan].vib_table := event[chan].effect; end else begin macro_table[chan].vib_count := 1; macro_table[chan].vib_pos := 0; macro_table[chan].vib_table := event[chan].effect; macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; end; end; ef_SetCustomSpeedTab: generate_custom_vibrato(event[chan].effect); end; Case event[chan].effect_def2 of ef_SwapArpeggio: begin If (event[chan].effect_def = ef_Extended) and (event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart) then begin If (macro_table[chan].arpg_pos > songdata.macro_table[event[chan].effect2].arpeggio.length) then macro_table[chan].arpg_pos := songdata.macro_table[event[chan].effect2].arpeggio.length; macro_table[chan].arpg_table := event[chan].effect2; end else begin macro_table[chan].arpg_count := 1; macro_table[chan].arpg_pos := 0; macro_table[chan].arpg_table := event[chan].effect2; macro_table[chan].arpg_note := event_table[chan].note; end; end; ef_SwapVibrato: begin If (event[chan].effect_def = ef_Extended) and (event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart) then begin If (macro_table[chan].vib_table > songdata.macro_table[event[chan].effect2].vibrato.length) then macro_table[chan].vib_pos := songdata.macro_table[event[chan].effect2].vibrato.length; macro_table[chan].vib_table := event[chan].effect2; end else begin macro_table[chan].vib_count := 1; macro_table[chan].vib_pos := 0; macro_table[chan].vib_table := event[chan].effect2; macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; end; end; ef_SetCustomSpeedTab: generate_custom_vibrato(event[chan].effect2); end; update_fine_effects(chan); end; If pattern_delay then begin time_playing := time_playing+1/tempo*tickD; If (time_playing > 3600-1) then time_playing := 0; end else begin time_playing := time_playing+1/tempo*speed; If (time_playing > 3600-1) then time_playing := 0; end; end; procedure portamento_up(chan: Byte; slide: Word; limit: Word); var freq: Word; begin freq := calc_freq_shift_up(freq_table[chan] AND $1fff,slide); If (freq <= limit) then change_frequency(chan,freq) else change_frequency(chan,limit); end; procedure portamento_down(chan: Byte; slide: Word; limit: Word); var freq: Word; begin freq := calc_freq_shift_down(freq_table[chan] AND $1fff,slide); If (freq >= limit) then change_frequency(chan,freq) else change_frequency(chan,limit); end; procedure macro_vibrato__porta_up(chan: Byte; depth: Byte); var freq: Word; begin freq := calc_freq_shift_up(macro_table[chan].vib_freq AND $1fff,depth); If (freq <= nFreq(12*8+1)) then change_freq(chan,freq) else change_freq(chan,nFreq(12*8+1)); end; procedure macro_vibrato__porta_down(chan: Byte; depth: Byte); var freq: Word; begin freq := calc_freq_shift_down(macro_table[chan].vib_freq AND $1fff,depth); If (freq >= nFreq(0)) then change_freq(chan,freq) else change_freq(chan,nFreq(0)); end; procedure tone_portamento(chan: Byte); begin If (freq_table[chan] AND $1fff > porta_table[chan].freq) then portamento_down(chan,porta_table[chan].speed,porta_table[chan].freq) else If (freq_table[chan] AND $1fff < porta_table[chan].freq) then portamento_up(chan,porta_table[chan].speed,porta_table[chan].freq); end; procedure tone_portamento2(chan: Byte); begin If (freq_table[chan] AND $1fff > porta_table2[chan].freq) then portamento_down(chan,porta_table2[chan].speed,porta_table2[chan].freq) else If (freq_table[chan] AND $1fff < porta_table2[chan].freq) then portamento_up(chan,porta_table2[chan].speed,porta_table2[chan].freq); end; procedure slide_carrier_volume_up(chan: Byte; slide,limit: Byte); var vol: Word; vLo,vHi: Byte; begin vLo := LO(volume_table[chan]); vHi := HI(volume_table[chan]); If (vHi-slide >= limit) then vol := concw(vLo,vHi-slide) else vol := concw(vLo,limit); set_ins_volume(BYTE_NULL,HI(vol),chan); volume_table[chan] := vol; end; procedure slide_modulator_volume_up(chan: Byte; slide,limit: Byte); var vol: Word; vLo,vHi: Byte; begin vLo := LO(volume_table[chan]); vHi := HI(volume_table[chan]); If (vLo-slide >= limit) then vol := concw(vLo-slide,vHi) else vol := concw(limit,vHi); set_ins_volume(LO(vol),BYTE_NULL,chan); volume_table[chan] := vol; end; procedure slide_volume_up(chan,slide: Byte); var limit1,limit2: Byte; limit1_4op,limit2_4op: Word; _4op_flag: Dword; _4op_conn: Byte; _4op_ch1,_4op_ch2: Byte; _4op_ins1,_4op_ins2: Byte; begin _4op_flag := _4op_data_flag(chan); _4op_conn := (_4op_flag SHR 1) AND 3; _4op_ch1 := (_4op_flag SHR 3) AND 15; _4op_ch2 := (_4op_flag SHR 7) AND 15; _4op_ins1 := BYTE(_4op_flag SHR 11); _4op_ins2 := BYTE(_4op_flag SHR 19); If _4op_vol_valid_chan(chan) then begin If NOT peak_lock[_4op_ch1] then limit1_4op := 0 else limit1_4op := ins_parameter(_4op_ins1,3) AND $3f SHL 16 + ins_parameter(_4op_ins1,2) AND $3f; If NOT peak_lock[_4op_ch2] then limit2_4op := 0 else limit2_4op := ins_parameter(_4op_ins2,3) AND $3f SHL 16 + ins_parameter(_4op_ins2,2) AND $3f; end else begin If NOT peak_lock[chan] then limit1 := 0 else limit1 := ins_parameter(event_table[chan].instr_def,3) AND $3f; If NOT peak_lock[chan] then limit2 := 0 else limit2 := ins_parameter(event_table[chan].instr_def,2) AND $3f; end; Case volslide_type[chan] of 0: begin If NOT _4op_vol_valid_chan(chan) then begin slide_carrier_volume_up(chan,slide,limit1); If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then slide_modulator_volume_up(chan,slide,limit2); end else Case _4op_conn of // FM/FM 0: slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op)); // FM/AM 1: begin slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op)); slide_modulator_volume_up(_4op_ch2,slide,LO(limit2_4op)); end; // AM/FM 2: begin slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op)); slide_carrier_volume_up(_4op_ch2,slide,HI(limit2_4op)); end; // AM/AM 3: begin slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op)); slide_modulator_volume_up(_4op_ch1,slide,LO(limit1_4op)); slide_modulator_volume_up(_4op_ch2,slide,LO(limit2_4op)); end; end; end; 1: slide_carrier_volume_up(chan,slide,limit1); 2: slide_modulator_volume_up(chan,slide,limit2); 3: begin slide_carrier_volume_up(chan,slide,limit1); slide_modulator_volume_up(chan,slide,limit2); end; end; end; procedure slide_carrier_volume_down(chan: Byte; slide: Byte); var vol: Word; vLo,vHi: Byte; begin vLo := LO(volume_table[chan]); vHi := HI(volume_table[chan]); If (vHi+slide <= 63) then vol := concw(vLo,vHi+slide) else vol := concw(vLo,63); set_ins_volume(BYTE_NULL,HI(vol),chan); volume_table[chan] := vol; end; procedure slide_modulator_volume_down(chan: Byte; slide: Byte); var vol: Word; vLo,vHi: Byte; begin vLo := LO(volume_table[chan]); vHi := HI(volume_table[chan]); If (vLo+slide <= 63) then vol := concw(vLo+slide,vHi) else vol := concw(63,vHi); set_ins_volume(LO(vol),BYTE_NULL,chan); volume_table[chan] := vol; end; procedure slide_volume_down(chan,slide: Byte); var _4op_flag: Dword; _4op_conn: Byte; _4op_ch1,_4op_ch2: Byte; begin _4op_flag := _4op_data_flag(chan); _4op_conn := (_4op_flag SHR 1) AND 3; _4op_ch1 := (_4op_flag SHR 3) AND 15; _4op_ch2 := (_4op_flag SHR 7) AND 15; Case volslide_type[chan] of 0: begin If NOT _4op_vol_valid_chan(chan) then begin slide_carrier_volume_down(chan,slide); If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then slide_modulator_volume_down(chan,slide); end else Case _4op_conn of // FM/FM 0: slide_carrier_volume_down(_4op_ch1,slide); // FM/AM 1: begin slide_carrier_volume_down(_4op_ch1,slide); slide_modulator_volume_down(_4op_ch2,slide); end; // AM/FM 2: begin slide_carrier_volume_down(_4op_ch1,slide); slide_carrier_volume_down(_4op_ch2,slide); end; // AM/AM 3: begin slide_carrier_volume_down(_4op_ch1,slide); slide_modulator_volume_down(_4op_ch1,slide); slide_modulator_volume_down(_4op_ch2,slide); end; end; end; 1: slide_carrier_volume_down(chan,slide); 2: slide_modulator_volume_down(chan,slide); 3: begin slide_carrier_volume_down(chan,slide); slide_modulator_volume_down(chan,slide); end; end; end; procedure volume_slide(chan,up_speed,down_speed: Byte); begin If (up_speed <> 0) then slide_volume_up(chan,up_speed) else If (down_speed <> 0) then slide_volume_down(chan,down_speed); end; procedure global_volume_slide(up_speed,down_speed: Byte); begin If (up_speed <> BYTE_NULL) then global_volume := max(global_volume+up_speed,63); If (down_speed <> BYTE_NULL) then If (global_volume >= down_speed) then Dec(global_volume,down_speed) else global_volume := 0; set_global_volume; end; procedure arpeggio(chan: Byte); const arpgg_state: array[0..2] of Byte = (1,2,0); var freq: Word; begin Case arpgg_table[chan].state of 0: freq := nFreq(arpgg_table[chan].note-1); 1: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add1); 2: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add2); end; arpgg_table[chan].state := arpgg_state[arpgg_table[chan].state]; change_frequency(chan,freq+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end; procedure arpeggio2(chan: Byte); const arpgg_state: array[0..2] of Byte = (1,2,0); var freq: Word; begin Case arpgg_table2[chan].state of 0: freq := nFreq(arpgg_table2[chan].note-1); 1: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add1); 2: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add2); end; arpgg_table2[chan].state := arpgg_state[arpgg_table2[chan].state]; change_frequency(chan,freq+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end; procedure vibrato(chan: Byte); var freq,old_freq: Word; begin Inc(vibr_table[chan].pos,vibr_table[chan].speed*vibtrem_speed_factor); freq := calc_vibtrem_shift(chan,vibr_table); old_freq := freq_table[chan]; If (vibr_table[chan].dir = 0) then portamento_down(chan,freq,nFreq(0)) else portamento_up(chan,freq,nFreq(12*8+1)); freq_table[chan] := old_freq; end; procedure vibrato2(chan: Byte); var freq,old_freq: Word; begin Inc(vibr_table2[chan].pos,vibr_table2[chan].speed*vibtrem_speed_factor); freq := calc_vibtrem_shift(chan,vibr_table2); old_freq := freq_table[chan]; If (vibr_table2[chan].dir = 0) then portamento_down(chan,freq,nFreq(0)) else portamento_up(chan,freq,nFreq(12*8+1)); freq_table[chan] := old_freq; end; procedure tremolo(chan: Byte); var vol,old_vol: Word; begin Inc(trem_table[chan].pos,trem_table[chan].speed*vibtrem_speed_factor); vol := calc_vibtrem_shift(chan,trem_table); old_vol := volume_table[chan]; If (trem_table[chan].dir = 0) then slide_volume_down(chan,vol) else slide_volume_up(chan,vol); volume_table[chan] := old_vol; end; procedure tremolo2(chan: Byte); var vol,old_vol: Word; begin Inc(trem_table2[chan].pos,trem_table2[chan].speed*vibtrem_speed_factor); vol := calc_vibtrem_shift(chan,trem_table2); old_vol := volume_table[chan]; If (trem_table2[chan].pos = 0) then slide_volume_down(chan,vol) else slide_volume_up(chan,vol); volume_table[chan] := old_vol; end; procedure update_effects; var chan,eLo,eHi, eLo2,eHi2: Byte; function chanvol(chan: Byte): Byte; begin If (ins_parameter(voice_table[chan],10) AND 1 = 0) then chanvol := 63-HI(volume_table[chan]) else chanvol := 63-Round((LO(volume_table[chan])+HI(volume_table[chan]))/2); end; begin For chan := 1 to songdata.nm_tracks do begin eLo := LO(effect_table[chan]); eHi := HI(effect_table[chan]); eLo2 := LO(effect_table2[chan]); eHi2 := HI(effect_table2[chan]); Case eLo of ef_Arpeggio+ef_fix1: arpeggio(chan); ef_ArpggVSlide: begin volume_slide(chan,eHi DIV 16,eHi MOD 16); arpeggio(chan); end; ef_ArpggVSlideFine: arpeggio(chan); ef_FSlideUp: portamento_up(chan,eHi,nFreq(12*8+1)); ef_FSlideDown: portamento_down(chan,eHi,nFreq(0)); ef_FSlideUpVSlide: begin portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); volume_slide(chan,eHi DIV 16,eHi MOD 16); end; ef_FSlUpVSlF: portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); ef_FSlideDownVSlide: begin portamento_down(chan,fslide_table[chan],nFreq(0)); volume_slide(chan,eHi DIV 16,eHi MOD 16); end; ef_FSlDownVSlF: portamento_down(chan,fslide_table[chan],nFreq(0)); ef_FSlUpFineVSlide: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_FSlDownFineVSlide: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_TonePortamento: tone_portamento(chan); ef_TPortamVolSlide: begin volume_slide(chan,eHi DIV 16,eHi MOD 16); tone_portamento(chan); end; ef_TPortamVSlideFine: tone_portamento(chan); ef_Vibrato: If NOT vibr_table[chan].fine then vibrato(chan); ef_Tremolo: If NOT trem_table[chan].fine then tremolo(chan); ef_VibratoVolSlide: begin volume_slide(chan,eHi DIV 16,eHi MOD 16); If NOT vibr_table[chan].fine then vibrato(chan); end; ef_VibratoVSlideFine: If NOT vibr_table[chan].fine then vibrato(chan); ef_VolSlide: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_RetrigNote: If (retrig_table[chan] >= eHi) then begin retrig_table[chan] := 0; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Inc(retrig_table[chan]); ef_MultiRetrigNote: If (retrig_table[chan] >= eHi DIV 16) then begin Case eHi MOD 16 of 0,8: ; 1: slide_volume_down(chan,1); 2: slide_volume_down(chan,2); 3: slide_volume_down(chan,4); 4: slide_volume_down(chan,8); 5: slide_volume_down(chan,16); 9: slide_volume_up(chan,1); 10: slide_volume_up(chan,2); 11: slide_volume_up(chan,4); 12: slide_volume_up(chan,8); 13: slide_volume_up(chan,16); 6: slide_volume_down(chan,chanvol(chan)- Round(chanvol(chan)*2/3)); 7: slide_volume_down(chan,chanvol(chan)- Round(chanvol(chan)*1/2)); 14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)- chanvol(chan),63)); 15: slide_volume_up(chan,max(Round(chanvol(chan)*2)- chanvol(chan),63)); end; retrig_table[chan] := 0; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Inc(retrig_table[chan]); ef_Tremor: If (tremor_table[chan].pos >= 0) then begin If (SUCC(tremor_table[chan].pos) <= eHi DIV 16) then Inc(tremor_table[chan].pos) else begin slide_volume_down(chan,63); tremor_table[chan].pos := -1; end; end else If (PRED(tremor_table[chan].pos) >= -(eHi MOD 16)) then Dec(tremor_table[chan].pos) else begin set_ins_volume(LO(tremor_table[chan].volume), HI(tremor_table[chan].volume),chan); tremor_table[chan].pos := 1; end; ef_extended2+ef_fix2+ef_ex2_NoteDelay: If (notedel_table[chan] = 0) then begin notedel_table[chan] := BYTE_NULL; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Dec(notedel_table[chan]); ef_extended2+ef_fix2+ef_ex2_NoteCut: If (notecut_table[chan] = 0) then begin notecut_table[chan] := BYTE_NULL; key_off(chan); end else Dec(notecut_table[chan]); ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp: global_volume_slide(eHi,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn: global_volume_slide(BYTE_NULL,eHi); end; Case eLo2 of ef_Arpeggio+ef_fix1: arpeggio2(chan); ef_ArpggVSlide: begin volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); arpeggio2(chan); end; ef_ArpggVSlideFine: arpeggio2(chan); ef_FSlideUp: portamento_up(chan,eHi2,nFreq(12*8+1)); ef_FSlideDown: portamento_down(chan,eHi2,nFreq(0)); ef_FSlideUpVSlide: begin portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); end; ef_FSlUpVSlF: portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); ef_FSlideDownVSlide: begin portamento_down(chan,fslide_table2[chan],nFreq(0)); volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); end; ef_FSlDownVSlF: portamento_down(chan,fslide_table2[chan],nFreq(0)); ef_FSlUpFineVSlide: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_FSlDownFineVSlide: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_TonePortamento: tone_portamento2(chan); ef_TPortamVolSlide: begin volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); tone_portamento2(chan); end; ef_TPortamVSlideFine: tone_portamento2(chan); ef_Vibrato: If NOT vibr_table2[chan].fine then vibrato2(chan); ef_Tremolo: If NOT trem_table2[chan].fine then tremolo2(chan); ef_VibratoVolSlide: begin volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); If NOT vibr_table2[chan].fine then vibrato2(chan); end; ef_VibratoVSlideFine: If NOT vibr_table2[chan].fine then vibrato2(chan); ef_VolSlide: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_RetrigNote: If (retrig_table2[chan] >= eHi2) then begin retrig_table2[chan] := 0; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Inc(retrig_table2[chan]); ef_MultiRetrigNote: If (retrig_table2[chan] >= eHi2 DIV 16) then begin Case eHi2 MOD 16 of 0,8: ; 1: slide_volume_down(chan,1); 2: slide_volume_down(chan,2); 3: slide_volume_down(chan,4); 4: slide_volume_down(chan,8); 5: slide_volume_down(chan,16); 9: slide_volume_up(chan,1); 10: slide_volume_up(chan,2); 11: slide_volume_up(chan,4); 12: slide_volume_up(chan,8); 13: slide_volume_up(chan,16); 6: slide_volume_down(chan,chanvol(chan)- Round(chanvol(chan)*2/3)); 7: slide_volume_down(chan,chanvol(chan)- Round(chanvol(chan)*1/2)); 14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)- chanvol(chan),63)); 15: slide_volume_up(chan,max(Round(chanvol(chan)*2)- chanvol(chan),63)); end; retrig_table2[chan] := 0; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Inc(retrig_table2[chan]); ef_Tremor: If (tremor_table2[chan].pos >= 0) then begin If (SUCC(tremor_table2[chan].pos) <= eHi2 DIV 16) then Inc(tremor_table2[chan].pos) else begin slide_volume_down(chan,63); tremor_table2[chan].pos := -1; end; end else If (PRED(tremor_table2[chan].pos) >= -(eHi2 MOD 16)) then Dec(tremor_table2[chan].pos) else begin set_ins_volume(LO(tremor_table2[chan].volume), HI(tremor_table2[chan].volume),chan); tremor_table2[chan].pos := 1; end; ef_extended2+ef_fix2+ef_ex2_NoteDelay: If (notedel_table[chan] = 0) then begin notedel_table[chan] := BYTE_NULL; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Dec(notedel_table[chan]); ef_extended2+ef_fix2+ef_ex2_NoteCut: If (notecut_table[chan] = 0) then begin notecut_table[chan] := BYTE_NULL; key_off(chan); end else Dec(notecut_table[chan]); ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp: global_volume_slide(eHi2,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn: global_volume_slide(BYTE_NULL,eHi2); end; end; end; procedure update_fine_effects(chan: Byte); var eLo,eHi, eLo2,eHi2: Byte; begin eLo := LO(effect_table[chan]); eHi := HI(effect_table[chan]); eLo2 := LO(effect_table2[chan]); eHi2 := HI(effect_table2[chan]); Case eLo of ef_ArpggVSlideFine: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_FSlideUpFine: portamento_up(chan,eHi,nFreq(12*8+1)); ef_FSlideDownFine: portamento_down(chan,eHi,nFreq(0)); ef_FSlUpVSlF: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_FSlDownVSlF: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_FSlUpFineVSlide: portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); ef_FSlUpFineVSlF: begin portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); volume_slide(chan,eHi DIV 16,eHi MOD 16); end; ef_FSlDownFineVSlide: portamento_down(chan,fslide_table[chan],nFreq(0)); ef_FSlDownFineVSlF: begin portamento_down(chan,fslide_table[chan],nFreq(0)); volume_slide(chan,eHi DIV 16,eHi MOD 16); end; ef_TPortamVSlideFine: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_Vibrato: If vibr_table[chan].fine then vibrato(chan); ef_Tremolo: If trem_table[chan].fine then tremolo(chan); ef_VibratoVolSlide: If vibr_table[chan].fine then vibrato(chan); ef_VibratoVSlideFine: begin volume_slide(chan,eHi DIV 16,eHi MOD 16); If vibr_table[chan].fine then vibrato(chan); end; ef_VolSlideFine: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF: global_volume_slide(eHi,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF: global_volume_slide(BYTE_NULL,eHi); end; Case eLo2 of ef_ArpggVSlideFine: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_FSlideUpFine: portamento_up(chan,eHi2,nFreq(12*8+1)); ef_FSlideDownFine: portamento_down(chan,eHi2,nFreq(0)); ef_FSlUpVSlF: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_FSlDownVSlF: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_FSlUpFineVSlide: portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); ef_FSlUpFineVSlF: begin portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); end; ef_FSlDownFineVSlide: portamento_down(chan,fslide_table2[chan],nFreq(0)); ef_FSlDownFineVSlF: begin portamento_down(chan,fslide_table2[chan],nFreq(0)); volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); end; ef_TPortamVSlideFine: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_Vibrato: If vibr_table2[chan].fine then vibrato2(chan); ef_Tremolo: If trem_table2[chan].fine then tremolo2(chan); ef_VibratoVolSlide: If vibr_table2[chan].fine then vibrato2(chan); ef_VibratoVSlideFine: begin volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); If vibr_table2[chan].fine then vibrato2(chan); end; ef_VolSlideFine: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF: global_volume_slide(eHi2,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF: global_volume_slide(BYTE_NULL,eHi2); end; end; procedure update_extra_fine_effects; var chan,eLo,eHi, eLo2,eHi2: Byte; begin For chan := 1 to songdata.nm_tracks do begin eLo := LO(effect_table[chan]); eHi := HI(effect_table[chan]); eLo2 := LO(effect_table2[chan]); eHi2 := HI(effect_table2[chan]); Case eLo of ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF: global_volume_slide(eHi,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF: global_volume_slide(BYTE_NULL,eHi); ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF: volume_slide(chan,eHi,0); ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF: volume_slide(chan,0,eHi); ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF: portamento_up(chan,eHi,nFreq(12*8+1)); ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF: portamento_down(chan,eHi,nFreq(0)); ef_ExtraFineArpeggio: arpeggio(chan); ef_ExtraFineVibrato: If NOT vibr_table[chan].fine then vibrato(chan); ef_ExtraFineTremolo: If NOT trem_table[chan].fine then tremolo(chan); end; Case eLo2 of ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF: global_volume_slide(eHi2,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF: global_volume_slide(BYTE_NULL,eHi2); ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF: volume_slide(chan,eHi2,0); ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF: volume_slide(chan,0,eHi2); ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF: portamento_up(chan,eHi2,nFreq(12*8+1)); ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF: portamento_down(chan,eHi2,nFreq(0)); ef_ExtraFineArpeggio: arpeggio2(chan); ef_ExtraFineVibrato: If NOT vibr_table2[chan].fine then vibrato2(chan); ef_ExtraFineTremolo: If NOT trem_table2[chan].fine then tremolo2(chan); end; end; end; function calc_following_order(order: Byte): Integer; var result: Integer; index,jump_count: Byte; begin _debug_str_ := 'A2PLAYER.PAS:calc_following_order'; result := -1; index := order; jump_count := 0; Repeat If (songdata.pattern_order[index] < $80) then result := index else begin index := songdata.pattern_order[index]-$80; Inc(jump_count); end; until (jump_count > $7f) or (result <> -1); calc_following_order := result; end; function calc_order_jump: Integer; var temp: Byte; result: Integer; begin _debug_str_ := 'A2PLAYER.PAS:calc_order_jump'; result := 0; temp := 0; Repeat If (songdata.pattern_order[current_order] > $7f) then current_order := songdata.pattern_order[current_order]-$80; Inc(temp); until (temp > $7f) or (songdata.pattern_order[current_order] < $80); If (temp > $7f) then begin stop_playing; result := -1; end; calc_order_jump := result; end; procedure update_song_position; var temp: Byte; begin _debug_str_ := 'A2PLAYER.PAS:update_song_position'; If (current_line < PRED(songdata.patt_len)) and NOT pattern_break then Inc(current_line) else begin If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and (current_order < $7f) then begin FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); Inc(current_order); end; If pattern_break and (next_line AND $0f0 = pattern_loop_flag) then begin temp := next_line-pattern_loop_flag; next_line := loopbck_table[temp]; If (loop_table[temp][current_line] <> 0) then Dec(loop_table[temp][current_line]); end else If pattern_break and (next_line AND $0f0 = pattern_break_flag) then begin If (event_table[next_line-pattern_break_flag].effect_def2 = ef_PositionJump) then current_order := event_table[next_line-pattern_break_flag].effect2 else current_order := event_table[next_line-pattern_break_flag].effect; pattern_break := FALSE; end else If (current_order > $7f) then current_order := 0; If (songdata.pattern_order[current_order] > $7f) then If (calc_order_jump = -1) then EXIT; current_pattern := songdata.pattern_order[current_order]; If NOT pattern_break then current_line := 0 else begin pattern_break := FALSE; current_line := next_line; end; end; For temp := 1 to songdata.nm_tracks do begin glfsld_table[temp] := 0; glfsld_table2[temp] := 0; end; If (current_line = 0) and (current_order = calc_following_order(0)) and speed_update then begin tempo := songdata.tempo; speed := songdata.speed; update_timer(tempo); end; end; procedure poll_proc; var temp: Byte; var _debug_str_bak_: String; begin _debug_str_bak_ := _debug_str_; _debug_str_ := 'A2PLAYER.PAS:_poll_proc'; If (NOT pattern_delay and (ticks-tick0+1 >= speed)) or fast_forward then begin If (songdata.pattern_order[current_order] > $7f) then If (calc_order_jump = -1) then EXIT; current_pattern := songdata.pattern_order[current_order]; play_line; If NOT fast_forward then update_effects else For temp := 1 to speed do begin update_effects; If (temp MOD 4 = temp) then update_extra_fine_effects; Inc(ticks); end; pattern_break_docmd := pattern_break; pattern_break_oldord := current_order; If fast_forward or NOT pattern_delay then update_song_position; If (pattern_break_docmd = TRUE) then pattern_break_loop := current_order = pattern_break_oldord; tick0 := ticks; If fast_forward then If NOT pattern_delay then synchronize_song_timer; If fast_forward and pattern_delay then begin tickD := 0; pattern_delay := FALSE; end; end else begin update_effects; Inc(ticks); If pattern_delay and (tickD > 1) then Dec(tickD) else begin If pattern_delay then begin tick0 := ticks; update_song_position; end; pattern_delay := FALSE; end; end; Inc(tickXF); If (tickXF MOD 4 = 0) then begin update_extra_fine_effects; Dec(tickXF,4); end; _debug_str_ := _debug_str_bak_; end; procedure macro_poll_proc; const IDLE = $0fff; FINISHED = $0ffff; var chan: Byte; finished_flag: Word; var _debug_str_bak_: String; begin _debug_str_bak_ := _debug_str_; _debug_str_ := 'A2PLAYER.PAS:macro_poll_proc'; For chan := 1 to songdata.nm_tracks do begin If NOT keyoff_loop[chan] then finished_flag := FINISHED else finished_flag := IDLE; With macro_table[chan] do begin With songdata.instr_macros[fmreg_table] do If (fmreg_table <> 0) and (speed <> 0) then If (fmreg_duration > 1) then Dec(fmreg_duration) else begin fmreg_count := 1; If (fmreg_pos <= length) then If (loop_begin <> 0) and (loop_length <> 0) then If (fmreg_pos = loop_begin+PRED(loop_length)) then fmreg_pos := loop_begin else If (fmreg_pos < length) then Inc(fmreg_pos) else fmreg_pos := finished_flag else If (fmreg_pos < length) then Inc(fmreg_pos) else fmreg_pos := finished_flag else fmreg_pos := finished_flag; If (freq_table[chan] OR $2000 = freq_table[chan]) and (keyoff_pos <> 0) and (fmreg_pos >= keyoff_pos) then fmreg_pos := IDLE else If (freq_table[chan] OR $2000 <> freq_table[chan]) and (fmreg_pos <> 0) and (keyoff_pos <> 0) and ((fmreg_pos < keyoff_pos) or (fmreg_pos = IDLE)) then fmreg_pos := keyoff_pos; If (fmreg_pos <> 0) and (fmreg_pos <> IDLE) and (fmreg_pos <> finished_flag) then begin fmreg_duration := data[fmreg_pos].duration; If (fmreg_duration <> 0) then With data[fmreg_pos] do begin // force KEY-ON with missing ADSR instrument data force_macro_keyon := FALSE; If (fmreg_pos = 1) then If is_ins_adsr_data_empty(voice_table[chan]) and NOT (songdata.dis_fmreg_col[fmreg_table][0] and songdata.dis_fmreg_col[fmreg_table][1] and songdata.dis_fmreg_col[fmreg_table][2] and songdata.dis_fmreg_col[fmreg_table][3] and songdata.dis_fmreg_col[fmreg_table][12] and songdata.dis_fmreg_col[fmreg_table][13] and songdata.dis_fmreg_col[fmreg_table][14] and songdata.dis_fmreg_col[fmreg_table][15]) then force_macro_keyon := TRUE; If NOT songdata.dis_fmreg_col[fmreg_table][0] then fmpar_table[chan].adsrw_mod.attck := fm_data.ATTCK_DEC_modulator SHR 4; If NOT songdata.dis_fmreg_col[fmreg_table][1] then fmpar_table[chan].adsrw_mod.dec := fm_data.ATTCK_DEC_modulator AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][2] then fmpar_table[chan].adsrw_mod.sustn := fm_data.SUSTN_REL_modulator SHR 4; If NOT songdata.dis_fmreg_col[fmreg_table][3] then fmpar_table[chan].adsrw_mod.rel := fm_data.SUSTN_REL_modulator AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][4] then fmpar_table[chan].adsrw_mod.wform := fm_data.WAVEFORM_modulator AND $07; If NOT songdata.dis_fmreg_col[fmreg_table][6] then fmpar_table[chan].kslM := fm_data.KSL_VOLUM_modulator SHR 6; If NOT songdata.dis_fmreg_col[fmreg_table][7] then fmpar_table[chan].multipM := fm_data.AM_VIB_EG_modulator AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][8] then fmpar_table[chan].tremM := fm_data.AM_VIB_EG_modulator SHR 7; If NOT songdata.dis_fmreg_col[fmreg_table][9] then fmpar_table[chan].vibrM := fm_data.AM_VIB_EG_modulator SHR 6 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][10] then fmpar_table[chan].ksrM := fm_data.AM_VIB_EG_modulator SHR 4 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][11] then fmpar_table[chan].sustM := fm_data.AM_VIB_EG_modulator SHR 5 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][12] then fmpar_table[chan].adsrw_car.attck := fm_data.ATTCK_DEC_carrier SHR 4; If NOT songdata.dis_fmreg_col[fmreg_table][13] then fmpar_table[chan].adsrw_car.dec := fm_data.ATTCK_DEC_carrier AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][14] then fmpar_table[chan].adsrw_car.sustn := fm_data.SUSTN_REL_carrier SHR 4; If NOT songdata.dis_fmreg_col[fmreg_table][15] then fmpar_table[chan].adsrw_car.rel := fm_data.SUSTN_REL_carrier AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][16] then fmpar_table[chan].adsrw_car.wform := fm_data.WAVEFORM_carrier AND $07; If NOT songdata.dis_fmreg_col[fmreg_table][18] then fmpar_table[chan].kslC := fm_data.KSL_VOLUM_carrier SHR 6; If NOT songdata.dis_fmreg_col[fmreg_table][19] then fmpar_table[chan].multipC := fm_data.AM_VIB_EG_carrier AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][20] then fmpar_table[chan].tremC := fm_data.AM_VIB_EG_carrier SHR 7; If NOT songdata.dis_fmreg_col[fmreg_table][21] then fmpar_table[chan].vibrC := fm_data.AM_VIB_EG_carrier SHR 6 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][22] then fmpar_table[chan].ksrC := fm_data.AM_VIB_EG_carrier SHR 4 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][23] then fmpar_table[chan].sustC := fm_data.AM_VIB_EG_carrier SHR 5 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][24] then fmpar_table[chan].connect := fm_data.FEEDBACK_FM AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][25] then fmpar_table[chan].feedb := fm_data.FEEDBACK_FM SHR 1 AND 7; If NOT songdata.dis_fmreg_col[fmreg_table][27] then If NOT pan_lock[chan] then panning_table[chan] := panning; If NOT songdata.dis_fmreg_col[fmreg_table][5] then set_ins_volume(63-fm_data.KSL_VOLUM_modulator AND $3f, BYTE_NULL,chan); If NOT songdata.dis_fmreg_col[fmreg_table][17] then set_ins_volume(BYTE_NULL, 63-fm_data.KSL_VOLUM_carrier AND $3f,chan); update_modulator_adsrw(chan); update_carrier_adsrw(chan); update_fmpar(chan); If force_macro_keyon or NOT (fm_data.FEEDBACK_FM OR MACRO_NOTE_RETRIG_FLAG <> fm_data.FEEDBACK_FM) then begin If NOT (is_4op_chan(chan) and (chan in _4op_tracks_hi)) then begin output_note(event_table[chan].note, event_table[chan].instr_def,chan,FALSE,TRUE); If (is_4op_chan(chan) and (chan in _4op_tracks_lo)) then init_macro_table(PRED(chan),0,voice_table[PRED(chan)],0); end; end else If NOT (fm_data.FEEDBACK_FM OR MACRO_ENVELOPE_RESTART_FLAG <> fm_data.FEEDBACK_FM) then begin key_on(chan); change_freq(chan,freq_table[chan]); end else If NOT (fm_data.FEEDBACK_FM OR MACRO_ZERO_FREQ_FLAG <> fm_data.FEEDBACK_FM) then If (freq_table[chan] <> 0) then begin zero_fq_table[chan] := freq_table[chan]; freq_table[chan] := freq_table[chan] AND NOT $1fff; change_freq(chan,freq_table[chan]); end else else If (zero_fq_table[chan] <> 0) then begin freq_table[chan] := zero_fq_table[chan]; zero_fq_table[chan] := 0; change_freq(chan,freq_table[chan]); end; If NOT songdata.dis_fmreg_col[fmreg_table][26] then If (freq_slide > 0) then portamento_up(chan,freq_slide,nFreq(12*8+1)) else If (freq_slide < 0) then portamento_down(chan,Abs(freq_slide),nFreq(0)); end; end; end; With songdata.macro_table[arpg_table].arpeggio do If (arpg_table <> 0) and (speed <> 0) then If (arpg_count = speed) then begin arpg_count := 1; If (arpg_pos <= length) then If (loop_begin <> 0) and (loop_length <> 0) then If (arpg_pos = loop_begin+PRED(loop_length)) then arpg_pos := loop_begin else If (arpg_pos < length) then Inc(arpg_pos) else arpg_pos := finished_flag else If (arpg_pos < length) then Inc(arpg_pos) else arpg_pos := finished_flag else arpg_pos := finished_flag; If (freq_table[chan] OR $2000 = freq_table[chan]) and (keyoff_pos <> 0) and (arpg_pos >= keyoff_pos) then arpg_pos := IDLE else If (freq_table[chan] OR $2000 <> freq_table[chan]) and (keyoff_pos <> 0) and (keyoff_pos <> 0) and ((arpg_pos < keyoff_pos) or (arpg_pos = IDLE)) then arpg_pos := keyoff_pos; If (arpg_pos <> 0) and (arpg_pos <> IDLE) and (arpg_pos <> finished_flag) then Case data[arpg_pos] of 0: change_frequency(chan, nFreq(arpg_note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); 1..96: change_frequency(chan, nFreq(max(arpg_note+data[arpg_pos],97)-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); $80..$80+12*8+1: change_frequency(chan,nFreq(data[arpg_pos]-$80-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end; end else Inc(arpg_count); With songdata.macro_table[vib_table].vibrato do If NOT vib_paused and (vib_table <> 0) and (speed <> 0) then If (vib_count = speed) then If (vib_delay <> 0) then Dec(vib_delay) else begin vib_count := 1; If (vib_pos <= length) then If (loop_begin <> 0) and (loop_length <> 0) then If (vib_pos = loop_begin+PRED(loop_length)) then vib_pos := loop_begin else If (vib_pos < length) then Inc(vib_pos) else vib_pos := finished_flag else If (vib_pos < length) then Inc(vib_pos) else vib_pos := finished_flag else vib_pos := finished_flag; If (freq_table[chan] OR $2000 = freq_table[chan]) and (keyoff_pos <> 0) and (vib_pos >= keyoff_pos) then vib_pos := IDLE else If (freq_table[chan] OR $2000 <> freq_table[chan]) and (vib_pos <> 0) and (keyoff_pos <> 0) and ((vib_pos < keyoff_pos) or (vib_pos = IDLE)) then vib_pos := keyoff_pos; If (vib_pos <> 0) and (vib_pos <> IDLE) and (vib_pos <> finished_flag) then If (data[vib_pos] > 0) then macro_vibrato__porta_up(chan,data[vib_pos]) else If (data[vib_pos] < 0) then macro_vibrato__porta_down(chan,Abs(data[vib_pos])) else change_freq(chan,vib_freq); end else Inc(vib_count); end; end; _debug_str_ := _debug_str_bak_; end; procedure timer_poll_proc; var _debug_str_bak_: String; begin _debug_str_bak_ := _debug_str_; _debug_str_ := 'A2PLAYER.PAS:timer_poll_proc'; If (timer_200hz_counter < IRQ_freq DIV 200) then Inc(timer_200hz_counter) else begin timer_200hz_counter := 0; timer_200hz_flag := TRUE; end; If (timer_50hz_counter < IRQ_freq DIV 50) then Inc(timer_50hz_counter) else begin timer_50hz_counter := 0; timer_50hz_flag := TRUE; end; If (timer_20hz_counter < IRQ_freq DIV 20) then Inc(timer_20hz_counter) else begin timer_20hz_counter := 0; timer_20hz_flag := TRUE; end; If NOT replay_forbidden then begin If (current_order = 0) and (current_line = 0) and (tick0 = ticks) then begin song_timer := 0; timer_temp := 0; song_timer_tenths := 0; end; If (play_status = isPlaying) then begin song_timer_tenths := Trunc(100/IRQ_freq*timer_temp); If (song_timer_tenths = 100) then song_timer_tenths := 0; If (timer_temp < IRQ_freq) then Inc(timer_temp) else begin Inc(song_timer); timer_temp := 1; end; end; If (song_timer > 3600-1) then begin song_timer := 0; timer_temp := 0; song_timer_tenths := 0; end; If (ticklooper = 0) or fast_forward then poll_proc; If (macro_ticklooper = 0) then macro_poll_proc; Inc(ticklooper); If (ticklooper >= IRQ_freq DIV tempo) then ticklooper := 0; Inc(macro_ticklooper); If (macro_ticklooper >= IRQ_freq DIV (tempo*_macro_speedup)) then macro_ticklooper := 0; end; _debug_str_ := _debug_str_bak_; end; const ___IRQ_DATA_END___: Dword = 0; procedure ___IRQ_CODE_END___; begin end; procedure DisableTimerIRQ_proc; begin asm in al,21h or al,1 out 21h,al end; end; procedure EnableTimerIRQ_proc; begin asm in al,21h and al,0feh out 21h,al end; end; procedure TimerSetup(Hz: Longint); begin _debug_str_ := 'A2PLAYER.PAS:TimerSetup'; If (Hz < 19) then Hz := 19; If (Hz > 1193180) then Hz := 1193180; DisableTimerIRQ; If (timer_poll_proc_ptr <> NIL) then ISS_StopTimer(timer_poll_proc_ptr); timer_poll_proc_ptr := @timer_poll_proc; ISS_StartTimer(timer_poll_proc_ptr,ISS_TimerSpeed DIV Hz); EnableTimerIRQ; end; procedure TimerDone; begin _debug_str_ := 'A2PLAYER.PAS:TimerDone'; DisableTimerIRQ; If (timer_poll_proc_ptr <> NIL) then ISS_StopTimer(timer_poll_proc_ptr); timer_poll_proc_ptr := NIL; EnableTimerIRQ; end; procedure init_timer_proc; begin _debug_str_ := 'A2PLAYER.PAS:init_time_proc'; If timer_initialized then EXIT; timer_initialized := TRUE; TimerSetup(50); end; procedure done_timer_proc; begin _debug_str_ := 'A2PLAYER.PAS:done_timer_proc'; If NOT timer_initialized then EXIT; timer_initialized := FALSE; TimerDone; end; function calc_pattern_pos(pattern: Byte): Byte; var index: Integer; jump_count,pattern_pos: Byte; begin _debug_str_ := 'A2PLAYER.PAS:calc_pattern_pos'; pattern_pos := BYTE_NULL; jump_count := 0; index := calc_following_order(0); While (index <> -1) and (jump_count < $7f) do If (songdata.pattern_order[index] <> pattern) then If NOT (index < $7f) then BREAK else begin Inc(index); index := calc_following_order(index); Inc(jump_count); end else begin pattern_pos := index; BREAK; end; calc_pattern_pos := pattern_pos; end; procedure init_buffers; var temp: Byte; begin _debug_str_ := 'A2PLAYER.PAS:init_buffers'; FillChar(fmpar_table,SizeOf(fmpar_table),0); FillChar(pan_lock,SizeOf(pan_lock),BYTE(panlock)); FillChar(volume_table,SizeOf(volume_table),0); FillChar(vscale_table,SizeOf(vscale_table),0); FillChar(modulator_vol,SizeOf(modulator_vol),0); FillChar(carrier_vol,SizeOf(carrier_vol),0); FillChar(event_table,SizeOf(event_table),0); FillChar(freq_table,SizeOf(freq_table),0); FillChar(zero_fq_table,SizeOf(zero_fq_table),0); FillChar(effect_table,SizeOf(effect_table),0); FillChar(effect_table2,SizeOf(effect_table2),0); FillChar(fslide_table,SizeOf(fslide_table),0); FillChar(fslide_table2,SizeOf(fslide_table2),0); FillChar(glfsld_table,SizeOf(glfsld_table),0); FillChar(glfsld_table2,SizeOf(glfsld_table2),0); FillChar(porta_table,SizeOf(porta_table),0); FillChar(porta_table2,SizeOf(porta_table2),0); FillChar(portaFK_table,SizeOf(portaFK_table),BYTE(FALSE)); FillChar(arpgg_table,SizeOf(arpgg_table),0); FillChar(arpgg_table2,SizeOf(arpgg_table2),0); FillChar(vibr_table,SizeOf(vibr_table),0); FillChar(vibr_table2,SizeOf(vibr_table2),0); FillChar(trem_table,SizeOf(trem_table),0); FillChar(trem_table2,SizeOf(trem_table2),0); FillChar(retrig_table,SizeOf(retrig_table),0); FillChar(retrig_table2,SizeOf(retrig_table2),0); FillChar(tremor_table,SizeOf(tremor_table),0); FillChar(tremor_table2,SizeOf(tremor_table2),0); FillChar(last_effect,SizeOf(last_effect),0); FillChar(last_effect2,SizeOf(last_effect2),0); FillChar(voice_table,SizeOf(voice_table),0); FillChar(event_new,SizeOf(event_new),0); FillChar(notedel_table,SizeOf(notedel_table),BYTE_NULL); FillChar(notecut_table,SizeOf(notecut_table),BYTE_NULL); FillChar(ftune_table,SizeOf(ftune_table),0); FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); FillChar(reset_chan,SizeOf(reset_chan),BYTE(FALSE)); FillChar(keyoff_loop,SizeOf(keyoff_loop),BYTE(FALSE)); FillChar(macro_table,SizeOf(macro_table),0); If NOT lockvol then FillChar(volume_lock,SizeOf(volume_lock),0) else For temp := 1 to 20 do volume_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 4 AND 1); If NOT panlock then FillChar(panning_table,SizeOf(panning_table),0) else For temp := 1 to 20 do panning_table[temp] := songdata.lock_flags[temp] AND 3; If NOT lockVP then FillChar(peak_lock,SizeOf(peak_lock),0) else For temp := 1 to 20 do peak_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 5 AND 1); FillChar(vol4op_lock,SizeOf(vol4op_lock),BYTE(FALSE)); For temp := 1 to 6 do begin vol4op_lock[_4op_main_chan[temp]] := (songdata.lock_flags[_4op_main_chan[temp]] OR $40 = songdata.lock_flags[_4op_main_chan[temp]]); vol4op_lock[PRED(_4op_main_chan[temp])] := (songdata.lock_flags[PRED(_4op_main_chan[temp])] OR $40 = songdata.lock_flags[PRED(_4op_main_chan[temp])]); end; For temp := 1 to 20 do volslide_type[temp] := songdata.lock_flags[temp] SHR 2 AND 3; end; procedure init_player; var temp: Byte; begin _debug_str_ := 'A2PLAYER.PAS:init_player'; opl2out($01,0); For temp := 1 to 18 do opl2out($0b0+_chan_n[temp],0); For temp := $080 to $08d do opl2out(temp,BYTE_NULL); For temp := $090 to $095 do opl2out(temp,BYTE_NULL); speed_update := BOOLEAN(songdata.common_flag AND 1); lockvol := BOOLEAN(songdata.common_flag SHR 1 AND 1); lockVP := BOOLEAN(songdata.common_flag SHR 2 AND 1); tremolo_depth := songdata.common_flag SHR 3 AND 1; vibrato_depth := songdata.common_flag SHR 4 AND 1; panlock := BOOLEAN(songdata.common_flag SHR 5 AND 1); percussion_mode := BOOLEAN(songdata.common_flag SHR 6 AND 1); volume_scaling := BOOLEAN(songdata.common_flag SHR 7 AND 1); current_tremolo_depth := tremolo_depth; current_vibrato_depth := vibrato_depth; init_buffers; If NOT percussion_mode then begin _chan_n := _chmm_n; _chan_m := _chmm_m; _chan_c := _chmm_c; end else begin _chan_n := _chpm_n; _chan_m := _chpm_m; _chan_c := _chpm_c; end; misc_register := tremolo_depth SHL 7+ vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; opl2out($01,$20); opl2out($08,$40); opl3exp($0105); opl3exp($04+songdata.flag_4op SHL 8); key_off(17); key_off(18); opl2out(_instr[11],misc_register); global_volume := 63; vibtrem_speed_factor := def_vibtrem_speed_factor; vibtrem_table_size := def_vibtrem_table_size; Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table)); For temp := 1 to 20 do begin arpgg_table[temp].state := 1; voice_table[temp] := temp; end; end; procedure stop_playing; var temp: Byte; begin _debug_str_ := 'A2PLAYER.PAS:stop_playing'; play_status := isStopped; replay_forbidden := TRUE; global_volume := 63; current_tremolo_depth := tremolo_depth; current_vibrato_depth := vibrato_depth; pattern_break := FALSE; current_order := 0; current_pattern := 0; current_line := 0; song_timer := 0; timer_temp := 0; song_timer_tenths := 0; For temp := 1 to 20 do release_sustaining_sound(temp); opl2out(_instr[11],0); opl3exp($0004); opl3exp($0005); init_buffers; end; procedure init_old_songdata; begin _debug_str_ := 'A2PLAYER.PAS:init_old_songdata'; FillChar(old_songdata,SizeOf(old_songdata),0); FillChar(old_songdata.pattern_order,SizeOf(old_songdata.pattern_order),$080); FillChar(old_songdata.instr_data,SizeOf(old_songdata.instr_data),0); end; procedure init_songdata; begin _debug_str_ := 'A2PLAYER.PAS:init_songdata'; If (play_status <> isStopped) then stop_playing else init_buffers; FillChar(songdata,SizeOf(songdata),0); FillChar(songdata.pattern_order,SizeOf(songdata.pattern_order),$080); FillChar(pattdata^,PATTERN_SIZE*max_patterns,0); songdata.patt_len := 64; songdata.nm_tracks := 9; songdata.tempo := tempo; songdata.speed := speed; songdata.macro_speedup := 1; speed_update := FALSE; lockvol := FALSE; panlock := FALSE; lockVP := FALSE; tremolo_depth := 0; vibrato_depth := 0; volume_scaling := FALSE; If (songdata.nm_tracks <= 18) then begin percussion_mode := FALSE; _chan_n := _chmm_n; _chan_m := _chmm_m; _chan_c := _chmm_c; end else begin percussion_mode := TRUE; _chan_n := _chpm_n; _chan_m := _chpm_m; _chan_c := _chpm_c; end; end; procedure start_playing; begin _debug_str_ := 'A2PLAYER.PAS:start_playing'; stop_playing; If (error_code <> 0) then EXIT else init_player; current_order := 0; If (songdata.pattern_order[current_order] > $7f) then If (calc_order_jump = -1) then EXIT; current_pattern := songdata.pattern_order[current_order]; current_line := 0; pattern_break := FALSE; pattern_delay := FALSE; tickXF := 0; ticks := 0; tick0 := 0; next_line := 0; song_timer := 0; timer_temp := 0; song_timer_tenths := 0; replay_forbidden := FALSE; play_status := isPlaying; time_playing := 0; ticklooper := 0; macro_ticklooper := 0; speed := songdata.speed; macro_speedup := songdata.macro_speedup; update_timer(songdata.tempo); end; procedure get_chunk(pattern,line,chan: Byte; var chunk: tCHUNK); begin asm mov esi,[pattdata] mov edi,[chunk] mov al,pattern inc al cmp al,max_patterns jbe @@1 mov ecx,CHUNK_SIZE xor al,al rep stosb jmp @@2 @@1: xor eax,eax mov al,line mov ebx,CHUNK_SIZE mul ebx mov ecx,eax xor eax,eax mov al,chan dec eax mov ebx,256*CHUNK_SIZE mul ebx add ecx,eax xor eax,eax mov al,pattern mov ebx,8 div ebx push eax mov eax,edx mov ebx,20*256*CHUNK_SIZE mul ebx add ecx,eax pop eax mov ebx,8*20*256*CHUNK_SIZE mul ebx add ecx,eax add esi,ecx mov ecx,CHUNK_SIZE rep movsb @@2: end; end; procedure put_chunk(pattern,line,chan: Byte; chunk: tCHUNK); begin asm lea esi,[chunk] mov edi,[pattdata] mov al,pattern inc al cmp al,max_patterns jbe @@1 mov limit_exceeded,TRUE jmp @@2 @@1: xor eax,eax mov al,line mov ebx,CHUNK_SIZE mul ebx mov ecx,eax xor eax,eax mov al,chan dec eax mov ebx,256*CHUNK_SIZE mul ebx add ecx,eax xor eax,eax mov al,pattern mov ebx,8 div ebx push eax mov eax,edx mov ebx,20*256*CHUNK_SIZE mul ebx add ecx,eax pop eax mov ebx,8*20*256*CHUNK_SIZE mul ebx add ecx,eax add edi,ecx mov ecx,CHUNK_SIZE rep movsb @@2: end; end; procedure count_order(var entries: Byte); var index, index2: Byte; begin _debug_str_ := 'A2PLAYER.PAS:count_order'; index := 0; index2 := 0; Repeat If (songdata.pattern_order[index] <> $80) then begin If (songdata.pattern_order[index] > $80) then If (songdata.pattern_order[index]-$80 <> index2) then begin index := songdata.pattern_order[index]-$80; index2 := index; end else BREAK; end else BREAK; If (index < $80) then Inc(index); until (index > $7f); entries := index; end; var old_exit_proc: procedure; procedure new_exit_proc; begin Unlock_Data(___UNIT_DATA_START___,DWORD(Addr(___UNIT_DATA_END___))-DWORD(Addr(___UNIT_DATA_START___))); Unlock_Data(___IRQ_DATA_START___,DWORD(Addr(___IRQ_DATA_END___))-DWORD(Addr(___IRQ_DATA_START___))); Unlock_Code(@___IRQ_CODE_START___,DWORD(@___IRQ_CODE_END___)-DWORD(@___IRQ_CODE_START___)); ExitProc := @old_exit_proc; end; begin FillWord(_opl_regs_cache,SizeOf(_opl_regs_cache) DIV SizeOf(WORD),NOT 0); Lock_Data(___UNIT_DATA_START___,DWORD(Addr(___UNIT_DATA_END___))-DWORD(Addr(___UNIT_DATA_START___))); Lock_Data(___IRQ_DATA_START___,DWORD(Addr(___IRQ_DATA_END___))-DWORD(Addr(___IRQ_DATA_START___))); Lock_Code(@___IRQ_CODE_START___,DWORD(@___IRQ_CODE_END___)-DWORD(@___IRQ_CODE_START___)); @old_exit_proc := ExitProc; ExitProc := @new_exit_proc; end. adlibtracker2-2.4.23/adt2play/c.bat0000644000000000000000000000114213176573533015456 0ustar rootroot@echo off echo. echo ************************************ echo ** ** echo ** Compiling sources ** echo ** ** echo ************************************ ..\utils\val2 ..\iloaders.inc iloaders.inc if not exist *.exe goto :no_exe_file del *.exe >nul :no_exe_file if not exist *.ppu goto :no_ppu_file del *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del *.o >nul :no_o_file if not exist !log goto :no_log_file del !log >nul :no_log_file ppc386 -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Tgo32v2 adt2play >!log adlibtracker2-2.4.23/adt2play/txtscrio.pas0000644000000000000000000003211213176573533017131 0ustar rootrootunit TxtScrIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const Black = $00; DGray = $08; Blue = $01; LBlue = $09; Green = $02; LGreen = $0a; Cyan = $03; LCyan = $0b; Red = $04; LRed = $0c; Magenta = $05; LMagenta = $0d; Brown = $06; Yellow = $0e; LGray = $07; White = $0f; Blink = $80; const MAX_SCREEN_MEM_SIZE = 180*60*2; SCREEN_MEM_SIZE: Longint = MAX_SCREEN_MEM_SIZE; type tSCREEN_MEM = array[0..PRED(MAX_SCREEN_MEM_SIZE)] of Byte; tSCREEN_MEM_PTR = ^tSCREEN_MEM; var text_screen_shadow: tSCREEN_MEM; const screen_ptr: Pointer = Addr(text_screen_shadow); v_seg: Word = $0b800; v_ofs: Word = 0; v_mode: Byte = $03; MaxLn: Byte = 80; MaxCol: Byte = 25; var cursor_backup: Longint; DispPg: Byte; type tFADE = (first,fadeOut,fadeIn); tDELAY = (fast,delayed); type tFADE_BUF = Record action: tFADE; pal0: array[0..255] of Record r,g,b: Byte end; pal1: array[0..255] of Record r,g,b: Byte end; end; const fade_speed: Byte = 63; type tVIDEO_STATE = Record cursor: Longint; font: Byte; MaxLn,MaxCol,v_mode,DispPg: Byte; v_seg,v_ofs: Word; screen: tSCREEN_MEM; data: array[0..PRED(4096)] of Byte; end; procedure ShowC3Str(var dest; x,y: Byte; str: String; atr1,atr2,atr3: Byte); function iVGA: Boolean; function WhereX: Byte; function WhereY: Byte; procedure GotoXY(x,y: Byte); function GetCursor: Longint; procedure SetCursor(cursor: Longint); procedure ThinCursor; procedure WideCursor; procedure HideCursor; function GetCursorShape: Word; procedure SetCursorShape(shape: Word); procedure GetRGBitem(color: Byte; var red,green,blue: Byte); procedure SetRGBitem(color: Byte; red,green,blue: Byte); procedure GetPalette(var pal; first,last: Word); procedure SetPalette(var pal; first,last: Word); procedure WaitRetrace; procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY); procedure GetVideoState(var data: tVIDEO_STATE); procedure SetVideoState(var data: tVIDEO_STATE; restore_screen: Boolean); implementation uses GO32; var absolute_pos: Word; procedure DupChar; assembler; asm pushad { IN/ al -column } xor ebx,ebx { ah -line } xchg ax,bx { dl -character } xor eax,eax { dh -attribute } xchg ax,bx { ecx -count } mov bl,al { edi -ptr. to write } mov al,MaxCol mul ah add ax,bx mov bl,MaxCol sub ax,bx dec ax shl ax,1 jecxz @@1 add edi,eax xchg ax,dx rep stosw xchg ax,dx @@1: mov absolute_pos,ax popad end; procedure ShowC3Str(var dest; x,y: Byte; str: String; atr1,atr2,atr3: Byte); begin asm lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@3 push ecx mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos pop ecx add edi,edx mov ah,atr1 mov bl,atr2 mov bh,atr3 @@1: lodsb cmp al,'~' jz @@2 cmp al,'`' jz @@3 stosw loop @@1 jmp @@4 @@2: xchg ah,bl loop @@1 jmp @@4 @@3: xchg ah,bh loop @@1 @@4: end; end; procedure ScreenMemCopy(source,dest: tSCREEN_MEM_PTR); begin cursor_backup := GetCursor; asm xor edx,edx mov eax,SCREEN_MEM_SIZE cmp eax,16 jb @@1 mov ecx,4 div ecx mov ecx,eax jecxz @@1 mov esi,dword ptr [source] mov edi,dword ptr [dest] cld rep movsd mov ecx,edx jecxz @@2 rep movsb jmp @@2 @@1: mov ecx,SCREEN_MEM_SIZE mov esi,dword ptr [source] mov edi,dword ptr [dest] cld rep movsb @@2: end; end; function WhereX: Byte; var result: Byte; begin asm mov bh,DispPg mov ah,03h int 10h inc dl mov result,dl end; WhereX := result; end; function WhereY: Byte; var result: Byte; begin asm mov bh,DispPg mov ah,03h int 10h inc dh mov result,dh end; WhereY := result; end; procedure GotoXY(x,y: Byte); begin asm mov dh,y mov dl,x dec dh dec dl mov bh,DispPg mov ah,02h int 10h end; end; function GetCursor: Longint; var result: Longint; begin asm xor edx,edx mov bh,DispPg mov ah,03h int 10h shl edx,16 xor eax,eax push edx call GetCursorShape pop edx add edx,eax mov result,edx end; GetCursor := result; end; procedure SetCursor(cursor: Longint); begin asm xor eax,eax mov ax,word ptr [cursor] push eax call SetCursorShape mov dx,word ptr [cursor+2] mov bh,DispPg mov ah,02h int 10h end; end; procedure ThinCursor; begin SetCursorShape($0d0e); end; procedure WideCursor; begin SetCursorShape($010e); end; procedure HideCursor; begin SetCursorShape($1010); end; function GetCursorShape: Word; var result: Word; begin asm mov dx,03d4h mov al,0ah out dx,al inc dx in al,dx and al,1fh mov ah,al dec dx mov al,0bh out dx,al inc dx in al,dx and al,1fh mov result,ax end; GetCursorShape := result; end; procedure SetCursorShape(shape: Word); begin asm mov dx,03d4h mov al,0ah out dx,al inc dx in al,dx mov ah,byte ptr [shape+1] and al,0e0h or al,ah out dx,al dec dx mov al,0bh out dx,al inc dx in al,dx mov ah,byte ptr [shape] and al,0e0h or al,ah out dx,al end; end; procedure initialize; begin asm mov ah,0fh int 10h and al,7fh mov v_mode,al mov DispPg,bh end; MaxCol := MEM[0:$44a]; MaxLn := SUCC(MEM[0:$484]); FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); end; function iVGA: Boolean; var result: Boolean; begin asm mov ax,1a00h int 10h cmp al,1ah jnz @@1 cmp bl,7 jb @@1 cmp bl,0ffh jnz @@2 @@1: mov result,FALSE jmp @@3 @@2: mov result,TRUE @@3: end; iVGA := result; end; procedure GetRGBitem(color: Byte; var red,green,blue: Byte); begin outportb($3c7,color); red := inportb($3c9); green := inportb($3c9); blue := inportb($3c9); end; procedure SetRGBitem(color: Byte; red,green,blue: Byte); begin outportb($3c8,color); outportb($3c9,red); outportb($3c9,green); outportb($3c9,blue); end; procedure GetPalette(var pal; first,last: Word); begin asm xor eax,eax xor ecx,ecx mov ax,first mov cx,last sub ecx,eax inc ecx mov dx,03c7h out dx,al add dx,2 mov edi,[pal] add edi,eax add edi,eax add edi,eax mov eax,ecx add ecx,eax add ecx,eax rep insb end; end; procedure SetPalette(var pal; first,last: Word); begin asm mov dx,03dah @@1: in al,dx test al,8 jz @@1 xor eax,eax xor ecx,ecx mov ax,first mov cx,last sub ecx,eax inc ecx mov dx,03c8h out dx,al inc dx mov esi,[pal] add esi,eax add esi,eax add esi,eax mov eax,ecx add ecx,eax add ecx,eax rep outsb end; end; procedure WaitRetrace; begin asm mov dx,3dah @@1: in al,dx and al,08h jnz @@1 @@2: in al,dx and al,08h jz @@2 end; end; const fade_first: Byte = 0; fade_last: Byte = 255; procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY); var i,j: Byte; begin If (fade = fadeOut) and (data.action in [first,fadeIn]) then begin GetPalette(data.pal0,fade_first,fade_last); If delay = delayed then For i := fade_speed downto 0 do begin For j := fade_first to fade_last do begin data.pal1[j].r := data.pal0[j].r * i DIV fade_speed; data.pal1[j].g := data.pal0[j].g * i DIV fade_speed; data.pal1[j].b := data.pal0[j].b * i DIV fade_speed; end; SetPalette(data.pal1,fade_first,fade_last); WaitRetrace; end else begin FillChar(data.pal1,SizeOf(data.pal1),0); SetPalette(data.pal1,fade_first,fade_last); end; data.action := fadeOut; end; If (fade = fadeIn) and (data.action = fadeOut) then begin If delay = delayed then For i := 0 to fade_speed do begin For j := fade_first to fade_last do begin data.pal1[j].r := data.pal0[j].r * i DIV fade_speed; data.pal1[j].g := data.pal0[j].g * i DIV fade_speed; data.pal1[j].b := data.pal0[j].b * i DIV fade_speed; end; SetPalette(data.pal1,fade_first,fade_last); WaitRetrace; end else SetPalette(data.pal0,fade_first,fade_last); data.action := fadeIn; end; end; var regs: tRealRegs; dos_sel,dos_seg: Word; dos_mem_adr: Dword; bios_data_backup: array[0..167] of Byte; procedure GetVideoState(var data: tVIDEO_STATE); begin asm mov ah,0fh int 10h and al,7fh mov v_mode,al mov DispPg,bh end; dosmemget(v_seg,v_ofs,data.screen,MAX_SCREEN_MEM_SIZE); data.cursor := GetCursor; data.font := MEMW[Seg0040:$85]; data.v_seg := $0b800; data.v_ofs := MEM[Seg0040:$4e]; data.DispPg := DispPg; data.v_mode := v_mode; data.MaxCol := MEM[Seg0040:$4a]; data.MaxLn := SUCC(MEM[Seg0040:$84]); dosmemget(Seg0040,0,bios_data_backup,168); dos_mem_adr := global_dos_alloc(SizeOf(tVIDEO_STATE(data).data)); dos_sel := WORD(dos_mem_adr); dos_seg := WORD(dos_mem_adr SHR 16); regs.cx := 7; regs.es := dos_seg; regs.ax := $1c01; RealIntr($10,regs); dosmemput(Seg0040,0,bios_data_backup,168); dosmemget(dos_seg,0,tVIDEO_STATE(data).data,SizeOf(tVIDEO_STATE(data).data)); global_dos_free(dos_sel); end; procedure SetVideoState(var data: tVIDEO_STATE; restore_screen: Boolean); begin v_seg := data.v_seg; v_ofs := data.v_ofs; v_mode := data.v_mode; DispPg := data.DispPg; asm movzx ax,v_mode mov bh,DispPg int 10h end; MaxCol := data.MaxCol; MaxLn := data.MaxLn; dosmemget(Seg0040,0,bios_data_backup,168); dos_mem_adr := global_dos_alloc(SizeOf(tVIDEO_STATE(data).data)); dos_sel := WORD(dos_mem_adr); dos_seg := WORD(dos_mem_adr SHR 16); dosmemput(dos_seg,0,tVIDEO_STATE(data).data,SizeOf(tVIDEO_STATE(data).data)); regs.cx := 7; regs.es := dos_seg; regs.ax := $1c02; RealIntr($10,regs); global_dos_free(dos_sel); dosmemput(Seg0040,0,bios_data_backup,168); MEM[Seg0040:$4e] := data.v_ofs; MEM[Seg0040:$4a] := MaxCol; MEM[Seg0040:$84] := PRED(MaxLn); Case data.font of 8: asm mov ax,1112h; xor bl,bl; int 10h end; 14: asm mov ax,1111h; xor bl,bl; int 10h end; else asm mov ax,1114h; xor bl,bl; int 10h end; end; SetCursor(data.cursor); If restore_screen then dosmemput(v_seg,v_ofs,data.screen,MAX_SCREEN_MEM_SIZE); end; begin initialize; end. adlibtracker2-2.4.23/makefile.cross320000644000000000000000000000273613176573533016033 0ustar rootroot.PHONY: clean release release_ all: adtrack2 release: release_ rm -rf release/adtrack-*/ echo -e "\n\n\nyour files are ready at release/\n" release_: all rm -rf release mkdir release mkdir release/src cp -r *.pas *.inc Makefile TODO *.bat sdl.dll sdl utils package release/src/ cp -r package release/bin cp adtrack2 release/bin/ rm -f release/bin/techinfo.* cd release; \ echo "which minor version is this? NOTE that i assume 2.4.xx and that you're on debian wheezy x86!"; \ read ver; \ mv src adtrack-2.4.$${ver}-linux-src; \ mv bin adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86; \ tar cvzf adtrack-2.4.$${ver}-linux-src.tar.gz adtrack-2.4.$${ver}-linux-src; \ tar cvzf adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86.tar.gz adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86; clean: rm -f *.o *.s *.res *.ppu *.map *.fpd *.sym *.cfg adtrack2 rm -f sdl/*.o sdl/*.ppu mrproper: clean rm -rf bin/ mkdir bin/ rm -rf release/ adtrack2: adt2data.pas adt2ext2.pas adt2ext3.pas adt2ext4.pas adt2ext5.pas adt2extn.pas adt2keyb.pas adt2opl3.pas adt2pack.pas adt2sys.pas adt2text.pas adt2unit.pas adt2vesa.pas adtrack2.pas depackio.pas dialogio.pas iloaders.inc iloadins.inc instedit.inc ipattern.inc ipattord.inc iss_tim.pas menulib1.pas menulib2.pas opl3emu.pas parserio.pas realtime.inc stringio.pas txtscrio.pas typcons1.inc typcons2.inc ppcross386 -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Fusdl -Fl/usr/lib32 -Fl/usr/lib/gcc/x86_64-linux-gnu/4.7.2/32 adtrack2.pas -oadtrack2 adlibtracker2-2.4.23/sdl/0000755000000000000000000000000013176573533013610 5ustar rootrootadlibtracker2-2.4.23/sdl/build.sh0000644000000000000000000000005413176573533015242 0ustar rootroot#!/bin/sh for i in *.pp; do ppc386 $i; doneadlibtracker2-2.4.23/sdl/sdl_timer.pp0000644000000000000000000001224613176573533016140 0ustar rootrootunit SDL_timer; { Automatically converted by H2PAS.EXE from SDL_timer.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types; { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Header for the SDL time management routines } const { This is the OS scheduler timeslice, in milliseconds } SDL_TIMESLICE = 10; { This is the maximum resolution of the timer on all platforms } TIMER_RESOLUTION = 10; { Experimentally determined } { Get the number of milliseconds since the SDL library initialization. Note that this value wraps if the program runs for more than ~49 days. } function SDL_GetTicks:Uint32;cdecl; { Wait a specified number of milliseconds before returning } procedure SDL_Delay(ms:Uint32);cdecl; type { Function prototype for the timer callback function } SDL_TimerCallback = function (interval:Uint32):Longbool;cdecl; { Set a callback to run after the specified number of milliseconds has elapsed. The callback function is passed the current timer interval and returns the next timer interval. If the returned value is the same as the one passed in, the periodic alarm continues, otherwise a new alarm is scheduled. If the callback returns False, the periodic alarm is cancelled. To cancel a currently running timer, call SDL_SetTimer(0, nil); The timer callback function may run in a different thread than your main code, and so shouldn't call any functions from within itself. The maximum resolution of this timer is 10 ms, which means that if you request a 16 ms timer, your callback will run approximately 20 ms later on an unloaded system. If you wanted to set a flag signaling a frame update at 30 frames per second (every 33 ms), you might set a timer for 30 ms: SDL_SetTimer((33 div 10)*10, flag_update); If you use this function, you need to pass SDL_INIT_TIMER to SDL_Init. Under UNIX, you should not use raise or use SIGALRM and this function in the same program, as it is implemented using setitimer(). You also should not use this function in multi-threaded applications as signals to multi-threaded apps have undefined behavior in some implementations. } function SDL_SetTimer(interval:Uint32; callback:SDL_TimerCallback):longint;cdecl; { New timer API, supports multiple timers Written by Stephane Peter } { Function prototypye for the new timer callback function. The callback function is passed the current timer interval and returns the next timer interval. If the returned value is the same as the one passed in, the periodic alarm continues, otherwise a new alarm is scheduled. If the callback returns 0, the periodic alarm is cancelled. } type SDL_NewTimerCallback = function (interval: Uint32; param: Pointer):Uint32; cdecl; _SDL_TimerID = record end ; { No public Data} SDL_TimerID = ^_SDL_TimerID ; { Add a new timer to the pool of timers already running. Returns a timer ID, or Nil when an error occurs. } function SDL_AddTimer (interval: Uint32; callback: SDL_NewTimerCallback; param: Pointer): SDL_TimerID ; cdecl; { Remove one of the multiple timers knowing its ID. Returns a boolean value indicating success. } function SDL_RemoveTimer (t: SDL_TimerID): SDL_bool;cdecl; implementation function SDL_GetTicks:Uint32;cdecl;external 'SDL'; procedure SDL_Delay(ms:Uint32);cdecl;external 'SDL'; function SDL_SetTimer(interval:Uint32; callback:SDL_TimerCallback):longint;cdecl;external 'SDL'; function SDL_AddTimer (interval: Uint32; callback: SDL_NewTimerCallback; param: Pointer): SDL_TimerID ; cdecl;external 'SDL'; function SDL_RemoveTimer (t: SDL_TimerID): SDL_bool;cdecl;external 'SDL'; end. adlibtracker2-2.4.23/sdl/sdl__rwops.pp0000644000000000000000000001225713176573533016333 0ustar rootrootunit SDL__rwops; { Automatically converted by H2PAS.EXE from SDL_rwops.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types, stdio; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PByte = ^Byte; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { This file provides a general interface for SDL to read and write data sources. It can easily be extended to files, memory, etc. } { This is the read/write operation structure -- very basic } type pSDL_RWops = ^SDL_RWops; SDL_RWops = record { Seek to 'offset' relative to whence, one of stdio's whence values: SEEK_SET, SEEK_CUR, SEEK_END Returns the final offset in the data source. } seek : function (context:pSDL_RWops; offset:longint; whence:longint):longint;cdecl; { Read up to 'num' objects each of size 'objsize' from the data source to the area pointed at by 'ptr'. Returns the number of objects read, or -1 if the read failed. } read : function (context:pSDL_RWops; var data; size:longint; maxnum:longint):longint; { Write exactly 'num' objects each of size 'objsize' from the area pointed at by 'ptr' to data source. Returns 'num', or -1 if the write failed. } write : function (context:pSDL_RWops; var data; size:longint; num:longint):longint; { Close and free an allocated SDL_FSops structure } close : function (context:pSDL_RWops):longint; optype : Uint32; hidden : record case longint of 0 : ( stdio : record autoclose : longint; fp : PFile; {C file *} end ); 1 : ( mem : record base : PByte; here : PByte; stop : PByte; end ); 2 : ( unknown : record data1 : pointer; end ); end; end; { Functions to create SDL_RWops structures from various data sources } function SDL_RWFromFile(filename:pchar; mode:pchar):pSDL_RWops;cdecl; function SDL_RWFromFP(fp:Pointer; autoclose:longint):pSDL_RWops;cdecl; function SDL_RWFromMem(var mem; size:longint):pSDL_RWops;cdecl; function SDL_AllocRW:pSDL_RWops;cdecl; { Macros to easily read and write from an SDL_RWops structure } function SDL_RWseek(ctx: pSDL_RWops;offset,whence : longint) : longint; function SDL_RWtell(ctx : pSDL_RWops) : longint; function SDL_RWread(ctx : pSDL_RWops; var data;size,n : longint) : longint; function SDL_RWwrite(ctx : pSDL_RWops; var data;size,n : longint) : longint; function SDL_RWclose(ctx : pSDL_RWops) : longint; implementation function SDL_RWFromFile(filename:pchar; mode:pchar):pSDL_RWops;cdecl;external 'SDL'; function SDL_RWFromFP(fp:Pointer; autoclose:longint):pSDL_RWops;cdecl;external 'SDL'; function SDL_RWFromMem(var mem; size:longint):pSDL_RWops;cdecl;external 'SDL'; function SDL_AllocRW:pSDL_RWops;cdecl;external 'SDL'; function SDL_RWseek(ctx: pSDL_RWops;offset,whence : longint) : longint; begin SDL_RWseek:=ctx^.seek(ctx,offset,whence); end; function SDL_RWtell(ctx : pSDL_RWops) : longint; begin SDL_RWtell:=ctx^.seek(ctx,0,SEEK_CUR); end; function SDL_RWread(ctx : pSDL_RWops; var data;size,n : longint) : longint; begin SDL_RWread:=ctx^.read(ctx,data,size,n); end; function SDL_RWwrite(ctx : pSDL_RWops; var data;size,n : longint) : longint; begin SDL_RWwrite:=ctx^.write(ctx,data,size,n); end; function SDL_RWclose(ctx : pSDL_RWops) : longint; begin SDL_RWclose:=ctx^.close(ctx); end; end. adlibtracker2-2.4.23/sdl/sdl_audio.pp0000644000000000000000000002771413176573533016127 0ustar rootrootunit SDL_audio; { Automatically converted by H2PAS.EXE from SDL_audio.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types,SDL__rwops; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PByte = ^Byte; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } type { Access to the raw audio mixing buffer for the SDL library } { The calculated values in this structure are calculated by SDL_OpenAudio } pSDL_AudioSpec = ^SDL_AudioSpec; SDL_AudioSpec = record freq : longint; { DSP frequency -- samples per second } format : Uint16; { Audio data format } channels : Uint8; { Number of channels: 1 mono, 2 stereo } silence : Uint8; { Audio buffer silence value (calculated) } samples : Uint16; { Audio buffer size in samples } size : Uint32; { Audio buffer size in bytes (calculated) } { This function is called when the audio device needs more data. 'stream' is a pointer to the audio data buffer 'len' is the length of that buffer in bytes. Once the callback returns, the buffer will no longer be valid. Stereo samples are stored in a LRLRLR ordering. } callback : procedure (var userdata; stream:pByte; len:longint);cdecl; userdata : pointer; end; const { Audio format flags (defaults to LSB byte order) } { Unsigned 8-bit samples } AUDIO_U8 = $0008; { Signed 8-bit samples } AUDIO_S8 = $8008; { Unsigned 16-bit samples } AUDIO_U16LSB = $0010; { Signed 16-bit samples } AUDIO_S16LSB = $8010; { As above, but big-endian byte order } AUDIO_U16MSB = $1010; { As above, but big-endian byte order } AUDIO_S16MSB = $9010; AUDIO_U16 = AUDIO_U16LSB; AUDIO_S16 = AUDIO_S16LSB; type { A structure to hold a set of audio conversion filters and buffers } pSDL_AudioCVT = ^SDL_AudioCVT; SDL_FilterFunction = procedure (cvt:pSDL_AudioCVT; format:Uint16);cdecl; SDL_AudioCVT = record needed : longint; { Set to 1 if conversion possible } src_format : Uint16; { Source audio format } dst_format : Uint16; { Target audio format } rate_incr : double; { Rate conversion increment } buf : ^Uint8; { Buffer to hold entire audio data } len : longint; { Length of original audio buffer } len_cvt : longint; { Length of converted audio buffer } len_mult : longint; { buffer must be len*len_mult big } len_ratio : double; { Given len, final size is len*len_ratio } filters : array[0..9] of SDL_FilterFunction; filter_index : longint;{ Current audio conversion function } end; { Function prototypes } { This function opens the audio device with the desired parameters, and returns 0 if successful, placing the actual hardware parameters in the structure pointed to by 'obtained'. If 'obtained' is nil, the audio data passed to the callback function will be guaranteed to be in the requested format, and will be automatically converted to the hardware audio format if necessary. This function returns -1 if it failed to open the audio device, or couldn't set up the audio thread. When filling in the desired audio spec structure, 'desired^.freq' should be the desired audio frequency in samples-per-second. 'desired^.format' should be the desired audio format. 'desired^.samples' is the desired size of the audio buffer, in samples. This number should be a power of two, and may be adjusted by the audio driver to a value more suitable for the hardware. Good values seem to range between 512 and 8096 inclusive, depending on the application and CPU speed. Smaller values yield faster response time, but can lead to underflow if the application is doing heavy processing and cannot fill the audio buffer in time. A stereo sample consists of both right and left channels in LR ordering. Note that the number of samples is directly related to time by the following formula: ms = (samples*1000)/freq 'desired^.size' is the size in bytes of the audio buffer, and is calculated by SDL_OpenAudio. 'desired^.silence' is the value used to set the buffer to silence, and is calculated by SDL_OpenAudio. 'desired^.callback' should be set to a function that will be called when the audio device is ready for more data. It is passed a pointer to the audio buffer, and the length in bytes of the audio buffer. This function usually runs in a separate thread, and so you should protect data structures that it accesses by calling SDL_LockAudio and SDL_UnlockAudio in your code. 'desired^.userdata' is passed as the first parameter to your callback function. The audio device starts out playing silence when it's opened, and should be enabled for playing by calling SDL_PauseAudio(0) when you are ready for your audio callback function to be called. Since the audio driver may modify the requested size of the audio buffer, you should allocate any local mixing buffers after you open the audio device. } function SDL_OpenAudio(desired, obtained:pSDL_AudioSpec):longint;cdecl; type SDL_audiostatus = Longint; Const SDL_AUDIO_STOPPED = 0 ; SDL_AUDIO_PLAYING = 1 ; SDL_AUDIO_PAUSED = 2 ; { Get the current audio state } Function SDL_GetAudioStatus: SDL_audiostatus; cdecl; { This function pauses and unpauses the audio callback processing. It should be called with a parameter of 0 after opening the audio device to start playing sound. This is so you can safely initialize data for your callback function after opening the audio device. Silence will be written to the audio device during the pause. } procedure SDL_PauseAudio(pause_on:longint);cdecl; { This function loads a WAVE from the data source, automatically freeing that source if 'freesrc' is True. For example, to load a WAVE file, you could do: SDL_LoadWAV_RW(SDL_RWFromFile('sample.wav', 'rb'), 1, ...); If this function succeeds, it returns the given SDL_AudioSpec, filled with the audio data format of the wave data, and sets 'audio_buf' to a getmem'd buffer containing the audio data, and sets 'audio_len' to the length of that audio buffer, in bytes. You need to free the audio buffer with SDL_FreeWAV when you are done with it. This function returns nil and sets the SDL error message if the wave file cannot be opened, uses an unknown data format, or is corrupt. Currently raw and MS-ADPCM WAVE files are supported. } function SDL_LoadWAV_RW(src:pSDL_RWops; freesrc:LongBool; spec:pSDL_AudioSpec; var audio_buf:pByte; var audio_len:Uint32):pSDL_AudioSpec;cdecl; { Compatibility convenience function -- loads a WAV from a file } function SDL_LoadWAV(filename:PChar; spec:pSDL_AudioSpec; var audio_buf:pByte; var audio_len : Uint32) : pSDL_AudioSpec; { This function frees data previously allocated with SDL_LoadWAV_RW } procedure SDL_FreeWAV(audio_buf:pByte);cdecl; { This function takes a source format and rate and a destination format and rate, and initializes the 'cvt' structure with information needed by SDL_ConvertAudio to convert a buffer of audio data from one format to the other. This function returns 0, or -1 if there was an error. } function SDL_BuildAudioCVT(cvt:pSDL_AudioCVT; src_format:Uint16; src_channels:Uint8; src_rate:longint; dst_format:Uint16; dst_channels:Uint8; dst_rate:longint):longint;cdecl; { Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT, created an audio buffer cvt^.buf, and filled it with cvt^.len bytes of audio data in the source format, this function will convert it in-place to the desired format. The data conversion may expand the size of the audio data, so the buffer cvt^.buf should be allocated after the cvt structure is initialized by SDL_BuildAudioCVT, and should be cvt^.len*cvt^.len_mult bytes long. } function SDL_ConvertAudio(cvt:pSDL_AudioCVT):longint;cdecl; const SDL_MIX_MAXVOLUME = 128; { This takes two audio buffers of the playing audio format and mixes them, performing addition, volume adjustment, and overflow clipping. The volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME for full audio volume. Note this does not change hardware volume. This is provided for convenience -- you can mix your own audio data. } procedure SDL_MixAudio(dst:pByte; src:pByte; len:Uint32; volume:longint);cdecl; { The lock manipulated by these functions protects the callback function. During a LockAudio/UnlockAudio pair, you can be guaranteed that the callback function is not running. Do not call these from the callback function or you will cause deadlock. } procedure SDL_LockAudio;cdecl; procedure SDL_UnlockAudio;cdecl; { This function shuts down audio processing and closes the audio device. } procedure SDL_CloseAudio;cdecl; implementation function SDL_OpenAudio(desired, obtained:pSDL_AudioSpec):longint;cdecl;external 'SDL'; Function SDL_GetAudioStatus: SDL_audiostatus;cdecl;external 'SDL'; procedure SDL_PauseAudio(pause_on:longint);cdecl;external 'SDL'; function SDL_LoadWAV_RW(src:pSDL_RWops; freesrc:LongBool; spec:pSDL_AudioSpec; var audio_buf:pByte; var audio_len:Uint32):pSDL_AudioSpec;cdecl;external 'SDL'; function SDL_LoadWAV(filename:PChar; spec:pSDL_AudioSpec; var audio_buf:pByte; var audio_len : Uint32) : pSDL_AudioSpec; begin SDL_LoadWAV:=SDL_LoadWAV_RW(SDL_RWFromFile(filename,'rb'),True,spec,audio_buf,audio_len); end; procedure SDL_FreeWAV(audio_buf:pByte);cdecl;external 'SDL'; function SDL_BuildAudioCVT(cvt:pSDL_AudioCVT; src_format:Uint16; src_channels:Uint8; src_rate:longint; dst_format:Uint16; dst_channels:Uint8; dst_rate:longint):longint;cdecl;external 'SDL'; function SDL_ConvertAudio(cvt:pSDL_AudioCVT):longint;cdecl;external 'SDL'; procedure SDL_MixAudio(dst:pByte; src:pByte; len:Uint32; volume:longint);cdecl;external 'SDL'; procedure SDL_LockAudio;cdecl;external 'SDL'; procedure SDL_UnlockAudio;cdecl;external 'SDL'; procedure SDL_CloseAudio;cdecl;external 'SDL'; end. adlibtracker2-2.4.23/sdl/sdl_keyboard.pp0000644000000000000000000003201213176573533016611 0ustar rootrootunit SDL_keyboard; { Automatically converted by H2PAS.EXE from SDL_keyboard.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PBoolArray = ^BoolArray ; BoolArray = Array[0..322] of Boolean; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Include file for SDL keyboard event handling } { ***corresponding to SDL_keysym.h***} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { What we really want is a mapping of every raw key on the keyboard. To support international keyboards, we use the range 0xA1 - 0xFF as international virtual keycodes. We'll follow in the footsteps of X11... } type SDLKey = Longint; Const {The names of the keys} { The keyboard syms have been cleverly chosen to map to ASCII } SDLK_UNKNOWN = 0; SDLK_FIRST = 0; SDLK_BACKSPACE = 8; SDLK_TAB = 9; SDLK_CLEAR = 12; SDLK_RETURN = 13; SDLK_PAUSE = 19; SDLK_ESCAPE = 27; SDLK_SPACE = 32; SDLK_EXCLAIM = 33; SDLK_QUOTEDBL = 34; SDLK_HASH = 35; SDLK_DOLLAR = 36; SDLK_AMPERSAND = 38; SDLK_QUOTE = 39; SDLK_LEFTPAREN = 40; SDLK_RIGHTPAREN = 41; SDLK_ASTERISK = 42; SDLK_PLUS = 43; SDLK_COMMA = 44; SDLK_MINUS = 45; SDLK_PERIOD = 46; SDLK_SLASH = 47; SDLK_0 = 48; SDLK_1 = 49; SDLK_2 = 50; SDLK_3 = 51; SDLK_4 = 52; SDLK_5 = 53; SDLK_6 = 54; SDLK_7 = 55; SDLK_8 = 56; SDLK_9 = 57; SDLK_COLON = 58; SDLK_SEMICOLON = 59; SDLK_LESS = 60; SDLK_EQUALS = 61; SDLK_GREATER = 62; SDLK_QUESTION = 63; SDLK_AT = 64; { Skip uppercase letters } SDLK_LEFTBRACKET = 91; SDLK_BACKSLASH = 92; SDLK_RIGHTBRACKET = 93; SDLK_CARET = 94; SDLK_UNDERSCORE = 95; SDLK_BACKQUOTE = 96; SDLK_a = 97; SDLK_b = 98; SDLK_c = 99; SDLK_d = 100; SDLK_e = 101; SDLK_f = 102; SDLK_g = 103; SDLK_h = 104; SDLK_i = 105; SDLK_j = 106; SDLK_k = 107; SDLK_l = 108; SDLK_m = 109; SDLK_n = 110; SDLK_o = 111; SDLK_p = 112; SDLK_q = 113; SDLK_r = 114; SDLK_s = 115; SDLK_t = 116; SDLK_u = 117; SDLK_v = 118; SDLK_w = 119; SDLK_x = 120; SDLK_y = 121; SDLK_z = 122; SDLK_DELETE = 127; { End of ASCII mapped keysyms } { International keyboard syms } SDLK_WORLD_0 = 160; { 0xA0 } SDLK_WORLD_1 = 161; SDLK_WORLD_2 = 162; SDLK_WORLD_3 = 163; SDLK_WORLD_4 = 164; SDLK_WORLD_5 = 165; SDLK_WORLD_6 = 166; SDLK_WORLD_7 = 167; SDLK_WORLD_8 = 168; SDLK_WORLD_9 = 169; SDLK_WORLD_10 = 170; SDLK_WORLD_11 = 171; SDLK_WORLD_12 = 172; SDLK_WORLD_13 = 173; SDLK_WORLD_14 = 174; SDLK_WORLD_15 = 175; SDLK_WORLD_16 = 176; SDLK_WORLD_17 = 177; SDLK_WORLD_18 = 178; SDLK_WORLD_19 = 179; SDLK_WORLD_20 = 180; SDLK_WORLD_21 = 181; SDLK_WORLD_22 = 182; SDLK_WORLD_23 = 183; SDLK_WORLD_24 = 184; SDLK_WORLD_25 = 185; SDLK_WORLD_26 = 186; SDLK_WORLD_27 = 187; SDLK_WORLD_28 = 188; SDLK_WORLD_29 = 189; SDLK_WORLD_30 = 190; SDLK_WORLD_31 = 191; SDLK_WORLD_32 = 192; SDLK_WORLD_33 = 193; SDLK_WORLD_34 = 194; SDLK_WORLD_35 = 195; SDLK_WORLD_36 = 196; SDLK_WORLD_37 = 197; SDLK_WORLD_38 = 198; SDLK_WORLD_39 = 199; SDLK_WORLD_40 = 200; SDLK_WORLD_41 = 201; SDLK_WORLD_42 = 202; SDLK_WORLD_43 = 203; SDLK_WORLD_44 = 204; SDLK_WORLD_45 = 205; SDLK_WORLD_46 = 206; SDLK_WORLD_47 = 207; SDLK_WORLD_48 = 208; SDLK_WORLD_49 = 209; SDLK_WORLD_50 = 210; SDLK_WORLD_51 = 211; SDLK_WORLD_52 = 212; SDLK_WORLD_53 = 213; SDLK_WORLD_54 = 214; SDLK_WORLD_55 = 215; SDLK_WORLD_56 = 216; SDLK_WORLD_57 = 217; SDLK_WORLD_58 = 218; SDLK_WORLD_59 = 219; SDLK_WORLD_60 = 220; SDLK_WORLD_61 = 221; SDLK_WORLD_62 = 222; SDLK_WORLD_63 = 223; SDLK_WORLD_64 = 224; SDLK_WORLD_65 = 225; SDLK_WORLD_66 = 226; SDLK_WORLD_67 = 227; SDLK_WORLD_68 = 228; SDLK_WORLD_69 = 229; SDLK_WORLD_70 = 230; SDLK_WORLD_71 = 231; SDLK_WORLD_72 = 232; SDLK_WORLD_73 = 233; SDLK_WORLD_74 = 234; SDLK_WORLD_75 = 235; SDLK_WORLD_76 = 236; SDLK_WORLD_77 = 237; SDLK_WORLD_78 = 238; SDLK_WORLD_79 = 239; SDLK_WORLD_80 = 240; SDLK_WORLD_81 = 241; SDLK_WORLD_82 = 242; SDLK_WORLD_83 = 243; SDLK_WORLD_84 = 244; SDLK_WORLD_85 = 245; SDLK_WORLD_86 = 246; SDLK_WORLD_87 = 247; SDLK_WORLD_88 = 248; SDLK_WORLD_89 = 249; SDLK_WORLD_90 = 250; SDLK_WORLD_91 = 251; SDLK_WORLD_92 = 252; SDLK_WORLD_93 = 253; SDLK_WORLD_94 = 254; SDLK_WORLD_95 = 255; { 0xFF } { Numeric keypad } SDLK_KP0 = 256; SDLK_KP1 = 257; SDLK_KP2 = 258; SDLK_KP3 = 259; SDLK_KP4 = 260; SDLK_KP5 = 261; SDLK_KP6 = 262; SDLK_KP7 = 263; SDLK_KP8 = 264; SDLK_KP9 = 265; SDLK_KP_PERIOD = 266; SDLK_KP_DIVIDE = 267; SDLK_KP_MULTIPLY = 268; SDLK_KP_MINUS = 269; SDLK_KP_PLUS = 270; SDLK_KP_ENTER = 271; SDLK_KP_EQUALS = 272; { Arrows + Home/End pad } SDLK_UP = 273; SDLK_DOWN = 274; SDLK_RIGHT = 275; SDLK_LEFT = 276; SDLK_INSERT = 277; SDLK_HOME = 278; SDLK_END = 279; SDLK_PAGEUP = 280; SDLK_PAGEDOWN = 281; { Function keys } SDLK_F1 = 282; SDLK_F2 = 283; SDLK_F3 = 284; SDLK_F4 = 285; SDLK_F5 = 286; SDLK_F6 = 287; SDLK_F7 = 288; SDLK_F8 = 289; SDLK_F9 = 290; SDLK_F10 = 291; SDLK_F11 = 292; SDLK_F12 = 293; SDLK_F13 = 294; SDLK_F14 = 295; SDLK_F15 = 296; { Key state modifier keys } SDLK_NUMLOCK = 300; SDLK_CAPSLOCK = 301; SDLK_SCROLLOCK = 302; SDLK_RSHIFT = 303; SDLK_LSHIFT = 304; SDLK_RCTRL = 305; SDLK_LCTRL = 306; SDLK_RALT = 307; SDLK_LALT = 308; SDLK_RMETA = 309; SDLK_LMETA = 310; SDLK_LSUPER = 311; { Left "Windows" key } SDLK_RSUPER = 312; { Right "Windows" key } SDLK_MODE = 313; { "Alt Gr" key } SDLK_COMPOSE = 314; { Multi-key compose key } { Miscellaneous function keys } SDLK_HELP = 315; SDLK_PRINT = 316; SDLK_SYSREQ = 317; SDLK_BREAK = 318; SDLK_MENU = 319; { Power Macintosh power key } SDLK_POWER = 320; { Some european keyboards } SDLK_EURO = 321; { Add any other keys here } SDLK_LAST = 322; type SDLMod = Longint; Const { Enumeration of valid key mods (possibly OR'd together) } KMOD_NONE = $0000; KMOD_LSHIFT = $0001; KMOD_RSHIFT = $0002; KMOD_LCTRL = $0040; KMOD_RCTRL = $0080; KMOD_LALT = $0100; KMOD_RALT = $0200; KMOD_LMETA = $0400; KMOD_RMETA = $0800; KMOD_NUM = $1000; KMOD_CAPS = $2000; KMOD_MODE = $4000; KMOD_RESERVED = $8000; KMOD_CTRL = KMOD_LCTRL or KMOD_RCTRL; KMOD_SHIFT = KMOD_LSHIFT or KMOD_RSHIFT; KMOD_ALT = KMOD_LALT or KMOD_RALT; KMOD_META = KMOD_LMETA or KMOD_RMETA; { ***end of SDL_keysym.h***} type { Keysym structure - The scancode is hardware dependent, and should not be used by general applications. If no hardware scancode is available, it will be 0. - The 'unicode' translated character is only available when character translation is enabled by the SDL_EnableUNICODE API. If non-zero, this is a UNICODE character corresponding to the keypress. If the high 9 bits of the character are 0, then this maps to the equivalent ASCII character: var ch:char; if (keysym.unicode and $FF80) = 0 then ch := keysym.unicode and 0x7F else An international character... } SDL_keysym = record scancode : Uint8; { hardware specific scancode } sym : SDLKey; { SDL virtual keysym } modifier : SDLMod; { current key modifiers } unicode : Uint16; { translated character } end; const { This is the mask which refers to all hotkey bindings } SDL_ALL_HOTKEYS = $FFFFFFFF; { Function prototypes } { Enable/Disable UNICODE translation of keyboard input. This translation has some overhead, so translation defaults off. If 'enable' is 1, translation is enabled. If 'enable' is 0, translation is disabled. If 'enable' is -1, the translation state is not changed. It returns the previous state of keyboard translation. } function SDL_EnableUNICODE(enable:longint):longint;cdecl; { Get a snapshot of the current state of the keyboard. Returns an array of keystates, indexed by the SDLK_ syms. Used: keystate: PBoolArray; keystate := SDL_GetKeyState(nil); if keystate[SDLK_RETURN] then ... is pressed } function SDL_GetKeyState(var numkeys:longint):PBoolArray;cdecl; { Get the current key modifier state } function SDL_GetModState:SDLMod;cdecl; { Set the current key modifier state This does not change the keyboard state, only the key modifier flags. } procedure SDL_SetModState(modstate:SDLMod);cdecl; { Get the name of an SDL virtual keysym } function SDL_GetKeyName(key:SDLKey):Pchar;cdecl; function SDL_EnableKeyRepeat(keydelay, keytinterval: longint): longint; cdecl; implementation function SDL_EnableUNICODE(enable:longint):longint;cdecl;external 'SDL'; function SDL_GetKeyState(var numkeys:longint):PBoolArray;cdecl;external 'SDL'; function SDL_GetModState:SDLMod;cdecl;external 'SDL'; procedure SDL_SetModState(modstate:SDLMod);cdecl;external 'SDL'; function SDL_GetKeyName(key:SDLKey):Pchar;cdecl;external 'SDL'; function SDL_EnableKeyRepeat(keydelay, keytinterval: longint): longint; cdecl; external 'SDL'; end. adlibtracker2-2.4.23/sdl/sdl_events.pp0000644000000000000000000003533513176573533016330 0ustar rootrootunit SDL_events; { Automatically converted by H2PAS.EXE from SDL_events.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types, SDL_syswm, SDL_keyboard; { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Include file for SDL event handling } const { Event enumerations } SDL_NOEVENT=0; { Unused (do not remove) } SDL_EVENTACTIVE=1; { Application loses/gains visibility } SDL_KEYDOWN=2; { Keys pressed } SDL_KEYUP=3; { Keys released } SDL_MOUSEMOTION=4; { Mouse moved } SDL_MOUSEBUTTONDOWN=5; { Mouse button pressed } SDL_MOUSEBUTTONUP=6; { Mouse button released } SDL_JOYAXISMOTION=7; { Joystick axis motion } SDL_JOYBALLMOTION=8; { Joystick trackball motion } SDL_JOYHATMOTION=9; { Joystick hat position change } SDL_JOYBUTTONDOWN=10; { Joystick button pressed } SDL_JOYBUTTONUP=11; { Joystick button released } SDL_EVENTQUIT=12; { User-requested quit } SDL_EVENTSYSWM=13; { System specific event } SDL_EVENT_RESERVEDA=14; { Reserved for future use } SDL_EVENT_RESERVEDB=15; { Reserved for future use } SDL_VIDEORESIZE=16; { User resized video mode } SDL_VIDEOEXPOSE=17; { Screen needs to be redrawn } SDL_EVENT_RESERVED2=18; { Reserved for future use } SDL_EVENT_RESERVED3=19; { Reserved for future use } SDL_EVENT_RESERVED4=20; { Reserved for future use } SDL_EVENT_RESERVED5=21; { Reserved for future use } SDL_EVENT_RESERVED6=22; { Reserved for future use } SDL_EVENT_RESERVED7=23; { Reserved for future use } { Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use } SDL_EVENTUSER = 24; { This last event is only for bounding internal arrays It is the number of bits in the event mask datatype -- Uint32 } SDL_NUMEVENTS = 32; { Predefined event masks } SDL_ACTIVEEVENTMASK = 1 shl (SDL_EVENTACTIVE); SDL_KEYDOWNMASK = 1 shl (SDL_KEYDOWN); SDL_KEYUPMASK = 1 shl (SDL_KEYUP); SDL_MOUSEMOTIONMASK = 1 shl (SDL_MOUSEMOTION); SDL_MOUSEBUTTONDOWNMASK = 1 shl (SDL_MOUSEBUTTONDOWN); SDL_MOUSEBUTTONUPMASK = 1 shl (SDL_MOUSEBUTTONUP); SDL_MOUSEEVENTMASK = SDL_MOUSEMOTIONMASK or SDL_MOUSEBUTTONDOWNMASK or SDL_MOUSEBUTTONUPMASK; SDL_JOYAXISMOTIONMASK = 1 shl (SDL_JOYAXISMOTION); SDL_JOYBALLMOTIONMASK = 1 shl (SDL_JOYBALLMOTION); SDL_JOYHATMOTIONMASK = 1 shl (SDL_JOYHATMOTION); SDL_JOYBUTTONDOWNMASK = 1 shl (SDL_JOYBUTTONDOWN); SDL_JOYBUTTONUPMASK = 1 shl (SDL_JOYBUTTONUP); SDL_JOYEVENTMASK = SDL_JOYAXISMOTIONMASK or SDL_JOYBALLMOTIONMASK or SDL_JOYHATMOTIONMASK or SDL_JOYBUTTONDOWNMASK or SDL_JOYBUTTONUPMASK; SDL_VIDEORESIZEMASK = 1 shl (SDL_VIDEORESIZE); SDL_VIDEOEXPOSEMASK = 1 shl (SDL_VIDEOEXPOSE); SDL_QUITMASK = 1 shl (SDL_EVENTQUIT); SDL_SYSWMEVENTMASK = 1 shl (SDL_EVENTSYSWM); SDL_ALLEVENTS = $FFFFFFFF; type { Application visibility event structure } SDL_ActiveEvent = record eventtype : Uint8; { SDL_ACTIVEEVENT } gain : Uint8; { Whether given state were gained or lost (1/0) } state : Uint8; { A mask of the focus states } end; { Keyboard event structure } SDL_KeyboardEvent = record eventtype : Uint8; { SDL_KEYDOWN or SDL_KEYUP } which : Uint8; { The keyboard edvice index } state : Uint8; { SDL_PRESSED or SDL_RELEASED } keysym : SDL_keysym; end; { Mouse motion event structure } SDL_MouseMotionEvent = record eventtype : Uint8; { SDL_MOUSEMOTION } which : Uint8; { The mouse device index } state : Uint8; { The current button state } x, y : Uint16; { The x/y coordinates of the mouse } xrel : Sint16; { The relative motion in X direction } yrel : Sint16; { The relative motion in Y direction } end; { Mouse button event structure } SDL_MouseButtonEvent = record eventtype : Uint8; { SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP } which : Uint8; { The mouse device index } button : Uint8; { The mouse button index } state : Uint8; { SDL_PRESSED or SDL_RELEASED } x, y : Uint16; { The X/Y coordinates of the mouse at press time } end; { Joystick axis motion event structure } SDL_JoyAxisEvent = record eventtype : Uint8; { SDL_JOYAXISMOTION } which : Uint8; { The joystick device index } axis : Uint8; { The joystick axis index } value : Uint16; { The axis value: (range: -32768 to 32768) } end; { Joystick trackball motion event structure } SDL_JoyBallEvent = record eventtype : Uint8; { SDL_JOYBALLMOTION } which : Uint8; { The joystick device index } ball : Uint8; { The joystick trackball index } xrel : Uint16; { The relative motion in X direction } yrel : Uint16; { The relative motion in Y direction } end; { Joystick hat position change event structure } SDL_JoyHatEvent = record eventtype : Uint8; { SDL_JOYHATMOTION } which : Uint8; { The joystick device index } hat : Uint8; { The joystick hat index } value : Uint16; { The hat position value 8 1 2 7 0 3 6 5 4 Note that zero means the POV is centered. } end; { Joystick button event structure } SDL_JoyButtonEvent = record eventtype : Uint8; { SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP } which : Uint8; { The joystick device index } button : Uint8; { The joystick button index } state : Uint8; { SDL_PRESSED or SDL_RELEASED } end; { The "window resized" event When you get this event you are responsible for setting a new video mode with the new width and height. } SDL_ResizeEvent = record eventtype : Uint8; { SDL_VIDEORESIZE} w : Longint; { New width } h : Longint; { New height } end; { The "screen redraw" event } SDL_ExposeEvent = record eventtype : Uint8; { SDL_VIDEOEXPOSE } end; { The "quit requested" event } SDL_QuitEvent = record eventtype : Uint8; { SDL_QUIT } end; { A user defined event type } SDL_UserEvent = record eventtype : Uint8; { SDL_USEREVENT through SDL_NUMEVENTS-1 } code: Longint; { User defined event code } data1: Pointer; { User defined data pointer } data2: Pointer; { User defined data pointer } end; { If you want to use this event, you should include SDL_syswm.h } PSDL_SysWMmsg = ^SDL_SysWMmsg; SDL_SysWMEvent = record eventtype : Uint8; msg : PSDL_SysWMmsg; end; { General event structure } PSDL_Event = ^SDL_Event; SDL_Event = record case longint of 0 : ( eventtype : Uint8 ); 1 : ( active : SDL_ActiveEvent ); 2 : ( key : SDL_KeyboardEvent ); 3 : ( motion : SDL_MouseMotionEvent ); 4 : ( button : SDL_MouseButtonEvent ); 5 : ( jaxis : SDL_JoyAxisEvent ); 6 : ( jball : SDL_JoyBallEvent ); 7 : ( jhat : SDL_JoyHatEvent ); 8 : ( jbutton : SDL_JoyButtonEvent ); 9 : ( resize : SDL_ResizeEvent ); 10: ( expose : SDL_ExposeEvent ); 11: ( quit : SDL_QuitEvent ); 12: ( user : SDL_UserEvent ); 13: ( syswm : SDL_SysWMEvent ); end; { Function prototypes } { Pumps the event loop, gathering events from the input devices. This function updates the event queue and internal input device state. This should only be run in the thread that sets the video mode. } procedure SDL_PumpEvents;cdecl; { Checks the event queue for messages and optionally returns them. If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to the back of the event queue. If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front of the event queue, matching 'mask', will be returned and will not be removed from the queue. If 'action' is SDL_GETEVENT, up to 'numevents' events at the front of the event queue, matching 'mask', will be returned and will be removed from the queue. This function returns the number of events actually stored, or -1 if there was an error. This function is thread-safe. } type SDL_eventaction = Longint; Const SDL_ADDEVENT = 0; SDL_PEEKEVENT = 1; SDL_GETEVENT = 2; function SDL_PeepEvents(var events:SDL_Event; numevents:longint; action:SDL_eventaction; mask:Uint32):longint;cdecl; { Polls for currently pending events, and returns 1 if there are any pending events, or 0 if there are none available. If 'event' is not nil, the next event is removed from the queue and stored in that area. } function SDL_PollEvent(event:pSDL_Event):longint;cdecl; { Waits indefinitely for the next available event, returning 1, or 0 if there was an error while waiting for events. If 'event' is not nil, the next event is removed from the queue and stored in that area. } function SDL_WaitEvent(event:pSDL_Event):longint;cdecl; { Add an event to the event queue. This function returns 0, or -1 if the event couldn't be added to the event queue. If the event queue is full, this function fails. } function SDL_PushEvent (var event: SDL_Event):longint;cdecl; { This function sets up a filter to process all events before they change internal state and are posted to the internal event queue. The filter is protypted as: } type SDL_EventFilter = function (event:pSDL_Event):longint;cdecl; { If the filter returns 1, then the event will be added to the internal queue. If it returns 0, then the event will be dropped from the queue, but the internal state will still be updated. This allows selective filtering of dynamically arriving events. WARNING: Be very careful of what you do in the event filter function, as it may run in a different thread! There is one caveat when dealing with the SDL_QUITEVENT event type. The event filter is only called when the window manager desires to close the application window. If the event filter returns 1, then the window will be closed, otherwise the window will remain open if possible. If the quit event is generated by an interrupt signal, it will bypass the internal queue and be delivered to the application at the next event poll. } procedure SDL_SetEventFilter(filter:SDL_EventFilter);cdecl; { Return the current event filter - can be used to "chain" filters. If there is no filter set, this function returns nil. } function SDL_GetEventFilter:SDL_EventFilter;cdecl; { This function allows you to set the state of processing certain events. If 'state' is set to SDL_IGNORE, that event will be automatically dropped from the event queue and will not event be filtered. If 'state' is set to SDL_ENABLE, that event will be processed normally. If 'state' is set to SDL_QUERY, SDL_EventState will return the current processing state of the specified event. } const SDL_QUERY = -(1); SDL_IGNORE = 0; SDL_DISABLE = 0; SDL_ENABLE = 1; function SDL_EventState(eventtype:Uint8; state:longint):Uint8;cdecl; implementation procedure SDL_PumpEvents;cdecl;external 'SDL'; function SDL_PeepEvents(var events:SDL_Event; numevents:longint; action:SDL_eventaction; mask:Uint32):longint;cdecl;external 'SDL'; function SDL_PollEvent(event:pSDL_Event):longint;cdecl;external 'SDL'; function SDL_WaitEvent(event:pSDL_Event):longint;cdecl;external 'SDL'; function SDL_PushEvent (var event: SDL_Event):longint;cdecl;external 'SDL'; procedure SDL_SetEventFilter(filter:SDL_EventFilter);cdecl;external 'SDL'; function SDL_GetEventFilter:SDL_EventFilter;cdecl;external 'SDL'; function SDL_EventState(eventtype:Uint8; state:longint):Uint8;cdecl;external 'SDL'; end. adlibtracker2-2.4.23/sdl/sdl_types.pp0000644000000000000000000000374613176573533016171 0ustar rootrootunit SDL_types; { Automatically converted by H2PAS.EXE from SDL_types.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { General data types used by the SDL library } { /* The number of elements in a table */ #define SDL_TABLESIZE(table) (sizeof(table)/sizeof(table[0])) } { Basic data types } type Uint8 = byte; Sint8 = shortint; Uint16 = word; Sint16 = SmallInt; Uint32 = cardinal; Sint32 = Longint; Uint64 = record hi, lo: Uint32 ; end ; SDL_Bool = LongBool ; { General keyboard/mouse state definitions } const SDL_PRESSED = 1 ; SDL_RELEASED = 0; implementation end. adlibtracker2-2.4.23/sdl/TODO0000644000000000000000000000243113176573533014300 0ustar rootroot* Implement sdl_SysWM* structures (in a 'portable' fashion) I should make a different structure for each platform and choose with {$ifdef}s... It's done that way in . Now they're empty structures, regardless of the platform. * Get a better name for sdl__rwops The reason for the double underscore is that there is a structure there called SDL_rwops, and I can't repeat that identifier in the unit name (and don't want to change the name of the record). If you find a better idea for a name of this unit, tell me. * Find a better solution for the stdio.pp issue Read the source. This unit is a hack. * Test it!!!! I've just barely tested some part of it. There's almost no code, just external definitions, so it won't be very bad, but you never know... At least it compiles :-) * Packages (source&binary RPM/DEBs) instead of this ugly tarball... * Remaining SDL modules active, byteorder, endian, error, main, mutex, quit, thread, version are not implemented yet. I'll do this soon (I may decide not to implement some of them)... * Make a real build/install/clean script The current one only builds, and compiles some units twice (Ok, I know, I should write a Makefile) adlibtracker2-2.4.23/sdl/sdl_cdrom.pp0000644000000000000000000001712313176573533016123 0ustar rootrootunit SDL_cdrom; { Automatically converted by H2PAS.EXE from SDL_cdrom.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } interface uses SDL_types ; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PLongint = ^Longint; PByte = ^Byte; PWord = ^Word; PInteger = ^Integer; PCardinal = ^Cardinal; PReal = ^Real; PDouble = ^Double; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { This is the CD-audio control API for Simple DirectMedia Layer } { In order to use these functions, SDL_Init must have been called with the SDL_INIT_CDROM flag. This causes SDL to scan the system for CD-ROM drives, and load appropriate drivers. } { The maximum number of CD-ROM tracks on a disk } const SDL_MAX_TRACKS = 99; { The types of CD-ROM track possible } SDL_AUDIO_TRACK = $00; SDL_DATA_TRACK = $04; { The possible states which a CD-ROM drive can be in. } type CDstatus = Longint; Const CD_TRAYEMPTY = 0; CD_STOPPED = 1; CD_PLAYING = 2; CD_PAUSED = 3; CD_ERROR = -(1); { Given a status, returns true if there's a disk in the drive } function CD_INDRIVE(status : longint) : longBool; type SDL_CDtrack = record id : Uint8; { Track number } track_type : Uint8; { Data or audio track } unused: Uint16; length : Uint32; { Length, in frames, of this track } offset : Uint32; { Offset, in frames, from start of disk } end; { This structure is only current as of the last call to SDL_CDStatus } PSDL_CD = ^SDL_CD ; SDL_CD = record id : longint; { Private drive identifier } status : CDstatus; { Current drive status } numtracks : longint; { The rest of this structure is only valid if there's a CD in drive } cur_track : longint; { Number of tracks on disk } cur_frame : longint; { Current track position } { Current frame offset within current track } track : array[0..SDL_MAX_TRACKS] of SDL_CDtrack; end; { Conversion functions from frames to Minute/Second/Frames and vice versa } const CD_FPS = 75; procedure FRAMES_TO_MSF(v: Longint; var m,s,f: Longint) ; { CD-audio API functions: } { Returns the number of CD-ROM drives on the system, or -1 if SDL_Init has not been called with the SDL_INIT_CDROM flag. } function SDL_CDNumDrives:Longint;cdecl; { Returns a human-readable, system-dependent identifier for the CD-ROM. Example: "/dev/cdrom" "E:" "/dev/disk/ide/1/master" } function SDL_CDName(drive:longint):Pchar;cdecl; { Opens a CD-ROM drive for access. It returns a drive handle on success, or NULL if the drive was invalid or busy. This newly opened CD-ROM becomes the default CD used when other CD functions are passed a NULL CD-ROM handle. Drives are numbered starting with 0. Drive 0 is the system default CD-ROM. } function SDL_CDOpen(drive:longint):PSDL_CD;cdecl; { This function returns the current status of the given drive. If the drive has a CD in it, the table of contents of the CD and current play position of the CD will be stored in the SDL_CD structure. } function SDL_CDStatus(var cdrom:SDL_CD):CDstatus;cdecl; { Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks' tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play until the end of the CD. This function will skip data tracks. This function should only be called after calling SDL_CDStatus to get track information about the CD. For example: (* Play entire CD: *) if CD_INDRIVE(SDL_CDStatus(cdrom)) then SDL_CDPlayTracks(cdrom, 0, 0, 0, 0); (* Play last track: *) if CD_INDRIVE(SDL_CDStatus(cdrom)) then SDL_CDPlayTracks(cdrom, cdrom^.numtracks-1, 0, 0, 0); (* Play first and second track and 10 seconds of third track: *0 if CD_INDRIVE(SDL_CDStatus(cdrom)) then SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); This function returns 0, or -1 if there was an error. } function SDL_CDPlayTracks(cdrom:pSDL_CD; start_track:longint; start_frame:longint; ntracks:longint; nframes:longint):longint;cdecl; { Play the given CD starting at 'start' frame for 'length' frames. It returns 0, or -1 if there was an error. } function SDL_CDPlay(cdrom:pSDL_CD; start:longint; length:longint):longint;cdecl; { Pause play -- returns 0, or -1 on error } function SDL_CDPause(cdrom:pSDL_CD):longint;cdecl; { Resume play -- returns 0, or -1 on error } function SDL_CDResume(cdrom:pSDL_CD):longint;cdecl; { Stop play -- returns 0, or -1 on error } function SDL_CDStop(cdrom:pSDL_CD):longint;cdecl; { Eject CD-ROM -- returns 0, or -1 on error } function SDL_CDEject(cdrom:pSDL_CD):longint;cdecl; { Closes the handle for the CD-ROM drive } procedure SDL_CDClose(cdrom:pSDL_CD);cdecl; implementation { Implementation of macros } function CD_INDRIVE(status : longint) : longBool; begin CD_INDRIVE:=(longint(status)) > 0; end; procedure FRAMES_TO_MSF(v: Longint; var m,s,f: Longint) ; Begin f := v mod CD_FPS ; v := v div CD_FPS ; s := v mod 60 ; v := v div 60 ; m := v ; End ; { External functions } function SDL_CDNumDrives:LongInt;cdecl;external 'SDL'; function SDL_CDName(drive:longint):Pchar;cdecl;external 'SDL'; function SDL_CDOpen(drive:longint):PSDL_CD;cdecl;external 'SDL'; function SDL_CDStatus(var cdrom:SDL_CD):CDstatus;cdecl;external 'SDL'; function SDL_CDPlayTracks(cdrom:pSDL_CD; start_track:longint; start_frame:longint; ntracks:longint; nframes:longint):longint;cdecl;external 'SDL'; function SDL_CDPlay(cdrom:pSDL_CD; start:longint; length:longint):longint;cdecl;external 'SDL'; function SDL_CDPause(cdrom:pSDL_CD):longint;cdecl;external 'SDL'; function SDL_CDResume(cdrom:pSDL_CD):longint;cdecl;external 'SDL'; function SDL_CDStop(cdrom:pSDL_CD):longint;cdecl;external 'SDL'; function SDL_CDEject(cdrom:pSDL_CD):longint;cdecl;external 'SDL'; procedure SDL_CDClose(cdrom:pSDL_CD);cdecl;external 'SDL'; end. adlibtracker2-2.4.23/sdl/AUTHOR0000644000000000000000000000005113176573533014531 0ustar rootrootDaniel F Moisset adlibtracker2-2.4.23/sdl/CHANGES0000644000000000000000000000015613176573533014605 0ustar rootroot1.2.0.0 - Updated to SDL 1.2 added some demos added SDL_cdrom 1.0.0.0 - Initial releaseadlibtracker2-2.4.23/sdl/stdio.pp0000644000000000000000000000312413176573533015273 0ustar rootrootunit stdio; { SDL4FreePascal-1.2.0.0 - Simple DirectMedia Layer bindings for FreePascal Copyright (C) 2000, 2001 Daniel F Moisset This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Daniel F Moisset dmoisset@grulic.org.ar } { This unit groups some of the types/constants usually inside , and required to compile the other SDL units. I know, I should do this more cleanly, but I couldn't find an standard place to find this constants/types from freepascal } interface type { Some functions in SDL_rwops need a FILE* ... I don't know how to get one from freepascal } PFile = Pointer ; {FILE *} const { I should take this constants from some standard place... where? } SEEK_SET=0; { Seek from beginning of file. } SEEK_CUR=1; { Seek from current position. } SEEK_END=2; { Seek from end of file. } implementation end.adlibtracker2-2.4.23/sdl/sdl_syswm.pp0000644000000000000000000000472413176573533016204 0ustar rootrootunit SDL_syswm; { Automatically converted by H2PAS.EXE from SDL_syswm.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } interface { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Include file for SDL custom system window manager hooks } { Your application has access to a special type of event 'SDL_SYSWMEVENT', which contains window-manager specific information and arrives whenever an unhandled window event occurs. This event is ignored by default, but you can enable it with SDL_EventState() } type pSDL_SysWMinfo = ^SDL_SysWMinfo ; SDL_SysWMinfo = record { ***Not implemented*** } end; pSDL_SysWMmsg = ^SDL_SysWMmsg ; SDL_SysWMmsg = record { ***Not implemented*** } end; { Function prototypes } { This function gives you custom hooks into the window manager information. It fills the structure pointed to by 'info' with custom information and returns 1 if the function is implemented. If it's not implemented, or the version member of the 'info' structure is invalid, it returns 0. } function SDL_GetWMInfo(info:pSDL_SysWMinfo):longint;cdecl; implementation function SDL_GetWMInfo(info:pSDL_SysWMinfo):longint;cdecl;external 'SDL'; end. adlibtracker2-2.4.23/sdl/sdl.pp0000644000000000000000000000663613176573533014746 0ustar rootrootunit SDL; { Automatically converted by H2PAS.EXE from SDL.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types; { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Main include header for the SDL library } { As of version 0.5, SDL is loaded dynamically into the application } { These are the flags which may be passed to SDL_Init() -- you should specify the subsystems which you will be using in your application. } const SDL_INIT_TIMER = $00000001; SDL_INIT_AUDIO = $00000010; SDL_INIT_VIDEO = $00000020; SDL_INIT_CDROM = $00000100; SDL_INIT_JOYSTICK = $00000200; SDL_INIT_NOPARACHUTE = $00100000; { Don't catch fatal signals } SDL_INIT_EVENTTHREAD = $01000000; { Not supported on all OS's } SDL_INIT_EVERYTHING = $0000FFFF; { This function loads the SDL dynamically linked library and initializes the subsystems specified by 'flags' (and those satisfying dependencies) Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup signal handlers for some commonly ignored fatal signals (like SIGSEGV) } function SDL_Init(flags:Uint32):longint;cdecl; { This function initializes specific SDL subsystems } function SDL_InitSubSystem(flags:Uint32):longint;cdecl; { This function cleans up specific SDL subsystems } Procedure SDL_QuitSubSystem(flags:Uint32);cdecl; { This function returns mask of the specified subsystems which have been initialized. If 'flags' is 0, it returns a mask of all initialized subsystems. } Function SDL_WasInit(flags:Uint32):Uint32;cdecl; { This function cleans up the initialized subsystems and unloads the dynamically linked library. You should call it upon all exit conditions. } procedure SDL_Quit;cdecl; implementation {$IFDEF LINUX} {$LINKLIB pthread} {$ENDIF} function SDL_Init(flags:Uint32):longint;cdecl;external 'SDL'; function SDL_InitSubSystem(flags:Uint32):longint;cdecl;external 'SDL'; Procedure SDL_QuitSubSystem(flags:Uint32);cdecl;external 'SDL'; Function SDL_WasInit(flags:Uint32):Uint32;cdecl;external 'SDL'; procedure SDL_Quit;cdecl;external 'SDL'; end. adlibtracker2-2.4.23/sdl/sdl_video.pp0000644000000000000000000014724113176573533016132 0ustar rootrootunit SDL_video; { Automatically converted by H2PAS.EXE from SDL_video.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types, SDL__rwops ; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PByte = ^Byte; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Header file for access to the SDL raw framebuffer window } { Useful data types } const SDL_ALPHA_OPAQUE = 255; SDL_ALPHA_TRANSPARENT = 0; type PSDL_Rect = ^SDL_Rect; SDL_Rect = record x : Sint16; y : Sint16; w : Uint16; h : Uint16; end; PSDL_RectArray = ^SDL_RectArray; SDL_RectArray = array[0..0] of SDL_Rect ; PSDL_Color = ^SDL_COLOR ; SDL_Color = record r : Uint8; g : Uint8; b : Uint8; unused : Uint8; end; PSDL_ColorArray = ^SDL_ColorArray; SDL_ColorArray = Array[0..0] of SDL_Color ; SDL_Palette = record ncolors : longint; colors : PSDL_ColorArray; end; { Everything in the pixel format structure is read-only } PSDL_PixelFormat = ^SDL_PixelFormat; SDL_PixelFormat = record palette : ^SDL_Palette; BitsPerPixel : Uint8; BytesPerPixel : Uint8; Rloss : Uint8; Gloss : Uint8; Bloss : Uint8; Aloss : Uint8; Rshift : Uint8; Gshift : Uint8; Bshift : Uint8; Ashift : Uint8; Rmask : Uint32; Gmask : Uint32; Bmask : Uint32; Amask : Uint32; { RGB color key information } colorkey : Uint32; { Alpha value information (per-surface alpha) } alpha : Uint8; end; { This structure should be treated as read-only, except for 'pixels', which, if not nil, contains the raw pixel data for the surface. } PSDL_Surface = ^SDL_Surface; SDL_Surface = record flags : Uint32; { Read only } format : ^SDL_PixelFormat; { Read only } w : longint; { Read only } h : longint; { Read only } pitch : Uint16; { Read only } pixels : pointer; { Read-write } offset : longint; { Private } { Hardware-specific surface info } hwdata : Pointer; { ***"struct private_hwdata *"*** } clip_rect: SDL_Rect; { clipping information } unused1: Uint32; { for binary compatibility } locked: Uint32; { allow recursive locks } { info for fast blit mapping to other surfaces } map : Pointer; { Private } { ***"struct SDL_BlitMap *"*** } { format version, bumped at every evrsion to invalidate blit maps } format_version: Longint; { Reference count -- used when freeing surface } refcount : longint; { Read mostly } end; SDL_blit = function (src:PSDL_Surface; srcrect:pSDL_Rect; dst:PSDL_Surface; dstrect:pSDL_Rect):longint;cdecl; { These are the currently supported flags for the SDL_surface } const { Available for SDL_CreateRGBSurface or SDL_SetVideoMode } SDL_SWSURFACE = $00000000; { Surface is in system memory } SDL_HWSURFACE = $00000001; { Surface is in video memory } SDL_ASYNCBLIT = $00000004; { Use asynchronous blits if possible } { Available for SDL_SetVideoMode } { Allow any video depth/pixel-format } SDL_ANYFORMAT = $10000000; { Surface has exclusive palette } SDL_HWPALETTE = $20000000; { Set up double-buffered video mode } SDL_DOUBLEBUF = $40000000; { Surface is a full screen display } SDL_FULLSCREEN = $80000000; { Create an OpenGL rendering context} SDL_OPENGL = $00000002; { Create an OpenGL rendering context and use it for blitting } SDL_OPENGLBLIT = $0000000A; { This video mode may be resized } SDL_RESIZABLE = $00000010; { No window caption or edge frame } SDL_NOFRAME = $00000020; { Used internally (read-only) } { Blit uses hardware acceleration } SDL_HWACCEL = $00000100; { Blit uses a source color key } SDL_SRCCOLORKEY = $00001000; { Private flag } SDL_RLEACCELOK = $00002000; { Surface is RLE encoded } SDL_RLEACCEL = $00004000; { Blit uses source alpha blending } SDL_SRCALPHA = $00010000; { Surface uses preallocated memory } SDL_PREALLOC = $01000000; { Useful for determining the video hardware capabilities } type PSDL_VideoInfo = ^SDL_VideoInfo; SDL_VideoInfo = record flag0 : longint; video_mem : Uint32; { The total amount of video memory (in K) } vfmt : ^SDL_PixelFormat; { Value: The format of the video surface } end; { *** Accessors for the flags of SDL_VideoInfo *** } { Flag: Can you create hardware surfaces? } function hw_available(var a : SDL_VideoInfo) : Uint32; procedure set_hw_available(var a : SDL_VideoInfo; __hw_available : Uint32); { Flag: Can you talk to a window manager? } function wm_available(var a : SDL_VideoInfo) : Uint32; procedure set_wm_available(var a : SDL_VideoInfo; __wm_available : Uint32); function UnusedBits1(var a : SDL_VideoInfo) : Uint32; procedure set_UnusedBits1(var a : SDL_VideoInfo; __UnusedBits1 : Uint32); function UnusedBits2(var a : SDL_VideoInfo) : Uint32; procedure set_UnusedBits2(var a : SDL_VideoInfo; __UnusedBits2 : Uint32); { Flag: Accelerated blits HW --> HW } function blit_hw(var a : SDL_VideoInfo) : Uint32; procedure set_blit_hw(var a : SDL_VideoInfo; __blit_hw : Uint32); { Flag: Accelerated blits with Colorkey } function blit_hw_CC(var a : SDL_VideoInfo) : Uint32; procedure set_blit_hw_CC(var a : SDL_VideoInfo; __blit_hw_CC : Uint32); { Flag: Accelerated blits with Alpha } function blit_hw_A(var a : SDL_VideoInfo) : Uint32; procedure set_blit_hw_A(var a : SDL_VideoInfo; __blit_hw_A : Uint32); { Flag: Accelerated blits SW --> HW } function blit_sw(var a : SDL_VideoInfo) : Uint32; procedure set_blit_sw(var a : SDL_VideoInfo; __blit_sw : Uint32); { Flag: Accelerated blits with Colorkey } function blit_sw_CC(var a : SDL_VideoInfo) : Uint32; procedure set_blit_sw_CC(var a : SDL_VideoInfo; __blit_sw_CC : Uint32); { Flag: Accelerated blits with Alpha } function blit_sw_A(var a : SDL_VideoInfo) : Uint32; procedure set_blit_sw_A(var a : SDL_VideoInfo; __blit_sw_A : Uint32); { Flag: Accelerated color fill } function blit_fill(var a : SDL_VideoInfo) : Uint32; procedure set_blit_fill(var a : SDL_VideoInfo; __blit_fill : Uint32); function UnusedBits3(var a : SDL_VideoInfo) : Uint32; procedure set_UnusedBits3(var a : SDL_VideoInfo; __UnusedBits3 : Uint32); { Evaluates to true if the surface needs to be locked before access } Function SDL_MUSTLOCK (surface: PSDL_Surface): Boolean ; { The most common video overlay formats. For an explanation of these pixel formats, see: http://www.webartz.com/fourcc/indexyuv.htm For information on the relationship between color spaces, see: http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html } const SDL_YV12_OVERLAY=$32315659; { Planar mode: Y + V + U (3 planes) } SDL_IYUV_OVERLAY=$56555949; { Planar mode: Y + U + V (3 planes) } SDL_YUY2_OVERLAY=$32595559; { Packed mode: Y0+U0+Y1+V0 (1 plane) } SDL_UYVY_OVERLAY=$59565955; { Packed mode: U0+Y0+V0+Y1 (1 plane) } SDL_YVYU_OVERLAY=$55595659; { Packed mode: Y0+V0+Y1+U0 (1 plane) } { The YUV hardware video overlay } type TSDL_Plane = Array[0..0] of Uint8; PSDL_Plane = ^TSDL_Plane; TSDL_Overlay_PlaneArray = Array[0..0] of PSDL_Plane ; PSDL_Overlay_PlaneArray = ^TSDL_Overlay_PlaneArray ; pSDL_Overlay = ^SDL_Overlay; SDL_Overlay = record format: Uint32; { Read-only } w, h: Longint; { Read-only } planes: Longint; { Read-only } pitches: ^Uint16; { Read-only } pixels: PSDL_Overlay_PlaneArray; { Read-write } { Hardware-specific surface info } hwfuncs: Pointer; { struct private_yuvhwfuncs * } hwdata: Pointer; { struct private_yuvhwdata * } { Special flags } flag0: LongInt ; end ; { *** Accessors for the flags of SDL_Overlay *** } { Flag: This overlay hardware accelerated? } function hw_overlay (var o: SDL_Overlay): Uint32; procedure set_hw_overlay (var o: SDL_Overlay; value: Uint32); const SDL_GL_RED_SIZE = 0 ; SDL_GL_GREEN_SIZE = 1 ; SDL_GL_BLUE_SIZE = 2 ; SDL_GL_ALPHA_SIZE = 3 ; SDL_GL_BUFFER_SIZE = 4 ; SDL_GL_DOUBLEBUFFER = 5 ; SDL_GL_DEPTH_SIZE = 6 ; SDL_GL_STENCIL_SIZE = 7 ; SDL_GL_ACCUM_RED_SIZE = 8 ; SDL_GL_ACCUM_GREEN_SIZE = 9 ; SDL_GL_ACCUM_BLUE_SIZE = 10 ; SDL_GL_ACCUM_ALPHA_SIZE = 11 ; type { Public enumeration for setting the OpenGL window attributes. } SDL_GLattr = LongInt ; const { flags for SDL_SetPalette() } SDL_LOGPAL = $01; SDL_PHYSPAL = $02; { Function prototypes } { These functions are used internally, and should not be used unless you have a specific need to specify the video driver you want to use. You should normally use SDL_Init or SDL_InitSubSystem. SDL_VideoInit initializes the video subsystem -- sets up a connection to the window manager, etc, and determines the current video mode and pixel format, but does not initialize a window or graphics mode. Note that event handling is activated by this routine. If you use both sound and video in your application, you need to call SDL_Init before opening the sound device, otherwise under Win32 DirectX, you won't be able to set full-screen display modes. } { SDL_VideoInit } { SDL_VideoQuit } { This function fills the given character buffer with the name of the video driver, and returns a pointer to it if the video driver has been initialized. It returns nil if no driver has been initialized. } { SDL_VideoDriverName } { This function returns a pointer to the current display surface. If SDL is doing format conversion on the display surface, this function returns the publicly visible surface, not the real video surface. } function SDL_GetVideoSurface:PSDL_Surface;cdecl; { This function returns a read-only pointer to information about the video hardware. If this is called before SDL_SetVideoMode(), the 'vfmt' member of the returned structure will contain the pixel format of the "best" video mode. } function SDL_GetVideoInfo:PSDL_VideoInfo;cdecl; { Check to see if a particular video mode is supported. It returns 0 if the requested mode is not supported under any bit depth, or returns the bits-per-pixel of the closest available mode with the given width and height. If this bits-per-pixel is different from the one used when setting the video mode, SDL_SetVideoMode will succeed, but will emulate the requested bits-per-pixel with a shadow surface. The arguments to SDL_VideoModeOK are the same ones you would pass to SDL_SetVideoMode } function SDL_VideoModeOK(width:longint; height:longint; bpp:longint; flags:Uint32):longint;cdecl; { Return a pointer to an array of available screen dimensions for the given format and video flags, sorted largest to smallest. Returns NULL if there are no dimensions available for a particular format, or (SDL_Rect )-1 if any dimension is okay for the given format. If 'format' is NULL, the mode list will be for the format given by SDL_GetVideoInfo()->vfmt } function SDL_ListModes(format:pSDL_PixelFormat; flags:Uint32):PSDL_RectArray;cdecl; { Set up a video mode with the specified width, height and bits-per-pixel. If 'bpp' is 0, it is treated as the current display bits per pixel. If SDL_ANYFORMAT is set in 'flags', the SDL library will try to set the requested bits-per-pixel, but will return whatever video pixel format is available. The default is to emulate the requested pixel format if it is not natively available. If SDL_HWSURFACE is set in 'flags', the video surface will be placed in video memory, if possible, and you may have to call SDL_LockSurface in order to access the raw framebuffer. Otherwise, the video surface will be created in system memory. If SDL_ASYNCBLIT is set in 'flags', SDL will try to perform rectangle updates asynchronously, but you must always lock before accessing pixels. SDL will wait for updates to complete before returning from the lock. If SDL_HWPALETTE is set in 'flags', the SDL library will guarantee that the colors set by SDL_SetColors will be the colors you get. Otherwise, in 8-bit mode, SDL_SetColors may not be able to set all of the colors exactly the way they are requested, and you should look at the video surface structure to determine the actual palette. If SDL cannot guarantee that the colors you request can be set, i.e. if the colormap is shared, then the video surface may be created under emulation in system memory, overriding the SDL_HWSURFACE flag. If SDL_FULLSCREEN is set in 'flags', the SDL library will try to set a fullscreen video mode. The default is to create a windowed mode if the current graphics system has a window manager. If the SDL library is able to set a fullscreen video mode, this flag will be set in the surface that is returned. If SDL_DOUBLEBUF is set in 'flags', the SDL library will try to set up two surfaces in video memory and swap between them when you call SDL_Flip. This is usually slower than the normal single-buffering scheme, but prevents "tearing" artifacts caused by modifying video memory while the monitor is refreshing. It should only be used by applications that redraw the entire screen on every update. If SDL_RESIZABLE is set in 'flags', the SDL library will allow the window manager, if any, to resize the window at runtime. When this occurs, SDL will send a SDL_VIDEORESIZE event to your application, and you must respond to the event by re-calling SDL_SetVideoMode with the requested size (or another size that suits the application). If SDL_NOFRAME is set in 'flags', the SDL library will create a window without any title bar or frame decoration. Fullscreen video modes have this flag set automatically. This function returns the video framebuffer surface, or nil if it fails. If you rely on functionality provided by certain video flags, check the flags of the returned surface to make sure that functionality is available. SDL will fall back to reduced functionality if the exact flags you wanted are not available. } function SDL_SetVideoMode(width:longint; height:longint; bpp:longint; flags:Uint32):PSDL_Surface;cdecl; { Makes sure the given list of rectangles is updated on the given screen. If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire screen. These functions should not be called while 'screen' is locked. } procedure SDL_UpdateRects(screen:pSDL_Surface; numrects:longint; var rects:SDL_RectArray);cdecl; procedure SDL_UpdateRect(screen:pSDL_Surface; x:Sint32; y:Sint32; w:Uint32; h:Uint32);cdecl; { On hardware that supports double-buffering, this function sets up a flip and returns. The hardware will wait for vertical retrace, and then swap video buffers before the next video surface blit or lock will return. On hardware that doesn not support double-buffering, this is equivalent to calling SDL_UpdateRect(screen, 0, 0, 0, 0); The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode when setting the video mode for this function to perform hardware flipping. This function returns 0 if successful, or -1 if there was an error. } function SDL_Flip(screen:pSDL_Surface):longint;cdecl; { Set the gamma correction for each of the color channels. The gamma values range (approximately) between 0.1 and 10.0 If this function isn't supported directly by the hardware, it will be emulated using gamma ramps, if available. Iff successful, this function returns False. } function SDL_SetGamma (red, green, blue: Single): LongBool;cdecl; { Set the gamma translation table for the red, green, and blue channels of the video hardware. Each table is an array of 256 16-bit quantities, representing a mapping between the input and output for that channel. The input is the index into the array, and the output is the 16-bit gamma value at that index, scaled to the output color precision. You may pass nil for any of the channels to leave it unchanged. If the call succeeds, it will return False. If the display driver or hardware does not support gamma translation, or otherwise fails, this function will return True. } type TGammaRamp = array[Byte] of Word; PGammaRamp = ^TGammaRamp; function SDL_SetGammaRamp (red, green, blue: PGammaRamp): LongBool;cdecl; { Sets a portion of the colormap for the given 8-bit surface. If 'surface' is not a palettized surface, this function does nothing, returning 0. If all of the colors were set as passed to SDL_SetColors, it will return 1. If not all the color entries were set exactly as given, it will return 0, and you should look at the surface palette to determine the actual color palette. When 'surface' is the surface associated with the current display, the display colormap will be updated with the requested colors. If SDL_HWPALETTE was set in SDL_SetVideoMode flags, SDL_SetColors will always return 1, and the palette is guaranteed to be set the way you desire, even if the window colormap has to be warped or run under emulation. } function SDL_SetColors(surface:pSDL_Surface; var colors:SDL_ColorArray; firstcolor:longint; ncolors:longint):longint;cdecl; { Sets a portion of the colormap for a given 8-bit surface. 'flags' is one or both of: SDL_LOGPAL -- set logical palette, which controls how blits are mapped to/from the surface, SDL_PHYSPAL -- set physical palette, which controls how pixels look on the screen Only screens have physical palettes. Separate change of physical/logical palettes is only possible if the screen has SDL_HWPALETTE set. The return value is True iff all colours could be set as requested. SDL_SetColors is equivalent to calling this function with flags = (SDL_LOGPAL|SDL_PHYSPAL). } function SDL_SetPalette(surface:pSDL_Surface; flags: Longint; var colors:SDL_ColorArray; firstcolor:longint; ncolors:longint):longBool;cdecl; { Maps an RGB triple to an opaque pixel value for a given pixel format } function SDL_MapRGB(format:pSDL_PixelFormat; r, g, b:Uint8):Uint32;cdecl; { Maps an RGBA quadruple to a pixel value for a given pixel format } function SDL_MapRGBA(format:pSDL_PixelFormat; r, g, b, a:Uint8):Uint32;cdecl; { Maps a pixel value into the RGB components for a given pixel format } procedure SDL_GetRGB(pixel:Uint32; fmt:pSDL_PixelFormat; var r,g,b:Uint8);cdecl; { Maps a pixel value into the RGBA components for a given pixel format } procedure SDL_GetRGBA(pixel:Uint32; fmt:pSDL_PixelFormat; var r,g,b,a:Uint8);cdecl; { Allocate and free an RGB surface (must be called after SDL_SetVideoMode) If the depth is 4 or 8 bits, an empty palette is allocated for the surface. If the depth is greater than 8 bits, the pixel format is set using the flags '[RGB]mask'. If the function runs out of memory, it will return nil. The 'flags' tell what kind of surface to create. SDL_SWSURFACE means that the surface should be created in system memory. SDL_HWSURFACE means that the surface should be created in video memory, with the same format as the display surface. This is useful for surfaces that will not change much, to take advantage of hardware acceleration when being blitted to the display surface. SDL_ASYNCBLIT means that SDL will try to perform asynchronous blits with this surface, but you must always lock it before accessing the pixels. SDL will wait for current blits to finish before returning from the lock. SDL_SRCCOLORKEY indicates that the surface will be used for colorkey blits. If the hardware supports acceleration of colorkey blits between two surfaces in video memory, SDL will try to place the surface in video memory. If this isn't possible or if there is no hardware acceleration available, the surface will be placed in system memory. SDL_SRCALPHA means that the surface will be used for alpha blits and if the hardware supports hardware acceleration of alpha blits between two surfaces in video memory, to place the surface in video memory if possible, otherwise it will be placed in system memory. If the surface is created in video memory, blits will be _much_ faster, but the surface format must be identical to the video surface format, and the only way to access the pixels member of the surface is to use the SDL_LockSurface and SDL_UnlockSurface calls. If the requested surface actually resides in video memory, SDL_HWSURFACE will be set in the flags member of the returned surface. If for some reason the surface could not be placed in video memory, it will not have the SDL_HWSURFACE flag set, but will be created in system memory instead } function SDL_CreateRGBSurface(flags:Uint32; width:longint; height:longint; depth:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface;cdecl; { This is an alias for SDL_CreateRGBSurface} function SDL_AllocSurface(flags:Uint32; width:longint; height:longint; depth:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface; function SDL_CreateRGBSurfaceFrom(pixels:pointer; width:longint; height:longint; depth:longint; pitch:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface;cdecl; procedure SDL_FreeSurface(surface:pSDL_Surface);cdecl; { SDL_LockSurface sets up a surface for directly accessing the pixels. Between calls to SDL_LockSurface/SDL_UnlockSurface, you can write to and read from 'surface->pixels', using the pixel format stored in 'surface->format'. Once you are done accessing the surface, you should use SDL_UnlockSurface to release it. Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates to 0, then you can read and write to the surface at any time, and the pixel format of the surface will not change. In particular, if the SDL_HWSURFACE flag is not given when calling SDL_SetVideoMode, you will not need to lock the display surface before accessing it. No operating system or library calls should be made between lock/unlock pairs, as critical system locks may be held during this time. SDL_LockSurface returns 0, or -1 if the surface couldn't be locked. } function SDL_LockSurface(surface:pSDL_Surface):longint;cdecl; procedure SDL_UnlockSurface(surface:pSDL_Surface);cdecl; { Load a surface from a seekable SDL data source (memory or file.) If 'freesrc' is True, the source will be closed after being read. Returns the new surface, or nil if there was an error. The new surface should be freed with SDL_FreeSurface. } function SDL_LoadBMP_RW(src:pSDL_RWops; freesrc:LongBool):PSDL_Surface;cdecl; { Convenience macro -- load a surface from a file } function SDL_LoadBMP(filename:PChar) : PSDL_Surface; { Save a surface to a seekable SDL data source (memory or file.) If 'freedst' is True, the source will be closed after being written. Returns 0 if successful or -1 if there was an error. } function SDL_SaveBMP_RW(surface:pSDL_Surface; dst:pSDL_RWops; freedst:LongBool):longint;cdecl; { Convenience macro -- save a surface to a file } function SDL_SaveBMP(surface: pSDL_Surface;filename:PChar) : longint; { Sets the color key (transparent pixel) in a blittable surface. If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), 'key' will be the transparent pixel in the source image of a blit. SDL_RLEACCEL requests RLE acceleration for the surface if present, and removes RLE acceleration if absent. If 'flag' is 0, this function clears any current color key. This function returns 0, or -1 if there was an error. } function SDL_SetColorKey(surface:pSDL_Surface; flag:Uint32; key:Uint32):longint;cdecl; { This function sets the alpha value for the entire surface, as opposed to using the alpha component of each pixel. This value measures the range of transparency of the surface, 0 being completely transparent to 255 being completely opaque. An 'alpha' value of 255 causes blits to be opaque, the source pixels copied to the destination (the default). Note that per-surface alpha can be combined with colorkey transparency. If 'flag' is 0, alpha blending is disabled for the surface. If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface. OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed. } function SDL_SetAlpha(surface:pSDL_Surface; flag:Uint32; alpha:Uint8):longint;cdecl; { Sets the clipping rectangle for the destination surface in a blit. If the clip rectangle is nil, clipping will be disabled. If the clip rectangle doesn't intersect the surface, the function will return False and blits will be completely clipped. Otherwise the function returns True and blits to the surface will be clipped to the intersection of the surface area and the clipping rectangle. Note that blits are automatically clipped to the edges of the source and destination surfaces. } function SDL_SetClipRect(surface:pSDL_Surface; rect:pSDL_Rect): SDL_Bool;cdecl; { Gets the clipping rectangle for the destination surface in a blit. 'rect' will be filled with the correct values. } procedure SDL_GetClipRect(surface: pSDL_Surface; var rect: SDL_Rect);cdecl; { Creates a new surface of the specified format, and then copies and maps the given surface to it so the blit of the converted surface will be as fast as possible. If this function fails, it returns nil. The 'flags' parameter is passed to SDL_CreateRGBSurface and has those semantics. You can also pass SDL_RLEACCEL in the flags parameter and SDL will try to RLE accelerate colorkey and alpha blits in the resulting surface. This function is used internally by SDL_DisplayFormat. } function SDL_ConvertSurface(src:pSDL_Surface; fmt:pSDL_PixelFormat; flags:Uint32):PSDL_Surface;cdecl; { This performs a fast blit from the source surface to the destination surface. It assumes that the source and destination rectangles are the same size. If either 'srcrect' or 'dstrect' are nil, the entire surface (src or dst) is copied. The final blit rectangles are saved in 'srcrect' and 'dstrect' after all clipping is performed. If the blit is successful, it returns 0, otherwise it returns -1. The blit function should not be called on a locked surface. The blit semantics for surfaces with and without alpha and colorkey are defined as follows: RGBA->RGB: SDL_SRCALPHA set: alpha-blend (using alpha-channel). SDL_SRCCOLORKEY ignored. SDL_SRCALPHA not set: copy RGB. if SDL_SRCCOLORKEY set, only copy the pixels matching the RGB values of the source colour key, ignoring alpha in the comparison. RGB->RGBA: SDL_SRCALPHA set: alpha-blend (using the source per-surface alpha value); set destination alpha to opaque. SDL_SRCALPHA not set: copy RGB, set destination alpha to opaque. both: if SDL_SRCCOLORKEY set, only copy the pixels matching the source colour key. RGBA->RGBA: SDL_SRCALPHA set: alpha-blend (using the source alpha channel) the RGB values; leave destination alpha untouched. [Note: is this correct?] SDL_SRCCOLORKEY ignored. SDL_SRCALPHA not set: copy all of RGBA to the destination. if SDL_SRCCOLORKEY set, only copy the pixels matching the RGB values of the source colour key, ignoring alpha in the comparison. RGB->RGB: SDL_SRCALPHA set: alpha-blend (using the source per-surface alpha value). SDL_SRCALPHA not set: copy RGB. both: if SDL_SRCCOLORKEY set, only copy the pixels matching the source colour key. If either of the surfaces were in video memory, and the blit returns -2, the video memory was lost, so it should be reloaded with artwork and re-blitted: while SDL_BlitSurface(image, imgrect, screen, dstrect) = -2 do Begin while SDL_LockSurface(image) < 0 do Sleep(10); -- Write image pixels to image->pixels -- SDL_UnlockSurface(image); End; This happens under DirectX 5.0 when the system switches away from your fullscreen application. The lock will also fail until you have access to the video memory again. } { You should call SDL_BlitSurface unless you know exactly how SDL blitting works internally and how to use the other blit functions. } function SDL_BlitSurface(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint; { This is the public blit function, SDL_BlitSurface, and it performs rectangle validation and clipping before passing it to SDL_LowerBlit } function SDL_UpperBlit(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint;cdecl; { This is a semi-private blit function and it performs low-level surface blitting only. } function SDL_LowerBlit(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint;cdecl; { This function performs a fast fill of the given rectangle with 'color' The given rectangle is clipped to the destination surface clip area and the final fill rectangle is saved in the passed in pointer. If 'dstrect' is nil, the whole surface will be filled with 'color' The color should be a pixel of the format used by the surface, and can be generated by the SDL_MapRGB() function. This function returns 0 on success, or -1 on error. } function SDL_FillRect(dst:pSDL_Surface; dstrect:pSDL_Rect; color:Uint32):longint;cdecl; { This function takes a surface and copies it to a new surface of the pixel format and colors of the video framebuffer, suitable for fast blitting onto the display surface. It calls SDL_ConvertSurface If you want to take advantage of hardware colorkey or alpha blit acceleration, you should set the colorkey and alpha value before calling this function. If the conversion fails or runs out of memory, it returns nil } function SDL_DisplayFormat(surface:pSDL_Surface):PSDL_Surface;cdecl; { This function takes a surface and copies it to a new surface of the pixel format and colors of the video framebuffer (if possible), suitable for fast alpha blitting onto the display surface. The new surface will always have an alpha channel. If you want to take advantage of hardware colorkey or alpha blit acceleration, you should set the colorkey and alpha value before calling this function. If the conversion fails or runs out of memory, it returns nil } function SDL_DisplayFormatAlpha(surface:pSDL_Surface):pSDL_Surface;cdecl; { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { * YUV video surface overlay functions * } { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { This function creates a video output overlay Calling the returned surface an overlay is something of a misnomer because the contents of the display surface underneath the area where the overlay is shown is undefined - it may be overwritten with the converted YUV data. } function SDL_CreateYUVOverlay (width, height: Longint; format: Uint32; display: pSDL_Surface): pSDL_Overlay;cdecl; { Lock an overlay for direct access, and unlock it when you are done } function SDL_LockYUVOverlay(var overlay: SDL_Overlay):Longint;cdecl; procedure SDL_UnlockYUVOverlay(var overlay: SDL_Overlay);cdecl; { Blit a video overlay to the display surface. The contents of the video surface underneath the blit destination are not defined. The width and height of the destination rectangle may be different from that of the overlay, but currently only 2x scaling is supported. } function SDL_DisplayYUVOverlay(var overlay:SDL_Overlay; var dstrect: SDL_Rect):Longint;cdecl; { Free a video overlay } procedure SDL_FreeYUVOverlay(var overlay: SDL_Overlay);cdecl; { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { * OpenGL support functions. * } { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { Dynamically load a GL driver, if SDL is built with dynamic GL. SDL links normally with the OpenGL library on your system by default, but you can compile it to dynamically load the GL driver at runtime. If you do this, you need to retrieve all of the GL functions used in your program from the dynamic library using SDL_GL_GetProcAddress(). This is disabled in default builds of SDL. } function SDL_GL_LoadLibrary(path: PChar):Longint;cdecl; { Get the address of a GL function (for extension functions) } procedure SDL_GL_GetProcAddress(proc: PChar);cdecl; { Set an attribute of the OpenGL subsystem before intialization. } function SDL_GL_SetAttribute(attr: SDL_GLattr; value: Longint):Longint;cdecl; { Get an attribute of the OpenGL subsystem from the windowing interface, such as glX. This is of course different from getting the values from SDL's internal OpenGL subsystem, which only stores the values you request before initialization. Developers should track the values they pass into SDL_GL_SetAttribute themselves if they want to retrieve these values. } function SDL_GL_GetAttribute (attr: SDL_GLattr; var value: Longint):Longint;cdecl; { Swap the OpenGL buffers, if double-buffering is supported. } Procedure SDL_GL_SwapBuffers; cdecl; { Internal functions that should not be called unless you have read and understood the source code for these functions. } {extern DECLSPEC void SDL_GL_UpdateRects(int numrects, SDL_Rect* rects); extern DECLSPEC void SDL_GL_Lock(void); extern DECLSPEC void SDL_GL_Unlock(void);} { These functions allow interaction with the window manager, if any. } { Sets/Gets the title and icon text of the display window } procedure SDL_WM_SetCaption(title:pchar; icon:pchar);cdecl; procedure SDL_WM_GetCaption(title:ppchar; icon:ppchar);cdecl; { Sets the icon for the display window. This function must be called before the first call to SDL_SetVideoMode. It takes an icon surface, and a mask in MSB format. If 'mask' is nil, the entire icon surface will be used as the icon. } procedure SDL_WM_SetIcon(icon:pSDL_Surface; mask:pByte);cdecl; implementation { *** masks for implementing the bit fields accesors of SDL_VideoInfo *** } const bm_SDL_VideoInfo_hw_available = $1; bp_SDL_VideoInfo_hw_available = 0; bm_SDL_VideoInfo_wm_available = $2; bp_SDL_VideoInfo_wm_available = 1; bm_SDL_VideoInfo_UnusedBits1 = $FC; bp_SDL_VideoInfo_UnusedBits1 = 2; bm_SDL_VideoInfo_UnusedBits2 = $100; bp_SDL_VideoInfo_UnusedBits2 = 8; bm_SDL_VideoInfo_blit_hw = $200; bp_SDL_VideoInfo_blit_hw = 9; bm_SDL_VideoInfo_blit_hw_CC = $400; bp_SDL_VideoInfo_blit_hw_CC = 10; bm_SDL_VideoInfo_blit_hw_A = $800; bp_SDL_VideoInfo_blit_hw_A = 11; bm_SDL_VideoInfo_blit_sw = $1000; bp_SDL_VideoInfo_blit_sw = 12; bm_SDL_VideoInfo_blit_sw_CC = $2000; bp_SDL_VideoInfo_blit_sw_CC = 13; bm_SDL_VideoInfo_blit_sw_A = $4000; bp_SDL_VideoInfo_blit_sw_A = 14; bm_SDL_VideoInfo_blit_fill = $8000; bp_SDL_VideoInfo_blit_fill = 15; bm_SDL_VideoInfo_UnusedBits3 = $FFFF0000; bp_SDL_VideoInfo_UnusedBits3 = 16; { *** bit fields accesors of SDL_VideoInfo *** } function hw_available(var a : SDL_VideoInfo) : Uint32; begin hw_available:=(a.flag0 and bm_SDL_VideoInfo_hw_available) shr bp_SDL_VideoInfo_hw_available; end; procedure set_hw_available(var a : SDL_VideoInfo; __hw_available : Uint32); begin a.flag0:=a.flag0 or ((__hw_available shl bp_SDL_VideoInfo_hw_available) and bm_SDL_VideoInfo_hw_available); end; function wm_available(var a : SDL_VideoInfo) : Uint32; begin wm_available:=(a.flag0 and bm_SDL_VideoInfo_wm_available) shr bp_SDL_VideoInfo_wm_available; end; procedure set_wm_available(var a : SDL_VideoInfo; __wm_available : Uint32); begin a.flag0:=a.flag0 or ((__wm_available shl bp_SDL_VideoInfo_wm_available) and bm_SDL_VideoInfo_wm_available); end; function UnusedBits1(var a : SDL_VideoInfo) : Uint32; begin UnusedBits1:=(a.flag0 and bm_SDL_VideoInfo_UnusedBits1) shr bp_SDL_VideoInfo_UnusedBits1; end; procedure set_UnusedBits1(var a : SDL_VideoInfo; __UnusedBits1 : Uint32); begin a.flag0:=a.flag0 or ((__UnusedBits1 shl bp_SDL_VideoInfo_UnusedBits1) and bm_SDL_VideoInfo_UnusedBits1); end; function UnusedBits2(var a : SDL_VideoInfo) : Uint32; begin UnusedBits2:=(a.flag0 and bm_SDL_VideoInfo_UnusedBits2) shr bp_SDL_VideoInfo_UnusedBits2; end; procedure set_UnusedBits2(var a : SDL_VideoInfo; __UnusedBits2 : Uint32); begin a.flag0:=a.flag0 or ((__UnusedBits2 shl bp_SDL_VideoInfo_UnusedBits2) and bm_SDL_VideoInfo_UnusedBits2); end; function blit_hw(var a : SDL_VideoInfo) : Uint32; begin blit_hw:=(a.flag0 and bm_SDL_VideoInfo_blit_hw) shr bp_SDL_VideoInfo_blit_hw; end; procedure set_blit_hw(var a : SDL_VideoInfo; __blit_hw : Uint32); begin a.flag0:=a.flag0 or ((__blit_hw shl bp_SDL_VideoInfo_blit_hw) and bm_SDL_VideoInfo_blit_hw); end; function blit_hw_CC(var a : SDL_VideoInfo) : Uint32; begin blit_hw_CC:=(a.flag0 and bm_SDL_VideoInfo_blit_hw_CC) shr bp_SDL_VideoInfo_blit_hw_CC; end; procedure set_blit_hw_CC(var a : SDL_VideoInfo; __blit_hw_CC : Uint32); begin a.flag0:=a.flag0 or ((__blit_hw_CC shl bp_SDL_VideoInfo_blit_hw_CC) and bm_SDL_VideoInfo_blit_hw_CC); end; function blit_hw_A(var a : SDL_VideoInfo) : Uint32; begin blit_hw_A:=(a.flag0 and bm_SDL_VideoInfo_blit_hw_A) shr bp_SDL_VideoInfo_blit_hw_A; end; procedure set_blit_hw_A(var a : SDL_VideoInfo; __blit_hw_A : Uint32); begin a.flag0:=a.flag0 or ((__blit_hw_A shl bp_SDL_VideoInfo_blit_hw_A) and bm_SDL_VideoInfo_blit_hw_A); end; function blit_sw(var a : SDL_VideoInfo) : Uint32; begin blit_sw:=(a.flag0 and bm_SDL_VideoInfo_blit_sw) shr bp_SDL_VideoInfo_blit_sw; end; procedure set_blit_sw(var a : SDL_VideoInfo; __blit_sw : Uint32); begin a.flag0:=a.flag0 or ((__blit_sw shl bp_SDL_VideoInfo_blit_sw) and bm_SDL_VideoInfo_blit_sw); end; function blit_sw_CC(var a : SDL_VideoInfo) : Uint32; begin blit_sw_CC:=(a.flag0 and bm_SDL_VideoInfo_blit_sw_CC) shr bp_SDL_VideoInfo_blit_sw_CC; end; procedure set_blit_sw_CC(var a : SDL_VideoInfo; __blit_sw_CC : Uint32); begin a.flag0:=a.flag0 or ((__blit_sw_CC shl bp_SDL_VideoInfo_blit_sw_CC) and bm_SDL_VideoInfo_blit_sw_CC); end; function blit_sw_A(var a : SDL_VideoInfo) : Uint32; begin blit_sw_A:=(a.flag0 and bm_SDL_VideoInfo_blit_sw_A) shr bp_SDL_VideoInfo_blit_sw_A; end; procedure set_blit_sw_A(var a : SDL_VideoInfo; __blit_sw_A : Uint32); begin a.flag0:=a.flag0 or ((__blit_sw_A shl bp_SDL_VideoInfo_blit_sw_A) and bm_SDL_VideoInfo_blit_sw_A); end; function blit_fill(var a : SDL_VideoInfo) : Uint32; begin blit_fill:=(a.flag0 and bm_SDL_VideoInfo_blit_fill) shr bp_SDL_VideoInfo_blit_fill; end; procedure set_blit_fill(var a : SDL_VideoInfo; __blit_fill : Uint32); begin a.flag0:=a.flag0 or ((__blit_fill shl bp_SDL_VideoInfo_blit_fill) and bm_SDL_VideoInfo_blit_fill); end; function UnusedBits3(var a : SDL_VideoInfo) : Uint32; begin UnusedBits3:=(a.flag0 and bm_SDL_VideoInfo_UnusedBits3) shr bp_SDL_VideoInfo_UnusedBits3; end; procedure set_UnusedBits3(var a : SDL_VideoInfo; __UnusedBits3 : Uint32); begin a.flag0:=a.flag0 or ((__UnusedBits3 shl bp_SDL_VideoInfo_UnusedBits3) and bm_SDL_VideoInfo_UnusedBits3); end; { *** masks for implementing the bit fields accesors of SDL_Overlay *** } const bm_SDL_Overlay_hw_overlay = $1; bp_SDL_Overlay_hw_overlay = 0; { *** bit fields accesors of SDL_Overlay *** } function hw_overlay (var o: SDL_Overlay): Uint32; Begin hw_overlay := (o.flag0 and bm_SDL_Overlay_hw_overlay) shr bp_SDL_Overlay_hw_overlay ; End; procedure set_hw_overlay (var o: SDL_Overlay; value: Uint32); Begin o.flag0 := o.flag0 or ( (value shl bp_SDL_Overlay_hw_overlay) and bm_SDL_Overlay_hw_overlay) ; End; function SDL_GetVideoSurface:PSDL_Surface;cdecl;external 'SDL'; function SDL_GetVideoInfo:PSDL_VideoInfo;cdecl;external 'SDL'; function SDL_VideoModeOK(width:longint; height:longint; bpp:longint; flags:Uint32):longint;cdecl;external 'SDL'; function SDL_ListModes(format:pSDL_PixelFormat; flags:Uint32):PSDL_RectArray;cdecl;external 'SDL'; function SDL_SetVideoMode(width:longint; height:longint; bpp:longint; flags:Uint32):PSDL_Surface;cdecl;external 'SDL'; procedure SDL_UpdateRects(screen:pSDL_Surface; numrects:longint; var rects:SDL_RectArray);cdecl;external 'SDL'; procedure SDL_UpdateRect(screen:pSDL_Surface; x:Sint32; y:Sint32; w:Uint32; h:Uint32);cdecl;external 'SDL'; function SDL_Flip(screen:pSDL_Surface):longint;cdecl;external 'SDL'; function SDL_SetGamma (red, green, blue: Single): LongBool;cdecl;external 'SDL'; function SDL_SetGammaRamp (red, green, blue: PGammaRamp): LongBool;cdecl;external 'SDL'; function SDL_SetColors(surface:pSDL_Surface; var colors:SDL_ColorArray; firstcolor:longint; ncolors:longint):longint;cdecl;external 'SDL'; function SDL_SetPalette(surface:pSDL_Surface; flags: Longint; var colors:SDL_ColorArray; firstcolor:longint; ncolors:longint):longBool;cdecl;external 'SDL'; function SDL_MapRGB(format:pSDL_PixelFormat; r:Uint8; g:Uint8; b:Uint8):Uint32;cdecl;external 'SDL'; function SDL_MapRGBA(format:pSDL_PixelFormat; r, g, b, a:Uint8):Uint32;cdecl;external 'SDL'; procedure SDL_GetRGB(pixel:Uint32; fmt:pSDL_PixelFormat; var r,g,b:Uint8);cdecl;external 'SDL'; procedure SDL_GetRGBA(pixel:Uint32; fmt:pSDL_PixelFormat; var r,g,b,a:Uint8);cdecl;external 'SDL'; function SDL_CreateRGBSurface(flags:Uint32; width:longint; height:longint; depth:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface;cdecl;external 'SDL'; function SDL_CreateRGBSurfaceFrom(pixels:pointer; width:longint; height:longint; depth:longint; pitch:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface;cdecl;external 'SDL'; procedure SDL_FreeSurface(surface:pSDL_Surface);cdecl;external 'SDL'; function SDL_LockSurface(surface:pSDL_Surface):longint;cdecl;external 'SDL'; procedure SDL_UnlockSurface(surface:pSDL_Surface);cdecl;external 'SDL'; function SDL_LoadBMP_RW(src:pSDL_RWops; freesrc:LongBool):PSDL_Surface;cdecl;external 'SDL'; function SDL_SaveBMP_RW(surface:pSDL_Surface; dst:pSDL_RWops; freedst:LongBool):longint;cdecl;external 'SDL'; function SDL_SetColorKey(surface:pSDL_Surface; flag:Uint32; key:Uint32):longint;cdecl;external 'SDL'; function SDL_SetAlpha(surface:pSDL_Surface; flag:Uint32; alpha:Uint8):longint;cdecl;external 'SDL'; function SDL_SetClipRect(surface:pSDL_Surface; rect:pSDL_Rect): SDL_Bool;cdecl;external 'SDL'; procedure SDL_GetClipRect(surface: pSDL_Surface; var rect: SDL_Rect);cdecl;external 'SDL'; function SDL_ConvertSurface(src:pSDL_Surface; fmt:pSDL_PixelFormat; flags:Uint32):PSDL_Surface;cdecl;external 'SDL'; function SDL_UpperBlit(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint;cdecl;external 'SDL'; function SDL_LowerBlit(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint;cdecl;external 'SDL'; function SDL_FillRect(dst:pSDL_Surface; dstrect:pSDL_Rect; color:Uint32):longint;cdecl;external 'SDL'; function SDL_DisplayFormat(surface:pSDL_Surface):PSDL_Surface;cdecl;external 'SDL'; function SDL_DisplayFormatAlpha(surface:pSDL_Surface):pSDL_Surface;cdecl; external 'SDL'; function SDL_CreateYUVOverlay (width, height: Longint; format: Uint32; display: pSDL_Surface): pSDL_Overlay;cdecl;external 'SDL'; function SDL_LockYUVOverlay(var overlay: SDL_Overlay):Longint;cdecl;external 'SDL'; procedure SDL_UnlockYUVOverlay(var overlay: SDL_Overlay);cdecl;external 'SDL'; function SDL_DisplayYUVOverlay(var overlay:SDL_Overlay; var dstrect: SDL_Rect):Longint;cdecl;external 'SDL'; procedure SDL_FreeYUVOverlay(var overlay: SDL_Overlay);cdecl;external 'SDL'; function SDL_GL_LoadLibrary(path: PChar):Longint;cdecl;external 'SDL'; procedure SDL_GL_GetProcAddress(proc: PChar);cdecl;external 'SDL'; function SDL_GL_SetAttribute(attr: SDL_GLattr; value: Longint):Longint;cdecl;external 'SDL'; function SDL_GL_GetAttribute (attr: SDL_GLattr; var value: Longint):Longint;cdecl; external 'SDL'; Procedure SDL_GL_SwapBuffers; cdecl; external 'SDL'; procedure SDL_WM_SetCaption(title:pchar; icon:pchar);cdecl;external 'SDL'; procedure SDL_WM_GetCaption(title:ppchar; icon:ppchar);cdecl;external 'SDL'; procedure SDL_WM_SetIcon(icon:pSDL_Surface; mask:pByte);cdecl;external 'SDL'; { Macro } Function SDL_MUSTLOCK (surface: PSDL_Surface): Boolean ; Begin SDL_MUSTLOCK := (surface^.offset<>0) or ((surface^.flags and (SDL_HWSURFACE or SDL_ASYNCBLIT or SDL_RLEACCEL)) <>0) End ; {alias for SDL_CreateRGBSurface} function SDL_AllocSurface(flags:Uint32; width:longint; height:longint; depth:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface; Begin SDL_AllocSurface := SDL_CreateRGBSurface (flags, width, height, depth, Rmask, Gmask, Bmask, Amask); End; {convenience macros} function SDL_LoadBMP(filename:PChar) : PSDL_Surface; Begin SDL_LoadBMP := SDL_LoadBMP_RW (SDL_RWFromFile(filename, 'rb'), True) End; function SDL_SaveBMP(surface: pSDL_Surface;filename:PChar) : longint; begin SDL_SaveBMP := SDL_SaveBMP_RW(surface,SDL_RWFromFile(filename,'wb'), True); end; { alias for SDL_UpperBlit } function SDL_BlitSurface(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint; Begin SDL_BlitSurface := SDL_UpperBlit(src, srcrect, dst, dstrect) End ; end. adlibtracker2-2.4.23/sdl/INSTALL0000644000000000000000000000046613176573533014647 0ustar rootrootInstallation notes To compile the library: $ tar xzf SDL4Freepascal-1.2.0.0.tar.gz $ cd SDL4Freepascal-1.2.0.0 $ ./build.sh and to install it (as root): # mkdir /usr/lib/fpc/yourversion/units/linux/SDL4Freepascal-1.2.0.0 # mv *.o *.ppu /usr/lib/fpc/yourversion/units/linux/SDL4Freepascal-1.2.0.0adlibtracker2-2.4.23/sdl/sdl_copying.inc0000644000000000000000000000160613176573533016620 0ustar rootroot{ SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } adlibtracker2-2.4.23/sdl/README0000644000000000000000000000212713176573533014472 0ustar rootrootSDL4Freepascal-1.2.0.0 These are Freepascal units for using the SDL (Simple Directmedia Layer) library. They were made with H2PAS from the SDL-1.0.0 headers and adapted a little, then upgraded by hand to SDL 1.2. The version number is a.b.c.d where a.b.c is the version of the SDL headers, and d is a release number for this library. I haven't almost tested them, please, if (when) you find any bugs, email me to dmoisset@grulic.org.ar If you write some simple demos (in Pascal) that would be useful as examples, please, send them so I can include them in the package. Everything I will put here must be GPL or LGPL. There are some simple demos here, that are useful as a "mini-tutorial" too. This should(could) compile with Delphi, or other Pascal compilers similar to FreePascal, or by FreePascal in other platforms. If you make it work in another compiler/platform, please tell me; portability would be a nice thing to this lib. I've compiled and run it and the demos on FreePascal for windows, but haven't done more testing than that. Daniel F Moisset - dmoisset@grulic.org.aradlibtracker2-2.4.23/sdl/sdl_mouse.pp0000644000000000000000000001324013176573533016143 0ustar rootrootunit SDL_mouse; { Automatically converted by H2PAS.EXE from SDL_mouse.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types, SDL_video ; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PByte = ^Byte; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Include file for SDL mouse event handling } type { Implementation dependent } WMcursor = Pointer; pSDL_Cursor = ^SDL_Cursor ; SDL_Cursor = record area : SDL_Rect; { The area of the mouse cursor } hot_x : Sint16; hot_y : Sint16; { The "tip" of the cursor } data : ^Uint8; { B/W cursor data } mask : ^Uint8; { B/W cursor mask } save : array[0..1] of ^Uint8; { Place to save cursor area } wm_cursor : ^WMcursor; { Window-manager cursor } end; { Function prototypes } { Retrieve the current state of the mouse. The current button state is returned as a button bitmask, which can be tested using the SDL_BUTTON(X) function, and x and y are set to the current mouse cursor position. } function SDL_GetMouseState(var x:longint; var y:longint):Uint8;cdecl; { Retrieve the current state of the mouse. The current button state is returned as a button bitmask, which can be tested using the SDL_BUTTON(X) function, and x and y are set to the mouse deltas since the last call to SDL_GetRelativeMouseState. } function SDL_GetRelativeMouseState(var x:longint; var y:longint):Uint8;cdecl; { Set the position of the mouse cursor (generates a mouse motion event) } procedure SDL_WarpMouse(x:Uint16; y:Uint16);cdecl; { Create a cursor using the specified data and mask (in MSB format). The cursor width must be a multiple of 8 bits. The cursor is created in black and white according to the following: data mask resulting pixel on screen 0 1 White 1 1 Black 0 0 Transparent 1 0 Inverted color if possible, black if not. Cursors created with this function must be freed with SDL_FreeCursor. } function SDL_CreateCursor(data:pByte; mask:pByte; w:longint; h:longint; hot_x:longint; hot_y:longint):pSDL_Cursor;cdecl; { Set the currently active cursor to the specified one. If the cursor is currently visible, the change will be immediately represented on the display. } procedure SDL_SetCursor(cursor:pSDL_Cursor);cdecl; { Returns the currently active cursor. } function SDL_GetCursor:pSDL_Cursor;cdecl; { Deallocates a cursor created with SDL_CreateCursor. } procedure SDL_FreeCursor(cursor:pSDL_Cursor);cdecl; { Toggle whether or not the cursor is shown on the screen. The cursor start off displayed, but can be turned off. SDL_ShowCursor returns True iff the cursor was being displayed before the call. You can query the current state passing a 'toggle' value of -1 } function SDL_ShowCursor(toggle:Longint):LongBool;cdecl; { Used as a mask when testing buttons in buttonstate Button 1: Left mouse button Button 2: Middle mouse button Button 3: Right mouse button } function SDL_BUTTON(X : Uint8) : Uint8; const SDL_BUTTON_LEFT = 1; SDL_BUTTON_MIDDLE = 2; SDL_BUTTON_RIGHT = 3; SDL_BUTTON_LMASK = 1 shl SDL_BUTTON_LEFT; SDL_BUTTON_MMASK = 1 shl SDL_BUTTON_MIDDLE; SDL_BUTTON_RMASK = 1 shl SDL_BUTTON_RIGHT; implementation function SDL_GetMouseState(var x:longint; var y:longint):Uint8;cdecl;external 'SDL'; function SDL_GetRelativeMouseState(var x:longint; var y:longint):Uint8;cdecl;external 'SDL'; procedure SDL_WarpMouse(x:Uint16; y:Uint16);cdecl;external 'SDL'; function SDL_CreateCursor(data:pByte; mask:pByte; w:longint; h:longint; hot_x:longint; hot_y:longint):pSDL_Cursor;cdecl;external 'SDL'; procedure SDL_SetCursor(cursor:pSDL_Cursor);cdecl;external 'SDL'; function SDL_GetCursor:pSDL_Cursor;cdecl;external 'SDL'; procedure SDL_FreeCursor(cursor:pSDL_Cursor);cdecl;external 'SDL'; function SDL_ShowCursor(toggle:longint):longBool;cdecl;external 'SDL'; function SDL_BUTTON(X : Uint8 ) : Uint8; begin SDL_BUTTON:=SDL_PRESSED shl (X - 1); end; end. adlibtracker2-2.4.23/sdl/COPYING0000644000000000000000000006222213176573533014647 0ustar rootroot GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! adlibtracker2-2.4.23/adt2ext4.pas0000644000000000000000000075361713176573533015215 0ustar rootrootunit AdT2ext4; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const _arp_vib_loader: Boolean = FALSE; _arp_vib_mode: Boolean = FALSE; _macro_editor__pos: array[Boolean] of Byte = (1,8); _macro_editor__fmreg_hpos: array[Boolean] of Byte = (1,1); _macro_editor__fmreg_page: array[Boolean] of Byte = (1,1); _macro_editor__fmreg_left_margin: array[Boolean] of Byte = (1,1); _macro_editor__fmreg_cursor_pos: array[Boolean] of Byte = (1,1); _macro_editor__arpeggio_page: array[Boolean] of Byte = (1,1); _macro_editor__vibrato_hpos: array[Boolean] of Byte = (1,1); _macro_editor__vibrato_page: array[Boolean] of Byte = (1,1); const arpvib_arpeggio_table: Byte = 1; arpvib_vibrato_table: Byte = 1; procedure MACRO_EDITOR(instr: Byte; arp_vib_mode: Boolean); procedure MACRO_BROWSER(instrBrowser: Boolean; updateCurInstr: Boolean); implementation uses {$IFDEF GO32V2} CRT, {$ELSE} DOS, {$ENDIF} AdT2opl3,AdT2sys,AdT2keyb,AdT2unit,AdT2extn,AdT2ext2,AdT2ext3,AdT2ext5,AdT2text,AdT2pack, StringIO,DialogIO,ParserIO,TxtScrIO,DepackIO; const _pip_xloc: Byte = 1; _pip_yloc: Byte = 1; _pip_dest: tSCREEN_MEM_PTR = NIL; _pip_loop: Boolean = FALSE; _operator_enabled: array[1..4] of Boolean = (TRUE,TRUE,TRUE,TRUE); procedure _preview_indic_proc(state: Byte); begin Case state of 0: ShowStr(_pip_dest,_pip_xloc,_pip_yloc, #16' PREViEW '#17, macro_background+macro_text_dis); 1: ShowStr(_pip_dest,_pip_xloc,_pip_yloc, #16' PREViEW '#17, macro_background+macro_text); 2: ShowStr(_pip_dest,_pip_xloc,_pip_yloc, #16' PREViEW '#17, NOT (macro_background+macro_text)); end; If _pip_loop and (state <> 0) then ShowStr(_pip_dest,_pip_xloc,_pip_yloc-1, #12' LOOP', macro_background+macro_text) else ShowStr(_pip_dest,_pip_xloc,_pip_yloc-1, #12' LOOP', macro_background+macro_text_dis); end; var _m_temp,_m_temp2,_m_temp3,_m_temp5: Byte; _m_valid_key,_m_temp4: Boolean; _m_chan_handle: array[1..18] of Byte; _m_channels: Byte; _m_flag_4op: Byte; _m_event_table_bak: array[1..20] of tCHUNK; _m_freq_table_bak,_m_freqtable2_bak: array[1..20] of Word; _m_keyoff_loop_bak: array[1..20] of Boolean; _m_channel_flag_backup: array[1..20] of Boolean; _m_fmpar_table_backup: array[1..20] of tFM_PARAMETER_TABLE; _m_volume_table_backup: array[1..20] of Word; _m_pan_lock_backup: array[1..20] of Boolean; _m_volume_lock_backup: array[1..20] of Boolean; _m_peak_lock_backup: array[1..20] of Boolean; _m_panning_table_backup: array[1..20] of Byte; _m_status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; var _bak_arpeggio_table, _bak_vibrato_table: Byte; _bak_common_flag: Byte; _bak_volume_scaling: Boolean; _bak_current_inst: Byte; _4op_mode: Boolean; function _1op_preview_active: Boolean; var temp,nm_slots: Byte; begin nm_slots := 0; For temp := 1 to 4 do If _operator_enabled[temp] then Inc(nm_slots); _1op_preview_active := (nm_slots = 1); end; procedure _macro_preview_init(state,instr2: Byte); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:_macro_preview_init'; {$ENDIF} _4op_mode := (songdata.flag_4op <> 0) and (instr2 <> BYTE_NULL); Case state of 0: begin Move(_m_fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(_m_volume_table_backup,volume_table,SizeOf(volume_table)); Move(_m_panning_table_backup,panning_table,SizeOf(panning_table)); songdata.instr_macros[_bak_current_inst].arpeggio_table := _bak_arpeggio_table; songdata.instr_macros[_bak_current_inst].vibrato_table := _bak_vibrato_table; songdata.common_flag := _bak_common_flag; volume_scaling := _bak_volume_scaling; reset_player; Move(_m_channel_flag_backup,channel_flag,SizeOf(channel_flag)); Move(_m_event_table_bak,event_table,SizeOf(event_table)); Move(_m_pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(_m_volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(_m_peak_lock_backup,peak_lock,SizeOf(volume_lock)); really_no_status_refresh := FALSE; Move(_m_freq_table_bak,freq_table,SizeOf(freq_table)); Move(_m_freqtable2_bak,freqtable2,SizeOf(freqtable2)); Move(_m_keyoff_loop_bak,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := _m_status_backup.replay_forbidden; play_status := _m_status_backup.play_status; end; 1: begin _m_status_backup.replay_forbidden := replay_forbidden; _m_status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; really_no_status_refresh := TRUE; reset_player; FillChar(_m_chan_handle,SizeOf(_m_chan_handle),0); Move(channel_flag,_m_channel_flag_backup,SizeOf(_m_channel_flag_backup)); Move(event_table,_m_event_table_bak,SizeOf(_m_event_table_bak)); FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); Move(pan_lock,_m_pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,_m_volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,_m_peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,_m_panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); _m_flag_4op := songdata.flag_4op; If NOT percussion_mode and NOT (songdata.flag_4op <> 0) then _m_channels := 18 else If NOT (songdata.flag_4op <> 0) then _m_channels := 15 else begin If _4op_mode and NOT _1op_preview_active then begin _m_flag_4op := $3f; _m_channels := 6; end else begin _m_flag_4op := 0; If NOT percussion_mode then _m_channels := 18 else _m_channels := 15; end; end; _bak_arpeggio_table := songdata.instr_macros[current_inst].arpeggio_table; _bak_vibrato_table := songdata.instr_macros[current_inst].vibrato_table; _bak_common_flag := songdata.common_flag; _bak_volume_scaling := volume_scaling; _bak_current_inst := current_inst; songdata.instr_macros[current_inst].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[current_inst].vibrato_table := ptr_vibrato_table; songdata.common_flag := songdata.common_flag AND NOT $80; volume_scaling := FALSE; reset_player; Move(fmpar_table,_m_fmpar_table_backup,SizeOf(_m_fmpar_table_backup)); Move(volume_table,_m_volume_table_backup,SizeOf(_m_volume_table_backup)); Move(freq_table,_m_freq_table_bak,SizeOf(freq_table)); Move(freqtable2,_m_freqtable2_bak,SizeOf(freqtable2)); Move(keyoff_loop,_m_keyoff_loop_bak,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); misc_register := current_tremolo_depth SHL 7+ current_vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; opl2out($01,$20); opl2out($08,$40); opl3exp($0105); opl3exp($04+_m_flag_4op SHL 8); key_off(17); key_off(18); opl2out(_instr[11],misc_register); macro_speedup := songdata.macro_speedup; If (play_status = isStopped) then update_timer(songdata.tempo); end; end; end; procedure _macro_preview_body(instr,instr2,chan: Byte; fkey: Word); function output_note(chan,board_pos: Byte): Boolean; var note: Byte; freq: Word; ins: tADTRACK2_INS; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:_macro_preview_body:output_note'; {$ENDIF} note := board_pos+12*(current_octave-1); If NOT (note in [0..12*8+1]) then begin output_note := FALSE; EXIT; end; _m_chan_handle[chan] := board_scancodes[board_pos]; If _4op_mode then chan := _4op_main_chan[chan]; If _1op_preview_active then begin If _operator_enabled[1] or _operator_enabled[2] then ins := songdata.instr_data[instr] else ins := songdata.instr_data[instr2]; pBYTE(@ins)[10] := pBYTE(@ins)[10] OR 1; load_instrument(ins,chan); If _operator_enabled[1] or _operator_enabled[2] then set_ins_volume($3f-ORD(_operator_enabled[1])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[2])*($3f-HI(volume_table[chan])), chan) else set_ins_volume($3f-ORD(_operator_enabled[3])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[4])*($3f-HI(volume_table[chan])), chan); end else begin load_instrument(songdata.instr_data[instr],chan); set_ins_volume($3f-ORD(_operator_enabled[1])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[2])*($3f-HI(volume_table[chan])), chan); If percussion_mode and (songdata.instr_data[instr].perc_voice in [4,5]) then load_instrument(songdata.instr_data[instr],_perc_sim_chan[chan]); If _4op_mode then begin load_instrument(songdata.instr_data[instr2],PRED(chan)); set_ins_volume($3f-ORD(_operator_enabled[3])*($3f-LO(volume_table[PRED(chan)])), $3f-ORD(_operator_enabled[4])*($3f-HI(volume_table[PRED(chan)])), PRED(chan)); end; end; freq := nFreq(note-1)+$2000+ SHORTINT(pBYTE(@Addr(songdata.instr_data[instr])^)[12]); event_table[chan].note := note; freq_table[chan] := freq; freqtable2[chan] := freq; key_on(chan); change_freq(chan,freq); If NOT (_1op_preview_active and (_operator_enabled[3] or _operator_enabled[4])) then init_macro_table(chan,note,instr,freq) else init_macro_table(chan,note,instr2,freq); If _4op_mode and NOT _1op_preview_active then init_macro_table(PRED(chan),note,instr2,freq); end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:_macro_preview_body'; {$ENDIF} If ctrl_pressed or alt_pressed or shift_pressed then EXIT; _m_valid_key := FALSE; For _m_temp := 1 to 29 do If NOT shift_pressed then If (board_scancodes[_m_temp] = HI(fkey)) then begin _m_valid_key := TRUE; BREAK; end; If NOT _m_valid_key or NOT (_m_temp+12*(current_octave-1)-1 in [0..12*8+1]) then EXIT; _m_temp2 := _m_temp; If percussion_mode and (songdata.instr_data[instr].perc_voice in [1..5]) then begin output_note(songdata.instr_data[instr].perc_voice+15,_m_temp2); While scankey(board_scancodes[_m_temp2]) do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; end else begin Repeat _m_valid_key := FALSE; For _m_temp := 1 to 29 do begin _m_temp2 := board_scancodes[_m_temp]; _m_temp4 := scankey(_m_temp2); If NOT _4op_mode then begin _m_temp3 := get_chanpos(_m_chan_handle,_m_channels,_m_temp2); _m_temp5 := get_chanpos(_m_chan_handle,_m_channels,0) end else begin _m_temp3 := get_chanpos2(_m_chan_handle,_m_channels,_m_temp2); _m_temp5 := get_chanpos2(_m_chan_handle,_m_channels,0) end; If _m_temp4 then _m_valid_key := TRUE; If _m_temp4 and (_m_temp3 = 0) and (_m_temp5 <> 0) then output_note(_m_temp5,_m_temp); If NOT _m_temp4 and (_m_temp3 <> 0) then begin key_off(_m_temp3); _m_chan_handle[_m_temp3] := 0; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; until NOT _m_valid_key; end; end; procedure MACRO_EDITOR(instr: Byte; arp_vib_mode: Boolean); const EMPTY_FIELD = $0ffff; COMMON_FLAG = $08000; var window_area_inc_x: Byte; window_area_inc_y: Byte; procedure fmreg_page_refresh(xpos,ypos: Byte; page: Word); forward; procedure arpeggio_page_refresh(xpos,ypos: Byte; page: Word); forward; procedure arpeggio_page_refresh_alt(xpos,ypos: Byte; page: Word); forward; procedure vibrato_page_refresh(xpos,ypos: Byte; page: Word); forward; procedure vibrato_page_refresh_alt(xpos,ypos: Byte; page: Word); forward; procedure _show_proc(show_proc_index: integer; xpos,ypos: Byte; page: Word); begin Case show_proc_index of 1: fmreg_page_refresh(xpos,ypos,page); 2: arpeggio_page_refresh(xpos,ypos,page); 3: arpeggio_page_refresh_alt(xpos,ypos,page); 4: vibrato_page_refresh(xpos,ypos,page); 5: vibrato_page_refresh_alt(xpos,ypos,page); end; end; procedure show_queue(x,y: Byte; page_len: Byte; page,len: Word; show_proc_index: integer); var temp1,temp3: Byte; spos,epos: Byte; begin If (PRED(page) < page_len DIV 2) then spos := page_len DIV 2-PRED(page) else spos := 0; If (PRED(page) > len-page_len DIV 2-1) then epos := PRED(page)-(len-page_len DIV 2-1) else epos := 0; If (spos <> 0) or (epos <> 0) then begin If (spos <> 0) then For temp3 := 1 to spos do _show_proc(show_proc_index,x,y+temp3,EMPTY_FIELD); If (epos <> 0) then For temp3 := page_len downto page_len-epos+1 do _show_proc(show_proc_index,x,y+temp3,EMPTY_FIELD); end; For temp1 := 1+spos to page_len-epos do If (temp1 <> SUCC(page_len DIV 2)) then _show_proc(show_proc_index,x,y+temp1,PRED(page)+temp1-page_len DIV 2) else _show_proc(show_proc_index,x,y+temp1,PRED(page)+temp1-page_len DIV 2+COMMON_FLAG); end; const _panning: array[0..2] of Char = #241'<>'; _hex: array[0..15] of Char = '0123456789ABCDEF'; const new_keys: array[1..38] of Word = (kF1,kESC,kENTER,kSPACE,kTAB,kShTAB,kUP,kDOWN, kCtrlO,kF2,kCtrlF2,kF3,kCtrlL,kCtrlS,kCtrlM, kCtENTR,kAltC,kAltP,kCtrlC,kCtrlV, kCtPgUP,kCtPgDN,kSPACE, kCHplus,kNPplus,kCHmins,kNPmins, kCtLbr,kCtRbr,kAlt0,kAlt1,kAlt2,kAlt3,kAlt4, kCtHOME,kCtEND,kCtLEFT,kCtRGHT); var old_keys: array[1..38] of Word; temps,tstr: String; xstart,ystart,temp,temp1: Byte; fmreg_cursor_pos, fmreg_left_margin: Byte; fmreg_hpos: Byte; pos,vibrato_hpos: Byte; old_instr,old_pos,old_arp_ptr,old_vib_ptr: Byte; old_fmreg_page,old_arpeggio_page, old_vibrato_page: Byte; refresh_flag: Byte; attr: array[1..20] of Byte; frame_type: array[1..3] of String; fmreg_page,arpeggio_page, vibrato_page: Byte; fmreg_str: String; call_pickup_proc,call_pickup_proc2: Boolean; nope: Boolean; attr2: array[1..5] of Byte; _source_ins,_source_ins2: Byte; temp_marks: array[1..255] of Char; function min0(number: Integer; flag: Integer): Integer; begin If (number > 0) then min0 := number else min0 := flag; end; function fmreg_def_attr(page: Byte): Word; var attr, attr2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:fmreg_def_attr'; {$ENDIF} If (page <= songdata.instr_macros[instr].length) then If (page >= songdata.instr_macros[instr].loop_begin) and (page <= songdata.instr_macros[instr].loop_begin+ PRED(songdata.instr_macros[instr].loop_length)) and (songdata.instr_macros[instr].loop_begin > 0) and (songdata.instr_macros[instr].loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= songdata.instr_macros[instr].keyoff_pos) and (songdata.instr_macros[instr].keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; fmreg_def_attr := attr+attr2 SHL 8; end; function _fmreg_str(page: Byte): String; var fmreg_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_fmreg_str'; {$ENDIF} With songdata.instr_macros[instr].data[page].fm_data do begin fmreg_str := _hex[ATTCK_DEC_modulator SHR 4]+' '+ _hex[ATTCK_DEC_modulator AND $0f]+' '+ _hex[SUSTN_REL_modulator SHR 4]+' '+ _hex[SUSTN_REL_modulator AND $0f]+' '+ _hex[WAVEFORM_modulator AND 7]+' '+ byte2hex(KSL_VOLUM_modulator AND $3f)+' '+ _hex[KSL_VOLUM_modulator SHR 6]+' '+ _hex[AM_VIB_EG_modulator AND $0f]+' '; If (AM_VIB_EG_modulator SHR 7 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'T'; If (AM_VIB_EG_modulator SHR 6 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'V'; If (AM_VIB_EG_modulator SHR 4 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'K'; If (AM_VIB_EG_modulator SHR 5 AND 1 = 0) then fmreg_str := fmreg_str+#250' ' else fmreg_str := fmreg_str+'S '; fmreg_str := fmreg_str+ _hex[ATTCK_DEC_carrier SHR 4]+' '+ _hex[ATTCK_DEC_carrier AND $0f]+' '+ _hex[SUSTN_REL_carrier SHR 4]+' '+ _hex[SUSTN_REL_carrier AND $0f]+' '+ _hex[WAVEFORM_carrier AND 7]+' '+ byte2hex(KSL_VOLUM_carrier AND $3f)+' '+ _hex[KSL_VOLUM_carrier SHR 6]+' '+ _hex[AM_VIB_EG_carrier AND $0f]+' '; If (AM_VIB_EG_carrier SHR 7 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'T'; If (AM_VIB_EG_carrier SHR 6 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'V'; If (AM_VIB_EG_carrier SHR 4 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'K'; If (AM_VIB_EG_carrier SHR 5 AND 1 = 0) then fmreg_str := fmreg_str+#250' ' else fmreg_str := fmreg_str+'S '; fmreg_str := fmreg_str+_hex[FEEDBACK_FM AND 1]+' '; fmreg_str := fmreg_str+_hex[FEEDBACK_FM SHR 1 AND 7]+' '; end; With songdata.instr_macros[instr].data[page] do begin If (freq_slide < 0) then fmreg_str := fmreg_str+'-'+ExpStrL(Num2str(Abs(freq_slide),16),3,'0')+' ' else fmreg_str := fmreg_str+'+'+ExpStrL(Num2str(Abs(freq_slide),16),3,'0')+' '; fmreg_str := fmreg_str+ _panning[panning]+' '+ byte2hex(duration); end; _fmreg_str := fmreg_str; end; function _dis_fmreg_col(fmreg_col: Byte): Boolean; var result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_dis_fmreg_col'; {$ENDIF} result := FALSE; Case fmreg_col of 1,2,3,4, 5: If songdata.dis_fmreg_col[instr][fmreg_col-1] then result := TRUE; 6, 7: If songdata.dis_fmreg_col[instr][5] then result := TRUE; 8,9,10,11,12,13, 14,15,16,17, 18: If songdata.dis_fmreg_col[instr][fmreg_col-2] then result := TRUE; 19, 20: If songdata.dis_fmreg_col[instr][17] then result := TRUE; 21,22,23,24, 25,26,27, 28: If songdata.dis_fmreg_col[instr][fmreg_col-3] then result := TRUE; 29,30,31, 32: If songdata.dis_fmreg_col[instr][26] then result := TRUE; 33: If songdata.dis_fmreg_col[instr][27] then result := TRUE; end; If (fmreg_col in [14..28]) and (songdata.instr_data[current_inst].perc_voice in [2..5]) then result := TRUE; _dis_fmreg_col := result; end; function _str1(def_chr: Char): String; const _on_off: array[BOOLEAN] of Char = (#205,#254); var temp: Byte; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_str1'; {$ENDIF} temp_str := ''; _on_off[FALSE] := def_chr; For temp := 0 to 4 do temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][temp]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][5]]+ _on_off[songdata.dis_fmreg_col[instr][5]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][6]]+ def_chr+ _on_off[songdata.dis_fmreg_col[instr][7]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][8]]+ _on_off[songdata.dis_fmreg_col[instr][9]]+ _on_off[songdata.dis_fmreg_col[instr][10]]+ _on_off[songdata.dis_fmreg_col[instr][11]]+def_chr; For temp := 12 to 16 do temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][temp]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][17]]+ _on_off[songdata.dis_fmreg_col[instr][17]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][18]]+def_chr+ _on_off[songdata.dis_fmreg_col[instr][19]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][20]]+ _on_off[songdata.dis_fmreg_col[instr][21]]+ _on_off[songdata.dis_fmreg_col[instr][22]]+ _on_off[songdata.dis_fmreg_col[instr][23]]+def_chr; For temp := 24 to 25 do temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][temp]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][26]]+ _on_off[songdata.dis_fmreg_col[instr][26]]+ _on_off[songdata.dis_fmreg_col[instr][26]]+ _on_off[songdata.dis_fmreg_col[instr][26]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][27]]; _str1 := temp_str; end; function _str2(str: String; len: Byte): String; begin asm lea esi,[str] mov edi,@RESULT movzx ebx,len xor edx,edx push edi lodsb inc edi xor ecx,ecx mov ecx,ebx jecxz @@3 movzx ecx,al jecxz @@3 @@1: cmp edx,ebx jae @@3 lodsb stosb cmp al,'`' jz @@2 inc edx @@2: loop @@1 @@3: pop edi mov eax,esi lea esi,[str] sub eax,esi dec eax stosb end; end; procedure fmreg_page_refresh(xpos,ypos: Byte; page: Word); var attr,attr2: Byte; temps,fmreg_str2: String; fmreg_col,index, index2: Byte; dummy_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:fmreg_page_refresh'; {$ENDIF} attr := LO(fmreg_def_attr(page AND $0fff)); attr2 := HI(fmreg_def_attr(page AND $0fff)); fmreg_str := _fmreg_str(page AND $0fff); fmreg_str2 := fmreg_str; index := 0; index2 := 0; For fmreg_col := 1 to 35-1 do If _dis_fmreg_col(fmreg_col) then begin Insert('`',fmreg_str2,pos5[fmreg_col]+index); Insert('`',fmreg_str2,pos5[fmreg_col]+index+2); If (pos5[fmreg_col] < fmreg_left_margin) then Inc(index2,2); Inc(index,2); end; temps := Copy(fmreg_str2,fmreg_left_margin+index2, Length(fmreg_str2)-fmreg_left_margin-index2+1); dummy_str := macro_retrig_str[songdata.instr_macros[instr].data[page AND $0ff].fm_data. FEEDBACK_FM SHR 5]; If NOT arp_vib_mode then begin If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowC3Str(ptr_temp_screen,xpos,ypos, '~'+byte2hex(page)+'~ '#179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_area_inc_x)+'~', macro_background+macro_text, attr, macro_background+macro_text_dis) else ShowC3Str(ptr_temp_screen,xpos-1,ypos, ' ~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_area_inc_x)+'~ ', macro_current_bckg+macro_current, attr2, macro_current_bckg+macro_current_dis) else ShowStr(ptr_temp_screen,xpos,ypos,ExpStrL('',36,' '),attr); end else begin If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowC3Str(ptr_temp_screen,xpos,ypos, byte2hex(page)+' '#179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_area_inc_x)+'~', macro_background+macro_text_dis, macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowC3Str(ptr_temp_screen,xpos-1,ypos, ' '+ byte2hex(page AND NOT COMMON_FLAG)+' '#179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_area_inc_x)+'~ ', macro_background+macro_text_dis, macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowStr(ptr_temp_screen,xpos,ypos,ExpStrL('',36,' '), macro_background+macro_text_dis); end; end; function arpeggio_def_attr(page: Byte): Word; var attr, attr2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:arpeggio_def_attr'; {$ENDIF} If (page <= songdata.macro_table[ptr_arpeggio_table]. arpeggio.length) then If (page >= songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin) and (page <= songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ PRED(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length)) and (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin > 0) and (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos) and (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; arpeggio_def_attr := attr+attr2 SHL 8; end; procedure arpeggio_page_refresh(xpos,ypos: Byte; page: Word); var attr,attr2: Byte; temps: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:arpeggio_page_refresh'; {$ENDIF} attr := LO(arpeggio_def_attr(page AND $0fff)); attr2 := HI(arpeggio_def_attr(page AND $0fff)); Case songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[page AND $0fff] of 0: temps := #250#250#250; 1..96: temps := '+'+ExpStrR(Num2str(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[page AND $0fff],10),2,' '); $80..$80+12*8+1: temps := note_layout[songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[page AND $0fff]-$80]; end; If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowCStr(ptr_temp_screen,xpos,ypos, '~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179' ~'+ temps+'~', macro_background+macro_text,attr) else ShowCStr(ptr_temp_screen,xpos-1,ypos, ' ~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179' ~'+ temps+'~ ', macro_current_bckg+macro_current,attr2) else ShowStr(ptr_temp_screen,xpos,ypos,ExpStrL('',9,' '),attr); end; function vibrato_def_attr(page: Byte): Word; var attr, attr2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:vibrato_def_attr'; {$ENDIF} If (page <= songdata.macro_table[ptr_vibrato_table]. vibrato.length) then If (page >= songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin) and (page <= songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ PRED(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length)) and (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin > 0) and (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos) and (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; vibrato_def_attr := attr+attr2 SHL 8; end; procedure vibrato_page_refresh(xpos,ypos: Byte; page: Word); var attr,attr2: Byte; temps: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:vibrato_page_refresh'; {$ENDIF} attr := LO(vibrato_def_attr(page AND $0fff)); attr2 := HI(vibrato_def_attr(page AND $0fff)); If (songdata.macro_table[ptr_vibrato_table]. vibrato.data[page AND $0fff] = 0) then temps := #250#250#250 else If (songdata.macro_table[ptr_vibrato_table]. vibrato.data[page AND $0fff] < 0) then temps := '-'+byte2hex(Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[page AND $0fff])) else temps := '+'+byte2hex(Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[page AND $0fff])); If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowCStr(ptr_temp_screen,xpos,ypos, '~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179' ~'+ temps+'~', macro_background+macro_text,attr) else ShowCStr(ptr_temp_screen,xpos-1,ypos, ' ~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179' ~'+ temps+'~ ', macro_current_bckg+macro_current,attr2) else ShowStr(ptr_temp_screen,xpos,ypos,ExpStrL('',9,' '),attr); end; procedure arpeggio_page_refresh_alt(xpos,ypos: Byte; page: Word); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:arpeggio_page_refresh_alt'; {$ENDIF} If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowCStr(ptr_temp_screen,xpos,ypos, byte2hex(page AND NOT COMMON_FLAG)+' '#179' ~'+ #250#250#250'~', macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowCStr(ptr_temp_screen,xpos-1,ypos, ' '+ byte2hex(page AND NOT COMMON_FLAG)+' '#179' ~'+ #250#250#250'~ ', macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowStr(ptr_temp_screen,xpos,ypos, ExpStrL('',9,' '), macro_background+macro_text_dis); end; procedure vibrato_page_refresh_alt(xpos,ypos: Byte; page: Word); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:vibrato_page_refresh_alt'; {$ENDIF} temps := #250#250#250; If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowCStr(ptr_temp_screen,xpos,ypos, byte2hex(page AND NOT COMMON_FLAG)+' '#179' ~'+ #250#250#250'~', macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowCStr(ptr_temp_screen,xpos-1,ypos, ' '+ byte2hex(page AND NOT COMMON_FLAG)+' '#179' ~'+ #250#250#250'~ ', macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowStr(ptr_temp_screen,xpos,ypos, ExpStrL('',9,' '), macro_background+macro_text_dis); end; function _gfx_bar_str(value: Byte; neg: Boolean): String; var result: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_gfx_bar_str'; {$ENDIF} result := ''; If NOT neg then Repeat If (value > 15) then begin result := result+#219; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := result+CHR(127+value) until (value <= 15) else Repeat If (value > 15) then begin result := #219+result; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := CHR(158-value)+result; until (value <= 15); _gfx_bar_str := flipstr(result); end; function _fmreg_param(page,fmreg_hpos: Byte): Integer; var result: Integer; fmreg_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_fmreg_param'; {$ENDIF} fmreg_str := _fmreg_str(page); Case fmreg_hpos of {%n} 1,2,3,4,5,8,9,14,15,16,17, 18,21,22,27,28: result := Str2num(fmreg_str[pos5[fmreg_hpos]],16); {%nn} 6,7: result := Str2num(Copy(fmreg_str,pos5[6],2),16); 19,20: result := Str2num(Copy(fmreg_str,pos5[19],2),16); 34,35: result := Str2num(Copy(fmreg_str,pos5[34],2),16); {sw} 10,11,12,13,23,24, 25,26: If (fmreg_str[pos5[fmreg_hpos]] = #251) then result := 1 else result := 0; {fsl} 29,30,31,32: begin result := Str2num(Copy(fmreg_str,pos5[30],3),16); If (fmreg_str[pos5[29]] = '-') then result := -result; end; {pan} 33: Case SYSTEM.Pos(fmreg_str[pos5[33]],_panning) of 1: result := 0; 2: result := -1; 3: result := 1; end; end; _fmreg_param := result; end; const flag_FMREG = 1; flag_ARPEGGiO = 2; flag_VIBRATO = 4; procedure refresh(refresh_flag: Byte); var nm_slots: Byte; temp,max_value: Integer; d_factor: Real; temp_str: String; _add_prev_size, _sub_prev_xpos_a, _sub_prev_xpos_v: Integer; _axis_attr: Byte; _4op_pos_shift, _4op_ins1,_4op_ins2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:refresh'; {$ENDIF} For temp := 1 to 20 do If (pos = temp) then attr[temp] := macro_background+macro_hi_text else If (temp in [1..7]) and arp_vib_mode then attr[temp] := macro_background+macro_text_dis else If (temp in [8..13]) and (ptr_arpeggio_table = 0) then attr[temp] := macro_background+macro_text_dis else If (temp in [14..20]) and (ptr_vibrato_table = 0) then attr[temp] := macro_background+macro_text_dis else attr[temp] := macro_background+macro_text; If (ptr_arpeggio_table <> 0) then begin attr2[1] := macro_input_bckg+macro_input; attr2[3] := macro_background+macro_topic; end else begin attr2[1] := macro_background+macro_text_dis; attr2[3] := macro_background+macro_text_dis; end; If (ptr_vibrato_table <> 0) then begin attr2[2] := macro_input_bckg+macro_input; attr2[4] := macro_background+macro_topic; end else begin attr2[2] := macro_background+macro_text_dis; attr2[4] := macro_background+macro_text_dis; end; If NOT arp_vib_mode then attr2[5] := macro_input_bckg+macro_input else attr2[5] := macro_background+macro_text_dis; If (pos = 7) then frame_type[1] := frame_double else frame_type[1] := frame_single; If (pos = 13) then frame_type[2] := frame_double else frame_type[2] := frame_single; If (pos = 20) then frame_type[3] := frame_double else frame_type[3] := frame_single; If NOT arp_vib_mode then begin ShowStr(ptr_temp_screen,xstart+2,ystart+1,'FM-REGiSTER', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+2,ystart+2,'DEFiNiTiON MACRO-TABLE', macro_background+macro_topic); end else begin ShowStr(ptr_temp_screen,xstart+2,ystart+1,'FM-REGiSTER', macro_background+macro_text_dis); ShowStr(ptr_temp_screen,xstart+2,ystart+2,'DEFiNiTiON MACRO-TABLE', macro_background+macro_text_dis); end; ShowStr(ptr_temp_screen,xstart+2,ystart+3, ExpStrL('',78+window_area_inc_x,#205), macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+2,ystart+10, ExpStrL('',78+window_area_inc_x,#205), macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+2,ystart+22+window_area_inc_y, ExpStrL('',78+window_area_inc_x,#205), macro_background+macro_text); If NOT arp_vib_mode then begin ShowCStr(ptr_temp_screen,xstart+2,ystart+4, 'LENGTH ~'+ byte2hex(songdata.instr_macros[instr].length)+' ~', attr[1],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+5, 'LOOP BEGiN ~'+ byte2hex(songdata.instr_macros[instr].loop_begin)+' ~', attr[2],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+6, 'LOOP LENGTH ~'+ byte2hex(songdata.instr_macros[instr].loop_length)+' ~', attr[3],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+7, 'KEY-OFF ~'+ byte2hex(songdata.instr_macros[instr].keyoff_pos)+' ~', attr[4],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+8, 'ARPEGGiO TABLE ~'+ byte2hex(ptr_arpeggio_table)+' ~', attr[5],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+9, 'ViBRATO TABLE ~'+ byte2hex(ptr_vibrato_table)+' ~', attr[6],attr2[5]); _add_prev_size := window_area_inc_x DIV 2; _sub_prev_xpos_a := 0; _sub_prev_xpos_v := 0; end else begin _add_prev_size := 0; _sub_prev_xpos_a := 20; _sub_prev_xpos_v := -3; end; ShowStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+2,'ARPEGGiO ('+ byte2hex(ptr_arpeggio_table)+')', attr2[3]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+4, 'LENGTH ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length)+' ~', attr[8],attr2[1]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+5, 'SPEED ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed)+' ~', attr[9],attr2[1]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+6, 'LOOP BEGiN ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin)+' ~', attr[10],attr2[1]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+7, 'LOOP LENGTH ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length)+' ~', attr[11],attr2[1]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+8, 'KEY-OFF ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos)+' ~', attr[12],attr2[1]); ShowStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+2,'ViBRATO ('+ byte2hex(ptr_vibrato_table)+')', attr2[4]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+4, 'LENGTH ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.length)+' ~', attr[14],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+5, 'SPEED ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.speed)+' ~', attr[15],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+6, 'DELAY ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.delay)+' ~', attr[16],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+7, 'LOOP BEGiN ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin)+' ~', attr[17],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+8, 'LOOP LENGTH ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length)+' ~', attr[18],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+9, 'KEY-OFF ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos)+' ~', attr[19],attr2[2]); fr_setting.update_area := FALSE; fr_setting.shadow_enabled := FALSE; If (refresh_flag AND flag_FMREG = flag_FMREG) then Frame(ptr_temp_screen,xstart+2,ystart+11, xstart+42+_add_prev_size*2,ystart+21+window_area_inc_y, attr[7],'', macro_background+macro_text,frame_type[1]); If (refresh_flag AND flag_ARPEGGIO = flag_ARPEGGIO) then Frame(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+11, xstart+59+_add_prev_size*2,ystart+21+window_area_inc_y, attr[13],'', macro_background+macro_text,frame_type[2]); If (refresh_flag AND flag_VIBRATO = flag_VIBRATO) then Frame(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+11, xstart+76+_add_prev_size*2,ystart+21+window_area_inc_y, attr[20],'', macro_background+macro_text,frame_type[3]); fr_setting.update_area := TRUE; fr_setting.shadow_enabled := TRUE; show_queue(xstart+4,ystart+11,9+window_area_inc_y,fmreg_page,255,1); If (refresh_flag AND flag_FMREG = flag_FMREG) then If NOT arp_vib_mode then begin HScrollBar(ptr_temp_screen,xstart+29+_add_prev_size*2,ystart+21+window_area_inc_y, 13,35,fmreg_hpos,WORD_NULL, macro_scrbar_bckg+macro_scrbar_text, macro_scrbar_bckg+macro_scrbar_mark); VScrollBar(ptr_temp_screen,xstart+43+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,fmreg_page,WORD_NULL, macro_scrbar_bckg+macro_scrbar_text, macro_scrbar_bckg+macro_scrbar_mark); end else begin HScrollBar(ptr_temp_screen,xstart+29+_add_prev_size*2,ystart+21+window_area_inc_y, 13,35,fmreg_hpos,WORD_NULL, macro_background+macro_text_dis, macro_background+macro_text_dis); VScrollBar(ptr_temp_screen,xstart+43+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,fmreg_page,WORD_NULL, macro_background+macro_text_dis, macro_background+macro_text_dis); end; If (pos = 7) then ShowStr(ptr_temp_screen,xstart+2+8,ystart+11, Copy(_str1(#205),fmreg_left_margin,31), attr[7]) else ShowStr(ptr_temp_screen,xstart+2+8,ystart+11, Copy(_str1(#196),fmreg_left_margin,31), attr[7]); If (refresh_flag AND flag_ARPEGGIO = flag_ARPEGGIO) then If (ptr_arpeggio_table <> 0) then begin show_queue(xstart+50+_add_prev_size*2,ystart+11,9+window_area_inc_y,arpeggio_page,255,2); VScrollBar(ptr_temp_screen,xstart+60+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,arpeggio_page,WORD_NULL, macro_scrbar_bckg+macro_scrbar_text, macro_scrbar_bckg+macro_scrbar_mark) end else begin show_queue(xstart+50+_add_prev_size*2,ystart+11,9+window_area_inc_y,1,255,3); VScrollBar(ptr_temp_screen,xstart+60+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,1,WORD_NULL, macro_background+macro_text_dis, macro_background+macro_text_dis); end; If (refresh_flag AND flag_VIBRATO = flag_VIBRATO) then If (ptr_vibrato_table <> 0) then begin show_queue(xstart+67+_add_prev_size*2,ystart+11,9+window_area_inc_y,vibrato_page,255,4); VScrollBar(ptr_temp_screen,xstart+77+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,vibrato_page,WORD_NULL, macro_scrbar_bckg+macro_scrbar_text, macro_scrbar_bckg+macro_scrbar_mark); end else begin show_queue(xstart+67+_add_prev_size*2,ystart+11,9+window_area_inc_y,1,255,5); VScrollBar(ptr_temp_screen,xstart+77+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,1,WORD_NULL, macro_background+macro_text_dis, macro_background+macro_text_dis); end; If (pos <> 7) then ShowStr(ptr_temp_screen,xstart+2,ystart+23+window_area_inc_y, ExpStrR(macro_table_hint_str[pos],77,' '), macro_background+macro_hint) else ShowStr(ptr_temp_screen,xstart+2,ystart+23+window_area_inc_y, ExpStrR(macro_table_hint_str[20+fmreg_hpos],77,' '), macro_background+macro_hint); If (pos in [1..7]) then begin ShowStr(ptr_temp_screen,xstart+32+_add_prev_size,ystart+3, #253, macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+32+_add_prev_size,ystart+10, #252, macro_background+macro_text); If NOT (fmreg_hpos in [29..33]) then begin ShowVStr(ptr_temp_screen,xstart+22,ystart+4, #179#179#179#179#179#158, macro_background+macro_text); ShowVStr(ptr_temp_screen,xstart+42+window_area_inc_x,ystart+4, #179#179#179#179#179#158, macro_background+macro_text); end else begin ShowVStr(ptr_temp_screen,xstart+22,ystart+4, #179#179#158#179#179#179, macro_background+macro_text); ShowVStr(ptr_temp_screen,xstart+42+window_area_inc_x,ystart+4, #179#179#158#179#179#179, macro_background+macro_text); end; max_value := 0; For temp := 1 to 255 do If (Abs(_fmreg_param(temp,fmreg_hpos)) > max_value) then max_value := Abs(_fmreg_param(temp,fmreg_hpos)); If NOT (fmreg_hpos in [29..33]) then begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+4, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+5, '+', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+8, ' ', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+9, ExpStrR('',3,' '), macro_background+macro_topic); end else begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+4, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+5, '+', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+8, '-', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+9, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); end; If NOT (fmreg_hpos in [29..33]) then d_factor := 90/min(max_value,1) else d_factor := 45/min(max_value,1); If NOT (fmreg_hpos in [29..33]) then For temp := -9-_add_prev_size to 9+_add_prev_size do If (fmreg_page+temp >= 1) and (fmreg_page+temp <= 255) then If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL(_gfx_bar_str(Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor),FALSE),6,' '), LO(fmreg_def_attr(fmreg_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL(_gfx_bar_str(Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor),FALSE),6,' '), macro_background+macro_text_dis) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL('',6,' '), macro_background+macro_text) else For temp := -9-_add_prev_size to 9+_add_prev_size do If (fmreg_page+temp >= 1) and (fmreg_page+temp <= 255) then If (Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor) >= 0) then If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrR(ExpStrL(_gfx_bar_str(Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor),FALSE),3,' '),6,' '), LO(fmreg_def_attr(fmreg_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrR(ExpStrL(_gfx_bar_str(Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor),FALSE),3,' '),6,' '), macro_background+macro_text_dis) else If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(_fmreg_param(fmreg_page+temp,fmreg_hpos))*d_factor),TRUE),3,' '),6,' '), LO(fmreg_def_attr(fmreg_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(_fmreg_param(fmreg_page+temp,fmreg_hpos))*d_factor),TRUE),3,' '),6,' '), macro_background+macro_text_dis) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrR('',6,' '), macro_background+macro_text); end; If (pos in [8..13]) or arp_vib_mode then begin If NOT (pos in [8..13]) then _axis_attr := macro_background+macro_topic else begin ShowStr(ptr_temp_screen,xstart+32+_add_prev_size-_sub_prev_xpos_a,ystart+3, #253, macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+32+_add_prev_size-_sub_prev_xpos_a,ystart+10, #252, macro_background+macro_text); end; If (pos in [8..13]) then If arp_vib_mode then _axis_attr := macro_background+macro_hi_text else _axis_attr := macro_background+macro_text else _axis_attr := macro_background+macro_text; ShowVStr(ptr_temp_screen,xstart+22-_sub_prev_xpos_a,ystart+4, #179#179#179#179#179#158, _axis_attr); ShowVStr(ptr_temp_screen,xstart+42+window_area_inc_x-_sub_prev_xpos_a,ystart+4, #179#179#179#179#179#158, _axis_attr); max_value := 0; For temp := 1 to 255 do If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] > max_value) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] < $80) then max_value := Abs(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp]); If NOT arp_vib_mode then begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+4, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+5, '+ ', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+8, ' ', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+9, ExpStrR('',3,' '), macro_background+macro_topic); end else If (pos in [8..13]) then begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+4, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+5, '+ ', macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+8, ' ', macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+9, ExpStrR('',3,' '), macro_background+macro_hi_text); end; d_factor := 90/min(max_value,1); For temp := -9-_add_prev_size to 9+_add_prev_size do If (arpeggio_page+temp >= 1) and (arpeggio_page+temp <= 255) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page+temp] < $80) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_a,ystart+4, ExpStrL(_gfx_bar_str(Round(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page+temp]*d_factor),FALSE),6,' '), LO(arpeggio_def_attr(arpeggio_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_a,ystart+4, ExpStrL(FilterStr(note_layout[songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page+temp]-$80],'-',#241),6,' '), LO(arpeggio_def_attr(arpeggio_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_a,ystart+4, ExpStrL('',6,' '), macro_background+macro_text); end; If (pos in [14..20]) or arp_vib_mode then begin If NOT (pos in [14..20]) then _axis_attr := macro_background+macro_text else begin ShowStr(ptr_temp_screen,xstart+32+_add_prev_size-_sub_prev_xpos_v,ystart+3, #253, macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+32+_add_prev_size-_sub_prev_xpos_v,ystart+10, #252, macro_background+macro_text); end; If (pos in [14..20]) then If arp_vib_mode then _axis_attr := macro_background+macro_hi_text else _axis_attr := macro_background+macro_text else _axis_attr := macro_background+macro_text; ShowVStr(ptr_temp_screen,xstart+22-_sub_prev_xpos_v,ystart+4, #179#179#158#179#179#179, _axis_attr); ShowVStr(ptr_temp_screen,xstart+42+window_area_inc_x-_sub_prev_xpos_v,ystart+4, #179#179#158#179#179#179, _axis_attr); max_value := 0; For temp := 1 to 255 do If (Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp]) > max_value) then max_value := Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp]); If NOT arp_vib_mode then begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_v,ystart+4, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_v,ystart+5, '+', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_v,ystart+8, '-', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_v,ystart+9, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); end else If (pos in [14..20]) then begin ShowStr(ptr_temp_screen,xstart+20-_sub_prev_xpos_v,ystart+4, ExpStrL(ExpStrL(Num2Str(max_value,16),2,'0'),2,' '), macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+20-_sub_prev_xpos_v,ystart+5, ' +', macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+20-_sub_prev_xpos_v,ystart+8, ' -', macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+20-_sub_prev_xpos_v,ystart+9, ExpStrL(ExpStrL(Num2Str(max_value,16),2,'0'),2,' '), macro_background+macro_hi_text); end; d_factor := 45/min(max_value,1); For temp := -9-_add_prev_size to 9+_add_prev_size do If (vibrato_page+temp >= 1) and (vibrato_page+temp <= 255) then If (Round(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page+temp]*d_factor) >= 0) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_v,ystart+4, ExpStrR(ExpStrL(_gfx_bar_str(Round(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page+temp]*d_factor),FALSE),3,' '),6,' '), LO(vibrato_def_attr(vibrato_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_v,ystart+4, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page+temp])*d_factor),TRUE),3,' '),6,' '), LO(vibrato_def_attr(vibrato_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_v,ystart+4, ExpStrR('',6,' '), macro_background+macro_text); end; If NOT (get_4op_to_test <> 0) then _4op_pos_shift := 0 else _4op_pos_shift := 6; If (get_4op_to_test <> 0) then begin _4op_ins1 := HI(get_4op_to_test); _4op_ins2 := LO(get_4op_to_test); If (_4op_ins1 = _4op_ins2) then ShowC3Str(ptr_temp_screen,xstart+01,ystart+24+window_area_inc_y, ' `[`'#244+byte2hex(_4op_ins1)+ ','#245+byte2hex(_4op_ins1)+' '+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[10] AND 1]+'/'+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[10] AND 1]+ '`]` ', macro_background+macro_hi_text, macro_hi_text SHL 4, macro_background+macro_border) else If (current_inst = _4op_ins1) then ShowC3Str(ptr_temp_screen,xstart+01,ystart+24+window_area_inc_y, ' `[`~'#244+byte2hex(_4op_ins1)+ '~,'#245+byte2hex(_4op_ins2)+' ~'+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[10] AND 1]+'~/'+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[10] AND 1]+ '`]` ', macro_background+macro_hi_text, macro_hi_text SHL 4, macro_background+macro_border) else ShowC3Str(ptr_temp_screen,xstart+01,ystart+24+window_area_inc_y, ' `[`'#244+byte2hex(_4op_ins1)+ ',~'#245+byte2hex(_4op_ins2)+'~ '+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[10] AND 1]+'/~'+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[10] AND 1]+ '~`]` ', macro_background+macro_hi_text, macro_hi_text SHL 4, macro_background+macro_border); end else ShowCStr(ptr_temp_screen, xstart+01,ystart+24+window_area_inc_y, ' [~'+perc_voice_str[songdata.instr_data[current_inst].perc_voice]+'~] ', macro_background+macro_border, macro_background+macro_hi_text); If (songdata.instr_macros[current_inst].length <> 0) then temp_str := ' [~MACRO:FM' else temp_str := ' '; If NOT arp_vib_mode then begin If (ptr_arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'[~MACRO:ARP'; If (ptr_vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'[~MACRO:ViB'; end; If (temp_str <> ' ') then temp_str := temp_str+'~] '; ShowCStr(ptr_temp_screen,xstart+11+_4op_pos_shift,ystart+24+window_area_inc_y,ExpStrR(temp_str,21+2,#205), macro_background+macro_border, macro_background+macro_hi_text); If (songdata.instr_data[instr].perc_voice in [2..5]) then begin temp_str := '```` '; nm_slots := 1; end else If NOT (get_4op_to_test <> 0) then begin temp_str := ' `[`12`]` '; nm_slots := 2; end else begin temp_str := ' `[`1234`]` '; nm_slots := 4; end; temp_str := temp_str+'[~SPEED:'+Num2str(songdata.tempo*songdata.macro_speedup,10)+#174+'~] '; ShowC3Str(ptr_temp_screen,xstart+window_area_inc_x+59,ystart+24+window_area_inc_y, ExpStrL(temp_str,28,#205), macro_background+macro_border, macro_background+macro_context, macro_background+macro_context_dis); If (nm_slots > 1) then For temp := 1 to nm_slots do If (NOT _operator_enabled[temp]) then ShowStr(ptr_temp_screen,xstart+window_area_inc_x+83-C3StrLen(temp_str)-1+temp,ystart+24+window_area_inc_y, #250, instrument_bckg+instrument_border); _preview_indic_proc(0); move2screen_alt; end; function hex(chr: Char): Byte; begin hex := PRED(SYSTEM.Pos(UpCase(chr),_hex)); end; procedure copy_object; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:copy_object'; {$ENDIF} Case clipboard.object_type of objMacroTableLine: Case clipboard.mcrtab_type of mttFM_reg_table: clipboard.fmreg_table.data[1] := songdata.instr_macros[instr].data[fmreg_page]; mttArpeggio_table: clipboard.macro_table.arpeggio.data[1] := songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]; mttVibrato_table: clipboard.macro_table.vibrato.data[1] := songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page]; end; objMacroTableColumn: Case clipboard.mcrtab_type of mttFM_reg_table: begin clipboard.fmtab_def_typ := fmreg_hpos; For temp := 1 to 255 do clipboard.fmreg_table.data[temp] := songdata.instr_macros[instr].data[temp]; end; mttArpeggio_table: clipboard.macro_table.arpeggio := songdata.macro_table[ptr_arpeggio_table].arpeggio; mttVibrato_table: clipboard.macro_table.vibrato := songdata.macro_table[ptr_vibrato_table].vibrato; end; objMacroTable: Case clipboard.mcrtab_type of mttFM_reg_table: clipboard.fmreg_table := songdata.instr_macros[instr]; mttArpeggio_table: clipboard.macro_table.arpeggio := songdata.macro_table[ptr_arpeggio_table].arpeggio; mttVibrato_table: clipboard.macro_table.vibrato := songdata.macro_table[ptr_vibrato_table].vibrato; end; end; end; procedure paste_object; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:paste_object'; {$ENDIF} Case clipboard.object_type of objMacroTableLine: Case clipboard.mcrtab_type of mttFM_reg_table: If (pos = 7) then begin temp := songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM; songdata.instr_macros[instr].data[fmreg_page] := clipboard.fmreg_table.data[1]; songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM := temp AND $0c0+ songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM; end; mttArpeggio_table: If (pos = 13) then songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := clipboard.macro_table.arpeggio.data[1]; mttVibrato_table: If (pos = 20) then songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page] := clipboard.macro_table.vibrato.data[1]; end; objMacroTableColumn: Case clipboard.mcrtab_type of mttFM_reg_table: For temp := 1 to 255 do With songdata.instr_macros[instr].data[temp] do Case clipboard.fmtab_def_typ of 1: fm_data.ATTCK_DEC_modulator := clipboard.fmreg_table.data[temp].fm_data.ATTCK_DEC_modulator AND $0f0+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.ATTCK_DEC_modulator AND $0f; 3: fm_data.SUSTN_REL_modulator := clipboard.fmreg_table.data[temp].fm_data.SUSTN_REL_modulator AND $0f0+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.SUSTN_REL_modulator AND $0f; 5: fm_data.WAVEFORM_modulator := clipboard.fmreg_table.data[temp].fm_data.WAVEFORM_modulator; 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0+ clipboard.fmreg_table.data[temp].fm_data.KSL_VOLUM_modulator AND $3f; 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ clipboard.fmreg_table.data[temp].fm_data.KSL_VOLUM_modulator AND $0c0; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $0f; 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $80; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $40; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $10; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $20; 14: fm_data.ATTCK_DEC_carrier := clipboard.fmreg_table.data[temp].fm_data.ATTCK_DEC_carrier AND $0f0+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.ATTCK_DEC_carrier AND $0f; 16: fm_data.SUSTN_REL_carrier := clipboard.fmreg_table.data[temp].fm_data.SUSTN_REL_carrier AND $0f0+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.SUSTN_REL_carrier AND $0f; 18: fm_data.WAVEFORM_carrier := clipboard.fmreg_table.data[temp].fm_data.WAVEFORM_carrier; 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0+ clipboard.fmreg_table.data[temp].fm_data.KSL_VOLUM_carrier AND $3f; 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ clipboard.fmreg_table.data[temp].fm_data.KSL_VOLUM_carrier AND $0c0; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $0f; 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $80; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $40; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $10; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $20; 27: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0fe+ clipboard.fmreg_table.data[temp].fm_data.FEEDBACK_FM AND 1; 28: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0c1+ clipboard.fmreg_table.data[temp].fm_data.FEEDBACK_FM AND $03e; 29,30,31, 32: freq_slide := clipboard.fmreg_table.data[temp].freq_slide; 33: panning := clipboard.fmreg_table.data[temp].panning; 34, 35: duration := clipboard.fmreg_table.data[temp].duration; end; mttArpeggio_table: If (pos in [8..13]) then For temp := 1 to 255 do songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] := clipboard.macro_table.arpeggio.data[temp]; mttVibrato_table: If (pos in [14..20]) then For temp := 1 to 255 do songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp] := clipboard.macro_table.vibrato.data[temp]; end; objMacroTable: Case clipboard.mcrtab_type of mttFM_reg_table: If (pos in [1..7]) then songdata.instr_macros[instr] := clipboard.fmreg_table; mttArpeggio_table: If (pos in [8..13]) then songdata.macro_table[ptr_arpeggio_table].arpeggio := clipboard.macro_table.arpeggio; mttVibrato_table: If (pos in [14..20]) then songdata.macro_table[ptr_vibrato_table].vibrato := clipboard.macro_table.vibrato; end; end; end; procedure _scroll_cur_left; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_scroll_cur_left'; {$ENDIF} Repeat If (fmreg_cursor_pos > 1) then Dec(fmreg_cursor_pos) else Dec(fmreg_left_margin); until (fmreg_str[PRED(fmreg_left_margin+fmreg_cursor_pos-1)] = ' ') or (fmreg_left_margin+fmreg_cursor_pos-1 = 1); fmreg_cursor_pos := pos5[fmreg_hpos]-fmreg_left_margin+1; end; procedure _scroll_cur_right; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_scroll_cur_right'; {$ENDIF} Repeat If (fmreg_cursor_pos < max(57,31+window_area_inc_x)) then Inc(fmreg_cursor_pos) else Inc(fmreg_left_margin); until (fmreg_str[SUCC(fmreg_left_margin+fmreg_cursor_pos-1)] = ' ') or (fmreg_left_margin+fmreg_cursor_pos-1 = 57); fmreg_cursor_pos := pos5[fmreg_hpos]-fmreg_left_margin+1; end; function _inc(value,limit: Integer): Integer; begin If (value < limit) then Inc(value); _inc := value; end; function _dec(value,limit: Integer): Integer; begin If (value > limit) then Dec(value); _dec := value; end; procedure _set_operator_flag(operator: Byte; toggle: Boolean); var _temp_operator_enabled: array[1..4] of Boolean; begin If (songdata.instr_data[instr].perc_voice in [2..5]) or (NOT (get_4op_to_test <> 0) and NOT (operator in [1..2])) or (NOT (operator in [1..4])) then EXIT; If NOT toggle then begin FillChar(_operator_enabled,SizeOf(_operator_enabled),FALSE); _operator_enabled[operator] := TRUE; EXIT; end; Move(_operator_enabled,_temp_operator_enabled,SizeOf(_temp_operator_enabled)); If NOT (get_4op_to_test <> 0) and (operator in [1,2]) then begin _temp_operator_enabled[operator] := NOT _temp_operator_enabled[operator]; If NOT ((_temp_operator_enabled[1] = FALSE) and (_temp_operator_enabled[2] = FALSE)) then Move(_temp_operator_enabled,_operator_enabled,SizeOf(_operator_enabled)); end else If (get_4op_to_test <> 0) and (operator in [1,2,3,4]) then begin _temp_operator_enabled[operator] := NOT _temp_operator_enabled[operator]; If NOT ((_temp_operator_enabled[1] = FALSE) and (_temp_operator_enabled[2] = FALSE) and (_temp_operator_enabled[3] = FALSE) and (_temp_operator_enabled[4] = FALSE)) then Move(_temp_operator_enabled,_operator_enabled,SizeOf(_operator_enabled)); end; end; function _check_macro_speed_change: Boolean; begin _check_macro_speed_change := FALSE; Case is_environment.keystroke of kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If (current_inst > 1) then begin Dec(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); STATUS_LINE_refresh; keyboard_reset_buffer; _check_macro_speed_change := TRUE; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If (current_inst < 255) then begin Inc(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); STATUS_LINE_refresh; keyboard_reset_buffer; _check_macro_speed_change := TRUE; end; end; If (is_environment.keystroke = kAlt0) or (is_environment.keystroke = kAlt1) or (is_environment.keystroke = kAlt2) or (is_environment.keystroke = kAlt3) or (is_environment.keystroke = kAlt4) then begin _check_macro_speed_change := TRUE; Case is_environment.keystroke of kAlt0: FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); kAlt1: If shift_pressed then _set_operator_flag(1,TRUE) else _set_operator_flag(1,FALSE); kAlt2: If shift_pressed then _set_operator_flag(2,TRUE) else _set_operator_flag(2,FALSE); kAlt3: If shift_pressed then _set_operator_flag(3,TRUE) else _set_operator_flag(3,FALSE); kAlt4: If shift_pressed then _set_operator_flag(4,TRUE) else _set_operator_flag(4,FALSE); end; end; end; procedure _check_fmreg_general_keys; begin Case is_environment.keystroke of kCtHOME: If NOT shift_pressed then If (songdata.instr_macros[instr].length > 0) then Dec(songdata.instr_macros[instr].length) else else If (songdata.instr_macros[instr].loop_begin > 0) then begin Dec(songdata.instr_macros[instr].loop_begin); While NOT ((songdata.instr_macros[instr]. keyoff_pos > songdata.instr_macros[instr]. loop_begin+ min0(songdata.instr_macros[instr]. loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); end; kCtEND: If NOT shift_pressed then If (songdata.instr_macros[instr].length < 255) then Inc(songdata.instr_macros[instr].length) else else If (songdata.instr_macros[instr].loop_begin < 255) then begin Inc(songdata.instr_macros[instr].loop_begin); While NOT ((songdata.instr_macros[instr]. keyoff_pos > songdata.instr_macros[instr]. loop_begin+ min0(songdata.instr_macros[instr]. loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); end; kCtPgUP: If NOT shift_pressed then else If (songdata.instr_macros[instr].loop_length > 0) then begin Dec(songdata.instr_macros[instr].loop_length); While NOT ((songdata.instr_macros[instr]. keyoff_pos > songdata.instr_macros[instr]. loop_begin+ min0(songdata.instr_macros[instr]. loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); end; kCtPgDN: If NOT shift_pressed then else If (songdata.instr_macros[instr].loop_length < 255) then begin Inc(songdata.instr_macros[instr].loop_length); While NOT ((songdata.instr_macros[instr]. keyoff_pos > songdata.instr_macros[instr]. loop_begin+ min0(songdata.instr_macros[instr]. loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); end; end; end; procedure _check_arp_general_keys; begin Case is_environment.keystroke of kCtHOME: If NOT shift_pressed then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.length > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin > 0) then begin Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin); While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; kCtEND: If NOT shift_pressed then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.length < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin < 255) then begin Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin); While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; kCtPgUP: If NOT shift_pressed then If (ptr_arpeggio_table > 1) then Dec(ptr_arpeggio_table) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length > 0) then begin Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length); While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; kCtPgDN: If NOT shift_pressed then If (ptr_arpeggio_table < 255) then Inc(ptr_arpeggio_table) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length < 255) then begin Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length); While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; end; end; procedure _check_vib_general_keys; begin Case is_environment.keystroke of kCtHOME: If NOT shift_pressed then If (songdata.macro_table[ptr_vibrato_table]. vibrato.length > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.length) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin > 0) then begin Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin); While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; kCtEND: If NOT shift_pressed then If (songdata.macro_table[ptr_vibrato_table]. vibrato.length < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.length) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin < 255) then begin Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin); While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; kCtPgUP: If NOT shift_pressed then If (ptr_vibrato_table > 1) then Dec(ptr_vibrato_table) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length > 0) then begin Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length); While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; kCtPgDN: If NOT shift_pressed then If (ptr_vibrato_table < 255) then Inc(ptr_vibrato_table) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length < 255) then begin Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length); While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; end; end; label _jmp1,_jmp2,_end2; begin { MACRO_EDITOR } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR'; {$ENDIF} _arp_vib_mode := arp_vib_mode; If is_default_screen_mode then begin window_area_inc_x := 0; window_area_inc_y := 0; end else begin If NOT arp_vib_mode then window_area_inc_x := 10 else window_area_inc_x := 0; window_area_inc_y := 10; end; call_pickup_proc := FALSE; _source_ins := instrum_page; call_pickup_proc2 := FALSE; _source_ins2 := instrum_page; _jmp1: If NOT arp_vib_mode then begin ptr_arpeggio_table := songdata.instr_macros[instr].arpeggio_table; ptr_vibrato_table := songdata.instr_macros[instr].vibrato_table; end else begin ptr_arpeggio_table := arpvib_arpeggio_table; ptr_vibrato_table := arpvib_vibrato_table; end; pos := _macro_editor__pos[arp_vib_mode]; If arp_vib_mode and (pos < 8) then pos := 8 else If NOT arp_vib_mode and (((ptr_arpeggio_table = 0) and (pos in [8..13])) or ((ptr_vibrato_table = 0) and (pos in [14..20]))) then pos := 1; fmreg_hpos := _macro_editor__fmreg_hpos[arp_vib_mode]; fmreg_page := _macro_editor__fmreg_page[arp_vib_mode]; fmreg_left_margin := _macro_editor__fmreg_left_margin[arp_vib_mode]; fmreg_cursor_pos := _macro_editor__fmreg_cursor_pos[arp_vib_mode]; arpeggio_page := _macro_editor__arpeggio_page[arp_vib_mode]; vibrato_hpos := _macro_editor__vibrato_hpos[arp_vib_mode]; vibrato_page := _macro_editor__vibrato_page[arp_vib_mode]; If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; songdata.instr_names[temp][1] := ' '; end; songdata_crc := Update32(songdata,SizeOf(songdata),0); For temp := 1 to 255 do songdata.instr_names[temp][1] := temp_marks[temp]; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; If NOT arp_vib_mode then centered_frame(xstart,ystart,81+window_area_inc_x,24+window_area_inc_y, ' iNSTRUMENT MACRO EDiTOR (iNS_ ) ', macro_background+dialog_border, macro_background+dialog_title, frame_double) else centered_frame(xstart,ystart,81+window_area_inc_x,24+window_area_inc_y, ' ARPEGGiO/ViBRATO MACRO EDiTOR (iNS_ ) ', macro_background+dialog_border, macro_background+dialog_title, frame_double); _pip_xloc := xstart+30+(window_area_inc_x DIV 2); _pip_yloc := ystart+2; _pip_dest := ptr_temp_screen; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+81+2+window_area_inc_x; move_to_screen_area[4] := ystart+24+1+window_area_inc_y; refresh(flag_FMREG+flag_ARPEGGIO+flag_VIBRATO); move_to_screen_area[1] := xstart+1; move_to_screen_area[2] := ystart+1; move_to_screen_area[3] := xstart+80+window_area_inc_x; move_to_screen_area[4] := ystart+24+window_area_inc_y; If (pos = 1) then GotoXY(xstart+17,ystart+4); ThinCursor; centered_frame_vdest := screen_ptr; Move(is_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,is_setting.terminate_keys,SizeOf(new_keys)); old_instr := instr; old_pos := pos; old_arp_ptr := ptr_arpeggio_table; old_vib_ptr := ptr_vibrato_table; old_fmreg_page := fmreg_page; old_arpeggio_page := arpeggio_page; old_vibrato_page := vibrato_page; _jmp2: If NOT arp_vib_mode then begin songdata.instr_macros[instr].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[instr].vibrato_table := ptr_vibrato_table; end; If (instr <> current_inst) then instr := current_inst; If NOT arp_vib_mode then begin ptr_arpeggio_table := songdata.instr_macros[instr].arpeggio_table; ptr_vibrato_table := songdata.instr_macros[instr].vibrato_table; end; If arp_vib_mode and (pos < 8) then pos := 8 else If NOT arp_vib_mode and (((ptr_arpeggio_table = 0) and (pos in [8..13])) or ((ptr_vibrato_table = 0) and (pos in [14..20]))) then pos := 1; If NOT arp_vib_mode then ShowStr(centered_frame_vdest,xstart+54+(window_area_inc_x DIV 2),ystart, byte2hex(instr),macro_background+dialog_title) else ShowStr(centered_frame_vdest,xstart+57+(window_area_inc_x DIV 2),ystart, byte2hex(instr),macro_background+dialog_title); If NOT _force_program_quit then Repeat If arp_vib_mode then refresh(flag_ARPEGGIO+flag_VIBRATO) else begin Case pos of 1..7: begin refresh_flag := flag_FMREG; If (old_pos in [8..13]) or (old_arpeggio_page <> arpeggio_page) or (old_arp_ptr <> ptr_arpeggio_table) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_ARPEGGIO; If (old_pos in [14..20]) or (old_vibrato_page <> vibrato_page) or (old_vib_ptr <> ptr_vibrato_table) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_VIBRATO; end; 8..13: begin refresh_flag := flag_ARPEGGIO; If (old_pos in [1..7]) or (old_fmreg_page <> fmreg_page) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_FMREG; If (old_pos in [14..20]) or (old_vibrato_page <> vibrato_page) or (old_vib_ptr <> ptr_vibrato_table) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_VIBRATO; end; 14..20: begin refresh_flag := flag_VIBRATO; If (old_pos in [1..7]) or (old_fmreg_page <> fmreg_page) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_FMREG; If (old_pos in [8..13]) or (old_arpeggio_page <> arpeggio_page) or (old_arp_ptr <> ptr_arpeggio_table) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_ARPEGGIO; end; end; old_instr := instr; old_pos := pos; old_arp_ptr := ptr_arpeggio_table; old_vib_ptr := ptr_vibrato_table; old_fmreg_page := fmreg_page; old_arpeggio_page := arpeggio_page; old_vibrato_page := vibrato_page; refresh(refresh_flag); end; is_setting.append_enabled := TRUE; is_environment.locate_pos := 1; Case pos of (* FM_op_table table - pos: 1..7 *) 1: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.instr_macros[instr].length), xstart+17,ystart+4, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.instr_macros[instr].length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.instr_macros[instr].length < 255) then Inc(songdata.instr_macros[instr].length); kCHmins, kNPmins: If (songdata.instr_macros[instr].length > 0) then Dec(songdata.instr_macros[instr].length); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 2 else If (is_environment.keystroke = kUP) then pos := 7 else If (is_environment.keystroke = kShTAB) then If (ptr_vibrato_table <> 0) then pos := 20 else If (ptr_arpeggio_table <> 0) then pos := 13 else pos := 7; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 14 else If (ptr_arpeggio_table <> 0) then pos := 8; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 2: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.instr_macros[instr].loop_begin), xstart+17,ystart+5, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.instr_macros[instr].loop_begin := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.instr_macros[instr].loop_begin < 255) then Inc(songdata.instr_macros[instr].loop_begin); kCHmins, kNPmins: If (songdata.instr_macros[instr].loop_begin > 0) then Dec(songdata.instr_macros[instr].loop_begin); end; While NOT ((songdata.instr_macros[instr].keyoff_pos > songdata.instr_macros[instr].loop_begin+ min0(songdata.instr_macros[instr].loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 3 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 1; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 17 else If (ptr_arpeggio_table <> 0) then pos := 10; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 10 else If (ptr_vibrato_table <> 0) then pos := 17; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 3: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.instr_macros[instr].loop_length), xstart+17,ystart+6, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.instr_macros[instr].loop_length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.instr_macros[instr].loop_length < 255) then Inc(songdata.instr_macros[instr].loop_length); kCHmins, kNPmins: If (songdata.instr_macros[instr].loop_length > 0) then Dec(songdata.instr_macros[instr].loop_length); end; While NOT ((songdata.instr_macros[instr].keyoff_pos > songdata.instr_macros[instr].loop_begin+ min0(songdata.instr_macros[instr].loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 4 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 2; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 18 else If (ptr_arpeggio_table <> 0) then pos := 11; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 11 else If (ptr_vibrato_table <> 0) then pos := 18; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 4: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.instr_macros[instr].keyoff_pos), xstart+17,ystart+7, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or (Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255) and (Str2num(temps,16) > songdata.instr_macros[instr].loop_begin+ min0(songdata.instr_macros[instr].loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (Str2num(temps,16) = 0); songdata.instr_macros[instr].keyoff_pos := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos <> 0) then If (songdata.instr_macros[instr].keyoff_pos < 255) then Inc(songdata.instr_macros[instr].keyoff_pos) else else If (songdata.instr_macros[instr].loop_begin+ songdata.instr_macros[instr].loop_length <= 255) then songdata.instr_macros[instr].keyoff_pos := songdata.instr_macros[instr].loop_begin+ songdata.instr_macros[instr].loop_length; kCHmins, kNPmins: If (min0(songdata.instr_macros[instr].keyoff_pos-1,0) > songdata.instr_macros[instr].loop_begin+ min0(songdata.instr_macros[instr].loop_length-1,0)) or ((songdata.instr_macros[instr].keyoff_pos > 0) and ((songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0))) then Dec(songdata.instr_macros[instr].keyoff_pos); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 5 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 3; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 19 else If (ptr_arpeggio_table <> 0) then pos := 12; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 12 else If (ptr_vibrato_table <> 0) then pos := 19; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 5: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(ptr_arpeggio_table), xstart+17,ystart+8, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); ptr_arpeggio_table := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (ptr_arpeggio_table < 255) then Inc(ptr_arpeggio_table); kCHmins, kNPmins: If (ptr_arpeggio_table > 0) then Dec(ptr_arpeggio_table); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 6 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 4; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 14 else If (ptr_arpeggio_table <> 0) then pos := 8; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14; end; end; 6: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(ptr_vibrato_table), xstart+17,ystart+9, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); ptr_vibrato_table := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (ptr_vibrato_table < 255) then Inc(ptr_vibrato_table); kCHmins, kNPmins: If (ptr_vibrato_table > 0) then Dec(ptr_vibrato_table); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 7 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 5; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 14 else If (ptr_arpeggio_table <> 0) then pos := 8; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 7: begin GotoXY(xstart+10+fmreg_cursor_pos-1,ystart+16+(window_area_inc_y DIV 2)); is_environment.keystroke := getkey; If (HI(is_environment.keystroke) = HI(kSlashR)) then With songdata.instr_macros[instr].data[fmreg_page] do begin nope := TRUE; Case fmreg_hpos of 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator XOR $80; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator XOR $40; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator XOR $10; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator XOR $20; 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier XOR $80; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier XOR $40; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier XOR $10; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier XOR $20; 33: begin nope := FALSE; Case panning of 0: panning := 2; 1: panning := 0; 2: panning := 1; end; end else nope := FALSE; end; If nope then If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT shift_pressed then If (ptr_vibrato_table <> 0) then pos := 20 else If (ptr_arpeggio_table <> 0) then pos := 13 else else If (fmreg_page > songdata.instr_macros[instr].length) then fmreg_page := min(1,songdata.instr_macros[instr].length) else fmreg_page := 1; kCtRGHT: If NOT shift_pressed then If (ptr_arpeggio_table <> 0) then pos := 13 else If (ptr_vibrato_table <> 0) then pos := 20 else else If (fmreg_page < songdata.instr_macros[instr].length) then fmreg_page := min(1,songdata.instr_macros[instr].length) else fmreg_page := 255; kUP: If (fmreg_page > 1) then Dec(fmreg_page) else If cycle_pattern then fmreg_page := 255; kDOWN: If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; kPgUP: If (fmreg_page > 16) then Dec(fmreg_page,16) else fmreg_page := 1; kPgDOWN: If (fmreg_page+16 < 255) then Inc(fmreg_page,16) else fmreg_page := 255; kHOME: If NOT shift_pressed then fmreg_page := 1 else begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kEND: If NOT shift_pressed then fmreg_page := 255 else begin fmreg_hpos := 35; fmreg_cursor_pos := max(57,31+window_area_inc_x); fmreg_left_margin := min(pos5[fmreg_hpos]-(31+window_area_inc_x)+1,1); end; kNPHOME: If shift_pressed then begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kNPEND: If shift_pressed then begin fmreg_hpos := 35; fmreg_cursor_pos := max(57,31+window_area_inc_x); fmreg_left_margin := min(pos5[fmreg_hpos]-(31+window_area_inc_x)+1,1); end; kLEFT: If (fmreg_hpos > 1) then begin Dec(fmreg_hpos); _scroll_cur_left; end else If cycle_pattern then begin fmreg_hpos := 35; fmreg_cursor_pos := max(57,31+window_area_inc_x); fmreg_left_margin := min(pos5[fmreg_hpos]-(31+window_area_inc_x)+1,1); end; kRIGHT: If (fmreg_hpos < 35) then begin Inc(fmreg_hpos); _scroll_cur_right; end else If cycle_pattern then begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kTAB: If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1; kShTAB: pos := 6; kENTER: If NOT shift_pressed then begin If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1; end else call_pickup_proc2 := TRUE; kCtrlC: begin If NOT shift_pressed then clipboard.object_type := objMacroTableLine else clipboard.object_type := objMacroTableColumn; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: begin paste_object; If (clipboard.object_type = objMacroTableLine) and (clipboard.mcrtab_type = mttFM_reg_table) then If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kAltC: If ctrl_pressed and (fmreg_hpos in [1..13]) then For temp := 1 to 255 do With songdata.instr_macros[instr].data[temp] do Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := (fm_data.ATTCK_DEC_carrier SHR 4) SHL 4+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ (fm_data.ATTCK_DEC_carrier AND $0f); 3: fm_data.SUSTN_REL_modulator := (fm_data.SUSTN_REL_carrier SHR 4) SHL 4+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ (fm_data.SUSTN_REL_carrier AND $0f); 5: fm_data.WAVEFORM_modulator := fm_data.WAVEFORM_carrier; 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0+ (fm_data.KSL_VOLUM_carrier AND $3f); 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ (fm_data.KSL_VOLUM_carrier SHR 6) SHL 6; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ (fm_data.AM_VIB_EG_carrier AND $0f); 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f+ (fm_data.AM_VIB_EG_carrier SHR 7) SHL 7; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf+ (fm_data.AM_VIB_EG_carrier SHR 6 AND 1) SHL 6; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef+ (fm_data.AM_VIB_EG_carrier SHR 4 AND 1) SHL 4; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df+ (fm_data.AM_VIB_EG_carrier SHR 5 AND 1) SHL 5; end; kAltM: If ctrl_pressed and (fmreg_hpos in [14..26]) then For temp := 1 to 255 do With songdata.instr_macros[instr].data[temp] do Case fmreg_hpos of 14: fm_data.ATTCK_DEC_carrier := (fm_data.ATTCK_DEC_modulator SHR 4) SHL 4+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ (fm_data.ATTCK_DEC_modulator AND $0f); 16: fm_data.SUSTN_REL_carrier := (fm_data.SUSTN_REL_modulator SHR 4) SHL 4+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ (fm_data.SUSTN_REL_modulator AND $0f); 18: fm_data.WAVEFORM_carrier := fm_data.WAVEFORM_modulator; 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0+ (fm_data.KSL_VOLUM_modulator AND $3f); 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ (fm_data.KSL_VOLUM_modulator SHR 6) SHL 6; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ (fm_data.AM_VIB_EG_modulator AND $0f); 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f+ (fm_data.AM_VIB_EG_modulator SHR 7) SHL 7; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf+ (fm_data.AM_VIB_EG_modulator SHR 6 AND 1) SHL 6; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef+ (fm_data.AM_VIB_EG_modulator SHR 4 AND 1) SHL 4; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df+ (fm_data.AM_VIB_EG_modulator SHR 5 AND 1) SHL 5; end; kCtrlE: begin If (songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM OR MACRO_ENVELOPE_RESTART_FLAG <> songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f + MACRO_ENVELOPE_RESTART_FLAG else songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kCtrlN: begin If (songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM OR MACRO_NOTE_RETRIG_FLAG <> songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f + MACRO_NOTE_RETRIG_FLAG else songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kCtrlZ: begin If (songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM OR MACRO_ZERO_FREQ_FLAG <> songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f + MACRO_ZERO_FREQ_FLAG else songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kAltE: If ctrl_pressed then For temp := 1 to 255 do If (songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM OR MACRO_ENVELOPE_RESTART_FLAG = songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM AND $1f; kAltN: If ctrl_pressed then For temp := 1 to 255 do If (songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM OR MACRO_NOTE_RETRIG_FLAG = songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM AND $1f; kAltZ: If ctrl_pressed then For temp := 1 to 255 do If (songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM OR MACRO_ZERO_FREQ_FLAG = songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM AND $1f; kCtENTR: If NOT shift_pressed then begin temp := songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM; songdata.instr_macros[instr].data[fmreg_page].fm_data := songdata.instr_data[instr].fm_data; songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM := temp AND $0c0+ songdata.instr_data[instr].fm_data.FEEDBACK_FM; songdata.instr_macros[instr].data[fmreg_page].panning := songdata.instr_data[instr].panning; songdata.instr_macros[instr].data[fmreg_page].duration := min(songdata.instr_macros[instr].data[fmreg_page].duration,1); With songdata.instr_macros[instr].data[fmreg_page].fm_data do begin KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $c0+ 63-KSL_VOLUM_modulator AND $3f; KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $c0+ 63-KSL_VOLUM_carrier AND $3f; end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end else call_pickup_proc := TRUE; kINSERT: begin For temp := 255-1 downto fmreg_page do begin songdata.instr_macros[instr].data[SUCC(temp)] := songdata.instr_macros[instr].data[temp] end; FillChar(songdata.instr_macros[instr].data[fmreg_page], SizeOf(songdata.instr_macros[instr].data[fmreg_page]),0); end; kDELETE: begin For temp := fmreg_page to 255-1 do begin songdata.instr_macros[instr].data[temp] := songdata.instr_macros[instr].data[SUCC(temp)] end; FillChar(songdata.instr_macros[instr].data[255], SizeOf(songdata.instr_macros[instr].data[255]),0); end; kCHplus, kNPplus: With songdata.instr_macros[instr].data[fmreg_page] do Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := _inc(fm_data.ATTCK_DEC_modulator SHR 4,15) SHL 4+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ _inc(fm_data.ATTCK_DEC_modulator AND $0f,15); 3: fm_data.SUSTN_REL_modulator := _inc(fm_data.SUSTN_REL_modulator SHR 4,15) SHL 4+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ _inc(fm_data.SUSTN_REL_modulator AND $0f,15); 5: fm_data.WAVEFORM_modulator := _inc(fm_data.WAVEFORM_modulator,7); 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0+ _inc(fm_data.KSL_VOLUM_modulator AND $3f,63); 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ _inc(fm_data.KSL_VOLUM_modulator SHR 6,3) SHL 6; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ _inc(fm_data.AM_VIB_EG_modulator AND $0f,15); 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f+ _inc(fm_data.AM_VIB_EG_modulator SHR 7,1) SHL 7; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf+ _inc(fm_data.AM_VIB_EG_modulator SHR 6 AND 1,1) SHL 6; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef+ _inc(fm_data.AM_VIB_EG_modulator SHR 4 AND 1,1) SHL 4; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df+ _inc(fm_data.AM_VIB_EG_modulator SHR 5 AND 1,1) SHL 5; 14: fm_data.ATTCK_DEC_carrier := _inc(fm_data.ATTCK_DEC_carrier SHR 4,15) SHL 4+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ _inc(fm_data.ATTCK_DEC_carrier AND $0f,15); 16: fm_data.SUSTN_REL_carrier := _inc(fm_data.SUSTN_REL_carrier SHR 4,15) SHL 4+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ _inc(fm_data.SUSTN_REL_carrier AND $0f,15); 18: fm_data.WAVEFORM_carrier := _inc(fm_data.WAVEFORM_carrier,7); 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0+ _inc(fm_data.KSL_VOLUM_carrier AND $3f,63); 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ _inc(fm_data.KSL_VOLUM_carrier SHR 6,3) SHL 6; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ _inc(fm_data.AM_VIB_EG_carrier AND $0f,15); 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f+ _inc(fm_data.AM_VIB_EG_carrier SHR 7,1) SHL 7; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf+ _inc(fm_data.AM_VIB_EG_carrier SHR 6 AND 1,1) SHL 6; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef+ _inc(fm_data.AM_VIB_EG_carrier SHR 4 AND 1,1) SHL 4; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df+ _inc(fm_data.AM_VIB_EG_carrier SHR 5 AND 1,1) SHL 5; 27: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0fe+ _inc(fm_data.FEEDBACK_FM AND 1,1); 28: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND 1+ _inc(fm_data.FEEDBACK_FM SHR 1,7) SHL 1; 29,30,31, 32: freq_slide := _inc(freq_slide,1023); 33: Case panning of 0: panning := 2; 1: panning := 0; end; 34, 35: duration := _inc(duration,255); end; kCHmins, kNPmins: With songdata.instr_macros[instr].data[fmreg_page] do Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := _dec(fm_data.ATTCK_DEC_modulator SHR 4,0) SHL 4+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ _dec(fm_data.ATTCK_DEC_modulator AND $0f,0); 3: fm_data.SUSTN_REL_modulator := _dec(fm_data.SUSTN_REL_modulator SHR 4,0) SHL 4+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ _dec(fm_data.SUSTN_REL_modulator AND $0f,0); 5: fm_data.WAVEFORM_modulator := _dec(fm_data.WAVEFORM_modulator,0); 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0+ _dec(fm_data.KSL_VOLUM_modulator AND $3f,0); 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ _dec(fm_data.KSL_VOLUM_modulator SHR 6,0) SHL 6; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ _dec(fm_data.AM_VIB_EG_modulator AND $0f,0); 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f+ _dec(fm_data.AM_VIB_EG_modulator SHR 7,0) SHL 7; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf+ _dec(fm_data.AM_VIB_EG_modulator SHR 6 AND 1,0) SHL 6; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef+ _dec(fm_data.AM_VIB_EG_modulator SHR 4 AND 1,0) SHL 4; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df+ _dec(fm_data.AM_VIB_EG_modulator SHR 5 AND 1,0) SHL 5; 14: fm_data.ATTCK_DEC_carrier := _dec(fm_data.ATTCK_DEC_carrier SHR 4,0) SHL 4+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ _dec(fm_data.ATTCK_DEC_carrier AND $0f,0); 16: fm_data.SUSTN_REL_carrier := _dec(fm_data.SUSTN_REL_carrier SHR 4,0) SHL 4+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ _dec(fm_data.SUSTN_REL_carrier AND $0f,0); 18: fm_data.WAVEFORM_carrier := _dec(fm_data.WAVEFORM_carrier,0); 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0+ _dec(fm_data.KSL_VOLUM_carrier AND $3f,0); 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ _dec(fm_data.KSL_VOLUM_carrier SHR 6,0) SHL 6; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ _dec(fm_data.AM_VIB_EG_carrier AND $0f,0); 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f+ _dec(fm_data.AM_VIB_EG_carrier SHR 7,0) SHL 7; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf+ _dec(fm_data.AM_VIB_EG_carrier SHR 6 AND 1,0) SHL 6; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef+ _dec(fm_data.AM_VIB_EG_carrier SHR 4 AND 1,0) SHL 4; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df+ _dec(fm_data.AM_VIB_EG_carrier SHR 5 AND 1,0) SHL 5; 27: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0fe+ _dec(fm_data.FEEDBACK_FM AND 1,0); 28: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND 1+ _dec(fm_data.FEEDBACK_FM SHR 1,0) SHL 1; 29,30,31, 32: freq_slide := _dec(freq_slide,-1023); 33: Case panning of 0: panning := 1; 2: panning := 0; end; 34, 35: duration := _dec(duration,0); end; kBkSPC: If NOT shift_pressed then With songdata.instr_macros[instr].data[fmreg_page] do begin Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0; 3: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0; 5: fm_data.WAVEFORM_modulator := 0; 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0; 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0; 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df; 14: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0; 16: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0; 18: fm_data.WAVEFORM_carrier := 0; 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0; 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0; 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df; 27: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0fe; 28: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0c1; 29,30,31, 32: freq_slide := 0; 33: panning := 0; 34, 35: duration := 0; end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end else begin FillChar(songdata.instr_macros[instr].data[fmreg_page].fm_data, SizeOf(songdata.instr_macros[instr].data[fmreg_page].fm_data),0); songdata.instr_macros[instr].data[fmreg_page].freq_slide := 0; songdata.instr_macros[instr].data[fmreg_page].panning := 0; songdata.instr_macros[instr].data[fmreg_page].duration := 0; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kCtBkSp: Case fmreg_hpos of 1,2,3,4, 5: songdata.dis_fmreg_col[instr][fmreg_hpos-1] := NOT songdata.dis_fmreg_col[instr][fmreg_hpos-1]; 6, 7: songdata.dis_fmreg_col[instr][5] := NOT songdata.dis_fmreg_col[instr][5]; 8,9,10,11,12,13, 14,15,16,17, 18: songdata.dis_fmreg_col[instr][fmreg_hpos-2] := NOT songdata.dis_fmreg_col[instr][fmreg_hpos-2]; 19, 20: songdata.dis_fmreg_col[instr][17] := NOT songdata.dis_fmreg_col[instr][17]; 21,22,23,24, 25,26,27, 28: songdata.dis_fmreg_col[instr][fmreg_hpos-3] := NOT songdata.dis_fmreg_col[instr][fmreg_hpos-3]; 29,30,31, 32: songdata.dis_fmreg_col[instr][26] := NOT songdata.dis_fmreg_col[instr][26]; 33: songdata.dis_fmreg_col[instr][27] := NOT songdata.dis_fmreg_col[instr][27]; end; kAltS: Case fmreg_hpos of 1,2,3,4, 5: For temp := 0 to 27 do If (temp <> fmreg_hpos-1) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 6, 7: For temp := 0 to 27 do If (temp <> 5) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 8,9,10,11,12,13, 14,15,16,17, 18: For temp := 0 to 27 do If (temp <> fmreg_hpos-2) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 19, 20: For temp := 0 to 27 do If (temp <> 17) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 21,22,23,24, 25,26,27, 28: For temp := 0 to 27 do If (temp <> fmreg_hpos-3) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 29,30,31, 32: For temp := 0 to 27 do If (temp <> 26) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 33: For temp := 0 to 27 do If (temp <> 27) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; end; kAltR: For temp := 0 to 27 do songdata.dis_fmreg_col[instr][temp] := FALSE; kAstrsk, kNPastr: For temp := 0 to 27 do songdata.dis_fmreg_col[instr][temp] := NOT songdata.dis_fmreg_col[instr][temp]; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['0'..'9','A'..'F']) and NOT shift_pressed then With songdata.instr_macros[instr].data[fmreg_page] do begin nope := TRUE; Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := hex(CHAR(LO(is_environment.keystroke))) SHL 4+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 3: fm_data.SUSTN_REL_modulator := hex(CHAR(LO(is_environment.keystroke))) SHL 4+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 5: If (hex(CHAR(LO(is_environment.keystroke))) <= 7) then fm_data.WAVEFORM_modulator := hex(CHAR(LO(is_environment.keystroke))) else nope := FALSE; 6: If (hex(CHAR(LO(is_environment.keystroke))) <= 3) then fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0cf+ hex(CHAR(LO(is_environment.keystroke))) SHL 4 else nope := FALSE; 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 8: If (hex(CHAR(LO(is_environment.keystroke))) <= 3) then fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ hex(CHAR(LO(is_environment.keystroke))) SHL 6 else nope := FALSE; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 14: fm_data.ATTCK_DEC_carrier := hex(CHAR(LO(is_environment.keystroke))) SHL 4+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 16: fm_data.SUSTN_REL_carrier := hex(CHAR(LO(is_environment.keystroke))) SHL 4+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 18: If (hex(CHAR(LO(is_environment.keystroke))) <= 7) then fm_data.WAVEFORM_carrier := hex(CHAR(LO(is_environment.keystroke))) else nope := FALSE; 19: If (hex(CHAR(LO(is_environment.keystroke))) <= 3) then fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0cf+ hex(CHAR(LO(is_environment.keystroke))) SHL 4 else nope := FALSE; 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 21: If (hex(CHAR(LO(is_environment.keystroke))) <= 3) then fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ hex(CHAR(LO(is_environment.keystroke))) SHL 6 else nope := FALSE; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 27: If (hex(CHAR(LO(is_environment.keystroke))) <= 1) then fm_data.FEEDBACK_FM := hex(CHAR(LO(is_environment.keystroke)))+ fm_data.FEEDBACK_FM AND $0fe else nope := FALSE; 28: If (hex(CHAR(LO(is_environment.keystroke))) <= 7) then fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0c1+ hex(CHAR(LO(is_environment.keystroke))) SHL 1 else nope := FALSE; 30: If (freq_slide > 0) or ((freq_slide = 0) and (songdata.instr_macros[instr].data[min(fmreg_page-1,1)].freq_slide >= 0)) then freq_slide := freq_slide AND $0ff+ hex(CHAR(LO(is_environment.keystroke))) SHL 8 else freq_slide := -(Abs(freq_slide) AND $0ff+ hex(CHAR(LO(is_environment.keystroke))) SHL 8); 31: If (freq_slide > 0) or ((freq_slide = 0) and (songdata.instr_macros[instr].data[min(fmreg_page-1,1)].freq_slide >= 0)) then freq_slide := freq_slide AND $0f0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4 else freq_slide := -(Abs(freq_slide) AND $0f0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4); 32: If (freq_slide > 0) or ((freq_slide = 0) and (songdata.instr_macros[instr].data[min(fmreg_page-1,1)].freq_slide >= 0)) then freq_slide := freq_slide AND $0ff0+ hex(CHAR(LO(is_environment.keystroke))) else freq_slide := -(Abs(freq_slide) AND $0ff0+ hex(CHAR(LO(is_environment.keystroke)))); 34: duration := duration AND $0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4; 35: duration := duration AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); else nope := FALSE; end; If nope then Case fmreg_hpos of 6,19,30,31, 34: If NOT (command_typing = 2) then begin If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end else begin Inc(fmreg_hpos); _scroll_cur_right; end; 7,20,32, 35: begin If (command_typing = 2) then begin If (fmreg_hpos <> 32) then Dec(fmreg_hpos) else Dec(fmreg_hpos,2); _scroll_cur_left; end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; else If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['L','C','R']) and NOT shift_pressed then With songdata.instr_macros[instr].data[fmreg_page] do begin nope := TRUE; Case fmreg_hpos of 33: Case UpCase(CHAR(LO(is_environment.keystroke))) of 'L': panning := 1; 'C': panning := 0; 'R': panning := 2; end; else nope := FALSE; end; If nope then If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['+','-']) and (fmreg_hpos = 29) then With songdata.instr_macros[instr].data[fmreg_page] do begin Case UpCase(CHAR(LO(is_environment.keystroke))) of '+': freq_slide := Abs(freq_slide); '-': freq_slide := -Abs(freq_slide); end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; If shift_pressed and ((is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN)) then begin If (ptr_arpeggio_table <> 0) then arpeggio_page := fmreg_page; If (ptr_vibrato_table <> 0) then vibrato_page := fmreg_page; end; end; (* Arpeggio table - pos: 8..13 *) 8: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length), xstart+60+window_area_inc_x,ystart+4, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_arpeggio_table]. arpeggio.length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.length < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.length > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 9 else If (is_environment.keystroke = kUP) then pos := 13 else If (is_environment.keystroke = kShTAB) then If NOT arp_vib_mode then pos := 7 else pos := 20; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 1 else pos := 14; kCtRGHT: If arp_vib_mode then pos := 14 else If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 9: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed), xstart+60+window_area_inc_x,ystart+5, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 10 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 8; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 1 else pos := 15; kCtRGHT: If arp_vib_mode then pos := 15 else If (ptr_vibrato_table <> 0) then pos := 15 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 10: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin), xstart+60+window_area_inc_x,ystart+6, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin); end; While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 11 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 9; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 2 else pos := 17; kCtRGHT: If arp_vib_mode then pos := 17 else If (ptr_vibrato_table <> 0) then pos := 17 else pos := 2; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 11: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length), xstart+60+window_area_inc_x,ystart+7, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length); end; While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 12 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 10; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 3 else pos := 18; kCtRGHT: If arp_vib_mode then pos := 18 else If (ptr_vibrato_table <> 0) then pos := 18 else pos := 3; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 12: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos), xstart+60+window_area_inc_x,ystart+8, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or (Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255) and (Str2num(temps,16) > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (Str2num(temps,16) = 0); songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos <> 0) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length <= 255) then songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos := songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length; kCHmins, kNPmins: If (min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos-1,0) > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > 0) and ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0))) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 13 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 11; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 4 else pos := 19; kCtRGHT: If arp_vib_mode then pos := 19 else If (ptr_vibrato_table <> 0) then pos := 19 else pos := 4; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 13: begin GotoXY(xstart+55+window_area_inc_x,ystart+16+(window_area_inc_y DIV 2)); is_environment.keystroke := getkey; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT shift_pressed then If NOT arp_vib_mode then pos := 7 else pos := 20 else If (arpeggio_page > songdata.macro_table[ptr_arpeggio_table].arpeggio.length) then arpeggio_page := min(1,songdata.macro_table[ptr_arpeggio_table].arpeggio.length) else arpeggio_page := 1; kCtRGHT: If NOT shift_pressed then If NOT arp_vib_mode then If (ptr_vibrato_table <> 0) then pos := 20 else pos := 7 else pos := 20 else If (arpeggio_page < songdata.macro_table[ptr_arpeggio_table].arpeggio.length) then arpeggio_page := min(1,songdata.macro_table[ptr_arpeggio_table].arpeggio.length) else arpeggio_page := 255; kUP: If (arpeggio_page > 1) then Dec(arpeggio_page) else If cycle_pattern then arpeggio_page := 255; kDOWN: If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; kPgUP: If (arpeggio_page > 16) then Dec(arpeggio_page,16) else arpeggio_page := 1; kPgDOWN: If (arpeggio_page+16 < 255) then Inc(arpeggio_page,16) else arpeggio_page := 255; kHOME: arpeggio_page := 1; kEND: arpeggio_page := 255; kENTER,kTAB: If NOT arp_vib_mode then If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1 else pos := 14; kShTAB: pos := 12; kCtrlC: begin If NOT shift_pressed then clipboard.object_type := objMacroTableLine else clipboard.object_type := objMacroTableColumn; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: begin paste_object; If (clipboard.object_type = objMacroTableLine) and (clipboard.mcrtab_type = mttArpeggio_table) then If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end; kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] < $80) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] < 96) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] < $80+96+1) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] < $80) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] > 1) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] > $80+1) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]); kBkSPC: begin songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := 0; If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end; kINSERT: begin For temp := 255-1 downto arpeggio_page do begin songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[SUCC(temp)] := songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] end; FillChar(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page], SizeOf(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]),0); end; kDELETE: begin For temp := arpeggio_page to 255-1 do begin songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] := songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[SUCC(temp)] end; FillChar(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[255], SizeOf(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[255]),0); end; end; If shift_pressed and ((is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN)) then begin fmreg_page := arpeggio_page; If (ptr_vibrato_table <> 0) then vibrato_page := arpeggio_page; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['A',UpCase(b_note),'C'..'G']) and NOT shift_pressed then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['1'..'9','a',b_note,'c'..'g', 'A',UpCase(b_note),'C'..'F','#','-']; is_environment.locate_pos := 2; tstr := CHAR(LO(is_environment.keystroke)); Repeat tstr := InputStr(tstr,xstart+55+window_area_inc_x,ystart+16+(window_area_inc_y DIV 2),3,3, macro_input_bckg+macro_input, macro_def_bckg+macro_def); is_setting.append_enabled := TRUE; If (UpCase(tstr[1]) in ['+','0'..'9','A',UpCase(b_note),'C'..'G']) and ((is_environment.keystroke = kENTER) or (is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB)) then begin nope := FALSE; If (tstr[1] = '+') then Delete(tstr,1,1); If (tstr[1] in ['0'..'9']) and (Str2num(tstr,10) >= 0) and (Str2num(tstr,10) <= 96) then begin nope := TRUE; songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := Str2num(tstr,10); If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end else begin If (Length(tstr) = 2) then If tstr[2] in ['1'..'9'] then Insert('-',tstr,2) else If tstr[2] in ['-','#'] then tstr := tstr + Num2str(current_octave,10); If (Length(tstr) = 1) then tstr := tstr + '-' + Num2str(current_octave,10); For temp1 := 1 to 12*8+1 do If (Upper(tstr) = note_layout[temp1]) then begin nope := TRUE; songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := $80+temp1; BREAK; end; If NOT nope and (Length(tstr) = 2) then For temp1 := 1 to 12*8+1 do If (Copy(Upper(tstr),1,2) = Copy(note_layout[temp1],1,2)) then begin nope := TRUE; songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := $80+temp1; BREAK; end; If nope then Case is_environment.keystroke of kUP: If (arpeggio_page > 1) then Dec(arpeggio_page) else If cycle_pattern then arpeggio_page := 255; kDOWN, kENTER: If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end; If NOT nope then Case songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] of 0: tstr := '+0'; 1..96: tstr := '+'+Num2str(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page],10); $80..$80+12*8+1: tstr := note_layout[songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]-$80]; end; end; end; until (nope or (is_environment.keystroke = kESC)) and ((is_environment.keystroke = kESC) or (is_environment.keystroke = kENTER) or (is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB)); nope := FALSE; Case is_environment.keystroke of kTAB: If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1; kShTAB: pos := 12; kESC: is_environment.keystroke := kENTER; end; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['+','0'..'9']) and NOT shift_pressed then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['+','0'..'9']; is_environment.locate_pos := 2; tstr := CHAR(LO(is_environment.keystroke)); If (CHAR(LO(is_environment.keystroke)) <> '+') then begin tstr := '+'+tstr; Inc(is_environment.locate_pos); end; Repeat tstr := InputStr(tstr,xstart+55+window_area_inc_x,ystart+16+(window_area_inc_y DIV 2),3,3, macro_input_bckg+macro_input, macro_def_bckg+macro_def); is_setting.append_enabled := TRUE; temps := tstr; If ((is_environment.keystroke = kENTER) or (is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB)) then begin nope := FALSE; If (tstr[1] = '+') then Delete(tstr,1,1); If (tstr[1] in ['0'..'9']) and (Str2num(tstr,10) >= 0) and (Str2num(tstr,10) <= 96) then begin nope := TRUE; songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := Str2num(tstr,10); end else tstr := temps; If nope then Case is_environment.keystroke of kUP: If (arpeggio_page > 1) then Dec(arpeggio_page) else If cycle_pattern then arpeggio_page := 255; kDOWN, kENTER: If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end; If NOT nope then Case songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] of 0: tstr := '+0'; 1..96: tstr := '+'+Num2str(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page],10); $80..$80+12*8+1: tstr := note_layout[songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]-$80]; end; end; until (nope or (is_environment.keystroke = kESC)) and ((is_environment.keystroke = kESC) or (is_environment.keystroke = kENTER) or (is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB)); nope := FALSE; Case is_environment.keystroke of kTAB: If NOT arp_vib_mode then If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1 else pos := 14; kShTAB: pos := 12; kESC: is_environment.keystroke := kENTER; end; end; end; (* Vibrato table - pos: 14..20 *) 14: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.length), xstart+77+window_area_inc_x,ystart+4, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.length < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.length); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.length > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.length); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 15 else If (is_environment.keystroke = kUP) then pos := 20 else If (is_environment.keystroke = kShTAB) then If NOT arp_vib_mode then If (ptr_arpeggio_table <> 0) then pos := 13 else pos := 7 else pos := 13; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 8 else If (ptr_arpeggio_table <> 0) then pos := 8 else pos := 1; kCtRGHT: If arp_vib_mode then pos := 8 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 15: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.speed), xstart+77+window_area_inc_x,ystart+5, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.speed := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.speed < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.speed); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.speed > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.speed); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 16 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 14; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 9 else If (ptr_arpeggio_table <> 0) then pos := 9 else pos := 1; kCtRGHT: If arp_vib_mode then pos := 9 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 16: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.delay), xstart+77+window_area_inc_x,ystart+6, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.delay := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.delay < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.delay); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.delay > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.delay); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 17 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 15; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 8 else If (ptr_arpeggio_table <> 0) then pos := 8 else pos := 1; kCtRGHT: If arp_vib_mode then pos := 8 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 17: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin), xstart+77+window_area_inc_x,ystart+7, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin); end; While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 18 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 16; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 10 else If (ptr_arpeggio_table <> 0) then pos := 10 else pos := 2; kCtRGHT: If arp_vib_mode then pos := 10 else pos := 2; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 18: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length), xstart+77+window_area_inc_x,ystart+8, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length); end; While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 19 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 17; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 11 else If (ptr_arpeggio_table <> 0) then pos := 11 else pos := 3; kCtRGHT: If arp_vib_mode then pos := 11 else pos := 3; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 19: begin is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos), xstart+77+window_area_inc_x,ystart+9, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or (Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255) and (Str2num(temps,16) > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (Str2num(temps,16) = 0); songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos <> 0) then If (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length <= 255) then songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos := songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length; kCHmins, kNPmins: If (min0(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos-1,0) > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > 0) and ((songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0))) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 20 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 18; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 12 else If (ptr_arpeggio_table <> 0) then pos := 12 else pos := 4; kCtRGHT: If arp_vib_mode then pos := 12 else pos := 4; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 20: begin GotoXY(xstart+72+vibrato_hpos-1+window_area_inc_x,ystart+16+(window_area_inc_y DIV 2)); is_environment.keystroke := getkey; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT shift_pressed then If NOT arp_vib_mode then If (ptr_arpeggio_table <> 0) then pos := 13 else pos := 7 else pos := 13 else If (vibrato_page > songdata.macro_table[ptr_vibrato_table].vibrato.length) then vibrato_page := min(1,songdata.macro_table[ptr_vibrato_table].vibrato.length) else vibrato_page := 1; kCtRGHT: If NOT shift_pressed then If NOT arp_vib_mode then pos := 7 else pos := 13 else If (vibrato_page < songdata.macro_table[ptr_vibrato_table].vibrato.length) then vibrato_page := min(1,songdata.macro_table[ptr_vibrato_table].vibrato.length) else vibrato_page := 255; kUP: If (vibrato_page > 1) then Dec(vibrato_page) else If cycle_pattern then vibrato_page := 255; kDOWN: If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; kPgUP: If (vibrato_page > 16) then Dec(vibrato_page,16) else vibrato_page := 1; kPgDOWN: If (vibrato_page+16 < 255) then Inc(vibrato_page,16) else vibrato_page := 255; kHOME: vibrato_page := 1; kEND: vibrato_page := 255; kLEFT: If (vibrato_hpos > 1) then Dec(vibrato_hpos) else vibrato_hpos := 3; kRIGHT: If (vibrato_hpos < 3) then Inc(vibrato_hpos) else vibrato_hpos := 1; kENTER,kTAB: If NOT arp_vib_mode then pos := 1 else pos := 8; kShTAB: pos := 19; kCtrlC: begin If NOT shift_pressed then clipboard.object_type := objMacroTableLine else clipboard.object_type := objMacroTableColumn; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: begin paste_object; If (clipboard.object_type = objMacroTableLine) and (clipboard.mcrtab_type = mttVibrato_table) then If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; end; kBkSPC: begin songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page] := 0; If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; end; kINSERT: begin For temp := 255-1 downto vibrato_page do begin songdata.macro_table[ptr_vibrato_table]. vibrato.data[SUCC(temp)] := songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp] end; FillChar(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page], SizeOf(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page]),0); end; kDELETE: begin For temp := vibrato_page to 255-1 do begin songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp] := songdata.macro_table[ptr_vibrato_table]. vibrato.data[SUCC(temp)] end; FillChar(songdata.macro_table[ptr_vibrato_table]. vibrato.data[255], SizeOf(songdata.macro_table[ptr_vibrato_table]. vibrato.data[255]),0); end; end; If shift_pressed and ((is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN)) then begin fmreg_page := vibrato_page; If (ptr_arpeggio_table <> 0) then arpeggio_page := vibrato_page; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['0'..'9','A'..'F','+','-']) then With songdata.macro_table[ptr_vibrato_table].vibrato do begin nope := TRUE; Case vibrato_hpos of 1: Case UpCase(CHAR(LO(is_environment.keystroke))) of '+': data[vibrato_page] := Abs(data[vibrato_page]); '-': data[vibrato_page] := -Abs(data[vibrato_page]); else nope := FALSE; end; 2: Case UpCase(CHAR(LO(is_environment.keystroke))) of '0'..'7': If (data[vibrato_page] > 0) or ((data[vibrato_page] = 0) and (data[min(vibrato_page-1,1)] >= 0)) then data[vibrato_page] := data[vibrato_page] AND $0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4 else data[vibrato_page] := -(Abs(data[vibrato_page]) AND $0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4); '8'..'F': If (data[vibrato_page] > 0) or ((data[vibrato_page] = 0) and (data[min(vibrato_page-1,1)] >= 0)) then data[vibrato_page] := $7f else data[vibrato_page] := -$7f; '+': begin If (data[vibrato_page] < $7f) then Inc(data[vibrato_page]); nope := FALSE; end; '-': begin If (data[vibrato_page] > -$7f) then Dec(data[vibrato_page]); nope := FALSE; end; end; 3: Case UpCase(CHAR(LO(is_environment.keystroke))) of '0'..'9', 'A'..'F': If (data[vibrato_page] > 0) or ((data[vibrato_page] = 0) and (data[min(vibrato_page-1,1)] >= 0)) then data[vibrato_page] := data[vibrato_page] AND $0f0+ hex(CHAR(LO(is_environment.keystroke))) else data[vibrato_page] := -(Abs(data[vibrato_page]) AND $0f0+ hex(CHAR(LO(is_environment.keystroke)))); '+': begin If (data[vibrato_page] < $7f) then Inc(data[vibrato_page]); nope := FALSE; end; '-': begin If (data[vibrato_page] > -$7f) then Dec(data[vibrato_page]); nope := FALSE; end; end; end; If nope then Case vibrato_hpos of 1,3: begin If (command_typing = 2) and NOT (UpCase(CHAR(LO(is_environment.keystroke))) in ['-','+']) and (vibrato_hpos = 3) then Dec(vibrato_hpos); If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; end; 2: If NOT (command_typing = 2) or (UpCase(CHAR(LO(is_environment.keystroke))) in ['-','+']) then begin If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; end else Inc(vibrato_hpos); end; end; end; end; If NOT shift_pressed and (is_environment.keystroke = kSPACE) then begin refresh(0); HideCursor; _pip_dest := screen_ptr; If (get_4op_to_test <> 0) then _macro_preview_init(1,BYTE(NOT BYTE_NULL)) else _macro_preview_init(1,BYTE_NULL); If ctrl_pressed and (is_environment.keystroke = kSPACE) then begin _pip_loop := TRUE; For temp := 1 to 20 do keyoff_loop[temp] := _pip_loop; end else For temp := 1 to 20 do keyoff_loop[temp] := _pip_loop; macro_preview_indic_proc := _preview_indic_proc; is_environment.keystroke := WORD_NULL; If NOT _force_program_quit then Repeat // update octave For temp := 1 to 8 do If (temp <> current_octave) then show_str(30+temp,30,CHR(48+temp), main_background+main_stat_line) else show_str(30+temp,30,CHR(48+temp), main_background+main_hi_stat_line); If keypressed then begin is_environment.keystroke := getkey; Case is_environment.keystroke of kF7: For temp := 1 to 20 do reset_chan_data(temp); kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; reset_player; end else If (current_inst > 1) then begin Dec(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); STATUS_LINE_refresh; reset_player; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; reset_player; end else If (current_inst < 255) then begin Inc(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); STATUS_LINE_refresh; reset_player; end; kAlt0: FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); kAlt1: If shift_pressed then _set_operator_flag(1,TRUE) else _set_operator_flag(1,FALSE); kAlt2: If shift_pressed then _set_operator_flag(2,TRUE) else _set_operator_flag(2,FALSE); kAlt3: If shift_pressed then _set_operator_flag(3,TRUE) else _set_operator_flag(3,FALSE); kAlt4: If shift_pressed then _set_operator_flag(4,TRUE) else _set_operator_flag(4,FALSE); end; If (is_environment.keystroke = kCtLbr) or (is_environment.keystroke = kCtRbr) or (is_environment.keystroke = kAlt0) or (is_environment.keystroke = kAlt1) or (is_environment.keystroke = kAlt2) or (is_environment.keystroke = kAlt3) or (is_environment.keystroke = kAlt4) then begin keyboard_reset_buffer; If NOT arp_vib_mode then begin songdata.instr_macros[instr].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[instr].vibrato_table := ptr_vibrato_table; end; If (get_4op_to_test <> 0) then _macro_preview_init(0,BYTE(NOT BYTE_NULL)) else _macro_preview_init(0,BYTE_NULL); instr := current_inst; If NOT arp_vib_mode then begin ptr_arpeggio_table := songdata.instr_macros[instr].arpeggio_table; ptr_vibrato_table := songdata.instr_macros[instr].vibrato_table; end; If arp_vib_mode and (pos < 8) then pos := 8 else If NOT arp_vib_mode and (((ptr_arpeggio_table = 0) and (pos in [8..13])) or ((ptr_vibrato_table = 0) and (pos in [14..20]))) then pos := 1; If NOT arp_vib_mode then ShowStr(centered_frame_vdest,xstart+54+(window_area_inc_x DIV 2),ystart, byte2hex(instr),macro_background+dialog_title) else ShowStr(centered_frame_vdest,xstart+57+(window_area_inc_x DIV 2),ystart, byte2hex(instr),macro_background+dialog_title); refresh(flag_FMREG+flag_ARPEGGIO+flag_VIBRATO); If (get_4op_to_test <> 0) then _macro_preview_init(1,BYTE(NOT BYTE_NULL)) else _macro_preview_init(1,BYTE_NULL); end; If (get_4op_to_test <> 0) then _macro_preview_body(LO(get_4op_to_test),HI(get_4op_to_test),count_channel(pattern_hpos),is_environment.keystroke) else _macro_preview_body(instrum_page,BYTE_NULL,count_channel(pattern_hpos),is_environment.keystroke); If ctrl_pressed and NOT shift_pressed and (is_environment.keystroke = kSPACE) then begin _pip_loop := NOT _pip_loop; For temp := 1 to 20 do keyoff_loop[temp] := _pip_loop; is_environment.keystroke := WORD_NULL; end; If shift_pressed and (is_environment.keystroke = kSPACE) then is_environment.keystroke := WORD_NULL; end else If NOT (seconds_counter >= ssaver_time) then GOTO _end2 //CONTINUE else begin screen_saver; GOTO _end2; //CONTINUE; end; _end2: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (is_environment.keystroke = kSPACE) or (is_environment.keystroke = kESC); If (get_4op_to_test <> 0) then _macro_preview_init(0,BYTE(NOT BYTE_NULL)) else _macro_preview_init(0,BYTE_NULL); macro_preview_indic_proc := NIL; _pip_dest := ptr_temp_screen; ThinCursor; end; {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (is_environment.keystroke = kESC) or (is_environment.keystroke = kCtrlO) or (is_environment.keystroke = kF1) or (is_environment.keystroke = kF2) or (is_environment.keystroke = kCtrlF2) or (is_environment.keystroke = kF3) or (is_environment.keystroke = kCtrlL) or (is_environment.keystroke = kCtrlS) or (is_environment.keystroke = kCtrlM) or (NOT ctrl_pressed and (is_environment.keystroke = kAltC)) or call_pickup_proc or call_pickup_proc2; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); _macro_editor__pos[arp_vib_mode] := pos; _macro_editor__fmreg_hpos[arp_vib_mode] := fmreg_hpos; _macro_editor__fmreg_page[arp_vib_mode] := fmreg_page; _macro_editor__fmreg_left_margin[arp_vib_mode] := fmreg_left_margin; _macro_editor__fmreg_cursor_pos[arp_vib_mode] := fmreg_cursor_pos; _macro_editor__arpeggio_page[arp_vib_mode] := arpeggio_page; _macro_editor__vibrato_hpos[arp_vib_mode] := vibrato_hpos; _macro_editor__vibrato_page[arp_vib_mode] := vibrato_page; If NOT arp_vib_mode then begin songdata.instr_macros[instr].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[instr].vibrato_table := ptr_vibrato_table; end else begin If shift_pressed then begin songdata.instr_macros[current_inst].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[current_inst].vibrato_table := ptr_vibrato_table; end; arpvib_arpeggio_table := ptr_arpeggio_table; arpvib_vibrato_table := ptr_vibrato_table; end; For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; songdata.instr_names[temp][1] := ' '; end; If (Update32(songdata,SizeOf(songdata),0) <> songdata_crc) then module_archived := FALSE; For temp := 1 to 255 do songdata.instr_names[temp][1] := temp_marks[temp]; HideCursor; Move(old_keys,is_setting.terminate_keys,SizeOf(old_keys)); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+81+2+window_area_inc_x; move_to_screen_area[4] := ystart+24+1+window_area_inc_x; move2screen; Case is_environment.keystroke of kAltC: If NOT ctrl_pressed then begin If (pos in [7,13,20]) then begin copy_menu_str4[13] := copy_macro_str[2]; copy_menu_str4[14] := copy_macro_str[4]; end else begin copy_menu_str4[13] := copy_macro_str[1]; copy_menu_str4[14] := copy_macro_str[3]; end; mn_setting.cycle_moves := TRUE; temp := Menu(copy_menu_str4,01,01,copypos4,30,15,15,' COPY OBJECT '); copy_menu_str4[13] := copy_macro_str[2]; copy_menu_str4[14] := copy_macro_str[4]; If (mn_environment.keystroke <> kESC) then begin copypos4 := temp; clipboard.object_type := tCOPY_OBJECT(temp); Case pos of 1..7: clipboard.mcrtab_type := mttFM_reg_table; 8..13: clipboard.mcrtab_type := mttArpeggio_table; 14..20: clipboard.mcrtab_type := mttVibrato_table; end; copy_object; end; GOTO _jmp1; end; kENTER: If call_pickup_proc2 then begin call_pickup_proc2 := FALSE; temp := INSTRUMENT_CONTROL_alt(_source_ins2,'FM-REGiSTER MACRO: PASTE DATA TO iNSTRUMENT'); If (temp <> 0) then begin _source_ins2 := temp; songdata.instr_data[_source_ins2].fm_data := songdata.instr_macros[instr].data[fmreg_page].fm_data; songdata.instr_data[_source_ins2].panning := songdata.instr_macros[instr].data[fmreg_page].panning; songdata.instr_data[_source_ins2].fine_tune := songdata.instr_data[instr].fine_tune; songdata.instr_data[_source_ins2].perc_voice := songdata.instr_data[instr].perc_voice; songdata.instr_data[_source_ins2].fm_data.FEEDBACK_FM := songdata.instr_data[_source_ins2].fm_data.FEEDBACK_FM AND $3f; With songdata.instr_data[_source_ins2].fm_data do begin KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $c0+ 63-KSL_VOLUM_modulator AND $3f; KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $c0+ 63-KSL_VOLUM_carrier AND $3f; end; end; GOTO _jmp1; end; kCtENTR: If call_pickup_proc then begin call_pickup_proc := FALSE; temp := INSTRUMENT_CONTROL_alt(_source_ins,'FM-REGiSTER MACRO: PASTE DATA FROM iNSTRUMENT'); If (temp <> 0) then begin _source_ins := temp; temp := songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM; songdata.instr_macros[instr].data[fmreg_page].fm_data := songdata.instr_data[_source_ins].fm_data; songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM := temp AND $0c0+ songdata.instr_data[_source_ins].fm_data.FEEDBACK_FM AND $3f; songdata.instr_macros[instr].data[fmreg_page].panning := songdata.instr_data[_source_ins].panning; songdata.instr_macros[instr].data[fmreg_page].duration := min(songdata.instr_macros[instr].data[fmreg_page].duration,1); With songdata.instr_macros[instr].data[fmreg_page].fm_data do begin KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $c0+ 63-KSL_VOLUM_modulator AND $3f; KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $c0+ 63-KSL_VOLUM_carrier AND $3f; end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; GOTO _jmp1; end; kF2, kCtrlS: begin quick_cmd := FALSE; If NOT arp_vib_mode then FILE_save('a2f') else FILE_save('a2w'); GOTO _jmp1; end; kCtrlF2: begin quick_cmd := FALSE; If NOT arp_vib_mode then FILE_save('a2w'); GOTO _jmp1; end; kF3, kCtrlL: begin If (pos < 8) then temps := '*.a2i$*.a2f$*.a2b$*.a2w$'+ '*.bnk$*.cif$*.fib$*.fin$*.ibk$*.ins$*.sbi$*.sgi$' else temps := '*.a2w$'; quick_cmd := FALSE; If NOT (pos < 8) then _arp_vib_loader := TRUE else _arp_vib_loader := FALSE; If _arp_vib_loader then begin arp_tab_selected := pos in [8..13]; vib_tab_selected := pos in [14..20]; If NOT arp_vib_mode then begin arpvib_arpeggio_table := ptr_arpeggio_table; arpvib_vibrato_table := ptr_vibrato_table; end; end else begin arp_tab_selected := ptr_arpeggio_table <> 0; vib_tab_selected := ptr_vibrato_table <> 0; If NOT (arp_tab_selected or vib_tab_selected) then begin arp_tab_selected := TRUE; vib_tab_selected := TRUE; end; end; FILE_open(temps,FALSE); update_instr_data(instrum_page); GOTO _jmp1; end; kCtrlO: begin OCTAVE_CONTROL; GOTO _jmp1; end; kCtrlM: begin MACRO_BROWSER((pos < 8),FALSE); GOTO _jmp1; end; kF1: begin If NOT arp_vib_mode then HELP('macro_editor') else HELP('macro_editor_(av)'); GOTO _jmp1; end; end; _pip_loop := FALSE; end; procedure MACRO_BROWSER(instrBrowser: Boolean; updateCurInstr: Boolean); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_BROWSER'; {$ENDIF} songdata_crc := Update32(songdata,SizeOf(songdata),0); a2w_file_loader(FALSE,NOT instrBrowser,TRUE,FALSE,updateCurInstr); // browse internal A2W data If (Update32(songdata,SizeOf(songdata),0) <> songdata_crc) then module_archived := FALSE; end; end. adlibtracker2-2.4.23/make_win.bat0000644000000000000000000000365713176573533015323 0ustar rootroot@echo off set homedir=%~d1\AT2_Compilation_Environment cd %homedir%\git set ERR_RESULT=??? rem ------------------------------------- set VERSION=2.4.23 rem ------------------------------------- echo. echo ************************************ echo ** ** echo ** STEP 1/4 ** echo ** Validating version info ** echo ** ** echo ************************************ echo. copy /y utils\val_win.exe validate.exe >nul validate.exe %VERSION% del validate.exe >nul echo. echo ************************************ echo ** ** echo ** STEP 2/4 ** echo ** Compiling sources ** echo ** ** echo ************************************ echo. call makefile.bat >!log if not exist adtrack2.exe goto :compile_error if not %ERR_RESULT% == "OK" GOTO :compile_error if not exist *.ppu goto :no_ppu_file del /F /Q *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del /F /Q *.o >nul :no_o_file if not exist *.or goto :no_or_file del /F /Q *.or >nul :no_or_file if not exist *.res goto :no_res_file del /F /Q *.res >nul :no_res_file if not exist !log goto :no_log_file del /F /Q !log >nul :no_log_file echo. echo ************************************ echo ** ** echo ** STEP 3/4 ** echo ** UPX: Compressing EXE file ** echo ** ** echo ************************************ echo. upx -9 adtrack2.exe >nul echo. echo ************************************ echo ** ** echo ** STEP 4/4 ** echo ** Executing program ** echo ** ** echo ************************************ echo. start adtrack2 goto :end :compile_error start %windir%\notepad.exe !log. :end adlibtracker2-2.4.23/iloaders.inc0000644000000000000000000102146113176573533015330 0ustar rootroot{ function check_byte(var data; _byte: Byte; size: Longint): Boolean; procedure import_old_a2m_event1(patt,line,chan: Byte; old_chunk: tOLD_CHUNK; processing_whole_song: Boolean); procedure replace_old_adsr(patterns: Byte); procedure import_old_a2m_patterns1(block: Byte; count: Byte); procedure import_old_a2m_event2(patt,line,chan: Byte; old_chunk: tOLD_CHUNK); procedure import_old_a2m_patterns2(block: Byte; count: Byte); procedure import_old_flags; procedure import_old_songdata(old_songdata: pOLD_FIXED_SONGDATA); procedure import_old_instruments(old_songdata: pOLD_FIXED_SONGDATA; new_songdata: pFIXED_SONGDATA; instr,count: Byte); procedure import_single_old_instrument(old_songdata: pOLD_FIXED_SONGDATA; pos,instr: Byte); function insert_command(cmd,cmd2: Word; patterns: Byte; chan: Byte; exceptions: tByteSet): Boolean; procedure a2m_file_loader; procedure a2t_file_loader; procedure a2p_file_loader; function dec2hex(dec: Byte): Byte; function truncate_string(str: String): String; procedure amd_file_loader; procedure import_cff_event(patt,line,chan,byte0,byte1,byte2: Byte); procedure import_cff_patterns(var data; patterns: Byte); procedure cff_file_loader; procedure import_standard_instrument(inst: Byte; var data); procedure dfm_file_loader; procedure import_hsc_event(patt,line,chan: Byte; event: Word); procedure import_hsc_patterns(var data; patterns: Byte); procedure import_hsc_instrument(inst: Byte; var data); procedure hsc_file_loader; procedure mtk_file_loader; procedure rad_file_loader; procedure fix_s3m_commands(patterns: Byte); procedure fix_single_pattern(patt: Byte); procedure s3m_file_loader; procedure fix_fmk_commands(patterns: Byte); procedure import_fin_instrument(inst: Byte; var data); procedure fmk_file_loader; procedure import_sat_instrument(inst: Byte; var data); function import_sat_instrument_name(var data; inst: Byte): String; procedure sat_file_loader; function _sal(op1,op2: Word): Byte; function _sar(op1,op2: Word): Byte; procedure import_sa2_effect(effect,def1,def2: Byte; var out1,out2: Byte); procedure sa2_file_loader; } function check_byte(var data; _byte: Byte; size: Longint): Boolean; var result: Boolean; begin asm mov edi,[data] mov ecx,size jecxz @@1 mov al,_byte repnz scasb jnz @@1 mov result,TRUE jmp @@2 @@1: mov result,FALSE @@2: end; check_byte := result; end; var adsr_carrier: array[1..9] of Boolean; procedure import_old_a2m_event1(patt,line,chan: Byte; old_chunk: tOLD_CHUNK; processing_whole_song: Boolean); const fx_Arpeggio = $00; fx_FSlideUp = $01; fx_FSlideDown = $02; fx_FSlideUpFine = $03; fx_FSlideDownFine = $04; fx_TonePortamento = $05; fx_TPortamVolSlide = $06; fx_Vibrato = $07; fx_VibratoVolSlide = $08; fx_SetOpIntensity = $09; fx_SetInsVolume = $0a; fx_PatternBreak = $0b; fx_PatternJump = $0c; fx_SetTempo = $0d; fx_SetTimer = $0e; fx_Extended = $0f; fx_ex_DefAMdepth = $00; fx_ex_DefVibDepth = $01; fx_ex_DefWaveform = $02; fx_ex_ManSlideUp = $03; fx_ex_ManSlideDown = $04; fx_ex_VSlideUp = $05; fx_ex_VSlideDown = $06; fx_ex_VSlideUpFine = $07; fx_ex_VSlideDownFine = $08; fx_ex_RetrigNote = $09; fx_ex_SetAttckRate = $0a; fx_ex_SetDecayRate = $0b; fx_ex_SetSustnLevel = $0c; fx_ex_SetReleaseRate = $0d; fx_ex_SetFeedback = $0e; fx_ex_ExtendedCmd = $0f; var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); chunk.note := old_chunk.note; chunk.instr_def := old_chunk.instr_def; chunk.effect_def := old_chunk.effect_def; chunk.effect := old_chunk.effect; Case old_chunk.effect_def of fx_Arpeggio: chunk.effect_def := ef_Arpeggio; fx_FSlideUp: chunk.effect_def := ef_FSlideUp; fx_FSlideDown: chunk.effect_def := ef_FSlideDown; fx_FSlideUpFine: chunk.effect_def := ef_FSlideUpFine; fx_FSlideDownFine: chunk.effect_def := ef_FSlideDownFine; fx_TonePortamento: chunk.effect_def := ef_TonePortamento; fx_TPortamVolSlide: chunk.effect_def := ef_TPortamVolSlide; fx_Vibrato: chunk.effect_def := ef_Vibrato; fx_VibratoVolSlide: chunk.effect_def := ef_VibratoVolSlide; fx_SetInsVolume: chunk.effect_def := ef_SetInsVolume; fx_PatternJump: chunk.effect_def := ef_PositionJump; fx_PatternBreak: chunk.effect_def := ef_PatternBreak; fx_SetTempo: chunk.effect_def := ef_SetSpeed; fx_SetTimer: chunk.effect_def := ef_SetTempo; fx_SetOpIntensity: If (old_chunk.effect DIV 16 <> 0) then begin chunk.effect_def := ef_SetCarrierVol; chunk.effect := 3+(old_chunk.effect DIV 16)*4; end else If (old_chunk.effect MOD 16 <> 0) then begin chunk.effect_def := ef_SetModulatorVol; chunk.effect := 3+(old_chunk.effect MOD 16)*4; end else chunk.effect_def := 0; fx_Extended: Case old_chunk.effect DIV 16 of fx_ex_DefAMdepth: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetTremDepth*16+old_chunk.effect MOD 16; end; fx_ex_DefVibDepth: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetVibDepth*16+old_chunk.effect MOD 16; end; fx_ex_DefWaveform: begin chunk.effect_def := ef_SetWaveform; Case old_chunk.effect MOD 16 of 0..3: chunk.effect := (old_chunk.effect MOD 16)*16+$0f; 4..7: chunk.effect := $0f0+(old_chunk.effect MOD 16)-4; end; end; fx_ex_VSlideUp: begin chunk.effect_def := ef_VolSlide; chunk.effect := (old_chunk.effect MOD 16)*16; end; fx_ex_VSlideDown: begin chunk.effect_def := ef_VolSlide; chunk.effect := old_chunk.effect MOD 16; end; fx_ex_VSlideUpFine: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := (old_chunk.effect MOD 16)*16; end; fx_ex_VSlideDownFine: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := old_chunk.effect MOD 16; end; fx_ex_ManSlideUp: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneUp*16+old_chunk.effect MOD 16; end; fx_ex_ManSlideDown: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneDown*16+old_chunk.effect MOD 16; end; fx_ex_RetrigNote: begin chunk.effect_def := ef_RetrigNote; chunk.effect := SUCC(old_chunk.effect MOD 16); end; fx_ex_SetAttckRate: begin chunk.effect_def := ef_Extended; chunk.effect := old_chunk.effect MOD 16; If NOT adsr_carrier[chan] then Inc(chunk.effect,ef_ex_SetAttckRateM*16) else Inc(chunk.effect,ef_ex_SetAttckRateC*16); end; fx_ex_SetDecayRate: begin chunk.effect_def := ef_Extended; chunk.effect := old_chunk.effect MOD 16; If NOT adsr_carrier[chan] then Inc(chunk.effect,ef_ex_SetDecayRateM*16) else Inc(chunk.effect,ef_ex_SetDecayRateC*16); end; fx_ex_SetSustnLevel: begin chunk.effect_def := ef_Extended; chunk.effect := old_chunk.effect MOD 16; If NOT adsr_carrier[chan] then Inc(chunk.effect,ef_ex_SetSustnLevelM*16) else Inc(chunk.effect,ef_ex_SetSustnLevelC*16); end; fx_ex_SetReleaseRate: begin chunk.effect_def := ef_Extended; chunk.effect := old_chunk.effect MOD 16; If NOT adsr_carrier[chan] then Inc(chunk.effect,ef_ex_SetRelRateM*16) else Inc(chunk.effect,ef_ex_SetRelRateC*16); end; fx_ex_SetFeedback: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetFeedback*16+old_chunk.effect MOD 16; end; fx_ex_ExtendedCmd: If (old_chunk.effect MOD 16 in [0..9]) then begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16; Case old_chunk.effect MOD 16 of 0: Inc(chunk.effect,ef_ex_cmd2_RSS); 1: Inc(chunk.effect,ef_ex_cmd2_LockVol); 2: Inc(chunk.effect,ef_ex_cmd2_UnlockVol); 3: Inc(chunk.effect,ef_ex_cmd2_LockVP); 4: Inc(chunk.effect,ef_ex_cmd2_UnlockVP); 5: begin If processing_whole_song then chunk.effect_def := 255 else chunk.effect_def := 0; chunk.effect := 0; adsr_carrier[chan] := TRUE; end; 6: begin If processing_whole_song then chunk.effect_def := 255 else chunk.effect_def := 0; If processing_whole_song then chunk.effect := 1 else chunk.effect := 0; adsr_carrier[chan] := FALSE; end; 7: Inc(chunk.effect,ef_ex_cmd2_VSlide_car); 8: Inc(chunk.effect,ef_ex_cmd2_VSlide_mod); 9: Inc(chunk.effect,ef_ex_cmd2_VSlide_def); end; end else begin chunk.effect_def := 0; chunk.effect := 0; end; end; end; put_chunk(patt,line,chan,chunk); end; procedure replace_old_adsr(patterns: Byte); var chunk,chunk2: tCHUNK; temp2,temp3: Byte; patt_break: Byte; order,patt: Byte; patts: String; begin patts := ''; FillChar(adsr_carrier,SizeOf(adsr_carrier),0); order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; patt_break := BYTE_NULL; For temp2 := 0 to $3f do For temp3 := 1 to 9 do begin get_chunk(patt,temp2,temp3,chunk); chunk2 := chunk; If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then patt_break := temp2; If (chunk.effect_def in [$ff,ef_Extended]) then begin If (chunk.effect_def = $ff) then begin chunk2.effect_def := 0; chunk2.effect := 0; If (temp2 <= patt_break) then Case chunk.effect of 0: adsr_carrier[temp3] := TRUE; 1: adsr_carrier[temp3] := FALSE; end; end; If (chunk.effect_def = ef_Extended) then Case chunk.effect DIV 16 of ef_ex_SetAttckRateM, ef_ex_SetAttckRateC: If adsr_carrier[temp3] then chunk2.effect := ef_ex_SetAttckRateC*16+chunk.effect MOD 16 else chunk2.effect := ef_ex_SetAttckRateM*16+chunk.effect MOD 16; ef_ex_SetDecayRateM, ef_ex_SetDecayRateC: If adsr_carrier[temp3] then chunk2.effect := ef_ex_SetDecayRateC*16+chunk.effect MOD 16 else chunk2.effect := ef_ex_SetDecayRateM*16+chunk.effect MOD 16; ef_ex_SetSustnLevelM, ef_ex_SetSustnLevelC: If adsr_carrier[temp3] then chunk2.effect := ef_ex_SetSustnLevelC*16+chunk.effect MOD 16 else chunk2.effect := ef_ex_SetSustnLevelM*16+chunk.effect MOD 16; ef_ex_SetRelRateM, ef_ex_SetRelRateC: If adsr_carrier[temp3] then chunk2.effect := ef_ex_SetRelRateC*16+chunk.effect MOD 16 else chunk2.effect := ef_ex_SetRelRateM*16+chunk.effect MOD 16; end; If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then If (chunk.effect_def <> chunk2.effect_def) or (chunk.effect <> chunk2.effect) then put_chunk(patt,temp2,temp3,chunk2); end; end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); end; procedure import_old_a2m_patterns1(block: Byte; count: Byte); procedure get_old_chunk(pattern,line,channel: Byte; var chunk: tOLD_CHUNK); begin chunk := old_hash_buffer[pattern][line][channel]; end; var patt,line,chan: Byte; chunk: tOLD_CHUNK; begin { import_old_a2m_patterns1 } For patt := 0 to max(PRED(count),15) do For line := 0 to $3f do For chan := 1 to 9 do begin get_old_chunk(patt,line,chan,chunk); import_old_a2m_event1(block*16+patt,line,chan,chunk,TRUE); end; end; procedure import_old_a2m_event2(patt,line,chan: Byte; old_chunk: tOLD_CHUNK); const ef_ManualFSlide = 22; var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); chunk.note := old_chunk.note; chunk.instr_def := old_chunk.instr_def; If (old_chunk.effect_def <> ef_ManualFSlide) then begin chunk.effect_def := old_chunk.effect_def; chunk.effect := old_chunk.effect; end else If (old_chunk.effect DIV 16 <> 0) then begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneUp*16+old_chunk.effect DIV 16; end else begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneDown*16+old_chunk.effect MOD 16; end; put_chunk(patt,line,chan,chunk); end; procedure import_old_a2m_patterns2(block: Byte; count: Byte); procedure get_old_chunk(pattern,line,channel: Byte; var chunk: tOLD_CHUNK); begin chunk := hash_buffer[pattern][channel][line]; end; var patt,line,chan: Byte; chunk: tOLD_CHUNK; begin { import_old_a2m_patterns2 } For patt := 0 to max(PRED(count),7) do For line := 0 to $3f do For chan := 1 to 18 do begin get_old_chunk(patt,line,chan,chunk); import_old_a2m_event2(block*8+patt,line,chan,chunk); end; end; procedure import_old_flags; var temp: Byte; begin If (songdata.common_flag OR 2 = songdata.common_flag) then For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] OR $10; If (songdata.common_flag OR 4 = songdata.common_flag) then For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] OR $20; If (songdata.common_flag OR $20 = songdata.common_flag) then For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] AND NOT 3; end; procedure import_old_songdata(old_songdata: pOLD_FIXED_SONGDATA); var temp: Byte; begin songdata.songname := old_songdata^.songname; songdata.composer := old_songdata^.composer; For temp := 1 to 250 do begin songdata.instr_names[temp] := old_songdata^.instr_names[temp]; songdata.instr_data[temp].fm_data := old_songdata^.instr_data[temp].fm_data; songdata.instr_data[temp].panning := old_songdata^.instr_data[temp].panning; songdata.instr_data[temp].fine_tune := old_songdata^.instr_data[temp].fine_tune; songdata.instr_data[temp].perc_voice := 0; end; Move(old_songdata^.pattern_order, songdata.pattern_order, SizeOf(old_songdata^.pattern_order)); songdata.tempo := old_songdata^.tempo; songdata.speed := old_songdata^.speed; songdata.common_flag := old_songdata^.common_flag; import_old_flags; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} procedure import_single_old_instrument(old_songdata: pOLD_FIXED_SONGDATA; pos,instr: Byte); begin songdata.instr_names[pos] := Copy(songdata.instr_names[pos],1,9)+ Copy(old_songdata^.instr_names[instr],10,22); songdata.instr_data[pos].fm_data := old_songdata^.instr_data[instr].fm_data; songdata.instr_data[pos].panning := old_songdata^.instr_data[instr].panning; songdata.instr_data[pos].fine_tune := old_songdata^.instr_data[instr].fine_tune; songdata.instr_data[pos].perc_voice := 0; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} function insert_command(cmd,cmd2: Word; patterns: Byte; chan: Byte; exceptions: tByteSet): Boolean; var chunk: tCHUNK; temp2,temp3: Byte; patt_break: Byte; order,patt: Byte; patts: String; begin patts := ''; order := 0; patt := BYTE_NULL; insert_command := FALSE; Repeat If (Pos(CHR(songdata.pattern_order[order]),patts) <> 0) or (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; patt_break := songdata.patt_len; For temp3 := 1 to songdata.nm_tracks do For temp2 := 0 to PRED(songdata.patt_len) do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) or (chunk.effect_def2 in [ef_PositionJump,ef_PatternBreak]) then patt_break := temp2; If (temp3 = chan) and (temp2 <= patt_break) then If (cmd2 = 0) then If (chunk.effect_def+chunk.effect = 0) or (chunk.effect_def SHL 8 + chunk.effect = cmd) or (chunk.effect_def in exceptions) then begin chunk.effect_def := HI(cmd); chunk.effect := LO(cmd); put_chunk(patt,temp2,temp3,chunk); insert_command := TRUE; EXIT; end else If (chunk.effect_def2+chunk.effect2 = 0) or (chunk.effect_def2 SHL 8 + chunk.effect2 = cmd2) or (chunk.effect_def2 in exceptions) then begin chunk.effect_def2 := HI(cmd); chunk.effect2 := LO(cmd); put_chunk(patt,temp2,temp3,chunk); insert_command := TRUE; EXIT; end else else If ((chunk.effect_def+chunk.effect = 0) or (chunk.effect_def SHL 8 + chunk.effect = cmd) or (chunk.effect_def in exceptions)) and ((chunk.effect_def2+chunk.effect2 = 0) or (chunk.effect_def2 SHL 8 + chunk.effect2 = cmd2) or (chunk.effect_def2 in exceptions)) then begin chunk.effect_def := HI(cmd); chunk.effect := LO(cmd); chunk.effect_def2 := HI(cmd2); chunk.effect2 := LO(cmd2); put_chunk(patt,temp2,temp3,chunk); insert_command := TRUE; EXIT; end; end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); end; procedure a2m_file_loader; type tOLD_HEADER = Record ident: array[1..10] of Char; crc32: Longint; ffver: Byte; patts: Byte; b0len: Word; b1len: Word; b2len: Word; b3len: Word; b4len: Word; b5len: Word; b6len: Word; b7len: Word; b8len: Word; end; type tHEADER = Record ident: array[1..10] of Char; crc32: Longint; ffver: Byte; patts: Byte; b0len: Longint; b1len: array[0..15] of Longint; end; const id = '_A2module_'; const old_a2m_header_size = 26; var f: File; header: tHEADER; header2: tOLD_HEADER; temp,temp2: Longint; crc: Longint; xlen: array[0..6] of Word; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:a2m_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If NOT (header.ffver in [1..FFVER_A2M]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} init_old_songdata; If (header.ffver in [1..4]) then begin FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE)); ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; xlen[0] := header2.b2len; xlen[1] := header2.b3len; xlen[2] := header2.b4len; SeekF(f,old_a2m_header_size); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 0 to 2 do If ((header2.patts-1) DIV 16 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header2.b0len,2,crc); crc := Update32(header2.b1len,2,crc); For temp2 := 0 to 2 do crc := Update32(xlen[temp2],2,crc); If (crc <> header2.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; SeekF(f,old_a2m_header_size); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Case header2.ffver of 4: Move(buf1,old_songdata,header2.b0len); 3: LZSS_decompress(buf1,old_songdata,header2.b0len); 2: LZW_decompress(buf1,old_songdata); 1: SIXPACK_decompress(buf1,old_songdata,header2.b0len); end; For temp := 1 to 250 do old_songdata.instr_data[temp].panning := 0; BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Case header2.ffver of 4: Move(buf1,old_hash_buffer,header2.b1len); 3: LZSS_decompress(buf1,old_hash_buffer,header2.b1len); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b1len); end; import_old_a2m_patterns1(0,16); For temp2 := 0 to 2 do If ((header2.patts-1) DIV 16 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Case header2.ffver of 4: Move(buf1,old_hash_buffer,xlen[temp2]); 3: LZSS_decompress(buf1,old_hash_buffer,xlen[temp2]); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,xlen[temp2]); end; import_old_a2m_patterns1(SUCC(temp2),16); end; replace_old_adsr(header2.patts); import_old_songdata(Addr(old_songdata)); end; If (header.ffver in [5..8]) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; xlen[0] := header2.b2len; xlen[1] := header2.b3len; xlen[2] := header2.b4len; xlen[3] := header2.b5len; xlen[4] := header2.b6len; xlen[5] := header2.b7len; xlen[6] := header2.b8len; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 0 to 6 do If ((header2.patts-1) DIV 8 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header2.b0len,2,crc); crc := Update32(header2.b1len,2,crc); For temp2 := 0 to 6 do crc := Update32(xlen[temp2],2,crc); If (crc <> header2.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 18 else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; SeekF(f,SizeOf(header2)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Case header2.ffver of 8: Move(buf1,old_songdata,header2.b0len); 7: LZSS_decompress(buf1,old_songdata,header2.b0len); 6: LZW_decompress(buf1,old_songdata); 5: SIXPACK_decompress(buf1,old_songdata,header2.b0len); end; BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Case header2.ffver of 8: Move(buf1,hash_buffer,header2.b1len); 7: LZSS_decompress(buf1,hash_buffer,header2.b1len); 6: LZW_decompress(buf1,hash_buffer); 5: SIXPACK_decompress(buf1,hash_buffer,header2.b1len); end; import_old_a2m_patterns2(0,8); For temp2 := 0 to 6 do If ((header2.patts-1) DIV 8 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Case header2.ffver of 8: Move(buf1,hash_buffer,header2.b2len); 7: LZSS_decompress(buf1,hash_buffer,header2.b2len); 6: LZW_decompress(buf1,hash_buffer); 5: SIXPACK_decompress(buf1,hash_buffer,header2.b2len); end; import_old_a2m_patterns2(SUCC(temp2),8); end; import_old_songdata(Addr(old_songdata)); end; If (header.ffver in [9,10,11]) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header.b0len,2,crc); For temp2 := 0 to 15 do crc := Update32(header.b1len[temp2],2,crc); If (crc <> header.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (header.ffver = 9) then import_old_flags; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} For temp := 1 to 255 do Insert(songdata.instr_names[temp][1]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); If (header.ffver = 11) then For temp := 0 to $7f do Insert(songdata.pattern_names[temp][1]+ 'PAT_'+byte2hex(temp)+' '#247' ', songdata.pattern_names[temp],1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} APACK_decompress(buf1,pattdata^[0]); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (temp2*8+8 <= max_patterns) then APACK_decompress(buf1,pattdata^[temp2]) else limit_exceeded := TRUE; end; end; If (header.ffver in [12,FFVER_A2M]) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header.b0len,2,crc); For temp2 := 0 to 15 do crc := Update32(header.b1len[temp2],2,crc); If (crc <> header.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} progress_num_steps := (header.patts-1) DIV 8 +2; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} LZH_decompress(buf1,songdata,header.b0len); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} For temp := 1 to 255 do Insert(songdata.instr_names[temp][1]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); For temp := 0 to $7f do Insert(songdata.pattern_names[temp][1]+ 'PAT_'+byte2hex(temp)+' '#247' ', songdata.pattern_names[temp],1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} LZH_decompress(buf1,pattdata^[0],header.b1len[0]); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (temp2*8+8 <= max_patterns) then begin LZH_decompress(buf1,pattdata^[temp2],header.b1len[temp2]); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end else limit_exceeded := TRUE; end; end; speed := songdata.speed; tempo := songdata.tempo; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> Case header.ffver of {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> 1..4: load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> else load_flag := 2; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} temp := calc_max_speedup(songdata.tempo); If (songdata.macro_speedup > temp) then begin Dialog('DUE TO SYSTEM LiMiTATiONS, ~MACRO SPEEDUP~ VALUE IS ~CHANGED~$'+ 'SLOWDOWN: ~'+Num2str(songdata.macro_speedup,10)+'X -> '+Num2str(temp,10)+'X~$', '~O~KAY$',' A2M LOADER ',1); songdata.macro_speedup := temp; end; load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; procedure a2t_file_loader; type tOLD_HEADER1 = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; b0len: Word; b1len: Word; b2len: Word; b3len: Word; b4len: Word; b5len: Word; end; type tOLD_HEADER2 = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; b0len: Word; b1len: Word; b2len: Word; b3len: Word; b4len: Word; b5len: Word; b6len: Word; b7len: Word; b8len: Word; b9len: Word; end; type tOLD_HEADER3 = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; patln: Word; nmtrk: Byte; mcspd: Word; b0len: Longint; b1len: Longint; b2len: Longint; b3len: Longint; b4len: array[0..15] of Longint; end; type tOLD_HEADER4 = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; patln: Word; nmtrk: Byte; mcspd: Word; is4op: Byte; locks: array[1..20] of Byte; b0len: Longint; b1len: Longint; b2len: Longint; b3len: Longint; b4len: array[0..15] of Longint; end; type tHEADER = Record ident: array[1..15] of Char; crc32: Longint; ffver: Byte; patts: Byte; tempo: Byte; speed: Byte; cflag: Byte; patln: Word; nmtrk: Byte; mcspd: Word; is4op: Byte; locks: array[1..20] of Byte; b0len: Longint; b1len: Longint; b2len: Longint; b3len: Longint; b4len: Longint; b5len: array[0..15] of Longint; end; const id = '_A2tiny_module_'; var f: File; header: tHEADER; header2: tOLD_HEADER1; header3: tOLD_HEADER2; header4: tOLD_HEADER3; header5: tOLD_HEADER4; temp,temp2: Longint; crc: Longint; xlen: array[0..6] of Word; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:a2t_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If NOT (header.ffver in [1..FFVER_A2T]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_old_songdata; If (header.ffver in [1..4]) then begin FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE)); ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; xlen[0] := header2.b3len; xlen[1] := header2.b4len; xlen[2] := header2.b5len; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b2len,temp); If NOT (temp = header2.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 0 to 2 do If ((header2.patts-1) DIV 16 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header2.b0len,2,crc); crc := Update32(header2.b1len,2,crc); crc := Update32(header2.b2len,2,crc); For temp2 := 0 to 2 do crc := Update32(xlen[temp2],2,crc); If (crc <> header2.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; SeekF(f,SizeOf(header2)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; old_songdata.tempo := header2.tempo; old_songdata.speed := header2.speed; Case header2.ffver of 4: Move(buf1,old_songdata.instr_data,header2.b0len); 3: LZSS_decompress(buf1,old_songdata.instr_data,header2.b0len); 2: LZW_decompress(buf1,old_songdata.instr_data); 1: SIXPACK_decompress(buf1,old_songdata.instr_data,header2.b0len); end; For temp := 1 to 250 do old_songdata.instr_data[temp].panning := 0; BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Case header2.ffver of 4: Move(buf1,old_songdata.pattern_order,header2.b1len); 3: LZSS_decompress(buf1,old_songdata.pattern_order,header2.b1len); 2: LZW_decompress(buf1,old_songdata.pattern_order); 1: SIXPACK_decompress(buf1,old_songdata.pattern_order,header2.b1len); end; BlockReadF(f,buf1,header2.b2len,temp); If NOT (temp = header2.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(old_hash_buffer,SizeOf(old_hash_buffer),0); Case header2.ffver of 4: Move(buf1,old_hash_buffer,header2.b2len); 3: LZSS_decompress(buf1,old_hash_buffer,header2.b2len); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b2len); end; import_old_a2m_patterns1(0,16); For temp2 := 0 to 2 do If ((header2.patts-1) DIV 16 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(old_hash_buffer,SizeOf(old_hash_buffer),0); Case header2.ffver of 4: Move(buf1,old_hash_buffer,header2.b3len); 3: LZSS_decompress(buf1,old_hash_buffer,header2.b3len); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,header2.b3len); end; import_old_a2m_patterns1(SUCC(temp2),16); end; replace_old_adsr(header2.patts); import_old_songdata(Addr(old_songdata)); end; If (header.ffver in [5..8]) then begin ResetF(f); BlockReadF(f,header3,SizeOf(header3),temp); If NOT ((temp = SizeOf(header3)) and (header3.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; xlen[0] := header3.b3len; xlen[1] := header3.b4len; xlen[2] := header3.b5len; xlen[3] := header3.b6len; xlen[4] := header3.b7len; xlen[5] := header3.b8len; xlen[6] := header3.b9len; crc := DWORD_NULL; BlockReadF(f,buf1,header3.b0len,temp); If NOT (temp = header3.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header3.b1len,temp); If NOT (temp = header3.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header3.b2len,temp); If NOT (temp = header3.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 0 to 6 do If ((header3.patts-1) DIV 8 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header3.b0len,2,crc); crc := Update32(header3.b1len,2,crc); crc := Update32(header3.b2len,2,crc); For temp2 := 0 to 6 do crc := Update32(xlen[temp2],2,crc); If (crc <> header3.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 18 else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; SeekF(f,SizeOf(header3)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header3.b0len,temp); If NOT (temp = header3.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; old_songdata.tempo := header3.tempo; old_songdata.speed := header3.speed; old_songdata.common_flag := header3.cflag; Case header3.ffver of 8: Move(buf1,old_songdata.instr_data,header3.b0len); 7: LZSS_decompress(buf1,old_songdata.instr_data,header3.b0len); 6: LZW_decompress(buf1,old_songdata.instr_data); 5: SIXPACK_decompress(buf1,old_songdata.instr_data,header3.b0len); end; BlockReadF(f,buf1,header3.b1len,temp); If NOT (temp = header3.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Case header3.ffver of 8: Move(buf1,old_songdata.pattern_order,header3.b1len); 7: LZSS_decompress(buf1,old_songdata.pattern_order,header3.b1len); 6: LZW_decompress(buf1,old_songdata.pattern_order); 5: SIXPACK_decompress(buf1,old_songdata.pattern_order,header3.b1len); end; BlockReadF(f,buf1,header3.b2len,temp); If NOT (temp = header3.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(hash_buffer,SizeOf(hash_buffer),0); Case header3.ffver of 8: Move(buf1,hash_buffer,header3.b2len); 7: LZSS_decompress(buf1,hash_buffer,header3.b2len); 6: LZW_decompress(buf1,hash_buffer); 5: SIXPACK_decompress(buf1,hash_buffer,header3.b2len); end; import_old_a2m_patterns2(0,8); For temp2 := 0 to 6 do If ((header3.patts-1) DIV 8 > temp2) then begin BlockReadF(f,buf1,xlen[temp2],temp); If NOT (temp = xlen[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(hash_buffer,SizeOf(hash_buffer),0); Case header3.ffver of 8: Move(buf1,hash_buffer,header3.b3len); 7: LZSS_decompress(buf1,hash_buffer,header3.b3len); 6: LZW_decompress(buf1,hash_buffer); 5: SIXPACK_decompress(buf1,hash_buffer,header3.b3len); end; import_old_a2m_patterns2(SUCC(temp2),8); end; import_old_songdata(Addr(old_songdata)); end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header4,SizeOf(header4),temp); If NOT ((temp = SizeOf(header4)) and (header4.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header4.b0len,temp); If NOT (temp = header4.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b1len,temp); If NOT (temp = header4.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b2len,temp); If NOT (temp = header4.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b3len,temp); If NOT (temp = header4.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b4len[0],temp); If NOT (temp = header4.b4len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header4.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header4.b4len[temp2],temp); If NOT (temp = header4.b4len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header4.b0len,2,crc); crc := Update32(header4.b1len,2,crc); crc := Update32(header4.b2len,2,crc); crc := Update32(header4.b3len,2,crc); For temp2 := 0 to 15 do crc := Update32(header4.b4len[temp2],2,crc); If (crc <> header4.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header4)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header4.b0len,temp); If NOT (temp = header4.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header4.b1len,temp); If NOT (temp = header4.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header4.b2len,temp); If NOT (temp = header4.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header4.b3len,temp); If NOT (temp = header4.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; songdata.tempo := header4.tempo; songdata.speed := header4.speed; songdata.common_flag := header4.cflag; songdata.patt_len := header4.patln; songdata.nm_tracks := header4.nmtrk; songdata.macro_speedup := header4.mcspd; import_old_flags; APACK_decompress(buf1,songdata.pattern_order); BlockReadF(f,buf1,header4.b4len[0],temp); If NOT (temp = header4.b4len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,pattdata^[0]); For temp2 := 1 to 15 do If ((header4.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header4.b4len[temp2],temp); If NOT (temp = header4.b4len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (temp2*8+8 <= max_patterns) then APACK_decompress(buf1,pattdata^[temp2]) else limit_exceeded := TRUE; end; end; If (header.ffver = 10) then begin ResetF(f); BlockReadF(f,header5,SizeOf(header5),temp); If NOT ((temp = SizeOf(header5)) and (header5.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header5.b0len,temp); If NOT (temp = header5.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b1len,temp); If NOT (temp = header5.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b2len,temp); If NOT (temp = header5.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b3len,temp); If NOT (temp = header5.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b4len[0],temp); If NOT (temp = header5.b4len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header5.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header5.b4len[temp2],temp); If NOT (temp = header5.b4len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header5.b0len,2,crc); crc := Update32(header5.b1len,2,crc); crc := Update32(header5.b2len,2,crc); crc := Update32(header5.b3len,2,crc); For temp2 := 0 to 15 do crc := Update32(header5.b4len[temp2],2,crc); If (crc <> header5.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header5)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header5.b0len,temp); If NOT (temp = header5.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header5.b1len,temp); If NOT (temp = header5.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header5.b2len,temp); If NOT (temp = header5.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header5.b3len,temp); If NOT (temp = header5.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; songdata.tempo := header5.tempo; songdata.speed := header5.speed; songdata.common_flag := header5.cflag; songdata.patt_len := header5.patln; songdata.nm_tracks := header5.nmtrk; songdata.macro_speedup := header5.mcspd; songdata.flag_4op := header5.is4op; Move(header5.locks,songdata.lock_flags,SizeOf(songdata.lock_flags)); APACK_decompress(buf1,songdata.pattern_order); BlockReadF(f,buf1,header5.b4len[0],temp); If NOT (temp = header5.b4len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,pattdata^[0]); For temp2 := 1 to 15 do If ((header5.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header5.b4len[temp2],temp); If NOT (temp = header5.b4len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (temp2*8+8 <= max_patterns) then APACK_decompress(buf1,pattdata^[temp2]) else limit_exceeded := TRUE; end; end; If (header.ffver = 11) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b5len[temp2],temp); If NOT (temp = header.b5len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header.b0len,2,crc); crc := Update32(header.b1len,2,crc); crc := Update32(header.b2len,2,crc); crc := Update32(header.b3len,2,crc); crc := Update32(header.b4len,2,crc); For temp2 := 0 to 15 do crc := Update32(header.b5len[temp2],2,crc); If (crc <> header.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.dis_fmreg_col); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; songdata.tempo := header.tempo; songdata.speed := header.speed; songdata.common_flag := header.cflag; songdata.patt_len := header.patln; songdata.nm_tracks := header.nmtrk; songdata.macro_speedup := header.mcspd; songdata.flag_4op := header.is4op; Move(header.locks,songdata.lock_flags,SizeOf(songdata.lock_flags)); APACK_decompress(buf1,songdata.pattern_order); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,pattdata^[0]); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b5len[temp2],temp); If NOT (temp = header.b5len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (temp2*8+8 <= max_patterns) then APACK_decompress(buf1,pattdata^[temp2]) else limit_exceeded := TRUE; end; end; If (header.ffver in [12,FFVER_A2T]) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b5len[temp2],temp); If NOT (temp = header.b5len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); end; crc := Update32(header.b0len,2,crc); crc := Update32(header.b1len,2,crc); crc := Update32(header.b2len,2,crc); crc := Update32(header.b3len,2,crc); crc := Update32(header.b4len,2,crc); For temp2 := 0 to 15 do crc := Update32(header.b5len[temp2],2,crc); If (crc <> header.crc32) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} progress_num_steps := (header.patts-1) DIV 8 +6; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} temp := LZH_decompress(buf1,buf2,header.b0len); Move(buf2,songdata.ins_4op_flags,SizeOf(songdata.ins_4op_flags)); Move(buf2[SizeOf(songdata.ins_4op_flags)],songdata.reserved_data, SizeOf(songdata.reserved_data)); Move(buf2[SizeOf(songdata.ins_4op_flags)],songdata.reserved_data, SizeOf(songdata.reserved_data)); Move(buf2[SizeOf(songdata.ins_4op_flags)+ SizeOf(songdata.reserved_data)],songdata.instr_data, temp-SizeOf(songdata.ins_4op_flags)+ SizeOf(songdata.reserved_data)); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} If (header.b1len <> 0) then begin BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; LZH_decompress(buf1,songdata.instr_macros,header.b1len); end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} If (header.b2len <> 0) then begin BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; LZH_decompress(buf1,songdata.macro_table,header.b2len); end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} If (header.b3len <> 0) then begin BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; LZH_decompress(buf1,songdata.dis_fmreg_col,header.b3len); end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; songdata.tempo := header.tempo; songdata.speed := header.speed; songdata.common_flag := header.cflag; songdata.patt_len := header.patln; songdata.nm_tracks := header.nmtrk; songdata.macro_speedup := header.mcspd; songdata.flag_4op := header.is4op; Move(header.locks,songdata.lock_flags,SizeOf(songdata.lock_flags)); LZH_decompress(buf1,songdata.pattern_order,header.b4len); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; LZH_decompress(buf1,pattdata^[0],header.b5len[0]); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} For temp2 := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(temp2)) then begin BlockReadF(f,buf1,header.b5len[temp2],temp); If NOT (temp = header.b5len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (temp2*8+8 <= max_patterns) then begin LZH_decompress(buf1,pattdata^[temp2],header.b5len[temp2]); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end else limit_exceeded := TRUE; end; end; speed := songdata.speed; tempo := songdata.tempo; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> Case header.ffver of {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> 1..4: load_flag := 3; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> else load_flag := 4; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} temp := calc_max_speedup(songdata.tempo); If (songdata.macro_speedup > temp) then begin Dialog('DUE TO SYSTEM LiMiTATiONS, ~MACRO SPEEDUP~ VALUE IS ~CHANGED~$'+ 'SLOWDOWN: ~'+Num2str(songdata.macro_speedup,10)+'X -> '+Num2str(temp,10)+'X~$', '~O~KAY$',' A2T LOADER ',1); songdata.macro_speedup := temp; end; load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} procedure a2p_file_loader; type tOLD_HEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; type tHEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; type tNEW_HEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; const id = '_A2pattern_'; var f: File; header: tOLD_HEADER; header2: tHEADER; temp: Longint; line,chan: Byte; temp_str: String; crc: Longint; _pattern: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:a2p_file_loader'; {$ENDIF} If (pattern2use <> BYTE_NULL) then _pattern := pattern2use else _pattern := pattern_patt; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2P]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; init_old_songdata; If (header.ffver in [1..4]) then begin FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE)); crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header.b0len,2,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; Case header.ffver of 4: Move(buf1,old_hash_buffer,header.b0len); 3: LZSS_decompress(buf1,old_hash_buffer,header.b0len); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,header.b0len); end; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then begin For line := 0 to $3f do For chan := 1 to 9 do import_old_a2m_event1(temp,line,chan,old_hash_buffer[0][line][chan],FALSE); songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end; end else begin For line := 0 to $3f do For chan := 1 to 9 do import_old_a2m_event1(_pattern,line,chan,old_hash_buffer[0][line][chan],FALSE); songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; If (header.ffver in [5..8]) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header.b0len,2,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; Case header.ffver of 8: Move(buf1,hash_buffer[0],header.b0len); 7: LZSS_decompress(buf1,hash_buffer[0],header.b0len); 6: LZW_decompress(buf1,hash_buffer[0]); 5: SIXPACK_decompress(buf1,hash_buffer[0],header.b0len); end; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then begin For line := 0 to $3f do For chan := 1 to 18 do import_old_a2m_event2(temp,line,chan,hash_buffer[0][chan][line]); songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end; end else begin For line := 0 to $3f do For chan := 1 to 18 do import_old_a2m_event2(_pattern,line,chan,hash_buffer[0][chan][line]); songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header2.b0len,2,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then APACK_decompress(buf1,pattdata^[temp DIV 8][temp MOD 8]); songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end else begin APACK_decompress(buf1,pattdata^[_pattern DIV 8][_pattern MOD 8]); songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; If (header.ffver = 10) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header2.b0len,2,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then begin APACK_decompress(buf1,buf2); Move(buf2,pattdata^[temp DIV 8][temp MOD 8],PATTERN_SIZE); Move(buf2[PATTERN_SIZE],temp_str,buf2[PATTERN_SIZE]+1); If (temp_str <> '') then songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ temp_str else songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end; end else begin APACK_decompress(buf1,buf2); Move(buf2,pattdata^[_pattern DIV 8][_pattern MOD 8],PATTERN_SIZE); Move(buf2[PATTERN_SIZE],temp_str,buf2[PATTERN_SIZE]+1); If (temp_str <> '') then songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ temp_str else songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; If (header.ffver = FFVER_A2P) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header2.b0len,2,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; progress_num_steps := 0; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then begin LZH_decompress(buf1,buf2,header2.b0len); Move(buf2,pattdata^[temp DIV 8][temp MOD 8],PATTERN_SIZE); Move(buf2[PATTERN_SIZE],temp_str,buf2[PATTERN_SIZE]+1); If (temp_str <> '') then songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ temp_str else songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end; end else begin LZH_decompress(buf1,buf2,header2.b0len); Move(buf2,pattdata^[_pattern DIV 8][_pattern MOD 8],PATTERN_SIZE); Move(buf2[PATTERN_SIZE],temp_str,buf2[PATTERN_SIZE]+1); If (temp_str <> '') then songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ temp_str else songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; CloseF(f); load_flag := 1; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} function dec2hex(dec: Byte): Byte; begin dec2hex := (dec DIV 10)*16 +(dec MOD 10); end; function truncate_string(str: String): String; begin While (Length(str) > 0) and (str[Length(str)] in [#0,#32,#255]) do Delete(str,Length(str),1); truncate_string := str; end; procedure amd_file_loader; type tPATDAT = array[0..$24] of array[0..$3f] of array[1..9] of array[0..2] of Byte; type tINSDAT = Record iName: array[1..23] of Char; { Instrument name } iData: array[0..10] of Byte; { Instrument data } end; type tHEADER = Record sname: array[1..24] of Char; { Name of song [ASCIIZ] } aname: array[1..24] of Char; { Name of author [ASCIIZ] } instr: array[0..25] of tINSDAT; { 26 instruments } snlen: Byte; { Song length } nopat: Byte; { Number of patterns -1 } order: array[0..$7f] of Byte; { Pattern table } ident: array[1..9] of Char; { ID } versn: Byte; { Version 10h=normal module } { 11h=packed module } end; const id_amd = ' 0) then chunk.instr_def := (byte2 SHR 4)+(byte1 AND 1) SHL 4; If (byte1 SHR 4 in [1..12]) and ((byte1 SHR 1) AND 7 in [0..7]) then chunk.note := 12*((byte1 SHR 1) AND 7)+(byte1 SHR 4); param := byte3 AND $7f; Case byte2 AND $0f of { ARPEGGIO } $00: begin chunk.effect_def := ef_Arpeggio; chunk.effect := dec2hex(param); end; { SLIDE FREQUENCY UP } $01: begin chunk.effect_def := ef_FSlideUp; chunk.effect := param; end; { SLIDE FREQUENCY DOWN } $02: begin chunk.effect_def := ef_FSlideDown; chunk.effect := param; end; { SET CARRIER/MODULATOR INTENSITY } $03: If (param DIV 10 in [1..9]) then begin chunk.effect_def := ef_SetCarrierVol; chunk.effect := (param DIV 10)*7; end else If (param MOD 10 in [1..9]) then begin chunk.effect_def := ef_SetModulatorVol; chunk.effect := (param MOD 10)*7; end; { SET THE VOLUME } $04: begin chunk.effect_def := ef_SetInsVolume; If (param < 64) then chunk.effect := param else chunk.effect := 63; end; { JUMP INTO PATTERN } $05: begin chunk.effect_def := ef_PositionJump; If (param < 100) then chunk.effect := param else chunk.effect := 99; end; { PATTERNBREAK } $06: begin chunk.effect_def := ef_PatternBreak; If (param < 64) then chunk.effect := param else chunk.effect := 63; end; { SET SONGSPEED } $07: If (param < 99) then If (param in [1..31]) then begin chunk.effect_def := ef_SetSpeed; chunk.effect := param; end else begin chunk.effect_def := ef_SetTempo; If (param = 0) then chunk.effect := 18 else chunk.effect := param; end; { TONEPORTAMENTO } $08: begin chunk.effect_def := ef_TonePortamento; chunk.effect := param; end; { EXTENDED COMMAND } $09: If (param < 60) then Case param DIV 10 of { DEFINE CELL-TREMOLO } 0: If (param MOD 10 < 2) then begin chunk.effect_def := ef_Extended; chunk.effect := dec2hex(param); end; { DEFINE CELL-VIBRATO } 1: If (param MOD 10 < 2) then begin chunk.effect_def := ef_Extended; chunk.effect := $10+dec2hex(param); end; { INCREASE VOLUME FAST } 2: begin chunk.effect_def := ef_VolSlide; chunk.effect := (param MOD 10)*16; end; { DECREASE VOLUME FAST } 3: begin chunk.effect_def := ef_VolSlide; chunk.effect := param MOD 10; end; { INCREASE VOLUME FINE } 4: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_VolSlideUpXF*16+(param MOD 10); end; { DECREASE VOLUME FINE } 5: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_VolSlideDnXF*16+(param MOD 10); end; end; end; // specific corrections for Amusic event If (chunk.note = 0) then chunk.instr_def := 0; put_chunk(pattern,line,channel,chunk); end; procedure import_amd_packed_patterns(var data; patterns: Byte); var temp,temp2,temp3,temp4,temp5: Word; count: Byte; var tracks: Word; track_order: array[0..$3f] of array[1..9] of Word; track: array[0..$3f] of tCHUNK; begin temp := (patterns+1)*9*SizeOf(WORD); Move(data,track_order,temp); tracks := pBYTE(@data)[temp]+(pBYTE(@data)[temp+1]) SHL 8; Inc(temp,2); temp3 := 0; temp4 := 0; count := 0; Repeat If (count = 0) then begin If (temp3 = 0) then begin temp2 := pBYTE(@data)[temp]+(pBYTE(@data)[temp+1]) SHL 8; Inc(temp,2); end; If (pBYTE(@data)[temp] OR $80 <> pBYTE(@data)[temp]) then begin If (temp2 DIV 9 <= $3f) and (temp2 MOD 9 < 9) then import_amd_event(temp2 DIV 9,temp3,temp2 MOD 9 +1, pBYTE(@data)[temp+2], pBYTE(@data)[temp+1], pBYTE(@data)[temp+0]); Inc(temp,3); end else begin count := (pBYTE(@data)[temp] AND $7f)-1; Inc(temp); end; end else Dec(count); Inc(temp3); If (temp3 > $3f) then begin temp3 := 0; count := 0; Inc(temp4); end; until NOT (temp4 < tracks); For temp := 0 to patterns do For temp2 := 1 to 9 do begin temp3 := track_order[temp][temp2]; temp4 := temp3 DIV 9; If (temp3 < 64*9) then begin For temp5 := 0 to $3f do get_chunk(temp4,temp5,temp3 MOD 9 +1,track[temp5]); For temp5 := 0 to $3f do put_chunk( temp,temp5,temp2,track[temp5]); end; end; end; function get_byte(var pos: Longint): Byte; begin If (pos = SizeOf(buf1)) then begin Move(buf3,buf1,SizeOf(buf3)); pos := 0; end; get_byte := buf1[pos]; Inc(pos); end; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:amd_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and ((header.ident = id_amd) or (header.ident = id_xms))) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If NOT (header.versn in [$10,$11]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; tmp2 := WORD_NULL; If (temp = SizeOf(buf1)) then begin FillChar(buf3,SizeOf(buf3),0); BlockReadF(f,buf3,SizeOf(buf3),tmp2); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 50; speed := 6; songdata.tempo := tempo; songdata.speed := speed; For temp2 := 0 to header.snlen-1 do If (temp2 < 128) and (header.order[temp2] in [0..header.nopat]) then songdata.pattern_order[temp2] := header.order[temp2]; For temp2 := 0 to 25 do begin import_amd_instrument(temp2+1,header.instr[temp2].iData); songdata.instr_names[temp2+1] := Copy(songdata.instr_names[temp2+1],1,9)+ truncate_string(header.instr[temp2].iName); end; temp := 0; If (header.versn = $10) then For temp2 := 0 to header.nopat do For temp3 := 0 to $3f do For temp4 := 1 to 9 do begin byte3 := get_byte(temp); byte2 := get_byte(temp); byte1 := get_byte(temp); import_amd_event(temp2,temp3,temp4,byte1,byte2,byte3); end else import_amd_packed_patterns(buf1,header.nopat); songdata.common_flag := songdata.common_flag OR $80; songdata.songname := CutStr(asciiz_string(header.sname)); songdata.composer := CutStr(asciiz_string(header.aname)); import_old_flags; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> If (header.ident = id_amd) then load_flag := 5} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> else load_flag := 6;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; procedure import_hsc_instrument(inst: Byte; var data); forward; procedure import_cff_event(patt,line,chan,byte0,byte1,byte2: Byte); var chunk: tCHUNK; temp1,temp2,temp3,temp4: Byte; begin FillChar(chunk,SizeOf(chunk),0); temp1 := byte2; temp2 := temp1 DIV 16; temp3 := temp1 MOD 16; Case CHAR(byte1) of { SET SPEED } 'A': If (temp1 > 0) then begin chunk.effect_def := ef_SetSpeed; chunk.effect := temp1; end; { SET CARRIER WAVEFORM } 'B': If (temp1 < 4) then begin chunk.effect_def := ef_SetWaveform; chunk.effect := temp1*16; end; { SET MODULATOR VOLUME } 'C': begin chunk.effect_def := ef_SetModulatorVol; If (temp1 < 64) then chunk.effect := 63-temp1 else chunk.effect := 0; end; { VOLUME SLIDE UP/DOWN } 'D': begin chunk.effect_def := ef_VolSlide; chunk.effect := temp1; end; { SLIDE DOWN } 'E': If (temp1 <> 0) then begin chunk.effect_def := ef_FSlideDown; chunk.effect := temp1; end; { SLIDE UP } 'F': If (temp1 <> 0) then begin chunk.effect_def := ef_FSlideUp; chunk.effect := temp1; end; { SET CARRIER VOLUME } 'G': begin chunk.effect_def := ef_SetCarrierVol; If (temp1 < 64) then chunk.effect := 63-temp1 else chunk.effect := 0; end; { SET TEMPO } 'H': If (temp1 > 0) then begin chunk.effect_def := ef_SetTempo; If NOT (temp1 > 21) then temp1 := 125; temp4 := 1412926 DIV LONGINT(temp1 SHR 1); chunk.effect := 1; While (1193180 DIV chunk.effect > temp4) and (chunk.effect < 255) do Inc(chunk.effect); end; { SET INSTRUMENT } 'I': If (temp1 < 47) then begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; chunk.instr_def := temp1+1; end; { ARPEGGIO } 'J': begin chunk.effect_def := ef_Arpeggio; chunk.effect := temp1; end; { JUMP TO ORDER } 'K': If (temp1 < 128) then begin chunk.effect_def := ef_PositionJump; chunk.effect := temp1; end; { JUMP TO NEXT PATTERN IN ORDER } 'L': chunk.effect_def := ef_PatternBreak; { SET TREMOLO HIGHER / SET VIBRATO DEEPER } 'M': begin chunk.effect_def := ef_Extended; If (temp2 = 1) and (temp3 = 0) then chunk.effect := dec2hex(01); If (temp2 = 0) and (temp3 = 1) then chunk.effect := dec2hex(10); If (temp2 = 1) and (temp3 = 1) then chunk.effect := dec2hex(11); end; end; Case byte0 of { REGULAR NOTE } 1..12*8+1: begin If NOT fix_c_note_bug then chunk.note := byte0 else begin chunk.note := byte0+1; If (chunk.note > 12*8+1) then chunk.note := 12*8+1; end; end; { PAUSE } $6d: chunk.note := BYTE_NULL; end; put_chunk(patt,line,chan,chunk); end; procedure import_cff_patterns(var data; patterns: Byte); type tPATDAT = array[0..$24] of array[0..$3f] of array[1..9] of array[0..2] of Byte; var voice: array[1..9] of Byte; arpgg: array[1..9] of Byte; chunk: tCHUNK; temp,temp2,temp3,temp4: Byte; order,patt: Byte; patt_break: Byte; patts: String; function _empty_event(var data): Boolean; begin _empty_event := (pBYTE(@data)[0] = 0) and (pBYTE(@data)[1] = 0) and (pBYTE(@data)[2] = 0); end; begin patts := ''; FillChar(arpgg,SizeOf(arpgg),0); If NOT accurate_conv then For temp := 1 to 9 do voice[temp] := temp else For temp := 1 to 9 do voice[temp] := 0; For temp := 0 to $24 do For temp2 := 0 to $3f do For temp3 := 1 to 9 do If NOT _empty_event(tPATDAT(data)[temp][temp2][temp3]) then import_cff_event(temp,temp2,temp3,tPATDAT(data)[temp][temp2][temp3][0], tPATDAT(data)[temp][temp2][temp3][1], tPATDAT(data)[temp][temp2][temp3][2]); order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] > $24) then Inc(order) else begin patt := songdata.pattern_order[order]; patt_break := BYTE_NULL; For temp2 := 0 to $3f do For temp3 := 1 to 9 do begin get_chunk(patt,temp2,temp3,chunk); temp4 := tPATDAT(data)[patt][temp2][temp3][2]; Case CHAR(tPATDAT(data)[patt][temp2][temp3][1]) of { SET MODULATOR VOLUME } 'C': If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; { SET CARRIER VOLUME } 'G': If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; { SET INSTRUMENT } 'I': If (temp4 < 47) then If (temp2 <> patt_break) then begin voice[temp3] := temp4+1; If NOT accurate_conv then chunk.instr_def := voice[temp3]; end; { ARPEGGIO } 'J': begin chunk.effect_def := ef_Arpeggio; If (temp4 <> 0) then begin chunk.effect := temp4; arpgg[temp3] := temp4; end else chunk.effect := arpgg[temp3]; end; { JUMP TO ORDER } 'K': If (temp4 < 128) then patt_break := temp2+1; { JUMP TO NEXT PATTERN IN ORDER } 'L': patt_break := temp2+1; end; Case tPATDAT(data)[patt][temp2][temp3][0] of { REGULAR NOTE } 1..12*8+1: begin If accurate_conv then If (voice[temp3] = 0) then begin voice[temp3] := temp3; chunk.instr_def := voice[temp3]; end; If NOT accurate_conv then chunk.instr_def := voice[temp3]; end; end; If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then put_chunk(patt,temp2,temp3,chunk); end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $40); end; procedure cff_file_loader; type tHEADER = Record ident: array[1..16] of Char; { Identification } versn: Byte; { Format version } fsize: Word; { Filesize -32 } cflag: Byte; { Flag 1=compressed data } resrv: array[0..11] of Byte; { Reserved } end; type tINSDAT = Record iData: array[0..11] of Byte; { Instrument data } iName: array[1..20] of Char; { Instrument name } end; type tHEADR2 = Record instr: array[0..46] of tINSDAT; { 47 instruments } nopat: Byte; { Number of patterns } ascii: array[1..31] of Char; { ASCII blab } writr: array[1..20] of Char; { Song writer } sname: array[1..20] of Char; { Song name } order: array[0..64] of Byte; { Pattern order } end; const _PRE_ASCII_BLAB_SIZE = $5e1; // SizeOf(tHEADR2.instr)+SizeOf(tHEADR2.nopat) const id = ''+#26+CHR($de)+CHR($e0); ascii_blab = 'CUD-FM-File - SEND A POSTCARD -'; var f: File; header: tHEADER; headr2: tHEADR2; temp,temp2: Longint; offs,out_size: Longint; function LZTYR_decompress(var input,output): Longint; type tSTRING = array[0..255] of Byte; var input_idx: Longint; the_string, temp_string: tSTRING; old_code_length: Byte; repeat_length: Byte; repeat_counter: Longint; output_length: Longint; code_length: Byte; bits_buffer: Longint; bits_left: Word; old_code: Longint; new_code: Longint; idx: Word; _cff_heap_length: Word; _cff_dictionary_length: Word; _cff_dictionary: array[0..32767] of Pointer; function get_code: Longint; var code: Longint; begin While (bits_left < code_length) do begin bits_buffer := bits_buffer OR (pBYTE(@input)[input_idx] SHL bits_left); Inc(input_idx); Inc(bits_left,8); end; code := bits_buffer AND ((1 SHL code_length)-1); bits_buffer := bits_buffer SHR code_length; Dec(bits_left,code_length); get_code := code; end; procedure translate_code(code: Longint; var str: tSTRING); var translated_string: tSTRING; begin If (code >= $104) then Move(_cff_dictionary[code-$104]^,translated_string, BYTE(_cff_dictionary[code-$104]^)+1) else begin translated_string[0] := 1; translated_string[1] := (code-4) AND $0ff; end; Move(translated_string,str,256); end; procedure startup; var idx: Longint; begin old_code := get_code; translate_code(old_code,the_string); If (the_string[0] > 0) then For idx := 0 to the_string[0]-1 do begin pBYTE(@output)[output_length] := the_string[idx+1]; Inc(output_length); end; end; procedure cleanup; begin code_length := 9; bits_buffer := 0; bits_left := 0; _cff_heap_length := 0; _cff_dictionary_length := 0; end; procedure expand__cff_dictionary(str: tSTRING); begin If (str[0] >= $0f0) then EXIT; Move(str,buf3[_cff_heap_length],str[0]+1); _cff_dictionary[_cff_dictionary_length] := Addr(buf3[_cff_heap_length]); Inc(_cff_dictionary_length); Inc(_cff_heap_length,str[0]+1); end; begin input_idx := 0; output_length := 0; cleanup; startup; Repeat new_code := get_code; // $00: end of data If (new_code = 0) then BREAK; // $01: end of block If (new_code = 1) then begin cleanup; startup; CONTINUE; end; // $02: expand code length If (new_code = 2) then begin Inc(code_length); CONTINUE; end; // $03: RLE If (new_code = 3) then begin old_code_length := code_length; code_length := 2; repeat_length := get_code+1; code_length := 4 SHL get_code; repeat_counter := get_code; For idx := 0 to PRED(repeat_counter*repeat_length) do begin pBYTE(@output)[output_length] := pBYTE(@output)[output_length-repeat_length]; Inc(output_length); end; code_length := old_code_length; startup; CONTINUE; end; If (new_code >= $104+_cff_dictionary_length) then begin Inc(the_string[0]); the_string[the_string[0]] := the_string[1]; end else begin translate_code(new_code,temp_string); Inc(the_string[0]); the_string[the_string[0]] := temp_string[1]; end; expand__cff_dictionary(the_string); translate_code(new_code,the_string); For idx := 0 to PRED(the_string[0]) do begin pBYTE(@output)[output_length] := the_string[idx+1]; Inc(output_length); end; old_code := new_code; until FALSE; LZTYR_decompress := output_length; end; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:cff_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) or (FileSize(f) > SizeOf(buf1)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If (header.cflag = 1) then begin FillChar(buf1,SizeOf(buf1),0); ResetF(f); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; CloseF(f); temp := LZTYR_decompress(buf1[$30],hash_buffer); out_size := temp; offs := SensitiveScan(hash_buffer,0,temp,ascii_blab); If (offs <> _PRE_ASCII_BLAB_SIZE) then begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR DECOMPRESSiNG MODULE DATA$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(buf1,SizeOf(buf1),0); Move(hash_buffer,headr2,SizeOf(headr2)); Move(POINTER(Ofs(hash_buffer)+SizeOf(headr2))^,buf1,out_size-SizeOf(headr2)); end else begin BlockReadF(f,headr2,SizeOf(headr2),temp); If NOT ((temp = SizeOf(headr2)) and (headr2.ascii = ascii_blab)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; CloseF(f); end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 51; speed := 6; songdata.tempo := tempo; songdata.speed := speed; For temp2 := 0 to 64 do If (headr2.order[temp2] in [0..headr2.nopat]) then songdata.pattern_order[temp2] := headr2.order[temp2]; For temp2 := 0 to 46 do begin import_hsc_instrument(temp2+1,headr2.instr[temp2].iData); songdata.instr_data[temp2+1].fine_tune := 0; songdata.instr_names[temp2+1] := Copy(songdata.instr_names[temp2+1],1,9)+ truncate_string(headr2.instr[temp2].iName); end; songdata.common_flag := songdata.common_flag OR 2; songdata.songname := CutStr(headr2.sname); songdata.composer := CutStr(headr2.writr); import_old_flags; import_cff_patterns(buf1,headr2.nopat); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 7;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; procedure import_standard_instrument(inst: Byte; var data); begin With songdata.instr_data[inst] do begin fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[6]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[7]; fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 3; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3; fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f; end; songdata.instr_data[inst].panning := 0; songdata.instr_data[inst].fine_tune := 0; end; procedure dfm_file_loader; const id = 'DFM'+#26; var header: Record ident: array[1..4] of Char; versn: Word; sname: String[32]; tempo: Byte; instn: array[1..32] of String[11]; instd: array[1..32] of tFM_INST_DATA; order: array[1..128] of Byte; patts: Byte; end; var f: File; temp,temp2,temp3: Longint; pattern,line,channel,byte1,byte2: Byte; procedure import_dfm_event(patt,line,chan,byte1,byte2: Byte); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); If (byte1 AND $0f in [1..12,15]) and ((byte1 SHR 4) AND 7 in [0..7]) then If (byte1 AND $0f <> 15) then chunk.note := SUCC(PRED(byte1 AND $0f)+((byte1 SHR 4) AND 7)*12) else chunk.note := BYTE_NULL; Case byte2 SHR 5 of { INSTRUMENT CHANGE } 1: chunk.instr_def := SUCC(byte2 AND $1f); { SET INSTRUMENT VOLUME } 2: begin chunk.effect_def := ef_SetInsVolume; chunk.effect := (byte2 AND $1f)*2; end; { TEMPO CHANGE } 3: begin chunk.effect_def := ef_SetSpeed; chunk.effect := SUCC(byte2 AND $1f); end; { SLIDE UP } 4: begin chunk.effect_def := ef_FSlideUpFine; chunk.effect := byte2 AND $1f; end; { SLIDE DOWN } 5: begin chunk.effect_def := ef_FSlideDownFine; chunk.effect := byte2 AND $1f; end; { END OF PATTERN } 7: chunk.effect_def := ef_PatternBreak; end; put_chunk(patt,line,chan,chunk); end; procedure process_dfm_patterns(patterns: Byte); var chunk: tCHUNK; temp2,temp3: Byte; order,patt: Byte; patts: String; instr_cache: array[1..18] of Byte; begin patts := ''; FillChar(instr_cache,SizeOf(instr_cache),0); order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; For temp2 := 0 to $3f do For temp3 := 1 to 9 do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.instr_def <> 0) then begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; instr_cache[temp3] := chunk.instr_def; If NOT (chunk.note in [1..12*8+1]) and NOT accurate_conv then chunk.instr_def := 0; end else If (chunk.note in [1..12*8+1]) and (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := instr_cache[temp3]; If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then put_chunk(patt,temp2,temp3,chunk); end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); end; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:dfm_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 135; speed := SUCC(header.tempo); songdata.songname := CutStr(header.sname); songdata.tempo := tempo; songdata.speed := speed; songdata.common_flag := songdata.common_flag OR 1; songdata.common_flag := songdata.common_flag OR 2; songdata.common_flag := songdata.common_flag OR 8; songdata.common_flag := songdata.common_flag OR $10; import_old_flags; For temp2 := 1 to 128 do If (header.order[temp2] in [0..$7f]) then songdata.pattern_order[temp2-1] := header.order[temp2] else If (header.order[temp2] = $80) then BREAK else songdata.pattern_order[temp2-1] := $80+temp2; For temp2 := 1 to 32 do begin songdata.instr_names[temp2] := Copy(songdata.instr_names[temp2],1,9)+ CutStr(header.instn[temp2]); While (BYTE(songdata.instr_names[temp2][ Length(songdata.instr_names[temp2])]) < 32) and (Length(songdata.instr_names[temp2]) <> 0) do Delete(songdata.instr_names[temp2], Length(songdata.instr_names[temp2]),1); import_standard_instrument(temp2,header.instd[temp2]); end; temp2 := 0; temp3 := 0; Repeat pattern := buf1[temp2]; If (pattern > 127) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Inc(temp2); Inc(temp3); For line := 0 to $3f do For channel := 1 to 9 do begin byte1 := buf1[temp2]; If (temp2 >= temp) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end else Inc(temp2); If (byte1 OR $80 <> byte1) then byte2 := 0 else begin byte2 := buf1[temp2]; Inc(temp2); end; import_dfm_event(pattern,line,channel,byte1,byte2); end; until (temp2 >= temp); process_dfm_patterns(temp3); CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 8;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; type tHSC_PATTERNS = array[0..$31] of array[0..$3f] of array[1..9] of Word; type tHSC_DATA = Record instr: array[0..$7f] of array[0..$0b] of Byte; order: array[0..$31] of Byte; patts: tHSC_PATTERNS; end; procedure import_hsc_event(patt,line,chan: Byte; event: Word); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); Case HI(event) of { REGULAR NOTE } 1..12*8+1: If NOT fix_c_note_bug then chunk.note := HI(event) else begin chunk.note := HI(event)+1; If (chunk.note > 12*8+1) then chunk.note := 12*8+1; end; { PAUSE } $7f: chunk.note := BYTE_NULL; { INSTRUMENT } $80: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; chunk.instr_def := LO(event)+1; chunk.note := BYTE_NULL; end; end; If (HI(event) <> $80) then Case (LO(event) AND $0f0) of { PATTERNBREAK } $00: If (LO(event) AND $0f = 1) then chunk.effect_def := ef_PatternBreak; { MANUAL SLIDE UP } $10: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneUp*16+ max(LO(event) AND $0f +1,15); end; { MANUAL SLIDE DOWN } $20: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_FineTuneDown*16+ max(LO(event) AND $0f +1,15); end; { SET CARRIER VOLUME } $a0: begin chunk.effect_def := ef_SetCarrierVol; chunk.effect := 63-(LO(event) AND $0f)*4; chunk.instr_def := LO(event)+1; end; { SET MODULATOR VOLUME } $b0: begin chunk.effect_def := ef_SetModulatorVol; chunk.effect := 63-(LO(event) AND $0f)*4; end; { SET INSTRUMENT VOLUME } $c0: begin chunk.effect_def := ef_SetInsVolume; chunk.effect := 63-(LO(event) AND $0f)*4; end; { SET SPEED } $f0: begin chunk.effect_def := ef_SetSpeed; chunk.effect := (LO(event) AND $0f)+1; end; end; put_chunk(patt,line,chan,chunk); end; procedure import_hsc_patterns(var data; patterns: Byte); var voice: array[1..9] of Byte; event: Word; chunk: tCHUNK; temp,temp2,temp3: Byte; order,patt: Byte; patt_break: Byte; patts: String; function _hsc_event(patt,line,chan: Byte): Word; begin _hsc_event := LO(tHSC_PATTERNS(data)[patt][line][chan+1])+ HI(tHSC_PATTERNS(data)[patt][line][chan]) SHL 8; end; begin { import_hsc_patterns } patts := ''; If NOT accurate_conv then For temp := 1 to 9 do voice[temp] := temp else For temp := 1 to 9 do voice[temp] := 0; For temp := 0 to $31 do For temp2 := 0 to $3f do For temp3 := 1 to 9 do If (_hsc_event(temp,temp2,temp3) <> 0) then import_hsc_event(temp,temp2,temp3,_hsc_event(temp,temp2,temp3)); order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] > $31) then Inc(order) else begin patt := songdata.pattern_order[order]; patt_break := BYTE_NULL; For temp2 := 0 to $3f do For temp3 := 1 to 9 do begin get_chunk(patt,temp2,temp3,chunk); event := _hsc_event(patt,temp2,temp3); Case HI(event) of { REGULAR NOTE } 1..12*8+1: begin If accurate_conv then If (voice[temp3] = 0) then begin voice[temp3] := temp3; chunk.instr_def := voice[temp3]; end; If NOT accurate_conv then chunk.instr_def := voice[temp3]; end; { INSTRUMENT } $80: If (temp2 <> patt_break) then begin voice[temp3] := LO(event)+1; If NOT accurate_conv then begin chunk.instr_def := voice[temp3]; chunk.note := BYTE_NULL; end; end; end; If (HI(event) <> $80) then Case (LO(event) AND $0f0) of { PATTERNBREAK } $00: If (LO(event) AND $0f = 1) then patt_break := temp2+1; { SET CARRIER VOLUME } $a0: If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; { SET MODULATOR VOLUME } $b0: If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; { SET INSTRUMENT VOLUME } $c0: If (chunk.instr_def = 0) and NOT accurate_conv then chunk.instr_def := voice[temp3] else If (chunk.instr_def = 0) and (voice[temp3] = 0) then chunk.instr_def := temp3; end; If (Pos(CHR(songdata.pattern_order[order]),patts) = 0) then put_chunk(patt,temp2,temp3,chunk); end; Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); end; procedure import_hsc_instrument(inst: Byte; var data); begin With songdata.instr_data[inst] do begin fm_data.AM_VIB_EG_carrier := pBYTE(@data)[0]; fm_data.AM_VIB_EG_modulator := pBYTE(@data)[1]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[2]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[3]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[4]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[5]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[6]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[7]; fm_data.FEEDBACK_FM := pBYTE(@data)[8] AND $0f; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 3; fm_data.WAVEFORM_modulator := pBYTE(@data)[10] AND 3; end; songdata.instr_data[inst].panning := 0; songdata.instr_data[inst].fine_tune := pBYTE(@data)[11] SHR 4; end; var hscbuf: tHSC_DATA; procedure hsc_file_loader; const HSC_KSL: array[0..3] of Byte = (0,3,2,1); var f: File; temp,temp2,temp3: Longint; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:hsc_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> If (Lower(ExtOnly(songdata_source)) <> 'hsc') then} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> begin} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> EXIT;} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> end;} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' HSC LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} FillChar(hscbuf,SizeOf(hscbuf),0); BlockReadF(f,hscbuf,SizeOf(hscbuf),temp); If (temp < SizeOf(hscbuf.instr)+SizeOf(hscbuf.order)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' HSC LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; For temp2 := 0 to $31 do If (hscbuf.order[temp2] > $b0) then hscbuf.order[temp2] := $080; temp3 := 0; While (temp3 < temp-SizeOf(hscbuf.instr)-SizeOf(hscbuf.order)) do begin If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3+1] in [1..12*8+1,$00,$7f,$80]) or NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3] AND $0f0 in [$00,$10,$20,$a0,$b0,$c0,$f0]) then begin If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3+1] in [1..12*8+1,$00,$7f,$80]) then pBYTE(@Addr(hscbuf.patts)^)[temp3+1] := $00; If NOT (pBYTE(@Addr(hscbuf.patts)^)[temp3] AND $0f0 in [$00,$10,$20,$a0,$b0,$c0,$f0]) then pBYTE(@Addr(hscbuf.patts)^)[temp3] := 0; end; Inc(temp3,2); end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 18; speed := 2; songdata.common_flag := songdata.common_flag OR 2; songdata.tempo := tempo; songdata.speed := speed; import_old_flags; For temp2 := 0 to $31 do songdata.pattern_order[temp2] := hscbuf.order[temp2]; import_hsc_patterns(hscbuf.patts,(temp-SizeOf(hscbuf.instr) -SizeOf(hscbuf.order)-1) DIV $480); // specific corrections for HSC-Tracker instrument For temp2 := 0 to $7f do begin import_hsc_instrument(temp2+1,hscbuf.instr[temp2]); With songdata.instr_data[temp2+1].fm_data do begin KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $3f+ HSC_KSL[KSL_VOLUM_modulator SHR 6] SHL 6; KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $3f+ HSC_KSL[KSL_VOLUM_carrier SHR 6] SHL 6; end; end; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 9;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; type tMTK_DATA = Record sname: String[33]; compo: String[33]; instn: array[0..$7f] of String[33]; instt: array[0..$7f] of array[0..$0b] of Byte; order: array[0..$7f] of Byte; patts: tHSC_PATTERNS; dummy: Byte; end; var buffer2: tMTK_DATA; procedure mtk_file_loader; var f: File; temp,temp2: Longint; crc: Word; old_c_fix: Boolean; const id = 'mpu401tr'#146'kk'#238'r@data'; var header: Record id_string: array[1..18] of Char; crc_16bit: Word; data_size: Word; end; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:mtk_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' MTK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id_string = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' MTK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); crc := 0; crc := Update16(buf1,temp,crc); If (crc <> header.crc_16bit) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' MTK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(buffer2,SizeOf(buffer2),0); temp2 := RDC_decompress(buf1,buffer2,temp); If NOT (temp2 = header.data_size) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' MTK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; tempo := 18; speed := 2; songdata.common_flag := songdata.common_flag OR 2; songdata.tempo := tempo; songdata.speed := speed; import_old_flags; For temp2 := 0 to $31 do If (buffer2.order[temp2] <> $ff) then songdata.pattern_order[temp2] := buffer2.order[temp2] else songdata.pattern_order[temp2] := $080; old_c_fix := fix_c_note_bug; fix_c_note_bug := FALSE; import_hsc_patterns(buffer2.patts, (header.data_size-SizeOf(buffer2.sname) -SizeOf(buffer2.compo) -SizeOf(buffer2.instn) -SizeOf(buffer2.instt) -SizeOf(buffer2.order)-1) DIV $480); fix_c_note_bug := old_c_fix; // specific corrections for MPU-401 TRAKKER instrument For temp2 := 0 to $7f do begin import_hsc_instrument(temp2+1,buffer2.instt[temp2]); With songdata.instr_data[temp2+1].fm_data do begin If (KSL_VOLUM_modulator > 128) then KSL_VOLUM_modulator := KSL_VOLUM_modulator DIV 3; If (KSL_VOLUM_carrier > 128) then KSL_VOLUM_carrier := KSL_VOLUM_carrier DIV 3; end; songdata.instr_names[temp2+1] := Copy(songdata.instr_names[temp2+1],1,9)+ truncate_string(Copy(buffer2.instn[temp2],10,32)); end; songdata.songname := CutStr(buffer2.sname); songdata.composer := CutStr(buffer2.compo); CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 10;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; procedure rad_file_loader; const id = 'RAD by REALiTY!!'; var header: Record ident: array[1..16] of Char; { Use this to recognize a RAD tune } rmver: Byte; { Version of RAD file (10h) } xbyte: Byte; { bit7 Set if a description follows } end; { bit6 Set if it's a "slow-timer" tune } { bit[4..0] The initial speed of the tune } var f: File; dscbuf: array[0..PRED(80*22)] of Char; pattoffs: array[0..$1f] of Word; temp,temp2,temp3,temp4,temp5,offs0: Longint; procedure import_rad_event(pattern,line,channel,byte1,byte2,byte3: Byte); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); If ((byte2 SHR 4)+(byte1 SHR 7) SHL 4 <> 0) then chunk.instr_def := (byte2 SHR 4)+(byte1 SHR 7) SHL 4; If (byte1 AND $0f in [1..12]) then chunk.note := 12*((byte1 SHR 4) AND 7)+(byte1 AND $0f)+1 else If (byte1 AND $0f = $0f) then chunk.note := BYTE_NULL; Case byte2 AND $0f of { PORTAMENTO (FREQUENCY SLIDE) UP } $01: begin chunk.effect_def := ef_FSlideUp; chunk.effect := byte3; end; { PORTAMENTO (FREQUENCY SLIDE) DOWN } $02: begin chunk.effect_def := ef_FSlideDown; chunk.effect := byte3; end; { PORTAMENTO TO NOTE } $03: begin chunk.effect_def := ef_TonePortamento; chunk.effect := byte3; end; { PORTAMENTO TO NOTE WITH VOLUME SLIDE } $05: If (byte3 in [1..49]) then begin chunk.effect_def := ef_TPortamVolSlide; chunk.effect := max(byte3,15); If (byte3 > 15) then begin chunk.effect_def2 := ef_TPortamVolSlide; chunk.effect2 := max(byte3-15,15); end; end else If (byte3 in [51..99]) then begin chunk.effect_def := ef_TPortamVolSlide; chunk.effect := max(byte3-50,15)*16; If (byte3-50 > 15) then begin chunk.effect_def2 := ef_TPortamVolSlide; chunk.effect2 := max(byte3-50-15,15); end; end; { VOLUME SLIDE } $0a: If (byte3 in [1..49]) then begin chunk.effect_def := ef_VolSlide; chunk.effect := max(byte3,15); If (byte3 > 15) then begin chunk.effect_def2 := ef_VolSlide; chunk.effect2 := max(byte3-15,15); end; end else If (byte3 in [51..99]) then begin chunk.effect_def := ef_VolSlide; chunk.effect := max(byte3-50,15)*16; If (byte3-50 > 15) then begin chunk.effect_def2 := ef_VolSlide; chunk.effect2 := max(byte3-50-15,15); end; end; { SET VOLUME } $0c: begin chunk.effect_def := ef_SetInsVolume; If (byte3 < 64) then chunk.effect := byte3 else chunk.effect := 63; end; { JUMP TO NEXT PATTERN IN ORDER LIST } $0d: begin chunk.effect_def := ef_PatternBreak; If (byte3 < 64) then chunk.effect := byte3 else chunk.effect := 63; end; { SET SPEED } $0f: begin chunk.effect_def := ef_SetSpeed; chunk.effect := byte3; end; end; // specific corrections for RAd-Tracker event If (chunk.effect_def in [ef_TonePortamento, ef_TPortamVolSlide]) and (chunk.note = BYTE_NULL) then chunk.note := 0; If (chunk.effect_def in [ef_TonePortamento, ef_TPortamVolSlide]) then chunk.instr_def := 0; If (chunk.note = 0) then chunk.instr_def := 0; put_chunk(pattern,line,channel+1,chunk); end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} procedure list_rad_description(length: Word); var desc: array[1..22] of String[80]; temp,fkey: Word; row,temp2: Byte; xstart,ystart: Byte; begin FillChar(desc,SizeOf(desc),0); temp := 0; row := 1; While (dscbuf[temp] <> #0) and (temp < length) do begin Case dscbuf[temp] of #1: If (row < 22) then Inc(row); #2..#31: For temp2 := 1 to BYTE(dscbuf[temp]) do desc[row] := desc[row]+' '; #32..#255: desc[row] := desc[row]+dscbuf[temp]; end; Inc(temp); end; temp2 := 0; For temp := 1 to 22 do If (truncate_string(desc[temp]) <> '') then Inc(temp2); If (temp2 = 0) then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; centered_frame(xstart,ystart,81,24,' RAD DESCRiPTiON ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); For temp := 1 to 22 do ShowStr(screen_ptr,xstart+1,ystart+temp,FilterStr2(desc[temp],_valid_characters,'_'), dialog_background+dialog_context_dis); ShowCStr(screen_ptr,xstart+36,ystart+23,' ~C~ONTiNUE ', dialog_sel_itm_bck+dialog_sel_itm, dialog_sel_itm_bck+dialog_sel_short); Repeat fkey := getkey; until (fkey = kESC) or (fkey = kENTER) or (HI(fkey) = $2e); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+81+2; move_to_screen_area[4] := ystart+24+1; move2screen; no_status_refresh := TRUE; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:rad_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; temp2 := 0; offs0 := SizeOf(header); If (header.xbyte OR $80 = header.xbyte) then begin While (temp2 < temp) and (buf1[temp2] <> 0) do Inc(temp2); If (temp2 >= temp) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; Inc(offs0,temp2+1); Dec(temp,temp2+1); Move(buf1,dscbuf,temp2+1); Move(buf1[temp2+1],buf1,temp); end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If mod_description and (temp2 <> 0) and NOT quick_cmd and NOT shift_pressed then list_rad_description(temp2+1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} init_songdata; load_flag := 0; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; If (header.xbyte OR $40 = header.xbyte) then tempo := 18 else tempo := 50; If (header.xbyte AND $1f in [1..31]) then speed := header.xbyte AND $1f else speed := 2; songdata.tempo := tempo; songdata.speed := speed; temp2 := 0; Repeat temp3 := buf1[temp2]; Inc(temp2); If (temp3 <> 0) and (temp2+11 < temp) then begin import_hsc_instrument(temp3,buf1[temp2]); songdata.instr_data[temp3].fine_tune := 0; Inc(temp2,11); end; until (temp3 = 0) or (temp3 >= temp); Inc(offs0,temp2); Dec(temp,temp2); Move(buf1[temp2],buf1,temp); Inc(offs0,buf1[0]+1); If (buf1[0] <> 0) then Move(buf1[1],songdata.pattern_order,buf1[0]); Inc(offs0,32*SizeOf(WORD)); Dec(temp,buf1[0]+1+32*SizeOf(WORD)); Move(buf1[buf1[0]+1],pattoffs,32*SizeOf(WORD)); Move(buf1[buf1[0]+32*SizeOf(WORD)+1],buf1,temp); temp5 := temp; For temp := 0 to 31 do begin temp2 := 0; temp3 := 0; If (pattoffs[temp] <> 0) and (pattoffs[temp] <= FileSize(f)) then Repeat temp2 := buf1[pattoffs[temp]-offs0+temp3]; Repeat Inc(temp3); temp4 := buf1[pattoffs[temp]-offs0+temp3]; If (buf1[pattoffs[temp]-offs0+temp3+2] AND $0f <> 0) then begin If (temp4 AND $0f in [0..8]) then import_rad_event(temp,temp2 AND $3f,temp4 AND $0f, buf1[pattoffs[temp]-offs0+temp3+1], buf1[pattoffs[temp]-offs0+temp3+2], buf1[pattoffs[temp]-offs0+temp3+3]); Inc(temp3,3); end else begin If (temp4 AND $0f in [0..8]) then import_rad_event(temp,temp2 AND $3f,temp4 AND $0f, buf1[pattoffs[temp]-offs0+temp3+1], buf1[pattoffs[temp]-offs0+temp3+2], 0); Inc(temp3,2); end; until (temp4 OR $80 = temp4) or (temp3 > temp5); Inc(temp3); until (temp2 OR $80 = temp2) or (temp3 > temp5); end; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 11;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; const temp_ef_Arpeggio = $0f0; temp_ef_rep = $0f1; temp_ef_XFVSlide = $0f2; var ins_c4factor: array[1..99] of Shortint; procedure fix_s3m_commands(patterns: Byte); var chunk,chunk2: tCHUNK; temp,temp4: Byte; patt_break: Byte; order,patt: Byte; patts: String; ins_cache, misc_cache, arpg_cache, volsld_cache, slide_cache, note_cache, patloop_cache: array[1..20] of Byte; prev_cache: array[1..20] of Record effect_def, effect, effect_def2, effect2: Byte; end; procedure fix_single_pattern(patt: Byte); var temp2,temp3: Byte; begin FillChar(prev_cache,SizeOf(prev_cache),0); FillChar(patloop_cache,SizeOf(patloop_cache),BYTE_NULL); patt_break := BYTE_NULL; For temp2 := 0 to $3f do For temp3 := 1 to 20 do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then patt_break := temp2; If (chunk.instr_def <> 0) and (temp2 <= patt_break) then ins_cache[temp3] := chunk.instr_def; If (chunk.note in [1..12*8+1]) and (temp2 <= patt_break) then note_cache[temp3] := chunk.note; If (chunk.instr_def <> 0) or ((chunk.instr_def = 0) and (chunk.note in [1..12*8+1]) and (ins_cache[temp3] <> 0)) then begin If (chunk.instr_def <> 0) then temp4 := chunk.instr_def else temp4 := ins_cache[temp3]; If (ins_c4factor[temp4] <> 0) and NOT (Pos(CHR(songdata.pattern_order[order]),patts) <> 0) then begin If (ins_c4factor[temp4] <> -127) then chunk.note := min(max(chunk.note+ins_c4factor[temp4],12*8+1),1) else chunk.note := 1; put_chunk(patt,temp2,temp3,chunk); end; end; If (chunk.effect_def = ef_Extended) and (chunk.effect DIV 16 = ef_ex_PatternLoop) and (chunk.effect MOD 16 <> 0) then If NOT (patloop_cache[temp3] in [0,BYTE_NULL]) and (temp2 <> 0) then begin If (prev_cache[temp3].effect_def = 0) and (prev_cache[temp3].effect = 0) then begin get_chunk(patt,PRED(temp2),temp3,chunk2); chunk2.effect_def := ef_Extended; chunk2.effect := ef_ex_PatternLoop*16; If NOT ((chunk2.effect_def = chunk2.effect_def2) and (chunk2.effect = chunk2.effect2)) then begin put_chunk(patt,PRED(temp2),temp3,chunk2); prev_cache[temp3].effect_def := chunk.effect_def; prev_cache[temp3].effect := chunk.effect; end; end else If (prev_cache[temp3].effect_def2 = 0) and (prev_cache[temp3].effect2 = 0) then begin get_chunk(patt,PRED(temp2),temp3,chunk2); chunk2.effect_def2 := ef_Extended; chunk2.effect2 := ef_ex_PatternLoop*16; If NOT ((chunk2.effect_def2 = chunk2.effect_def) and (chunk2.effect2 = chunk2.effect)) then begin put_chunk(patt,PRED(temp2),temp3,chunk2); prev_cache[temp3].effect_def2 := chunk.effect_def2; prev_cache[temp3].effect2 := chunk.effect2; end; end; end else If (patloop_cache[temp3] <> 0) and (temp2 <> 0) then begin get_chunk(patt,0,temp3,chunk2); If (chunk2.effect_def = 0) and (chunk2.effect = 0) then begin chunk2.effect_def := ef_Extended; chunk2.effect := ef_ex_PatternLoop*16; If NOT ((chunk2.effect_def = chunk2.effect_def2) and (chunk2.effect = chunk2.effect2)) then put_chunk(patt,0,temp3,chunk2); end else If (chunk2.effect_def2 = 0) and (chunk2.effect2 = 0) then begin chunk2.effect_def2 := ef_Extended; chunk2.effect2 := ef_ex_PatternLoop*16; If NOT ((chunk2.effect_def2 = chunk2.effect_def) and (chunk2.effect2 = chunk2.effect)) then put_chunk(patt,0,temp3,chunk2); end; end; If (temp2 <= patt_break) then begin If (chunk.effect DIV 16 <> 0) then misc_cache[temp3] := chunk.effect AND $0f0+ misc_cache[temp3] AND $0f else If (chunk.effect_def in [ef_Vibrato, ef_ExtraFineVibrato, ef_Tremolo, ef_Tremor, ef_MultiRetrigNote]) then begin chunk.effect := misc_cache[temp3] AND $0f0+ chunk.effect AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect MOD 16 <> 0) then misc_cache[temp3] := misc_cache[temp3] AND $0f0+ chunk.effect AND $0f else If (chunk.effect_def in [ef_Vibrato, ef_ExtraFineVibrato, ef_Tremolo, ef_Tremor, ef_MultiRetrigNote]) then begin chunk.effect := chunk.effect AND $0f0+ misc_cache[temp3] AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = temp_ef_Arpeggio) then If (chunk.effect <> 0) then arpg_cache[temp3] := chunk.effect else begin chunk.effect := arpg_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, ef_FSlideUp,ef_FSlideUpFine, ef_TonePortamento]) then If (chunk.effect <> 0) then slide_cache[temp3] := chunk.effect else begin chunk.effect := slide_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; // experimental method to fix up frequency slide If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, ef_FSlideUp,ef_FSlideUpFine, ef_Vibrato, ef_ExtraFineVibrato, ef_TonePortamento]) then If (note_cache[temp3] <> 0) then begin If (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato]) then begin temp := chunk.effect AND $0f0; chunk.effect := chunk.effect MOD 16; end; Case SUCC(PRED(note_cache[temp3]) DIV 12) of 1: chunk.effect := max(Round(chunk.effect*0.55),255); 2: chunk.effect := max(Round(chunk.effect*0.75),255); 3: chunk.effect := max(Round(chunk.effect*0.95),255); 4: chunk.effect := max(Round(chunk.effect*1.15),255); 5: chunk.effect := max(Round(chunk.effect*1.35),255); 6: chunk.effect := max(Round(chunk.effect*1.55),255); 7: chunk.effect := max(Round(chunk.effect*1.75),255); 8: chunk.effect := max(Round(chunk.effect*1.95),255); end; If (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato]) then chunk.effect := max(chunk.effect,15)+temp; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = ef_Extended2) and (chunk.effect DIV 16 in [ef_ex2_FreqSlideDnXF,ef_ex2_FreqSlideUpXF]) then If (chunk.effect MOD 16 <> 0) then slide_cache[temp3] := chunk.effect MOD 16 else begin chunk.effect := chunk.effect AND $0f0+slide_cache[temp3] AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_TPortamVolSlide,ef_VibratoVolSlide, ef_VolSlide,ef_VolSlideFine]) and (temp2 <= patt_break) then begin If (chunk.effect <> 0) then volsld_cache[temp3] := chunk.effect else begin chunk.effect := volsld_cache[temp3];; put_chunk(patt,temp2,temp3,chunk); end; end; If (chunk.effect_def = ef_Extended2) and (chunk.effect DIV 16 in [ef_ex2_VolSlideDnXF,ef_ex2_VolSlideUpXF]) then If (chunk.effect MOD 16 <> 0) then Case chunk.effect DIV 16 of ef_ex2_VolSlideDnXF: volsld_cache[temp3] := chunk.effect MOD 16; ef_ex2_VolSlideUpXF: volsld_cache[temp3] := chunk.effect MOD 16 SHL 4; end else begin Case chunk.effect DIV 16 of ef_ex2_VolSlideDnXF: chunk.effect := chunk.effect AND $0f0+volsld_cache[temp3] AND $0f; ef_ex2_VolSlideUpXF: chunk.effect := volsld_cache[temp3] AND $0f0+chunk.effect AND $0f; end; put_chunk(patt,temp2,temp3,chunk); end; end; If (prev_cache[temp3].effect_def in [ef_Vibrato,ef_ExtraFineVibrato,ef_VibratoVolSlide]) and NOT (chunk.effect_def in [ef_Vibrato,ef_ExtraFineVibrato,ef_VibratoVolSlide]) then If (chunk.effect_def = 0) and (chunk.effect = 0) then begin chunk2 := chunk; chunk2.effect_def := ef_Extended; chunk2.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff; If NOT ((chunk2.effect_def = chunk2.effect_def2) and (chunk2.effect = chunk2.effect2)) then begin put_chunk(patt,temp2,temp3,chunk2); chunk := chunk2; end; end else If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then begin chunk2 := chunk; chunk2.effect_def2 := ef_Extended; chunk2.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff; If NOT ((chunk2.effect_def2 = chunk2.effect_def) and (chunk2.effect2 = chunk2.effect)) then begin put_chunk(patt,temp2,temp3,chunk2); chunk := chunk2; end; end; If (chunk.effect_def = ef_Extended) and (chunk.effect DIV 16 = ef_ex_PatternLoop) then patloop_cache[temp3] := chunk.effect MOD 16; prev_cache[temp3].effect_def := chunk.effect_def; prev_cache[temp3].effect := chunk.effect; prev_cache[temp3].effect_def2 := chunk.effect_def2; prev_cache[temp3].effect2 := chunk.effect2; If (chunk.effect_def = temp_ef_Arpeggio) then begin chunk2 := chunk; chunk2.effect_def := ef_Arpeggio; put_chunk(patt,temp2,temp3,chunk2); end; end; end; begin { fix_s3m_commands } FillChar(ins_cache,SizeOf(ins_cache),0); FillChar(note_cache,SizeOf(note_cache),0); FillChar(volsld_cache,SizeOf(volsld_cache),0); FillChar(slide_cache,SizeOf(slide_cache),0); FillChar(misc_cache,SizeOf(misc_cache),0); FillChar(arpg_cache,SizeOf(arpg_cache),0); patts := ''; order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; If NOT (Pos(CHR(patt),patts) <> 0) then fix_single_pattern(patt); Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); For patt := 0 to PRED(patterns) do If NOT (Pos(CHR(patt),patts) <> 0) then fix_single_pattern(patt); end; procedure s3m_file_loader; type tS3M_HEADER = Record songname: array[1..28] of Char; { ASCIIZ } byte1a: Byte; { 1Ah } ftype: Byte; { File type: 16=ST3 module } resrvd1: array[0..1] of Byte; ordnum: Word; { Number of orders in file (should be even!) } insnum: Word; { Number of instruments in file } patnum: Word; { Number of patterns in file } flags: Word; { [ These are old flags for Ffv1. Not supported in ST3.01 } { | +1:st2vibrato } { | +2:st2tempo } { | +4:amigaslides } { | +32:enable filter/sfx with sb } { ] } { +8: 0vol optimizations } { Automatically turn off looping notes whose volume } { is zero for >2 note rows. } { +16: amiga limits } { Disallow any notes that go beyond the amiga hardware } { limits (like amiga does). This means that sliding } { up stops at B#5 etc. Also affects some minor amiga } { compatibility issues. } { +64: st3.00 volumeslides } { Normally volumeslide is NOT performed on first } { frame of each row (this is according to amiga } { playing). If this is set, volumeslide is performed } { ALSO on the first row. This is set by default } { if the Cwt/v files is 0x1300 } { +128: special custom data in file (see below) } cwt_v: Word; { Created with tracker / version: &0xfff=version, >>12=tracker } { ST3.00:0x1300 (NOTE: volumeslides on EVERY frame) } { ST3.01:0x1301 } { ST3.03:0x1303 } { ST3.20:0x1320 } ffi: Word; { File format information } { 1=[VERY OLD] signed samples } { 2=unsigned samples } id: array[1..4] of Char; { "SCRM" } g_v: Byte; { global volume (see next section) } i_s: Byte; { initial speed (command A) } i_t: Byte; { initial tempo (command T) } m_v: Byte; { master volume (see next section) 7 lower bits } { bit 8: stereo(1) / mono(0) } u_c: Byte; { ultra click removal } d_p: Byte; { 252 when default channel pan positions are present } { in the end of the header (xxx3). If !=252 ST3 doesn't } { try to load channel pan settings. } resrvd2: array[0..7] of Byte; special: Word; chan_set: array[1..32] of Byte; end; type tS3M_ADLINS = Record itype: Byte; { 2:amel 3:abd 4:asnare 5:atom 6:acym 7:ahihat } dosname: array[1..12] of Char; id0: array[0..2] of Char; fmdata: array[0..11] of Byte; { D00..D0B contains the adlib instrument specs packed like this: } { modulator: carrier: } { D00=[freq.muliplier]+[?scale env.]*16+[?sustain]*32+ =D01 } { [?pitch vib]*64+[?vol.vib]*128 } { D02=[63-volume]+[levelscale&1]*128+[l.s.&2]*64 =D03 } { D04=[attack]*16+[decay] =D05 } { D06=[15-sustain]*16+[release] =D07 } { D08=[wave select] =D09 } { D0A=[modulation feedback]*2+[?additive synthesis] } { D0B=unused } vol: Byte; { Default volume 0..64 } dsk: Byte; resrvd1: array[0..1] of Byte; c2spd: Word; { 'Herz' for middle C. ST3 only uses lower 16 bits. } { Actually this is a modifier since there is no } { clear frequency for adlib instruments. It scales } { the note freq sent to adlib. } hi_c2sp: Word; resrvd2: array[0..11] of Byte; smpname: array[1..28] of Char; { ASCIIZ } id: array[1..4] of Char; { "SCRI" or "SCRS" } end; const id_mod = 'SCRM'; id_ins_adl = 'SCRI'; id_ins_smp = 'SCRS'; var f: File; header: tS3M_HEADER; order_list: array[0..254] of Byte; paraptr_ins: array[1..99] of Word; default_vol: array[1..99] of Byte; paraptr_pat: array[0..99] of Word; temp,temp2: Longint; insdata: tS3M_ADLINS; pat,row,chan: Byte; note,ins,vol,cmd,info: Byte; patlen,index: Word; procedure import_s3m_event(pattern,line,channel,note,ins,vol,cmd,info: Byte); var chunk: tCHUNK; function scale_slide(slide: Byte): Byte; begin If (slide > 16) then scale_slide := Round(16+slide/8) else scale_slide := Round(slide*(2-slide/16)); end; begin FillChar(chunk,SizeOf(chunk),0); chunk.instr_def := ins; Case note of 254: chunk.note := BYTE_NULL; 255: chunk.note := 0; else If (note AND $0f in [0..11]) then chunk.note := 12*((note SHR 4) AND 7)+(note AND $0f)+1 end; If (vol <> BYTE_NULL) then begin chunk.effect_def2 := ef_SetInsVolume; chunk.effect2 := max(vol,63); end else If NOT (note in [254,255]) and (ins <> 0) and (max(default_vol[ins],63) <> 63) then begin chunk.effect_def2 := ef_SetInsVolume; chunk.effect2 := max(default_vol[ins],63); end; Case CHR(cmd+ORD('A')-1) of { NONE } '@': chunk.effect := info; { SET SPEED } 'A': If (info <> 0) then begin chunk.effect_def := ef_SetSpeed; chunk.effect := info; end; { JUMP TO ORDER } 'B': If (info <= 254) then begin chunk.effect_def := ef_PositionJump; chunk.effect := info; end; { BREAK PATTERN } 'C': If (info < 64) then begin chunk.effect_def := ef_PatternBreak; chunk.effect := Str2num(Num2str(info,16),10); end; { VOLUME SLIDE } 'D': { VOLUME SLIDE DOWN } Case info DIV 16 of { NORMAL } 0: begin chunk.effect_def := ef_VolSlide; chunk.effect := info MOD 16; end; { FINE } 15: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := info MOD 16; end; else { VOLUME SLIDE UP } Case info MOD 16 of { NORMAL } 0: begin chunk.effect_def := ef_VolSlide; chunk.effect := info AND $0f0; end; { FINE } 15: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := info AND $0f0; end; end; end; { SLIDE DOWN } 'E': Case info DIV 16 of { NORMAL } 0..13: begin chunk.effect_def := ef_FSlideDown; chunk.effect := scale_slide(info); end; { EXTRA FINE } 14: begin chunk.effect_def := ef_Extended2; If (info <> 0) then chunk.effect := ef_ex2_FreqSlideDnXF*16+min((info AND $0f) DIV 4,1) else chunk.effect := ef_ex2_FreqSlideDnXF*16; end; { FINE } 15: begin chunk.effect_def := ef_FSlideDownFine; chunk.effect := info AND $0f; end; end; { SLIDE UP } 'F': Case info DIV 16 of { NORMAL } 0..13: begin chunk.effect_def := ef_FSlideUp; chunk.effect := scale_slide(info); end; { EXTRA FINE } 14: begin chunk.effect_def := ef_Extended2; If (info <> 0) then chunk.effect := ef_ex2_FreqSlideUpXF*16+min((info AND $0f) DIV 4,1) else chunk.effect := ef_ex2_FreqSlideUpXF*16; end; { FINE } 15: begin chunk.effect_def := ef_FSlideUpFine; chunk.effect := info AND $0f; end; end; { TONE PORTAMENTO } 'G': begin chunk.effect_def := ef_TonePortamento; chunk.effect := scale_slide(info); end; { VIBRATO } 'H': begin chunk.effect_def := ef_Vibrato; chunk.effect := info; end; { FINE VIBRATO } 'U': begin chunk.effect_def := ef_ExtraFineVibrato; chunk.effect := info; end; { TREMOR } 'I': begin chunk.effect_def := ef_Tremor; chunk.effect := info; end; { ARPEGGIO } 'J': begin chunk.effect_def := temp_ef_Arpeggio; chunk.effect := info; end; { VIBRATO + VOLUME SLIDE } 'K': begin chunk.effect_def := ef_VibratoVolSlide; chunk.effect := info; end; { TONE PORTAMENTO + VOLUME SLIDE } 'L': begin chunk.effect_def := ef_TPortamVolSlide; chunk.effect := info; end; { RETRIG NOTE + VOLUME SLIDE } 'Q': begin chunk.effect_def := ef_MultiRetrigNote; chunk.effect := (info MOD 16)*16+info DIV 16; end; { TREMOLO } 'R': begin chunk.effect_def := ef_Tremolo; chunk.effect := info; end; { SPECIAL COMMAND } 'S': Case info DIV 16 of { PATTERN LOOP } $0b: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_PatternLoop*16+info MOD 16; end; { NOTE CUT } $0c: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_NoteCut*16+info MOD 16; end; { NOTE DELAY } $0d: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_NoteDelay*16+info MOD 16; end; { PATTERN DELAY } $0e: begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_PatDelayRow*16+info MOD 16; end; end; { TEMPO } 'T': If (info >= 32) then begin chunk.effect_def := ef_SetTempo; chunk.effect := Round(info/2.5); end; { SET GLOBAL VOLUME } 'V': begin chunk.effect_def := ef_SetGlobalVolume; chunk.effect := max(info,63); end; end; If (chunk.effect_def = 0) and (chunk.effect <> 0) then chunk.effect := 0; put_chunk(pattern,line,channel,chunk); end; // experimental method to fix up note fine-tuning function find_scale_factor(freq: Longint; var fine_tune: Shortint): Shortint; const _factor: array[-3..3+1] of Real = (1/8,1/4,1/2,1,2,4,8,16); const _freq: array[1..12+1] of Word = { C-2 C#2 D-2 } ( 33453 DIV 4,35441 DIV 4,37679 DIV 4, { D#2 E-2 F-2 } 39772 DIV 4,42441 DIV 4,44744 DIV 4, { F#2 G-2 G#2 } 47727 DIV 4,50416 DIV 4,53426 DIV 4, { A-2 A#2 B-2 } 56370 DIV 4,59658 DIV 4,63354 DIV 4, { C-3 } 33453 DIV 2); const _fm_freq: array[1..12+1] of Word = ($156, $16b, $181, $198, $1b0, $1ca, $1e5, $202, $220, $241, $263, $287, $2ae); var factor: Real; temp,scaler: Shortint; begin scaler := -3; fine_tune := 0; For scaler := -3 to 3+1 do For temp := 1 to 12 do begin factor := _factor[scaler]; If (freq >= Round(_freq[temp]*factor)) and (freq <= Round(_freq[SUCC(temp)]*factor)) then If (freq-Round(_freq[temp]*factor) < Round(_freq[SUCC(temp)]*factor)-freq) then begin fine_tune := Round((_fm_freq[SUCC(temp)]-_fm_freq[temp])/ (_freq[SUCC(temp)]-_freq[temp])* (freq-Round(_freq[temp]*factor))); find_scale_factor := scaler*12+PRED(temp); EXIT; end else begin fine_tune := Round((_fm_freq[SUCC(temp)]-_fm_freq[temp])/ (_freq[SUCC(temp)]-_freq[temp])* (freq-Round(_freq[SUCC(temp)]*factor))); If (temp <> 12) then find_scale_factor := scaler*12+temp else find_scale_factor := SUCC(scaler)*12; EXIT; end; end; find_scale_factor := -127; fine_tune := 0; end; (* // another method -- it's hard to say whether more or less accurate :) function find_scale_factor(freq: Longint; var fine_tune: Shortint): Shortint; const _factor: array[-3..3+1] of Real = (1/8,1/4,1/2,1,2,4,8,16); _finetune_factor: array[-3..3+1] of Real = (8,4,2,1,1/2,1/4,1/8,1/16); const _freq: array[1..12+1] of Word = { C-2 C#2 D-2 } ( 33453 DIV 4,35441 DIV 4,37679 DIV 4, { D#2 E-2 F-2 } 39772 DIV 4,42441 DIV 4,44744 DIV 4, { F#2 G-2 G#2 } 47727 DIV 4,50416 DIV 4,53426 DIV 4, { A-2 A#2 B-2 } 56370 DIV 4,59658 DIV 4,63354 DIV 4, { C-3 } 33453 DIV 2); var factor: Real; temp,scaler: Shortint; begin scaler := -3; fine_tune := 0; For scaler := -3 to 3+1 do For temp := 1 to 12 do begin factor := _factor[scaler]; If (freq >= Round(_freq[temp]*factor)) and (freq <= Round(_freq[SUCC(temp)]*factor)) then If (freq-Round(_freq[temp]*factor) < Round(_freq[SUCC(temp)]*factor)-freq) then begin fine_tune := Round((freq-Round(_freq[temp]*factor))/ Round(16/_finetune_factor[scaler])); find_scale_factor := scaler*12+PRED(temp); EXIT; end else begin If (temp = 12) then Inc(scaler); fine_tune := Round((freq-Round(_freq[SUCC(temp)]*factor))/ Round(16/_finetune_factor[scaler])); If (temp = 12) then temp := 0; find_scale_factor := scaler*12+temp; EXIT; end; end; find_scale_factor := -127; fine_tune := 0; end; *) begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:s3m_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id = id_mod)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If (header.byte1a <> $1a) or (header.ftype <> $10) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT TYPE$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} BlockReadF(f,order_list,header.ordnum,temp); If (IOresult <> 0) or (temp <> header.ordnum) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,paraptr_ins,header.insnum*2,temp); If (IOresult <> 0) or (temp <> header.insnum*2) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,paraptr_pat,header.patnum*2,temp); If (IOresult <> 0) or (temp <> header.patnum*2) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; If (header.i_s <> 0) then speed := header.i_s else speed := 1; If (Round(header.i_t/2.5) < 255) then tempo := Round(header.i_t/2.5) else tempo := 255; songdata.tempo := tempo; songdata.speed := speed; songdata.songname := truncate_string(asciiz_string(header.songname)); songdata.common_flag := songdata.common_flag OR $80; import_old_flags; For temp := 32 downto 1 do If (header.chan_set[temp] <> 255) then BREAK; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} For temp2 := 1 to max(temp,18) do If (header.chan_set[temp2] OR $80 = header.chan_set[temp2]) then channel_flag[temp2] := FALSE; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := max(temp,18) else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; For temp := 1 to max(header.ordnum,128) do Case order_list[temp-1] of 254: songdata.pattern_order[temp-1] := $80+temp; 255: songdata.pattern_order[temp-1] := $80; else songdata.pattern_order[temp-1] := order_list[temp-1]; end; FillChar(ins_c4factor,SizeOf(ins_c4factor),0); For temp := 1 to header.insnum do begin SeekF(f,paraptr_ins[temp]*16); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,insdata,SizeOf(insdata),temp2); If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (truncate_string(insdata.smpname) <> '') then songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ Copy(truncate_string(asciiz_string(insdata.smpname)),1,32) else songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ truncate_string(insdata.dosname); If (insdata.itype in [2..7]) then begin If (insdata.id <> id_ins_adl) and (insdata.id <> id_ins_smp) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; import_standard_instrument(temp,insdata.fmdata); end; default_vol[temp] := insdata.vol; If (insdata.c2spd <> 0) and (insdata.c2spd <> 8363) then ins_c4factor[temp] := find_scale_factor(insdata.c2spd,songdata.instr_data[temp].fine_tune); end; For pat := 0 to PRED(header.patnum) do begin SeekF(f,paraptr_pat[pat]*16); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,patlen,SizeOf(patlen),temp2); If (temp2 <> SizeOf(patlen)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (patlen = 0) then CONTINUE; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,patlen-2,temp2); index := 0; row := 0; Repeat If (buf1[index] <> 0) then begin note := BYTE_NULL; ins := 0; vol := BYTE_NULL; cmd := 0; info := 0; temp := buf1[index]; Inc(index); chan := SUCC(temp AND 31); If (temp OR $20 = temp) then begin note := buf1[index]; Inc(index); ins := buf1[index]; Inc(index); end; If (temp OR $40 = temp) then begin vol := buf1[index]; Inc(index); end; If (temp OR $80 = temp) then begin cmd := buf1[index]; Inc(index); info := buf1[index]; Inc(index); end; If (chan > songdata.nm_tracks) then songdata.nm_tracks := max(chan,18); If (chan in [1..songdata.nm_tracks]) then import_s3m_event(pat,row,chan,note,ins,vol,cmd,info); end else begin Inc(row); Inc(index); end; until (row = 64); end; fix_s3m_commands(header.patnum); CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 12;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; procedure fix_fmk_commands(patterns: Byte); var chunk,chunk2, chunk3: tCHUNK; patt_break: Byte; order,patt: Byte; patts: String; ins_cache, misc_cache, arpg_cache, forcevol_cache, volsld_cache, xfvolsld_cache, slide_cache: array[1..20] of Byte; _1st_ins_load: array[1..20] of Boolean; _speed_table_fixed: array[0..$7f] of Boolean; prev_cache: array[1..20] of Record effect_def, effect, effect_def2, effect2: Byte; end; procedure fix_single_pattern(patt: Byte); var temp2,temp3: Byte; begin FillChar(prev_cache,SizeOf(prev_cache),0); patt_break := BYTE_NULL; If NOT _speed_table_fixed[patt] then For temp2 := 0 to $3f do begin For temp3 := 1 to 20 do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.effect_def = 0) then begin chunk.effect_def := ef_SetCustomSpeedTab; chunk.effect := $0fa; put_chunk(patt,temp2,temp3,chunk); _speed_table_fixed[patt] := TRUE; end else If (chunk.effect_def2 = 0) then begin chunk.effect_def2 := ef_SetCustomSpeedTab; chunk.effect2 := $0fa; put_chunk(patt,temp2,temp3,chunk); _speed_table_fixed[patt] := TRUE; end; If _speed_table_fixed[patt] then BREAK; end; If _speed_table_fixed[patt] then BREAK; end; For temp2 := 0 to $3f do For temp3 := 1 to 20 do begin get_chunk(patt,temp2,temp3,chunk); If (chunk.effect_def = temp_ef_rep) then begin chunk.effect_def := prev_cache[temp3].effect_def; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = temp_ef_XFVSlide) then begin chunk.effect_def := ef_Extended2; If (xfvolsld_cache[temp3] <> 0) then chunk.effect := ef_ex2_VolSlideUpXF*16+volsld_cache[temp3] DIV 16 else chunk.effect := ef_ex2_VolSlideDnXF*16+volsld_cache[temp3] MOD 16; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_PositionJump,ef_PatternBreak]) then patt_break := temp2; If (temp2 <= patt_break) and (chunk.instr_def <> ins_cache[temp3]) and (chunk.effect_def2 <> ef_ForceInsVolume) then If (chunk.instr_def <> 0) then forcevol_cache[temp3] := 0; If ((chunk.effect_def = ef_Extended) and (chunk.effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol)) or ((chunk.effect_def2 = ef_Extended) and (chunk.effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol)) then forcevol_cache[temp3] := 0; If (chunk.effect_def2 = ef_ForceInsVolume) and (temp2 <= patt_break) then forcevol_cache[temp3] := 1; If (chunk.instr_def <> 0) and (temp2 <= patt_break) then ins_cache[temp3] := chunk.instr_def; If (chunk.instr_def <> 0) or ((chunk.instr_def = 0) and (chunk.note in [1..12*8+1]) and (ins_cache[temp3] <> 0)) then put_chunk(patt,temp2,temp3,chunk); If (temp2 <= patt_break) then begin If (chunk.effect DIV 16 <> 0) then misc_cache[temp3] := chunk.effect AND $0f0+ misc_cache[temp3] AND $0f else If (chunk.effect_def in [ef_Vibrato, ef_Tremolo]) then begin chunk.effect := misc_cache[temp3] AND $0f0+ chunk.effect AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect MOD 16 <> 0) then misc_cache[temp3] := misc_cache[temp3] AND $0f0+ chunk.effect AND $0f else If (chunk.effect_def in [ef_Vibrato, ef_Tremolo]) then begin chunk.effect := chunk.effect AND $0f0+ misc_cache[temp3] AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = ef_RetrigNote) then If (chunk.effect <> 0) then misc_cache[temp3] := chunk.effect else begin chunk.effect := misc_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = temp_ef_Arpeggio) then If (chunk.effect <> 0) then arpg_cache[temp3] := chunk.effect else begin chunk.effect := arpg_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_FSlideDown,ef_FSlideDownFine, ef_FSlideUp,ef_FSlideUpFine, ef_TonePortamento]) then If (chunk.effect <> 0) then slide_cache[temp3] := chunk.effect else begin chunk.effect := slide_cache[temp3]; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def = ef_Extended2) and (chunk.effect DIV 16 in [ef_ex2_FreqSlideDnXF,ef_ex2_FreqSlideUpXF]) then If (chunk.effect MOD 16 <> 0) then slide_cache[temp3] := chunk.effect MOD 16 else begin chunk.effect := chunk.effect AND $0f0+slide_cache[temp3] AND $0f; put_chunk(patt,temp2,temp3,chunk); end; If (chunk.effect_def in [ef_TPortamVolSlide,ef_VibratoVolSlide, ef_VolSlide,ef_VolSlideFine]) and (temp2 <= patt_break) then begin If (chunk.effect <> 0) then volsld_cache[temp3] := chunk.effect else begin chunk.effect := volsld_cache[temp3];; put_chunk(patt,temp2,temp3,chunk); end; end; If (chunk.effect_def = ef_Extended2) and (chunk.effect DIV 16 in [ef_ex2_VolSlideDnXF,ef_ex2_VolSlideUpXF]) then If (chunk.effect MOD 16 <> 0) then Case chunk.effect DIV 16 of ef_ex2_VolSlideDnXF: begin volsld_cache[temp3] := chunk.effect MOD 16; xfvolsld_cache[temp3] := 0; end; ef_ex2_VolSlideUpXF: begin volsld_cache[temp3] := chunk.effect MOD 16*16; xfvolsld_cache[temp3] := 1; end; end; end; If (prev_cache[temp3].effect_def in [ef_Vibrato,ef_VibratoVolSlide]) and NOT (chunk.effect_def in [ef_Vibrato,ef_VibratoVolSlide]) then If (chunk.effect_def = 0) and (chunk.effect = 0) then begin chunk2 := chunk; chunk2.effect_def := ef_Extended; chunk2.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff; If NOT ((chunk2.effect_def = chunk2.effect_def2) and (chunk2.effect = chunk2.effect2)) then begin put_chunk(patt,temp2,temp3,chunk2); chunk := chunk2; end; end else If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then begin chunk2 := chunk; chunk2.effect_def2 := ef_Extended; chunk2.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_VibrOff; If NOT ((chunk2.effect_def2 = chunk2.effect_def) and (chunk2.effect2 = chunk2.effect)) then begin put_chunk(patt,temp2,temp3,chunk2); chunk := chunk2; end; end; If (_1st_ins_load[temp3] and (chunk.instr_def <> 0)) or (forcevol_cache[temp3] <> 0) and (temp2 <= patt_break) and (chunk.instr_def <> 0) then If (chunk.effect_def2+chunk.effect2 = 0) then If NOT (chunk.effect_def in [ef_SetModulatorVol,ef_SetCarrierVol]) then begin chunk.effect_def2 := ef_Extended; chunk.effect2 := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; put_chunk(patt,temp2,temp3,chunk); forcevol_cache[temp3] := 0; _1st_ins_load[temp3] := FALSE; end else begin chunk.effect_def2 := chunk.effect_def; chunk.effect2 := chunk.effect; chunk.effect_def := ef_Extended; chunk.effect := ef_ex_ExtendedCmd2*16+ef_ex_cmd2_ResetVol; put_chunk(patt,temp2,temp3,chunk); forcevol_cache[temp3] := 0; _1st_ins_load[temp3] := FALSE; end; prev_cache[temp3].effect_def := chunk.effect_def; prev_cache[temp3].effect := chunk.effect; prev_cache[temp3].effect_def2 := chunk.effect_def2; prev_cache[temp3].effect2 := chunk.effect2; If is_4op_chan(temp3) and (temp3 in _4op_tracks_hi) then begin get_chunk(patt,temp2,SUCC(temp3),chunk3); If (chunk.instr_def = 0) and (chunk3.instr_def <> 0) then begin If (ins_cache[temp3] <> 0) then chunk.instr_def := ins_cache[temp3] else chunk.instr_def := chunk3.instr_def; put_chunk(patt,temp2,temp3,chunk); end; end; If (chunk.effect_def = temp_ef_Arpeggio) then begin chunk2 := chunk; chunk2.effect_def := ef_Arpeggio; put_chunk(patt,temp2,temp3,chunk2); end; If (chunk.effect_def in [ef_SetModulatorVol,ef_SetCarrierVol]) and (chunk.effect_def2 = ef_ForceInsVolume) then begin chunk2 := chunk; chunk2.effect_def := chunk.effect_def2; chunk2.effect := chunk.effect2; chunk2.effect_def2 := chunk.effect_def; chunk2.effect2 := chunk.effect; put_chunk(patt,temp2,temp3,chunk2); end; end; end; begin { fix_fmk_commands } FillChar(ins_cache,SizeOf(ins_cache),0); FillChar(_1st_ins_load,SizeOf(_1st_ins_load),TRUE); FillChar(_speed_table_fixed,SizeOf(_speed_table_fixed),FALSE); FillChar(xfvolsld_cache,SizeOf(volsld_cache),0); FillChar(volsld_cache,SizeOf(volsld_cache),0); FillChar(slide_cache,SizeOf(slide_cache),0); FillChar(misc_cache,SizeOf(misc_cache),0); FillChar(arpg_cache,SizeOf(arpg_cache),0); FillChar(forcevol_cache,SizeOf(forcevol_cache),0); patts := ''; order := 0; patt := BYTE_NULL; Repeat If (songdata.pattern_order[order] >= $80) then Inc(order) else begin patt := songdata.pattern_order[order]; fix_single_pattern(patt); Inc(order); patts := patts+CHR(patt); end; until (patt >= patterns) or (order > $7f); For patt := 0 to PRED(patterns) do If NOT (Pos(CHR(patt),patts) <> 0) then fix_single_pattern(patt); end; procedure import_fin_instrument(inst: Byte; var data); begin With songdata.instr_data[inst] do begin fm_data.AM_VIB_EG_modulator := pBYTE(@data)[0]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[1]; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[2]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[3]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[4]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[5]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[6]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[7]; fm_data.WAVEFORM_modulator := pBYTE(@data)[8] AND 7; fm_data.WAVEFORM_carrier := pBYTE(@data)[9] AND 7; fm_data.FEEDBACK_FM := pBYTE(@data)[10] AND $0f; end; songdata.instr_data[inst].panning := 0; songdata.instr_data[inst].fine_tune := 0; end; procedure fmk_file_loader; type tFMK_HEADER = Record id: array[1..4] of Char; { FMK! } songname: array[1..28] of Char; { Song name (28) } composer: array[1..28] of Char; { Composer name (28) } bytef4: Byte; { Value 244 (f4h), just for check. } ftype: Byte; { File type {1=evolution 1, 2=evolution 2 } glob_var: Byte; { Global variables, bits : 0 = stereo, 1 = opl3, 2 = rhythm } { 3 = 4.8 db tremolo 4 = 14 cent vibrato. } base_spd: Byte; { Song basespeed, ticks / second. this version : fixed 50. } init_spd: Byte; { Song initial speed. } reserved: array[0..8] of Byte; { Reserved } ordnum: Byte; { Length of song (order). } insnum: Byte; { Number of instruments. } patnum: Byte; { Number of patterns. } trk_pan: array[1..5] of Byte; { Track stereo pan positions, bits 0-1, 2-3, 4-5, 6-7. } { value 0 = left 1 = both 2 = right, from track 1 to 18. } trk_set: array[1..20] of Byte; { Track initial settings, 255=unused, bits : } { 0-2, type value: 0 = normal 1=hihat 2=cymbal 3=tom tom 4=snare 5=bass } { 6 = 4op 7=unused } { 3-7, OPL-channel number (1-18), 21 = none. } { ### if ftype=2 --> trk_set: 1..18; type_value: 0 = normal 6 = 4op 7=unused } end; const id = 'FMK!'; const _conv_fmk_pan: array[0..2] of Byte = (1,0,2); type tFIN_DATA = Record dname: array[1..12] of Char; iname: array[1..27] of Char; idata: tFM_INST_DATA; end; var f: File; header: tFMK_HEADER; order_list: array[0..254] of Byte; paraptr_ins: array[1..99] of Word; paraptr_pat: array[0..63] of Longint; paraptr_msg: Word; insdata: tFIN_DATA; temp,temp2,fpos_bak: Longint; pat,row,chan, desc_rows: Byte; note,ins,vol,cmd,info: Byte; patlen,index: Word; dscbuf: array[0..PRED(20*24)] of Char; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} procedure list_fmk_description(rows: Byte); var desc: array[1..24] of String[20]; temp,fkey: Word; row,temp2: Byte; xstart,ystart: Byte; begin FillChar(desc,SizeOf(desc),0); temp := 0; For row := 1 to rows do begin desc[row] := ''; For temp2 := 1 to 20 do begin desc[row] := desc[row]+dscbuf[temp]; Inc(temp); end; end; temp2 := 0; For temp := 1 to rows do If (truncate_string(desc[temp]) <> '') then Inc(temp2); If (temp2 = 0) then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; centered_frame(xstart,ystart,21,26,' FMK DESCRiPTiON ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); For temp := 1 to rows do ShowStr(screen_ptr,xstart+1,ystart+temp,FilterStr2(desc[temp],_valid_characters,'_'), dialog_background+dialog_context_dis); ShowCStr(screen_ptr,xstart+6,ystart+25,' ~C~ONTiNUE ', dialog_sel_itm_bck+dialog_sel_itm, dialog_sel_itm_bck+dialog_sel_short); Repeat fkey := getkey; until (fkey = kESC) or (fkey = kENTER) or (HI(fkey) = $2e); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+21+2; move_to_screen_area[4] := ystart+26+1; move2screen; no_status_refresh := TRUE; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} procedure import_fmk_event(pattern,line,channel,note,ins,vol,cmd,info: Byte); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); If (ins in [1..99]) then chunk.instr_def := ins; Case note of 254: chunk.note := BYTE_NULL; 255: chunk.note := 0; else If (note AND $0f in [1..12]) then chunk.note := 12*(note SHR 4)+(note AND $0f) end; If (vol <> BYTE_NULL) then begin chunk.effect_def2 := ef_ForceInsVolume; chunk.effect2 := 63-max(vol,63) end; Case CHR(cmd+ORD('A')-1) of { SET SPEED } 'A': If (info <> 0) then begin chunk.effect_def := ef_SetSpeed; chunk.effect := info; end; { JUMP TO ORDER } 'B': If (info <= 254) then begin chunk.effect_def := ef_PositionJump; chunk.effect := info; end; { CARRIER PARAM } 'C': Case info DIV 16 of 1: begin chunk.effect_def := ef_Extended3; chunk.effect := ef_ex3_SetMultipC*16+info MOD 16; end; 2: begin chunk.effect_def := ef_Extended3; chunk.effect := ef_ex3_SetKslC*16+(info MOD 16) AND 3; end; 3: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetAttckRateC*16+info MOD 16; end; 4: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetDecayRateC*16+info MOD 16; end; 5: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetSustnLevelC*16+info MOD 16; end; 6: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetRelRateC*16+info MOD 16; end; 7: begin chunk.effect_def := ef_SetWaveform; chunk.effect := info AND 7 SHL 4+$0f; end; 8: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetFeedback*16+info AND 7; end; end; { VOLUME SLIDE } 'D': { VOLUME SLIDE DOWN } Case info DIV 16 of { NORMAL } 0: If (info MOD 16 = 0) then chunk.effect_def := temp_ef_XFVSlide else begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_VolSlideDnXF*16+info MOD 16 end; { FINE } 15: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := info MOD 16; end; else { VOLUME SLIDE UP } Case info MOD 16 of { NORMAL } 0: If (info DIV 16 = 0) then chunk.effect_def := temp_ef_XFVSlide else begin chunk.effect_def := ef_Extended2; chunk.effect := ef_ex2_VolSlideUpXF*16+info DIV 16; end; { FINE } 15: begin chunk.effect_def := ef_VolSlideFine; chunk.effect := info AND $0f0; end; end; end; { SLIDE DOWN } 'E': Case info DIV 16 of { NORMAL } 0..14: begin chunk.effect_def := ef_FSlideDown; chunk.effect := info; end; { FINE } 15: begin chunk.effect_def := ef_FSlideDownFine; chunk.effect := info AND $0f; end; end; { SLIDE UP } 'F': Case info DIV 16 of { NORMAL } 0..14: begin chunk.effect_def := ef_FSlideUp; chunk.effect := info; end; { FINE } 15: begin chunk.effect_def := ef_FSlideUpFine; chunk.effect := info AND $0f; end; end; { TONE PORTAMENTO } 'G': begin chunk.effect_def := ef_TonePortamento; chunk.effect := info; end; { VIBRATO } 'H': begin chunk.effect_def := ef_Vibrato; If (info <> 0) and (info DIV 16 = 0) then chunk.effect := $10+info AND $0f else If (info <> 0) and (info MOD 16 = 0) then chunk.effect := info AND $0f0+1 else chunk.effect := info; end; { RETRIG NOTE } 'I': begin chunk.effect_def := ef_RetrigNote; If (info <> 0) then chunk.effect := max(info*2,255); end; { ARPEGGIO } 'J': begin chunk.effect_def := temp_ef_Arpeggio; chunk.effect := info; end; { MODLATOR PARAM } 'M': Case info DIV 16 of 1: begin chunk.effect_def := ef_Extended3; chunk.effect := ef_ex3_SetMultipM*16+info MOD 16; end; 2: begin chunk.effect_def := ef_Extended3; chunk.effect := ef_ex3_SetKslM*16+(info MOD 16) AND 3; end; 3: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetAttckRateM*16+info MOD 16; end; 4: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetDecayRateM*16+info MOD 16; end; 5: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetSustnLevelM*16+info MOD 16; end; 6: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetRelRateM*16+info MOD 16; end; 7: begin chunk.effect_def := ef_SetWaveform; chunk.effect := $0f0+info AND 7; end; 8: begin chunk.effect_def := ef_Extended; chunk.effect := ef_ex_SetFeedback*16+info AND 7; end; end; { SET VIBRATO/TREMOLO WAVEFORM } 'N': ; { BREAK PATTERN } 'P': If (info < 64) then begin chunk.effect_def := ef_PatternBreak; chunk.effect := Str2num(Num2str(info,16),10); end; { TREMOLO } 'R': begin chunk.effect_def := ef_Tremolo; If (info <> 0) and (info DIV 16 = 0) then chunk.effect := $10+info AND $0f else If (info <> 0) and (info MOD 16 = 0) then chunk.effect := info AND $0f0+1 else chunk.effect := info; end; { STEREO CONTROL } 'S': If (header.glob_var AND 1 = 1) then begin chunk.effect_def := ef_Extended; Case info of 1: chunk.effect := ef_ex_SetPanningPos*16+1; 2: chunk.effect := ef_ex_SetPanningPos*16+0; 3: chunk.effect := ef_ex_SetPanningPos*16+2; end; end; { MODULATOR VOLUME } 'T': begin chunk.effect_def := ef_SetModulatorVol; chunk.effect := info AND $3f; end; { CARRIER VOLUME } 'U': begin chunk.effect_def := ef_SetCarrierVol; chunk.effect := info AND $3f; end; end; If (chunk.effect_def = 0) and (chunk.effect <> 0) then chunk.effect := 0; put_chunk(pattern,line,channel,chunk); end; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:fmk_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If (header.bytef4 <> $f4) or NOT (header.ftype in [1,2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT TYPE$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} If (header.ftype = 2) then begin SeekF(f,SizeOf(header)-2); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; If (header.ordnum <> 0) then begin BlockReadF(f,order_list,header.ordnum,temp); If (IOresult <> 0) or (temp <> header.ordnum) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; BlockReadF(f,paraptr_msg,SizeOf(paraptr_msg),temp); If (IOresult <> 0) or (temp <> SizeOf(paraptr_msg)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; fpos_bak := FilePos(f); If (paraptr_msg <> 0) then begin SeekF(f,paraptr_msg); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,desc_rows,SizeOf(desc_rows),temp); If (IOresult <> 0) or (temp <> SizeOf(desc_rows)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (desc_rows <> 0) then begin BlockReadF(f,dscbuf,desc_rows*20,temp); If (IOresult <> 0) or (temp <> desc_rows*20) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If mod_description and (desc_rows <> 0) and NOT quick_cmd and NOT shift_pressed then list_fmk_description(desc_rows); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; SeekF(f,fpos_bak); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (header.insnum <> 0) then begin BlockReadF(f,paraptr_ins,header.insnum*2,temp); If (IOresult <> 0) or (temp <> header.insnum*2) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; If (header.patnum <> 0) then begin BlockReadF(f,paraptr_pat,header.patnum*4,temp); If (IOresult <> 0) or (temp <> header.patnum*4) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; init_songdata; load_flag := 0; If (header.init_spd <> 0) then speed := header.init_spd else speed := 1; If (header.base_spd <> 0) then tempo := header.base_spd else tempo := 50; songdata.tempo := tempo; songdata.speed := speed; songdata.songname := truncate_string(header.songname); songdata.composer := truncate_string(header.composer); songdata.common_flag := songdata.common_flag OR 1; songdata.common_flag := songdata.common_flag OR 2; songdata.common_flag := songdata.common_flag OR $80; For temp := 18 downto 1 do If NOT (header.trk_set[temp] AND 7 = 7) then BREAK; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := temp else If (songdata.nm_tracks < 18) then songdata.nm_tracks := 18; For temp2 := 1 to temp do If (header.trk_set[temp2] AND 7 = 6) then Case temp2 of 1,2: songdata.flag_4op := songdata.flag_4op OR 1; 3,4: songdata.flag_4op := songdata.flag_4op OR 2; 5,6: songdata.flag_4op := songdata.flag_4op OR 4; 10,11: songdata.flag_4op := songdata.flag_4op OR 8; 12,13: songdata.flag_4op := songdata.flag_4op OR $10; 14,15: songdata.flag_4op := songdata.flag_4op OR $20; end; If (header.glob_var AND 1 = 1) then songdata.common_flag := songdata.common_flag OR $20; If (header.glob_var SHR 3 AND 1 = 1) then songdata.common_flag := songdata.common_flag OR 8; If (header.glob_var SHR 4 AND 1 = 1) then songdata.common_flag := songdata.common_flag OR $10; import_old_flags; If (header.glob_var AND 1 = 1) then begin Inc(songdata.lock_flags[1], _conv_fmk_pan[header.trk_pan[1] AND 3]); Inc(songdata.lock_flags[2], _conv_fmk_pan[header.trk_pan[1] SHR 2 AND 3]); Inc(songdata.lock_flags[3], _conv_fmk_pan[header.trk_pan[1] SHR 4 AND 3]); Inc(songdata.lock_flags[4], _conv_fmk_pan[header.trk_pan[1] SHR 6 AND 3]); Inc(songdata.lock_flags[5], _conv_fmk_pan[header.trk_pan[2] AND 3]); Inc(songdata.lock_flags[6], _conv_fmk_pan[header.trk_pan[2] SHR 2 AND 3]); Inc(songdata.lock_flags[7], _conv_fmk_pan[header.trk_pan[2] SHR 4 AND 3]); Inc(songdata.lock_flags[8], _conv_fmk_pan[header.trk_pan[2] SHR 6 AND 3]); Inc(songdata.lock_flags[9], _conv_fmk_pan[header.trk_pan[3] AND 3]); Inc(songdata.lock_flags[10],_conv_fmk_pan[header.trk_pan[3] SHR 2 AND 3]); Inc(songdata.lock_flags[11],_conv_fmk_pan[header.trk_pan[3] SHR 4 AND 3]); Inc(songdata.lock_flags[12],_conv_fmk_pan[header.trk_pan[3] SHR 6 AND 3]); Inc(songdata.lock_flags[13],_conv_fmk_pan[header.trk_pan[4] AND 3]); Inc(songdata.lock_flags[14],_conv_fmk_pan[header.trk_pan[4] SHR 2 AND 3]); Inc(songdata.lock_flags[15],_conv_fmk_pan[header.trk_pan[4] SHR 4 AND 3]); Inc(songdata.lock_flags[16],_conv_fmk_pan[header.trk_pan[4] SHR 6 AND 3]); Inc(songdata.lock_flags[17],_conv_fmk_pan[header.trk_pan[5] AND 3]); Inc(songdata.lock_flags[18],_conv_fmk_pan[header.trk_pan[5] SHR 2 AND 3]); end; For temp := 1 to max(header.ordnum,128) do Case order_list[temp-1] of 255: songdata.pattern_order[temp-1] := $80; else songdata.pattern_order[temp-1] := order_list[temp-1]; end; For temp := 1 to header.insnum do begin SeekF(f,paraptr_ins[temp]); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,insdata,SizeOf(insdata),temp2); If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (truncate_string(insdata.iname) <> '') then songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ Copy(truncate_string(insdata.iname),1,32) else songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ truncate_string(insdata.dname); import_fin_instrument(temp,insdata.idata); end; For pat := 0 to PRED(header.patnum) do begin SeekF(f,paraptr_pat[pat]); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (paraptr_pat[pat] = 0) then CONTINUE; BlockReadF(f,patlen,SizeOf(patlen),temp2); If (temp2 <> SizeOf(patlen)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (patlen = 0) then CONTINUE; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,patlen,temp2); index := 0; row := 0; Repeat If (buf1[index] <> 0) then begin note := BYTE_NULL; ins := 0; vol := BYTE_NULL; cmd := 0; info := 0; temp := buf1[index]; Inc(index); chan := SUCC(temp AND 31); If (temp OR $20 = temp) then begin note := buf1[index]; Inc(index); ins := buf1[index]; Inc(index); end; If (temp OR $40 = temp) then begin vol := buf1[index]; Inc(index); end; If (temp OR $80 = temp) then begin cmd := buf1[index]; Inc(index); info := buf1[index]; Inc(index); end; If (PRED(chan) in [1..18]) then import_fmk_event(pat,row,PRED(chan),note,ins,vol,cmd,info); end else begin Inc(row); Inc(index); end; until (row = 64); end; fix_fmk_commands(header.patnum); CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 13;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; procedure import_sat_instrument(inst: Byte; var data); begin With songdata.instr_data[inst] do begin fm_data.FEEDBACK_FM := pBYTE(@data)[0] AND $0f; fm_data.AM_VIB_EG_modulator := pBYTE(@data)[1]; fm_data.AM_VIB_EG_carrier := pBYTE(@data)[2]; fm_data.ATTCK_DEC_modulator := pBYTE(@data)[3]; fm_data.ATTCK_DEC_carrier := pBYTE(@data)[4]; fm_data.SUSTN_REL_modulator := pBYTE(@data)[5]; fm_data.SUSTN_REL_carrier := pBYTE(@data)[6]; fm_data.WAVEFORM_modulator := pBYTE(@data)[7] AND 3; fm_data.WAVEFORM_carrier := pBYTE(@data)[8] AND 3; fm_data.KSL_VOLUM_modulator := pBYTE(@data)[9]; fm_data.KSL_VOLUM_carrier := pBYTE(@data)[10]; end; songdata.instr_data[inst].panning := 0; songdata.instr_data[inst].fine_tune := 0; end; function import_sat_instrument_name(var data; inst: Byte): String; var temp1: Word; temp2: Byte; temp3: String; begin temp1 := 0; temp2 := 0; temp3 := ''; While (temp1 < 496) do begin If (pBYTE(@data)[temp1] = BYTE(#16)) then Inc(temp2); Inc(temp1); If (temp2 = inst+1) then begin While (pBYTE(@data)[temp1] in [$20..$0ff]) and (Length(temp3) < 22) do begin temp3 := temp3+CHR(pBYTE(@data)[temp1]); Inc(temp1); end; BREAK; end; end; import_sat_instrument_name := temp3; end; procedure import_sa2_effect(effect,def1,def2: Byte; var out1,out2: Byte); forward; procedure sat_file_loader; type tHEADER = Record { version 1 } ident: array[1..4] of Char; { ident_string } vernm: Byte; { version_number (1) } instt: array[0..$1e] of { 31_instruments } array[0..$0a] of Byte; instn: array[0..495] of Byte; { 31_instrument_names } order: array[0..254] of Byte; { pattern_order } nopat: Word; { number of patterns } snlen: Byte; { song_length } rspos: Byte; { restart_position } calls: Word; { calls_per_second } end; type tHEADR2 = Record { version 6 } ident: array[1..4] of Char; { ident_string } vernm: Byte; { version_number (1) } instt: array[0..$1e] of { 31_instruments } array[0..$0e] of Byte; instn: array[0..495] of Byte; { 31_instrument_names } order: array[0..$7f] of Byte; { pattern_order } nopat: Word; { number of patterns } snlen: Byte; { song_length } rspos: Byte; { restart_position } calls: Word; { calls_per_second } arpgd: array[1..512] of Byte; { arpeggio_data } end; const id = 'SAdT'; var f: File; header: tHEADER; headr2: tHEADR2; SATver: Byte; temp,tmp2,tmp3,temp2,temp3, temp4,temp5: Longint; byte1,byte2,byte3,byte4,byte5,note_inc: Byte; procedure import_sat_event(pattern,line,channel, byte1,byte2,byte3,byte4,byte5: Byte); var chunk: tCHUNK; begin FillChar(chunk,SizeOf(chunk),0); If (byte2 in [1..31]) then chunk.instr_def := byte2; If (byte1 in [1..12*8+1]) then chunk.note := byte1+note_inc; import_sa2_effect(byte3,byte4,byte5,chunk.effect_def,chunk.effect); If (chunk.effect_def = ef_Extended) and (chunk.effect = ef_ex_ExtendedCmd2*16) and (chunk.note = 0) then begin chunk.note := BYTE_NULL; chunk.effect_def := 0; chunk.effect := 0; end; put_chunk(pattern,line,channel,chunk); end; var absolute: Longint; function get_byte(var pos: Longint): Byte; begin If (pos = SizeOf(buf1)-5) then begin If NOT (absolute > SizeOf(buf1)-5) then Move(buf3,buf1,SizeOf(buf3)-5) else Move(buf4,buf1,SizeOf(buf4)-5); pos := 0; end; get_byte := buf1[pos]; Inc(pos); Inc(absolute); end; begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:sat_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If NOT (header.vernm in [1,5,6]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} SATver := header.vernm; If (SATver in [5,6]) then begin SeekF(f,0); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,headr2,SizeOf(headr2),temp); If (temp <> SizeOf(headr2)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} temp5 := (FileSize(f)-temp) DIV (64*9*5); FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1)-5,temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; tmp2 := WORD_NULL; If (temp = SizeOf(buf1)-5) then begin FillChar(buf3,SizeOf(buf3),0); BlockReadF(f,buf3,SizeOf(buf3)-5,tmp2); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; tmp3 := WORD_NULL; If (tmp2 = SizeOf(buf3)-5) then begin FillChar(buf4,SizeOf(buf4),0); BlockReadF(f,buf4,SizeOf(buf4)-5,tmp3); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; init_songdata; load_flag := 0; songdata.common_flag := songdata.common_flag OR 8; songdata.common_flag := songdata.common_flag OR $10; import_old_flags; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] OR 4 OR 8; If (SATver = 1) then begin speed := 6; If (header.calls < 255) then tempo := header.calls else tempo := 255; songdata.tempo := tempo; songdata.speed := speed; For temp := 0 to max(header.snlen-1,127) do If (temp < 128) and (header.order[temp] in [0..63]) then songdata.pattern_order[temp] := header.order[temp]; If (header.rspos < 128) and (SUCC(temp) < 128) then songdata.pattern_order[SUCC(temp)] := $80+header.rspos; temp5 := max(temp5,header.nopat); For temp := 0 to $1e do begin import_sat_instrument(temp+1,header.instt[temp]); songdata.instr_names[temp+1] := Copy(songdata.instr_names[temp+1],1,9)+ truncate_string(import_sat_instrument_name(header.instn,temp)); end; end else begin speed := 6; If (headr2.calls < 255) then tempo := headr2.calls else tempo := 255; songdata.tempo := tempo; songdata.speed := speed; For temp := 0 to headr2.snlen-1 do If (temp < 128) and (headr2.order[temp] in [0..63]) then songdata.pattern_order[temp] := headr2.order[temp]; If (headr2.rspos < 128) and (SUCC(temp) < 128) then songdata.pattern_order[SUCC(temp)] := $80+headr2.rspos; temp5 := max(temp5,headr2.nopat); For temp := 0 to $1e do begin import_sat_instrument(temp+1,headr2.instt[temp]); songdata.instr_names[temp+1] := Copy(songdata.instr_names[temp+1],1,9)+ truncate_string(import_sat_instrument_name(headr2.instn,temp)); end; end; temp := 0; absolute := 0; Case SATver of 1: note_inc := 24; 5: note_inc := 12; 6: note_inc := 0; end; For temp2 := 0 to temp5-1 do For temp3 := 0 to 63 do For temp4 := 1 to 9 do begin byte1 := get_byte(temp); byte2 := get_byte(temp); byte3 := get_byte(temp); byte4 := get_byte(temp); byte5 := get_byte(temp); import_sat_event(temp2,temp3,temp4,byte1,byte2,byte3,byte4,byte5); end; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 14;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; function _sal(op1,op2: Word): Byte; var result: Byte; begin asm mov ax,op1 mov cx,op2 sal ax,cl mov result,al end; _sal := result; end; function _sar(op1,op2: Word): Byte; var result: Byte; begin asm mov ax,op1 mov cx,op2 sar ax,cl mov result,al end; _sar := result; end; procedure import_sa2_effect(effect,def1,def2: Byte; var out1,out2: Byte); begin Case effect of { NORMAL PLAY OR ARPEGGIO } $00: begin out1 := ef_Arpeggio; out2 := def1*16+def2; end; { SLIDE UP } $01: begin out1 := ef_FSlideUp; out2 := def1*16+def2; end; { SLIDE DOWN } $02: begin out1 := ef_FSlideDown; out2 := def1*16+def2; end; { TONE PORTAMENTO } $03: begin out1 := ef_TonePortamento; out2 := def1*16+def2; end; { VIBRATO } $04: begin out1 := ef_Vibrato; out2 := def1*16+def2; end; { TONE PORTAMENTO + VOLUME SLIDE } $05: If (def1+def2 <> 0) then If (def1 in [1..15]) then begin out1 := ef_TPortamVolSlide; out2 := min(_sar(def1,2),1)*16; end else begin out1 := ef_TPortamVolSlide; out2 := min(_sar(def2,2),1); end else begin out1 := ef_TPortamVolSlide; out2 := def1*16+def2; end; { VIBRATO + VOLUME SLIDE } $06: If (def1+def2 <> 0) then If (def1 in [1..15]) then begin out1 := ef_VibratoVolSlide; out2 := min(_sar(def1,2),1)*16; end else begin out1 := ef_VibratoVolSlide; out2 := min(_sar(def2,2),1); end else begin out1 := ef_VibratoVolSlide; out2 := def1*16+def2; end; { RELEASE SUSTAINING SOUND } $08: begin out1 := ef_Extended; out2 := ef_ex_ExtendedCmd2*16+0; end; { VOLUME SLIDE } $0a: If (def1+def2 <> 0) then If (def1 in [1..15]) then begin out1 := ef_VolSlide; out2 := min(_sar(def1,2),1)*16; end else begin out1 := ef_VolSlide; out2 := min(_sar(def2,2),1); end else begin out1 := ef_VolSlide; out2 := def1*16+def2; end; { POSITION JUMP } $0b: If (def1*16+def2 < 128) then begin out1 := ef_PositionJump; out2 := def1*16+def2; end; { SET VOLUME } $0c: begin out1 := ef_SetInsVolume; out2 := def1*16+def2; If (out2 > 63) then out2 := 63; end; { PATTERN BREAK } $0d: If (def1*16+def2 < 64) then begin out1 := ef_PatternBreak; out2 := def1*16+def2; end; { SET SPEED } $0f: If (def1*16+def2 < $20) then begin out1 := ef_SetSpeed; out2 := def1*16+def2; end else If (def1 < 16) and (def2 < 16) then begin out1 := ef_SetTempo; out2 := Round((def1*16+def2)/2.5); end; else begin out1 := 0; out2 := 0; end; end; end; procedure sa2_file_loader; type tHEADER = Record ident: array[1..4] of Char; { These bytes mark a song } vernm: Byte; { Version number (9) } instt: array[0..$1e] of { 31 instruments } array[0..$0e] of Byte; instn: array[0..495] of Byte; { 31_instrument_names } order: array[0..$7f] of Byte; { Pattern order } nopat: Word; { Number of patterns } snlen: Byte; { Length of song } rspos: Byte; { Restart position } snbpm: Word; { BPM } arpgd: array[1..512] of Byte; { Arpeggio data (list+commands) } ordr2: array[0..63] of { Track order } array[1..9] of Byte; chans: Word; { Active channels } end; const id = 'SAdT'; var f: File; header: tHEADER; temp,temp2,temp3,temp4,temp5: Longint; procedure import_sa2_event(pattern,line,channel, byte1,byte2,byte3: Byte); var chunk: tCHUNK; temp: Byte; begin FillChar(chunk,SizeOf(chunk),0); temp := (byte1 AND 1) SHL 4 +(byte2 SHR 4); If (temp in [1..31]) then chunk.instr_def := temp; If (byte1 SHR 1 in [1..12*8+1]) then chunk.note := (byte1 SHR 1); import_sa2_effect(byte2 AND $0f,byte3 SHR 4,byte3 AND $0f, chunk.effect_def,chunk.effect); If (chunk.effect_def = ef_Extended) and (chunk.effect = ef_ex_ExtendedCmd2*16) and (chunk.note = 0) then begin chunk.note := BYTE_NULL; chunk.effect_def := 0; chunk.effect := 0; end; put_chunk(pattern,line,channel,chunk); end; begin { sa2_file_loader } {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:sa2_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If NOT (header.vernm in [8,9]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If (header.vernm = 8) then begin SeekF(f,FilePos(f)-2); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1)-3,temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; songdata.common_flag := songdata.common_flag OR 8; songdata.common_flag := songdata.common_flag OR $10; import_old_flags; songdata.patt_len := 64; If adjust_tracks then songdata.nm_tracks := 9 else If (songdata.nm_tracks < 9) then songdata.nm_tracks := 9; For temp := 1 to 20 do songdata.lock_flags[temp] := songdata.lock_flags[temp] OR 4 OR 8; speed := 6; If (Round(header.snbpm/2.5) < 255) then tempo := Round(header.snbpm/2.5) else tempo := 255; songdata.tempo := tempo; songdata.speed := speed; temp2 := 0; temp3 := 0; temp4 := 1; Repeat While (header.ordr2[temp2][temp4] = 0) and (temp2 <= header.nopat-1) do begin Inc(temp4); If (temp4 > 9) then begin temp4 := 1; Inc(temp2); end; end; If (temp2 <= header.nopat-1) then begin temp5 := 64*3*(header.ordr2[temp2][temp4]-1)+temp3*3; import_sa2_event(temp2,temp3,temp4,buf1[temp5], buf1[temp5+1], buf1[temp5+2]); Inc(temp3); If (temp3 > $3f) then begin temp3 := 0; If (temp4 < 9) then Inc(temp4) else begin temp4 := 1; Inc(temp2); end; end; end; until (temp2 > header.nopat-1); For temp := 0 to header.snlen-1 do If (temp < 128) and (header.order[temp] in [0..63]) then songdata.pattern_order[temp] := header.order[temp]; If (header.rspos < 128) and (SUCC(temp) < 128) then songdata.pattern_order[SUCC(temp)] := $80+header.rspos; For temp := 0 to $1e do begin import_sat_instrument(temp+1,header.instt[temp]); songdata.instr_names[temp+1] := Copy(songdata.instr_names[temp+1],1,9)+ truncate_string(import_sat_instrument_name(header.instn,temp)); end; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 15;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; adlibtracker2-2.4.23/make_dos.bat0000644000000000000000000000357313176573533015310 0ustar rootroot@echo off rem ------------------------------------- set VERSION=2.3.56 rem ------------------------------------- if not exist *.exe goto :no_exe_file del *.exe >nul :no_exe_file if not exist *.ppu goto :no_ppu_file del *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del *.o >nul :no_o_file if not exist !log goto :no_log_file del !log >nul :no_log_file echo. echo ************************************ echo ** ** echo ** STEP 1/4 ** echo ** Validating version info ** echo ** ** echo ************************************ copy /y utils\val_dos.exe validate.exe >nul validate.exe %VERSION% del validate.exe >nul echo. echo ************************************ echo ** ** echo ** STEP 2/4 ** echo ** Compiling sources ** echo ** ** echo ************************************ ppc386 -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Tgo32v2 adtrack2.pas >!log if not exist adtrack2.exe goto :compile_error if not exist *.ppu goto :no_ppu_file del *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del *.o >nul :no_o_file if not exist !log goto :no_log_file del !log >nul :no_log_file echo. echo ************************************ echo ** ** echo ** STEP 3/4 ** echo ** UPX: Compressing EXE file ** echo ** ** echo ************************************ c:\utils\upx -9 adtrack2.exe >nul echo. echo ************************************ echo ** ** echo ** STEP 4/4 ** echo ** Executing program ** echo ** ** echo ************************************ echo. adtrack2 :compile_error adlibtracker2-2.4.23/makefile0000644000000000000000000000263713176573533014536 0ustar rootroot.PHONY: clean release release_ all: adtrack2 release: release_ rm -rf release/adtrack-*/ echo -e "\n\n\nyour files are ready at release/\n" release_: all rm -rf release mkdir release mkdir release/src cp -r *.pas *.inc Makefile TODO *.bat sdl.dll sdl utils package release/src/ cp -r package release/bin cp adtrack2 release/bin/ rm -f release/bin/techinfo.* cd release; \ echo "which minor version is this? NOTE that i assume 2.4.xx and that you're on debian wheezy x86!"; \ read ver; \ mv src adtrack-2.4.$${ver}-linux-src; \ mv bin adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86; \ tar cvzf adtrack-2.4.$${ver}-linux-src.tar.gz adtrack-2.4.$${ver}-linux-src; \ tar cvzf adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86.tar.gz adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86; clean: rm -f *.o *.s *.res *.ppu *.map *.fpd *.sym *.cfg adtrack2 rm -f sdl/*.o sdl/*.ppu mrproper: clean rm -rf bin/ mkdir bin/ rm -rf release/ adtrack2: adt2data.pas adt2ext2.pas adt2ext3.pas adt2ext4.pas adt2ext5.pas adt2extn.pas adt2keyb.pas adt2opl3.pas adt2pack.pas adt2sys.pas adt2text.pas adt2unit.pas adt2vesa.pas adtrack2.pas depackio.pas dialogio.pas iloaders.inc iloadins.inc instedit.inc ipattern.inc ipattord.inc iss_tim.pas menulib1.pas menulib2.pas opl3emu.pas parserio.pas realtime.inc stringio.pas txtscrio.pas typcons1.inc typcons2.inc fpc -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Fusdl adtrack2.pas -oadtrack2 adlibtracker2-2.4.23/stringio.pas0000644000000000000000000006104213176573533015374 0ustar rootrootunit StringIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface type tCHARSET = Set of Char; function byte2hex(value: Byte): String; function byte2dec(value: Byte): String; function Capitalize(str: String): String; function Upper(str: String): String; function Lower(str: String): String; function iCASE(str: String): String; function RotStrL(str1,str2: String; shift: Byte): String; function RotStrR(str1,str2: String; shift: Byte): String; function ExpStrL(str: String; size: Byte; chr: Char): String; function ExpStrR(str: String; size: Byte; chr: Char): String; function DietStr(str: String; size: Byte): String; function CutStr(str: String): String; function CutStrL(str: String; margin: Byte): String; function CutStrR(str: String; margin: Byte): String; function FlipStr(str: String): String; function FilterStr(str: String; chr0,chr1: Char): String; function FilterStr1(str: String; chr0: Char): String; function FilterStr2(str: String; chr0: tCHARSET; chr1: Char): String; function Num2str(num: Longint; base: Byte): String; function Str2num(str: String; base: Byte): Longint; type tINPUT_STR_SETTING = Record insert_mode, replace_enabled, append_enabled: Boolean; char_filter, character_set, valid_chars, word_characters: tCHARSET; terminate_keys: array[1..50] of Word; end; type tINPUT_STR_ENVIRONMENT = Record keystroke: Word; locate_pos: Byte; insert_mode: Boolean; end; const is_setting: tINPUT_STR_SETTING = (insert_mode: TRUE; replace_enabled: TRUE; append_enabled: TRUE; char_filter: [#32..#255]; character_set: [#32..#255]; valid_chars: [#32..#255]; word_characters: ['A'..'Z','a'..'z','0'..'9','_']; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); var is_environment: tINPUT_STR_ENVIRONMENT; function InputStr(s: String; x,y,ln,ln1: Byte; atr1,atr2: Byte): String; function SameName(str1,str2: String): Boolean; function PathOnly(path: String): String; function NameOnly(path: String): String; function BaseNameOnly(path: String): String; function ExtOnly(path: String): String; procedure StringIO_Init; implementation uses DOS, AdT2unit,AdT2sys,AdT2keyb, TxtScrIO; function byte2hex(value: Byte): String; const data: array[0..15] of char = '0123456789ABCDEF'; begin asm mov edi,@RESULT lea ebx,[data] mov al,2 stosb mov al,value xor ah,ah mov cl,16 div cl xlat stosb mov al,ah xlat stosb end; end; function byte2dec(value: Byte): String; const data: array[0..9] of char = '0123456789'; begin asm mov edi,@RESULT lea ebx,[data] mov al,value xor ah,ah mov cl,100 div cl mov ch,ah xchg ah,al or ah,ah jz @@1 mov al,3 stosb xchg ah,al xlat stosb mov al,ch jmp @@2 @@1: mov al,2 stosb mov al,value @@2: xor ah,ah mov cl,10 div cl xlat stosb mov al,ah xlat stosb end; end; function Capitalize(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@4 mov al,[esi] inc esi cmp al,'a' jb @@0 cmp al,'z' ja @@0 sub al,20h @@0: mov [edi],al inc edi @@1: mov ah,al mov al,[esi] inc esi cmp ah,' ' jnz @@2 cmp al,'a' jb @@2 cmp al,'z' ja @@2 sub al,20h jmp @@3 @@2: cmp al,'A' jb @@3 cmp al,'Z' ja @@3 add al,20h @@3: mov [edi],al inc edi loop @@1 @@4: end; end; function Upper(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@3 @@1: mov al,[esi] inc esi cmp al,'a' jb @@2 cmp al,'z' ja @@2 sub al,20h @@2: mov [edi],al inc edi loop @@1 @@3: end; end; function Lower(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@3 @@1: mov al,[esi] inc esi cmp al,'A' jb @@2 cmp al,'Z' ja @@2 add al,20h @@2: mov [edi],al inc edi loop @@1 @@3: end; end; function iCase(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@5 push edi push ecx @@1: mov al,[esi] inc esi cmp al,'a' jb @@2 cmp al,'z' ja @@2 sub al,20h @@2: mov [edi],al inc edi loop @@1 pop ecx pop edi @@3: mov al,[edi] cmp al,'i'-20h jnz @@4 add al,20h @@4: mov [edi],al inc edi loop @@3 @@5: end; end; function RotStrL(str1,str2: String; shift: Byte): String; begin RotStrL := Copy(str1,shift+1,Length(str1)-shift)+ Copy(str2,1,shift); end; function RotStrR(str1,str2: String; shift: Byte): String; begin RotStrR := Copy(str2,Length(str2)-shift+1,shift)+ Copy(str1,1,Length(str1)-shift); end; function ExpStrL(str: String; size: Byte; chr: Char): String; begin asm lea esi,[str] mov edi,@RESULT cld xor ecx,ecx lodsb cmp al,size jge @@1 mov ah,al mov al,size stosb mov al,ah mov cl,size sub cl,al mov al,chr rep stosb mov cl,ah rep movsb jmp @@2 @@1: stosb mov cl,al rep movsb @@2: end; end; function ExpStrR(str: String; size: Byte; chr: Char): String; begin asm lea esi,[str] mov edi,@RESULT cld xor ecx,ecx lodsb cmp al,size jge @@1 mov ah,al mov al,size stosb mov cl,ah rep movsb mov al,ah mov cl,size sub cl,al mov al,chr rep stosb jmp @@2 @@1: stosb mov cl,al rep movsb @@2: end; end; function DietStr(str: String; size: Byte): String; begin If (Length(str) <= size) then begin DietStr := str; EXIT; end; Repeat Delete(str,size DIV 2,1) until (Length(str)+3 = size); Insert('...',str,size DIV 2); DietStr := str end; function CutStr(str: String): String; begin While (BYTE(str[0]) <> 0) and (str[1] = ' ') do Delete(str,1,1); While (BYTE(str[0]) <> 0) and (str[BYTE(str[0])] = ' ') do Delete(str,BYTE(str[0]),1); CutStr := str; end; function CutStrL(str: String; margin: Byte): String; var idx: Byte; begin If (margin = 0) then margin := Length(str) else If (margin > Length(str)) then margin := Length(str); idx := 0; While (idx+1 <= margin) and (str[idx+1] = ' ') do Inc(idx); If (idx <> 0) then Delete(str,1,idx); CutStrL := str; end; function CutStrR(str: String; margin: Byte): String; var idx: Byte; begin If (margin > Length(str)) then margin := Length(str); idx := 0; While (str[BYTE(str[0])-idx] = ' ') and (BYTE(str[0])-idx >= margin) do Inc(idx); Dec(BYTE(str[0]),idx); CutStrR := str; end; function FlipStr(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi dec edi xor ecx,ecx mov cl,al jecxz @@2 add edi,ecx @@1: mov al,[esi] inc esi mov [edi],al dec edi loop @@1 @@2: end; end; function FilterStr(str: String; chr0,chr1: Char): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi xor ecx,ecx mov cl,al jecxz @@3 @@1: mov al,[esi] inc esi cmp al,chr0 jnz @@2 mov al,chr1 @@2: mov [edi],al inc edi loop @@1 @@3: end; end; function FilterStr1(str: String; chr0: Char): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi inc edi xor ecx,ecx mov cl,al mov ebx,ecx jecxz @@4 @@1: mov al,[esi] inc esi cmp al,chr0 jnz @@2 dec ebx jmp @@3 @@2: mov [edi],al inc edi @@3: loop @@1 @@4: mov eax,ebx mov edi,@RESULT mov [edi],al end; end; const _treat_char: array[$80..$a5] of Char = 'CueaaaaceeeiiiAAE_AooouuyOU_____aiounN'; function FilterStr2(str: String; chr0: tCHARSET; chr1: Char): String; var temp: Byte; begin For temp := 1 to Length(str) do If NOT (str[temp] in chr0) then If (str[temp] >= #128) and (str[temp] <= #165) then str[temp] := _treat_char[BYTE(str[temp])] else If (str[temp] = #0) then str[temp] := ' ' else str[temp] := chr1; FilterStr2 := str; end; function Num2str(num: Longint; base: Byte): String; const hexa: array[0..PRED(16)+32] of Char = '0123456789ABCDEF'+ #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0; begin asm xor eax,eax xor edx,edx xor edi,edi xor esi,esi mov eax,num xor ebx,ebx mov bl,base cmp bl,2 jb @@3 cmp bl,16 ja @@3 mov edi,32 @@1: dec edi xor edx,edx div ebx mov esi,edx mov dl,byte ptr [hexa+esi] mov byte ptr [hexa+edi+16],dl and eax,eax jnz @@1 mov esi,edi mov ecx,32 sub ecx,edi mov edi,@RESULT mov al,cl stosb @@2: mov al,byte ptr [hexa+esi+16] stosb inc esi loop @@2 jmp @@4 @@3: mov edi,@RESULT xor al,al stosb @@4: end; end; const digits: array[0..35] of Char = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; function Digit2index(digit: Char): Byte; var index: Byte; begin digit := UpCase(digit); index := 15; While (index > 0) and (digit <> digits[index]) do Dec(index); Digit2index := Index; end; function position_value(position,base: Byte): Longint; var value: Longint; index: Byte; begin value := 1; For index := 2 to position do value := value*base; position_value := value; end; function Str2num(str: String; base: Byte): Longint; var value: Longint; index: Byte; begin value := 0; For index := 1 to Length(str) do Inc(value,Digit2index(str[index])* position_value(Length(str)-index+1,base)); Str2num := value; end; function InputStr(s: String; x,y,ln,ln1: Byte; atr1,atr2: Byte): String; var appn,for1st,qflg,ins: Boolean; cloc,xloc,xint,attr: Byte; key: Word; s1,s2: String; function more(value1,value2: Byte): Byte; begin If (value1 >= value2) then more := value1 else more := value2; end; label _end; begin { InputStr } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'STRINGIO.PAS:InputStr'; {$ENDIF} s := Copy(s,1,ln); If (is_environment.locate_pos > ln1) then is_environment.locate_pos := ln1; If (is_environment.locate_pos > Length(s)+1) then is_environment.locate_pos := Length(s); cloc := is_environment.locate_pos; xloc := is_environment.locate_pos; xint := x; qflg := FALSE; ins := is_setting.insert_mode; appn := NOT is_setting.append_enabled; Dec(x); If ins then ThinCursor else WideCursor; s1 := s; If (BYTE(s1[0]) > ln1) then s1[0] := CHR(ln1); ShowStr(screen_ptr,xint,y,ExpStrR('',ln1,' '),atr1); ShowStr(screen_ptr,xint,y,FilterStr2(s1,is_setting.char_filter,'_'),atr2); for1st := TRUE; Repeat s2 := s1; If (xloc = 1) then s1 := Copy(s,cloc,ln1) else s1 := Copy(s,cloc-xloc+1,ln1); If NOT appn then attr := atr2 else attr := atr1; If appn and for1st then begin ShowStr(screen_ptr,xint,y,ExpStrR(FilterStr2(s1,is_setting.char_filter,'_'),ln1,' '),atr1); for1st := FALSE; end; If (s2 <> s1) then ShowStr(screen_ptr,xint,y,ExpStrR(FilterStr2(s1,is_setting.char_filter,'_'),ln1,' '),atr1); If (ln1 < ln) then If (cloc-xloc > 0) and (Length(s) > 0) then ShowStr(screen_ptr,xint,y,#17,(attr AND $0f0)+$0f) else If (cloc-xloc = 0) and (Length(s) <> 0) then ShowStr(screen_ptr,xint,y,s[1],attr) else ShowStr(screen_ptr,xint,y,' ',atr1); If (ln1 < ln) then If (cloc-xloc+ln1 < Length(s)) then ShowStr(screen_ptr,xint+ln1-1,y,#16,(attr AND $0f0)+$0f) else If (cloc-xloc+ln1 = Length(s)) then ShowStr(screen_ptr,xint+ln1-1,y,FilterStr2(s[Length(s)],is_setting.char_filter,'_'),attr) else ShowStr(screen_ptr,xint+ln1-1,y,' ',atr1); GotoXY(x+xloc,y); If keypressed then key := getkey else GOTO _end; If LookupKey(key,is_setting.terminate_keys,50) then qflg := TRUE; If NOT qflg then Case key of kTAB: appn := TRUE; kCtrlY: begin appn := TRUE; s := ''; cloc := 1; xloc := 1; end; kCtrlT: begin appn := TRUE; While (s[cloc] in is_setting.word_characters) and (cloc <= Length(s)) do Delete(s,cloc,1); While NOT (s[cloc] in is_setting.word_characters) and (cloc <= Length(s)) do Delete(s,cloc,1); end; kCtrlK: begin appn := TRUE; Delete(s,cloc,Length(s)); end; kCtBkSp: begin appn := TRUE; While (s[cloc-1] in is_setting.word_characters) and (cloc > 1) do begin Dec(cloc); Delete(s,cloc,1); If (xloc > 1) then Dec(xloc); end; While NOT (s[cloc-1] in is_setting.word_characters) and (cloc > 1) do begin Dec(cloc); Delete(s,cloc,1); If (xloc > 1) then Dec(xloc); end; end; kBkSPC: begin appn := TRUE; If (cloc > 1) then begin If (xloc > 1) then Dec(xloc); Dec(cloc); Delete(s,cloc,1); end; end; kDELETE: begin appn := TRUE; If (cloc <= Length(s)) then Delete(s,cloc,1); end; kCtLEFT: begin appn := TRUE; While (s[cloc] in is_setting.word_characters) and (cloc > 1) do begin Dec(cloc); If (xloc > 1) then Dec(xloc); end; While NOT (s[cloc] in is_setting.word_characters) and (cloc > 1) do begin Dec(cloc); If (xloc > 1) then Dec(xloc); end; end; kCtRGHT: begin appn := TRUE; While (s[cloc] in is_setting.word_characters) and (cloc < Length(s)) do begin Inc(cloc); If (xloc < ln1) then Inc(xloc); end; While NOT (s[cloc] in is_setting.word_characters) and (cloc < Length(s)) do begin Inc(cloc); If (xloc < ln1) then Inc(xloc); end; end; kLEFT: begin appn := TRUE; If (cloc > 1) then Dec(cloc); If (xloc > 1) then Dec(xloc); end; kRIGHT: begin appn := TRUE; If (cloc < Length(s)) or ((cloc = Length(s)) and ((Length(s) < more(ln,ln1)))) then Inc(cloc); If (xloc < ln1) and (xloc <= Length(s)) then Inc(xloc); end; kINSERT: If is_setting.replace_enabled then begin ins := NOT ins; If ins then ThinCursor else WideCursor; end; kHOME: begin appn := TRUE; cloc := 1; xloc := 1; end; kEND: begin appn := TRUE; If (Length(s) < more(ln,ln1)) then cloc := Succ(Length(s)) else cloc := Length(s); If (cloc < ln1) then xloc := cloc else xloc := ln1; end; else If (CHR(LO(key)) in tCHARSET(is_setting.character_set)) then begin If NOT appn then begin s := ''; cloc := 1; xloc := 1; end; appn := TRUE; If ins and (Length(CutStrR(s,cloc)) < ln) then begin If (Length(CutStrR(s,cloc)) < ln) then Insert(CHR(LO(key)),s,cloc) else s[cloc] := CHR(LO(key)); s := FilterStr2(s,is_setting.valid_chars,'_'); If (cloc < ln) then Inc(cloc); If (xloc < ln) and (xloc < ln1) then Inc(xloc) end else If (Length(s) < ln) or NOT ins then begin If (cloc > Length(s)) and (Length(s) < ln) then Inc(BYTE(s[0])); s[cloc] := CHR(LO(key)); s := FilterStr2(s,is_setting.valid_chars,'_'); If (cloc < ln) then Inc(cloc); If (xloc < ln) and (xloc < ln1) then Inc(xloc); end; end; end; _end: {$IFDEF GO32V2} // draw_screen; keyboard_reset_buffer_alt; {$ELSE} draw_screen; // keyboard_reset_buffer; {$ENDIF} until qflg; If (cloc = 0) then is_environment.locate_pos := 1 else is_environment.locate_pos := cloc; is_environment.keystroke := key; is_environment.insert_mode := ins; InputStr := s; end; function SameName(str1,str2: String): Boolean; var LastW: Word; result: Boolean; begin asm mov [LastW],0 xor eax,eax xor ecx,ecx xor ebx,ebx lea esi,[str1] lea edi,[str2] xor ah,ah mov al,[esi] inc esi mov cx,ax mov al,[edi] inc edi mov bx,ax or cx,cx jnz @@1 or bx,bx jz @@13 jmp @@14 xor dh,dh @@1: mov al,[esi] inc esi cmp al,'*' jne @@2 dec cx jz @@13 mov dh,1 mov LastW,cx jmp @@1 @@2: cmp al,'?' jnz @@3 inc edi or bx,bx je @@12 dec bx jmp @@12 @@3: or bx,bx je @@14 cmp al,'[' jne @@11 cmp word ptr [esi],']?' je @@9 mov ah,byte ptr [edi] xor dl,dl cmp byte ptr [esi],'!' jnz @@4 inc esi dec cx jz @@14 inc dx @@4: mov al,[esi] inc esi dec cx jz @@14 cmp al,']' je @@7 cmp ah,al je @@6 cmp byte ptr [esi],'-' jne @@4 inc esi dec cx jz @@14 cmp ah,al jae @@5 inc esi dec cx jz @@14 jmp @@4 @@5: mov al,[esi] inc esi dec cx jz @@14 cmp ah,al ja @@4 @@6: or dl,dl jnz @@14 inc dx @@7: or dl,dl jz @@14 @@8: cmp al,']' je @@10 @@9: mov al,[esi] inc esi cmp al,']' loopne @@9 jne @@14 @@10: dec bx inc edi jmp @@12 @@11: cmp [edi],al jne @@14 inc edi dec bx @@12: xor dh,dh dec cx jnz @@1 or bx,bx jnz @@14 @@13: mov result,TRUE jmp @@16 @@14: or dh,dh jz @@15 jecxz @@15 or bx,bx jz @@15 inc edi dec bx jz @@15 mov ax,LastW sub ax,cx add cx,ax movsx eax,ax sub esi,eax dec esi jmp @@1 @@15: mov result,FALSE @@16: end; SameName := result; end; var dir: DirStr; name: NameStr; ext: ExtStr; function PathOnly(path: String): String; begin FSplit(path,dir,name,ext); PathOnly := dir; end; function NameOnly(path: String): String; begin FSplit(path,dir,name,ext); NameOnly := name+ext; end; function BaseNameOnly(path: String): String; begin FSplit(path,dir,name,ext); BaseNameOnly := name; end; function ExtOnly(path: String): String; begin FSplit(path,dir,name,ext); Delete(ext,1,1); ExtOnly := Lower_filename(ext); end; procedure StringIO_Init; begin is_environment.locate_pos := 1; is_setting.char_filter := _valid_characters; is_setting.valid_chars := _valid_characters; end; end. adlibtracker2-2.4.23/realtime.inc0000644000000000000000000007576413176573533015346 0ustar rootroot{ function _decay_bar_str(value: Byte): String; procedure show_bar(chan,level,xpos,from_pos,to_pos,attr: Byte); procedure decay_bars_refresh; function _vol_bar_str(value: Byte): String; procedure status_refresh; procedure trace_update_proc; } function _decay_bar_str(value: Byte): String; var result: String; begin result := ''; Repeat If (value > 15) then begin result := result+#219; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := result+CHR(224+value) until (value <= 15); _decay_bar_str := FlipStr(result); end; procedure show_bar(chan,level,xpos,from_pos,to_pos,attr: Byte); var temp: Byte; begin For temp := from_pos to to_pos do show_vcstr(xpos+temp-1+PRED(chan)*15,MAX_PATTERN_ROWS+14, ExpStrL('~'+_decay_bar_str(Round(105/63*level))+'~',9,#224), analyzer_bckg+analyzer, analyzer_bckg+attr SHR 4); end; procedure decay_bars_refresh; var chan,temp: Byte; speedup_factor,speedown_factor: Real; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'REALTIME.INC:decay_bars_refresh'; {$ENDIF} show_bar(1,overall_volume,05,1,2, analyzer_ovrllvol+analyzer_ovrllvol SHL 4); show_bar(1,global_volume,MAX_COLUMNS-7,1,2, analyzer_volumelvl+analyzer_volumelvl SHL 4); {$IFDEF GO32V2} speedup_factor := 4.0*SUCC(fps_down_factor); speedown_factor :=4.0*SUCC(fps_down_factor); {$ELSE} speedup_factor := 2.5*(100/sdl_frame_rate); speedown_factor := 2.5*(100/sdl_frame_rate); {$ENDIF} chan := chan_pos; For temp := 1 to MAX_TRACKS do begin If (decay_bar[chan].dir1 = 1) then decay_bar[chan].lvl1 := decay_bar[chan].lvl1+ decay_bar[chan].dir1*(decay_bar_rise*speedup_factor) else decay_bar[chan].lvl1 := decay_bar[chan].lvl1+ decay_bar[chan].dir1*(decay_bar_fall*speedown_factor); If (decay_bar[chan].dir2 = 1) then decay_bar[chan].lvl2 := decay_bar[chan].lvl2+ decay_bar[chan].dir2*(decay_bar_rise*speedup_factor) else decay_bar[chan].lvl2 := decay_bar[chan].lvl2+ decay_bar[chan].dir2*(decay_bar_fall*speedown_factor); If (decay_bar[chan].lvl1 < 0) then decay_bar[chan].lvl1 := 0; If (decay_bar[chan].lvl1 > 63) then decay_bar[chan].lvl1 := 63; If (decay_bar[chan].lvl1 >= carrier_vol[chan]) then decay_bar[chan].dir1 := -1; If (decay_bar[chan].lvl2 < 0) then decay_bar[chan].lvl2 := 0; If (decay_bar[chan].lvl2 > 63) then decay_bar[chan].lvl2 := 63; If (decay_bar[chan].lvl2 >= modulator_vol[chan]) then decay_bar[chan].dir2 := -1; If (volum_bar[chan].dir = 1) then volum_bar[chan].lvl := volum_bar[chan].lvl+ volum_bar[chan].dir*(decay_bar_rise*speedup_factor) else volum_bar[chan].lvl := volum_bar[chan].lvl+ volum_bar[chan].dir*(decay_bar_fall*speedown_factor); If (volum_bar[chan].lvl < 0) then volum_bar[chan].lvl := 0; If (volum_bar[chan].lvl > 63) then volum_bar[chan].lvl := 63; If NOT (percussion_mode and (chan in [17..20])) then If (ins_parameter(voice_table[chan],10) AND 1 = 1) then If (volum_bar[chan].lvl >= (carrier_vol[chan]+modulator_vol[chan]) DIV 2) then volum_bar[chan].dir := -1 else else If (volum_bar[chan].lvl >= carrier_vol[chan]) then volum_bar[chan].dir := -1 else else If (volum_bar[chan].lvl >= modulator_vol[chan]) then volum_bar[chan].dir := -1; If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then show_bar(temp,Round(decay_bar[chan].lvl2),08,1,6, analyzer+analyzer_modulator SHL 4) else show_bar(temp, 63-(scale_volume(63-Round(decay_bar[chan].lvl2), 63-Round(decay_bar[chan].lvl1))), 08,1,6, analyzer+analyzer_modulator SHL 4); If NOT (percussion_mode and (chan in [17..20])) then show_bar(temp,Round(decay_bar[chan].lvl1),08,8,14, analyzer+analyzer_carrier SHL 4) else show_bar(temp,0,08,8,14, analyzer+analyzer_carrier SHL 4); Inc(chan); end; end; function _vol_bar_str(value: Byte): String; var result: String; begin result := ''; Repeat If (value > 3) then begin result := result+#168; Dec(value,3); end; If (value <= 3) and (value <> 0) then result := result+CHR(164+value) until (value <= 3); _vol_bar_str := result; end; procedure status_refresh; var temps: String; temp,temp2,chan: Byte; {$IFNDEF GO32V2} wav_indicator_attr: array[Boolean] of Byte; {$ENDIF} begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'REALTIME.INC:status_refresh:1/4'; {$ENDIF} If really_no_status_refresh then EXIT; show_str(21,06,status_layout[play_status][8]+status_layout[play_status][9], status_background+status_play_state); {$IFDEF GO32V2} _debug_str_ := 'REALTIME.INC:status_refresh:2/4'; {$ENDIF} If no_status_refresh then begin chan := chan_pos; For temp2 := 1 to MAX_TRACKS do begin If channel_flag[chan] then show_str(08+(temp2-1)*15,MAX_PATTERN_ROWS+11, ExpStrR('',14,#205), pattern_bckg+pattern_border); Inc(chan); end; EXIT; end; {$IFDEF GO32V2} _debug_str_ := 'REALTIME.INC:status_refresh:3/4'; {$ENDIF} temps := status_layout[play_status]; show_str(14,06,ExpStrR(temps,10,' '), status_background+status_play_state); If (@mn_environment.ext_proc_rt <> NIL) and is_default_screen_mode then show_str(02,01,' '+ExpStrR(temps,10,' '), main_background+main_border) else show_str(02,01,ExpStrR('',12,#196), main_background+main_border); If single_play then EXIT; {$IFDEF GO32V2} _debug_str_ := 'REALTIME.INC:status_refresh:4/4'; {$ENDIF} If play_single_patt then show_str(20,03,byte2hex(current_pattern)+' ', pattern_bckg+status_dynamic_txt) else begin temp := songdata.pattern_order[current_order]; If NOT (temp <= $7f) then temp := 0; If NOT replay_forbidden and repeat_pattern and NOT calibrating then show_str(20,03,byte2hex(temp)+' '#19, pattern_bckg+status_dynamic_txt) else If NOT calibrating then show_str(20,03,byte2hex(temp)+' ', status_background+status_dynamic_txt) else show_str(20,03,byte2hex(temp), status_background+status_dynamic_txt); end; If NOT play_single_patt then show_str(17,03,byte2hex(current_order), status_background+status_dynamic_txt) else show_str(17,03,'--', status_background+status_dynamic_txt); show_str(17,04,byte2hex(current_line), status_background+status_dynamic_txt); show_str(17,05,byte2hex(speed), status_background+status_dynamic_txt); If (tempo < 100) then If (tempo = 18) and timer_fix then show_str(20,05,byte2dec(tempo)+#5+#174, status_background+status_dynamic_txt) else show_str(20,05,byte2dec(tempo)+#174+' ', status_background+status_dynamic_txt) else show_str(20,05,byte2dec(tempo)+#174, status_background+status_dynamic_txt); If (play_status <> isStopped) then temps := ' ~'+byte2dec(max(song_timer DIV 60,99))+':'+ byte2dec(max(song_timer MOD 60,99))+'.'+ CHR(48+max(song_timer_tenths DIV 10,9))+'~ ' else temps := ' 00~:~00~.~0 '; show_cstr(13,07,temps, status_background+status_text_dis, status_background+status_border); If (@mn_environment.ext_proc_rt <> NIL) and is_default_screen_mode then show_cstr(16,01,temps, main_background+main_border, main_background+main_border) else show_str(16,01,ExpStrR('',11,#196), main_background+main_border); {$IFDEF GO32V2} temp := Pos('.',songdata_title); show_str(03,06,'['+ExpStrR(iCASE(Copy(songdata_title,1,PRED(temp))),8,' ')+']', status_background+status_dynamic_txt); show_str(03,07,'['+ExpStrR(iCASE(Copy(songdata_title,SUCC(temp),3)),3,' ')+']', status_background+status_border); If NOT module_archived then show_str(08,07,'['+#29+']', main_background+main_behavior) else show_str(08,07,#205#205#205, status_background+status_border); {$ELSE} temps := BaseNameOnly(FilterStr2(songdata_title,_valid_characters_fname,'_')); While (8+_name_scrl_shift > Length(temps)) and (_name_scrl_shift > 0) do Dec(_name_scrl_shift); show_str(03,06,'['+ExpStrR(iCASE(Copy(temps,1+_name_scrl_shift,8)),8,' ')+']', status_background+status_dynamic_txt); show_str(03,07,'['+ExpStrR(iCASE(Copy(ExtOnly(songdata_title),1,3)),3,' ')+']', status_background+status_border); If (_name_scrl_pending_frames <> 0) then Dec(_name_scrl_pending_frames) else begin _name_scrl_pending_frames := 20; If (_name_scrl_shift_ctr > 0) then If (8+_name_scrl_shift < Length(temps)) then Inc(_name_scrl_shift,_name_scrl_shift_ctr) else begin _name_scrl_shift_ctr := -1; _name_scrl_pending_frames := _name_scrl_pending_frames*10; end else If (_name_scrl_shift > 0) then Inc(_name_scrl_shift,_name_scrl_shift_ctr) else begin _name_scrl_shift_ctr := 1; _name_scrl_pending_frames := _name_scrl_pending_frames*50; end; end; wav_indicator_attr[FALSE] := main_background+main_behavior; If (play_status = isPlaying) and NOT opl3_channel_recording_mode then wav_indicator_attr[TRUE] := (main_behavior SHL 4) AND $0f0 else wav_indicator_attr[TRUE] := main_background+main_behavior; If is_default_screen_mode and (@mn_environment.ext_proc_rt <> NIL) then If (sdl_opl3_emulator <> 0) then show_str(13,01,'WAV',wav_indicator_attr[_generic_blink_event_flag]) else show_str(13,01,#196#196#196,main_background+main_border) else If (sdl_opl3_emulator = 1) then show_str(08,07,'[WAV]',wav_indicator_attr[_generic_blink_event_flag]) else If NOT module_archived then show_cstr(08,07,'~['+#29+']~'#205#205, status_background+status_border, main_background+main_behavior) else show_str(08,07,#205#205#205#205#205, status_background+status_border); {$ENDIF} If (command_typing = 1) then If NOT cycle_pattern then show_str(MAX_COLUMNS-17,MAX_PATTERN_ROWS+12,'A',main_background+main_behavior) else show_str(MAX_COLUMNS-17,MAX_PATTERN_ROWS+12,'F',main_background+main_behavior) else If (command_typing = 2) and NOT cycle_pattern then show_str(MAX_COLUMNS-17,MAX_PATTERN_ROWS+12,'S',main_background+main_behavior) else show_str(MAX_COLUMNS-17,MAX_PATTERN_ROWS+12,#196,main_background+main_border); If (songdata.flag_4op <> 0) then show_cstr(MAX_COLUMNS-43,MAX_PATTERN_ROWS+12,'~[~'+#4#3+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line) else show_cstr(MAX_COLUMNS-43,MAX_PATTERN_ROWS+12,'~[~'+#2+#3+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line); For temp := 1 to 8 do If (temp <> current_octave) then show_str(30+temp,MAX_PATTERN_ROWS+12,CHR(48+temp), main_background+main_stat_line) else show_str(30+temp,MAX_PATTERN_ROWS+12,CHR(48+temp), main_background+main_hi_stat_line); chan := chan_pos; For temp2 := 1 to max(MAX_TRACKS,songdata.nm_tracks) do begin If NOT pan_lock[chan] or ((play_status = isStopped) and NOT debugging) then temp := pattern_bckg+pattern_pan_indic else temp := pattern_bckg+pattern_gpan_indic; If NOT ((play_status = isStopped) and NOT debugging and NOT panlock) and channel_flag[chan] then begin If percussion_mode and (chan in [16..20]) then Case chan of 16: temps := '~BD~ '; 17: temps := '~SD~ '; 18: temps := '~TT~ '; 19: temps := '~TC~ '; 20: temps := '~HH~ '; end else Case chan of 1, 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 3, 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 5, 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 10, 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 12, 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 14, 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; end; If volume_lock[chan] then temps := temps+'V+'; If peak_lock[chan] then temps := temps+'P+'; If panlock and (play_status = isStopped) and NOT debugging then Case songdata.lock_flags[chan] AND 3 of 0: show_str(12+(temp2-1)*15,09,#21#22' ',temp); 1: show_str(12+(temp2-1)*15,09,#21' ',temp); 2: show_str(12+(temp2-1)*15,09,' '#22' ',temp); end else Case panning_table[chan] of 0: show_str(12+(temp2-1)*15,09,#21#22' ',temp); 1: show_str(12+(temp2-1)*15,09,#21' ',temp); 2: show_str(12+(temp2-1)*15,09,' '#22' ',temp); end; If NOT (chan in [16..20]) then show_cstr(12+(temp2-1)*15+3,09,ExpStrR(temps,7,' '), pattern_bckg+pattern_lock_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15+3,09,ExpStrR(temps,7,' '), pattern_bckg+pattern_lock_indic, pattern_bckg+pattern_perc_indic); end else If NOT percussion_mode and (chan in [16..20]) then show_str(12+(temp2-1)*15,09,#250#250' '+ExpStrL('',7,' '), pattern_bckg+pattern_pan_indic) else Case chan of 1, 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 3, 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 5, 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 10, 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 12, 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 14, 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 16: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('BD',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 17: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('SD',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 18: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('TT',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 19: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('TC',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 20: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('HH',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); else show_str(12+(temp2-1)*15,09,#250#250' '+ExpStrL('',7,' '), pattern_bckg+pattern_pan_indic); end; If NOT channel_flag[chan] then begin show_str(08+(temp2-1)*15,MAX_PATTERN_ROWS+11,#205#205#205, pattern_bckg+pattern_border); show_str(11+(temp2-1)*15,MAX_PATTERN_ROWS+11,' () OFF ', pattern_bckg+pattern_chan_indic); If (temp2 < max(MAX_TRACKS,songdata.nm_tracks)) then show_str(19+(temp2-1)*15,MAX_PATTERN_ROWS+11,#205#205#205#207, pattern_bckg+pattern_border) else show_str(19+(temp2-1)*15,MAX_PATTERN_ROWS+11,#205#205#205#202, pattern_bckg+pattern_border); If NOT percussion_mode and (chan in [16..20]) then show_str(12+(temp2-1)*15,09,#250#250' '+ExpStrL('',7,' '), pattern_bckg+pattern_pan_indic) else Case chan of 1, 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 3, 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 5, 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 10, 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 12, 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 14, 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 16: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('BD',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 17: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('SD',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 18: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('TT',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 19: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('TC',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 20: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('HH',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); else show_str(12+(temp2-1)*15,09,#250#250' '+ExpStrL('',7,' '), pattern_bckg+pattern_pan_indic); end; end else begin temp := 0; {$IFDEF GO32V2} If NOT ((scr_scroll_y > 10) or NOT is_scrollable_screen_mode) then {$ELSE} If NOT ((screen_scroll_offset > 10) or NOT is_default_screen_mode) then {$ENDIF} If NOT is_4op_chan(chan) or (is_4op_chan(chan) and (((chan in _4op_tracks_lo) and (temp2 = 1)) or ((chan in _4op_tracks_hi) and (temp2 = max(MAX_TRACKS,songdata.nm_tracks))))) then begin temp := Round(42/63*volum_bar[chan].lvl); If (temp2 < max(MAX_TRACKS,songdata.nm_tracks)) then show_str(08+(temp2-1)*15,11+MAX_PATTERN_ROWS, ExpStrR(_vol_bar_str(temp),14,#205)+#207, pattern_bckg+pattern_border) else show_str(08+(temp2-1)*15,11+MAX_PATTERN_ROWS, ExpStrR(_vol_bar_str(temp),14,#205)+#202, pattern_bckg+pattern_border); end else If (chan in _4op_tracks_hi) then begin temp := Round(84/63*volum_bar[chan].lvl); temps := _vol_bar_str(temp); If (Length(temps) > 14) then begin temps[15] := #169; temps := ExpStrR(temps,29,#205); end else begin temps := ExpStrR(temps,29,#205); temps[15] := #207; end; If (temp2 < PRED(max(MAX_TRACKS,songdata.nm_tracks))) then temps := temps+#207 else temps := temps+#202; show_str(08+(temp2-1)*15,11+MAX_PATTERN_ROWS, temps, pattern_bckg+pattern_border); end else else show_str(08+(temp2-1)*15,11+MAX_PATTERN_ROWS,Copy(patt_win[5],07+(temp2-1)*15,15), pattern_bckg+pattern_border); end; Inc(chan); end; end; procedure trace_update_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:trace_update_proc'; {$ENDIF} space_pressed := scankey(SC_SPACE); If (play_status = isPlaying) then If (_traceprc_last_order <> current_order) or (_traceprc_last_pattern <> current_pattern) or (_traceprc_last_line <> current_line) then begin _traceprc_last_order := current_order; _traceprc_last_pattern := songdata.pattern_order[current_order]; _traceprc_last_line := current_line; If tracing then begin If NOT play_single_patt then pattern_patt := songdata.pattern_order[current_order]; pattern_page := current_line; pattord_page := 0; pattord_hpos := 1; pattord_vpos := 1; While (current_order <> pattord_vpos+4*(pattord_hpos+pattord_page-1)-1) do If (pattord_vpos < 4) then Inc(pattord_vpos) else If (pattord_hpos < MAX_ORDER_COLS) then begin Inc(pattord_hpos); pattord_vpos := 1; end else If (pattord_page < 23-(MAX_ORDER_COLS-9)) then begin Inc(pattord_page); pattord_vpos := 1; end; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; adlibtracker2-2.4.23/instedit.inc0000644000000000000000000044713613176573533015363 0ustar rootroot{ procedure reset_instrument_preview; procedure INSTRUMENT_test(instr,instr2: Byte; chan: Byte; fkey: Word; process_macros: Boolean); function _1st_marked: Byte; function _2nd_marked: Byte; function marked_instruments: Byte; procedure reset_marked_instruments; function get_4op_to_test: Word; function check_4op_to_test: Word; function check_4op_instrument(ins: Byte): Word; function check_4op_flag(ins: Byte): Boolean; procedure reset_4op_flag(ins: Byte); procedure set_4op_flag(ins: Byte); procedure update_4op_flag_marks; procedure INSTRUMENT_CONTROL_page_refresh(page: Byte); procedure _show_adsr(var dest; xstart,ystart: Byte; attack,decay,sustain,release,attenuation: Byte; eg_type: Byte; attr,attr_hi: Byte; reset: Boolean); procedure INSTRUMENT_CONTROL_page_refresh_alt(page: Byte); function _4op_conn_to_idx(str: String): Byte; procedure _show_conn_scheme(xstart,ystart,conn: Byte; hi_op: tSET_OF_CHARS); function _get_feedback_val: Byte; procedure _inc_feedback_val; procedure _dec_feedback_val; function _get_finetune_val: Shortint; procedure _inc_finetune_val; procedure _dec_finetune_val; procedure _page_build; procedure _page_refresh; procedure _sync_radio_buttons; procedure INSTRUMENT_CONTROL_edit; procedure copy_object; procedure paste_object(mode: Byte); procedure instr_control_ai; procedure instr_control_proc; function INSTRUMENT_CONTROL: Byte; procedure instr_control_proc_alt; function INSTRUMENT_CONTROL_alt(instr: Byte; title: String): Byte; } const _ADSR_preview_flag: Boolean = TRUE; const _operator_enabled: array[1..4] of Boolean = (TRUE,TRUE,TRUE,TRUE); _carrier_flag: array[BOOLEAN] of Byte = (2,1); _ins_mark_chr = #16; _4op_flag_chr_beg = #172; _4op_flag_chr_end = #173; _4op_flag_chars: Set of Char = [_4op_flag_chr_beg,_4op_flag_chr_end]; _4op_connection_str: array[0..3] of String[5] = ( 'FM/FM','FM/AM','AM/FM','AM/AM'); procedure reset_instrument_preview; var temp: Word; begin If (play_status <> isPlaying) then reset_player; temp := check_4op_to_test; If NOT (temp <> 0) then update_instr_data(instrum_page) else begin update_instr_data(LO(temp)); update_instr_data(HI(temp)); end; end; procedure INSTRUMENT_test(instr,instr2: Byte; chan: Byte; fkey: Word; process_macros: Boolean); var temp,temp2,temp3,temp5: Byte; valid_key,temp4: Boolean; chan_handle: array[1..20] of Byte; channels: Byte; _1op_preview,_4op_mode: Boolean; function _1op_preview_active: Boolean; var temp,nm_slots: Byte; begin nm_slots := 0; For temp := 1 to 4 do If _operator_enabled[temp] then Inc(nm_slots); _1op_preview_active := (nm_slots = 1); end; function output_note(chan,board_pos: Byte): Boolean; var note: Byte; freq: Word; ins: tADTRACK2_INS; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_test:output_note'; {$ENDIF} note := board_pos+12*(current_octave-1); If NOT (note in [0..12*8+1]) then begin output_note := FALSE; EXIT; end; chan_handle[chan] := board_scancodes[board_pos]; If _4op_mode then chan := _4op_main_chan[chan]; If _1op_preview then begin If _operator_enabled[1] or _operator_enabled[2] then ins := songdata.instr_data[instr] else ins := songdata.instr_data[instr2]; pBYTE(@ins)[10] := pBYTE(@ins)[10] OR 1; load_instrument(ins,chan); If _operator_enabled[1] or _operator_enabled[2] then set_ins_volume($3f-ORD(_operator_enabled[1])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[2])*($3f-HI(volume_table[chan])), chan) else set_ins_volume($3f-ORD(_operator_enabled[3])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[4])*($3f-HI(volume_table[chan])), chan); end else begin load_instrument(songdata.instr_data[instr],chan); set_ins_volume($3f-ORD(_operator_enabled[1])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[2])*($3f-HI(volume_table[chan])), chan); If percussion_mode and (songdata.instr_data[instr].perc_voice in [4,5]) then load_instrument(songdata.instr_data[instr],_perc_sim_chan[chan]); If _4op_mode then begin load_instrument(songdata.instr_data[instr2],PRED(chan)); set_ins_volume($3f-ORD(_operator_enabled[3])*($3f-LO(volume_table[PRED(chan)])), $3f-ORD(_operator_enabled[4])*($3f-HI(volume_table[PRED(chan)])), PRED(chan)); end; end; macro_speedup := songdata.macro_speedup; If (play_status = isStopped) then update_timer(songdata.tempo); freq := nFreq(note-1)+$2000+ SHORTINT(pBYTE(@Addr(songdata.instr_data[instr])^)[12]); event_table[chan].note := note; freq_table[chan] := freq; freqtable2[chan] := freq; key_on(chan); change_freq(chan,freq); If process_macros then If NOT (_1op_preview and (_operator_enabled[3] or _operator_enabled[4])) then init_macro_table(chan,note,instr,freq) else init_macro_table(chan,note,instr2,freq) else begin macro_table[chan].fmreg_table := 0; macro_table[chan].arpg_table := 0; macro_table[chan].vib_table := 0; end; If _4op_mode and NOT _1op_preview then begin If process_macros then init_macro_table(PRED(chan),note,instr2,freq) else begin macro_table[PRED(chan)].fmreg_table := 0; macro_table[PRED(chan)].arpg_table := 0; macro_table[PRED(chan)].vib_table := 0; end; end; end; begin { INSTRUMENT_test } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_test'; {$ENDIF} If ctrl_pressed or alt_pressed or shift_pressed then EXIT; _1op_preview := _1op_preview_active; _4op_mode := NOT _1op_preview_active and (songdata.flag_4op <> 0) and (instr2 <> 0); valid_key := FALSE; For temp := 1 to 29 do If NOT shift_pressed then If (board_scancodes[temp] = HI(fkey)) then begin valid_key := TRUE; BREAK; end; If NOT valid_key or NOT (temp+12*(current_octave-1)-1 in [0..12*8+1]) then EXIT; If (Empty(songdata.instr_data[instr],SizeOf(songdata.instr_data[instr])) and Empty(songdata.instr_macros[instr],SizeOf(songdata.instr_macros[instr]))) or (_4op_mode and Empty(songdata.instr_data[instr2],SizeOf(songdata.instr_data[instr2])) and Empty(songdata.instr_macros[instr2],SizeOf(songdata.instr_macros[instr2]))) then EXIT; temp2 := temp; ins_trailing_flag := TRUE; status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; really_no_status_refresh := TRUE; Move(channel_flag,channel_flag_backup,SizeOf(channel_flag_backup)); Move(event_table,event_table_backup,SizeOf(event_table_backup)); common_flag_backup := songdata.common_flag; volume_scaling_backup := volume_scaling; songdata.common_flag := songdata.common_flag AND NOT $80; volume_scaling := FALSE; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); Move(pan_lock,pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); flag_4op_backup := songdata.flag_4op; If NOT percussion_mode and NOT (songdata.flag_4op <> 0) then channels := 18 else If NOT (songdata.flag_4op <> 0) then channels := 15 else begin If _4op_mode then begin songdata.flag_4op := $3f; channels := 6; end else begin songdata.flag_4op := 0; If NOT percussion_mode then channels := 18 else channels := 15; end; end; reset_player; FillChar(chan_handle,SizeOf(chan_handle),0); Move(fmpar_table,fmpar_table_backup,SizeOf(fmpar_table_backup)); Move(volume_table,volume_table_backup,SizeOf(volume_table_backup)); Move(freq_table,freq_table_backup,SizeOf(freq_table)); Move(freqtable2,freqtable2_backup,SizeOf(freqtable2)); Move(keyoff_loop,keyoff_loop_backup,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); misc_register := current_tremolo_depth SHL 7+ current_vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; key_off(17); key_off(18); opl2out(_instr[11],misc_register); If percussion_mode and (songdata.instr_data[instr].perc_voice in [1..5]) then begin output_note(songdata.instr_data[instr].perc_voice+15,temp2); While scankey(board_scancodes[temp2]) do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; end else Repeat {$IFNDEF GO32V2} keyboard_poll_input; {$ENDIF} valid_key := FALSE; For temp := 1 to 29 do begin temp2 := board_scancodes[temp]; temp4 := scankey(temp2); If NOT _4op_mode then begin temp3 := get_chanpos(chan_handle,channels,temp2); temp5 := get_chanpos(chan_handle,channels,0); end else begin temp3 := get_chanpos2(chan_handle,channels,temp2); temp5 := get_chanpos2(chan_handle,channels,0); end; If temp4 then valid_key := TRUE; If temp4 and (temp3 = 0) and (temp5 <> 0) then output_note(temp5,temp); If NOT temp4 and (temp3 <> 0) then begin chan_handle[temp3] := 0; key_off(temp3); If alt_pressed then keyoff_loop[temp3] := TRUE; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; until NOT valid_key; While ctrl_pressed do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; For temp := 1 to 20 do key_off(temp); songdata.flag_4op := flag_4op_backup; Move(fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(volume_table_backup,volume_table,SizeOf(volume_table)); Move(panning_table_backup,panning_table,SizeOf(panning_table)); songdata.common_flag := common_flag_backup; volume_scaling := volume_scaling_backup; If (status_backup.play_status = isPlaying) then reset_player; Move(channel_flag_backup,channel_flag,SizeOf(channel_flag)); Move(event_table_backup,event_table,SizeOf(event_table)); Move(pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(peak_lock_backup,peak_lock,SizeOf(volume_lock)); really_no_status_refresh := FALSE; Move(freq_table_backup,freq_table,SizeOf(freq_table)); Move(freqtable2_backup,freqtable2,SizeOf(freqtable2)); Move(keyoff_loop_backup,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; ins_trailing_flag := FALSE; keyboard_reset_buffer; end; var color_table: array[1..3] of Byte; function _1st_marked: Byte; var temp,result: Byte; begin result := 0; For temp := 1 to 255 do If (songdata.instr_names[temp][1] = _ins_mark_chr) then begin result := temp; BREAK; end; _1st_marked := result; end; function _2nd_marked: Byte; var temp,result: Byte; begin result := 0; If (_1st_marked <> 0) then For temp := SUCC(_1st_marked) to 255 do If (songdata.instr_names[temp][1] = _ins_mark_chr) then begin result := temp; BREAK; end; _2nd_marked := result; end; function marked_instruments: Byte; var temp,result: Byte; begin result := 0; For temp := 1 to 255 do If (songdata.instr_names[temp][1] = _ins_mark_chr) then Inc(result); marked_instruments := result; end; procedure reset_marked_instruments; begin If (marked_instruments < 2) then If (songdata.instr_names[instrum_page][1] = _ins_mark_chr) then songdata.instr_names[instrum_page][1] := ' ' else else begin songdata.instr_names[_2nd_marked][1] := ' '; songdata.instr_names[_1st_marked][1] := ' '; end; update_4op_flag_marks; end; function get_4op_to_test: Word; var result: Word; begin result := 0; If (songdata.flag_4op <> 0) then If check_4op_flag(current_inst) then result := SUCC(current_inst)+current_inst SHL 8 else If (current_inst > 1) and check_4op_flag(PRED(current_inst)) then result := current_inst+PRED(current_inst) SHL 8; get_4op_to_test := result; end; function check_4op_to_test: Word; var result: Word; begin result := 0; If check_4op_flag(current_inst) then result := SUCC(current_inst)+current_inst SHL 8 else If (current_inst > 1) and check_4op_flag(PRED(current_inst)) then result := current_inst+PRED(current_inst) SHL 8; check_4op_to_test := result; end; function check_4op_instrument(ins: Byte): Word; var result: Word; begin result := 0; If check_4op_flag(ins) then result := SUCC(ins)+ins SHL 8 else If (ins > 1) and check_4op_flag(PRED(ins)) then result := ins+PRED(ins) SHL 8; check_4op_instrument := result; end; function check_4op_flag(ins: Byte): Boolean; var result: Boolean; idx: Byte; begin result := FALSE; For idx := 1 to songdata.ins_4op_flags.num_4op do If (songdata.ins_4op_flags.idx_4op[idx] = ins) then begin result := TRUE; BREAK; end; check_4op_flag := result; end; procedure reset_4op_flag(ins: Byte); var temp_ins_4op_flags: tINS_4OP_FLAGS; idx: Byte; begin If NOT check_4op_flag(ins) then EXIT; temp_ins_4op_flags.num_4op := 0; idx := 1; While (idx <= songdata.ins_4op_flags.num_4op) and (songdata.ins_4op_flags.idx_4op[idx] < ins) do begin Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := songdata.ins_4op_flags.idx_4op[idx]; Inc(idx); end; Inc(idx); While (idx <= songdata.ins_4op_flags.num_4op) do begin Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := songdata.ins_4op_flags.idx_4op[idx]; Inc(idx); end; songdata.ins_4op_flags := temp_ins_4op_flags; end; procedure set_4op_flag(ins: Byte); var temp_ins_4op_flags: tINS_4OP_FLAGS; idx: Byte; begin If (ins = 255) then EXIT; If check_4op_flag(ins) then reset_4op_flag(ins); If (ins > 1) and check_4op_flag(PRED(ins)) then reset_4op_flag(PRED(ins)); If (ins < 255) and check_4op_flag(SUCC(ins)) then reset_4op_flag(SUCC(ins)); temp_ins_4op_flags.num_4op := 0; idx := 1; While (idx <= songdata.ins_4op_flags.num_4op) and (songdata.ins_4op_flags.idx_4op[idx] < ins) do begin Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := songdata.ins_4op_flags.idx_4op[idx]; Inc(idx); end; Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := ins; While (idx <= songdata.ins_4op_flags.num_4op) do begin Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := songdata.ins_4op_flags.idx_4op[idx]; Inc(idx); end; songdata.ins_4op_flags := temp_ins_4op_flags; end; procedure update_4op_flag_marks; var temp: Byte; begin For temp := 1 to PRED(255) do If NOT check_4op_flag(temp) then begin If (songdata.instr_names[temp][1] in _4op_flag_chars) then songdata.instr_names[temp][1] := ' '; If (songdata.instr_names[SUCC(temp)][1] in _4op_flag_chars) then songdata.instr_names[SUCC(temp)][1] := ' '; end; For temp := 1 to PRED(255) do If check_4op_flag(temp) then begin If (songdata.instr_names[temp][1] = ' ') then songdata.instr_names[temp][1] := _4op_flag_chr_beg; If (songdata.instr_names[SUCC(temp)][1] = ' ') then songdata.instr_names[SUCC(temp)][1] := _4op_flag_chr_end; end; end; procedure INSTRUMENT_CONTROL_page_refresh(page: Byte); var temp: Byte; temp_str: String; _status_shift_pos: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_page_refresh'; {$ENDIF} update_4op_flag_marks; If (ins_parameter(page,10) AND 1 <> 1) then For temp := 1 to 18 do ShowCStr(mn_environment.v_dest, INSCTRL_xshift+10,INSCTRL_yshift+06+temp, inst_itm1[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm1[temp].colr]) else For temp := 1 to 18 do ShowCStr(mn_environment.v_dest, INSCTRL_xshift+10,INSCTRL_yshift+06+temp, inst_itm2[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm2[temp].colr]); ShowStr(mn_environment.v_dest, INSCTRL_xshift+56,INSCTRL_yshift+05, byte2hex(page), dialog_background+dialog_title); For temp := 1 to 10 do ShowStr(mn_environment.v_dest, INSCTRL_xshift+32,INSCTRL_yshift+08+pos2[temp], byte2hex(pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[temp]]), dialog_background+dialog_item); ShowCStr(mn_environment.v_dest, INSCTRL_xshift+30,INSCTRL_yshift+08+pos2[11], connection_str[pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[11]] AND 1]+'~/~'+ CHR(ORD('0')+(pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[11]] SHR 1 AND 7)), dialog_background+dialog_item, color_table[inst_itm1[temp].colr]); Case songdata.instr_data[page].panning of 0: ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'CENTER', dialog_background+dialog_item); 1: ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'LEFT ', dialog_background+dialog_item); 2: ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'RiGHT ', dialog_background+dialog_item); end; If (songdata.instr_data[page].fine_tune < 0) then ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[13], '-'+ExpStrR(Num2str(Abs(songdata.instr_data[page].fine_tune),16),2,' '), dialog_background+dialog_item) else ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[13], '+'+ExpStrR(Num2str(Abs(songdata.instr_data[page].fine_tune),16),2,' '), dialog_background+dialog_item); _status_shift_pos := 0; If (check_4op_flag(page) or ((page > 1) and check_4op_flag(PRED(page)))) then begin _status_shift_pos := 5; ShowCStr(mn_environment.v_dest, INSCTRL_xshift+09,INSCTRL_yshift+26, ' [~'#4#3'~] '#205#205#205, dialog_background+dialog_border, dialog_background+dialog_context) end else ShowCStr(mn_environment.v_dest, INSCTRL_xshift+09,INSCTRL_yshift+26, ' [~'+perc_voice_str[songdata.instr_data[page].perc_voice]+'~] ', dialog_background+dialog_border, dialog_background+dialog_context); If (songdata.instr_macros[page].length <> 0) then temp_str := ' [~MACRO:FM' else temp_str := ' '; With songdata.macro_table[ songdata.instr_macros[page].arpeggio_table].arpeggio do If (songdata.instr_macros[page].arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'[~MACRO:ARP'; With songdata.macro_table[ songdata.instr_macros[page].vibrato_table].vibrato do If (songdata.instr_macros[page].vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'[~MACRO:ViB'; If (temp_str <> ' ') then temp_str := temp_str+'~] '; ShowCStr(mn_environment.v_dest,INSCTRL_xshift+19-_status_shift_pos,INSCTRL_yshift+26, ExpStrR(temp_str,27,#205), dialog_background+dialog_border, dialog_background+dialog_context); STATUS_LINE_refresh; end; var adsr_bckg: Byte; procedure _show_adsr(dest: tSCREEN_MEM_PTR; xstart,ystart: Byte; attack,decay,sustain,release,attenuation: Byte; eg_type: Byte; attr,attr_hi: Byte; reset: Boolean); function _gfx_bar_str(value: Byte): String; var result: String; begin result := ''; Repeat If (value > 15) then begin result := result+#219; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := result+CHR(127+value) until (value <= 15); _gfx_bar_str := flipstr(result); end; var index,pos: Integer; temp,temp2: Real; function _conv(value,variant: Byte): Byte; begin If (value <> 0) then _conv := variant else _conv := 1; end; begin { _show_adsr } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:_show_adsr'; {$ENDIF} fr_setting.update_area := FALSE; fr_setting.shadow_enabled := FALSE; If NOT is_default_screen_mode then Frame(dest,xstart,ystart+1,xstart+61,ystart+11, instrument_bckg,'',0,frame_solid_type1) else If reset then Frame(dest,xstart,ystart,xstart+63,ystart+12, instrument_bckg,'',0,frame_solid_type1) else Frame(dest,xstart,ystart,xstart+63,ystart+12, instrument_adsr+instrument_text,' ADSR PREViEW ', instrument_adsr+instrument_text, frame_double); fr_setting.update_area := TRUE; fr_setting.shadow_enabled := TRUE; If (attack <> 0) then attack := min(ROUND(15/ln(15)*ln(attack)),1); If (decay <> 0) then decay := min(ROUND(15/ln(15)*ln(decay)),1) else sustain := 0; If (sustain <> 0) then sustain := min(ROUND(15/ln(15)*ln(sustain)),1); If (release <> 0) then release := min(ROUND(15/ln(15)*ln(release)),1); If reset then EXIT; pos := 1; temp := 0; For index := 0 to (15-attack) do begin temp := temp+8*16/(16-attack); If (attack <> 0) then begin ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr_hi); Inc(pos); end; end; If (attack = 0) then begin Inc(pos); temp := 8*16; end; If (decay = 0) and ((release <> 0) or ((sustain <> 0) and (eg_type = 1))) then decay := 15; If (decay <> 0) then For index := 0 to (15-decay) do begin temp := temp-8*16/16*sustain/(16-decay); ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr_hi); Inc(pos); end; If (decay = 0) then Inc(pos); If (eg_type <> 1) and (release <> 0) then sustain := 0; If (sustain = 0) and (release <> 0) then sustain := 1; For index := 1 to sustain do If (sustain <> 0) then begin ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr_hi); Inc(pos); end; If (sustain = 0) then Inc(pos); temp2 := temp; For index := 1 to (15-release) do begin temp := temp-temp2/(16-release); If (release <> 0) and (temp > 0) then begin If (eg_type <> 1) then ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr_hi) else ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr); Inc(pos); end; end; If (release > 0) then ShowStr(dest,xstart+2,ystart+10, Copy(Copy(ExpStrR(#246,_conv(attack,16-attack),' ')+ ExpStrR(#246,_conv(decay,16-decay),' ')+ ExpStrR(#246,_conv(sustain,sustain),' ')+ ExpStrR(#246,_conv(release,15-release),' '),1,60-1)+ #246+ExpStrL('',60,' '),1,60), attr_hi) else ShowStr(dest,xstart+2,ystart+10, ExpStrR(#246,_conv(attack,16-attack),' ')+ ExpStrR(#246,_conv(decay,16-decay),' ')+ ExpStrR(#246,_conv(sustain,sustain),' ')+ ExpStrR(#246,_conv(release,15-release)+ 15-_conv(release,15-release)+ 15-_conv(sustain,sustain)+ 15-_conv(decay,16-decay)+ 15-_conv(attack,16-attack),' '), attr_hi); If (release > 0) then ShowStr(dest,xstart+2,ystart+11, Copy(Copy(ExpStrR('A',_conv(attack,16-attack),#250)+ ExpStrR('D',_conv(decay,16-decay),#250)+ ExpStrR('S',_conv(sustain,sustain),#250)+ ExpStrR('R',_conv(release,15-release),#250),1,60-1)+ #175+ExpStrL('',60,#250),1,60), attr_hi) else ShowStr(dest,xstart+2,ystart+11, ExpStrR('A',_conv(attack,16-attack),#250)+ ExpStrR('D',_conv(decay,16-decay),#250)+ ExpStrR('S',_conv(sustain,sustain),#250)+ ExpStrR('R',_conv(release,15-release)+ 15-_conv(release,15-release)+ 15-_conv(sustain,sustain)+ 15-_conv(decay,16-decay)+ 15-_conv(attack,16-attack),#250), attr_hi); end; procedure INSTRUMENT_CONTROL_page_refresh_alt(page: Byte); var temp: Byte; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_page_refresh_alt'; {$ENDIF} update_4op_flag_marks; If (ins_parameter(page,10) AND 1 <> 1) then For temp := 1 to 18 do ShowCStr(mn_environment.v_dest,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm1[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm1[temp].colr]) else For temp := 1 to 18 do ShowCStr(mn_environment.v_dest,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm2[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm2[temp].colr]); For temp := 1 to 10 do ShowStr(mn_environment.v_dest,INSCTRL_xshift+32,INSCTRL_yshift+08+pos2[temp], byte2hex(pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[temp]]), instrument_bckg+instrument_hi_text); ShowCStr(mn_environment.v_dest, INSCTRL_xshift+30,INSCTRL_yshift+08+pos2[11], connection_str[pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[11]] AND 1]+'~/~'+ CHR(ORD('0')+(pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[11]] SHR 1 AND 7)), dialog_background+dialog_item, color_table[inst_itm1[temp].colr]); Case songdata.instr_data[page].panning of 0: ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'CENTER', instrument_bckg+instrument_hi_text); 1: ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'LEFT ', instrument_bckg+instrument_hi_text); 2: ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'RiGHT ', instrument_bckg+instrument_hi_text); end; If (songdata.instr_data[page].fine_tune < 0) then ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[13], '-'+ExpStrR(Num2str(Abs(songdata.instr_data[page].fine_tune),16),2,' '), instrument_bckg+instrument_hi_text) else ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[13], '+'+ExpStrR(Num2str(Abs(songdata.instr_data[page].fine_tune),16),2,' '), instrument_bckg+instrument_hi_text); ShowCStr(mn_environment.v_dest, INSCTRL_xshift+09,INSCTRL_yshift+26, ' [~'+perc_voice_str[songdata.instr_data[page].perc_voice]+'~] ', dialog_background+dialog_border, dialog_background+dialog_context); If (songdata.instr_macros[page].length <> 0) then temp_str := ' [~MACRO:FM' else temp_str := ' '; With songdata.macro_table[ songdata.instr_macros[page].arpeggio_table].arpeggio do If (songdata.instr_macros[page].arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'[~MACRO:ARP'; With songdata.macro_table[ songdata.instr_macros[page].vibrato_table].vibrato do If (songdata.instr_macros[page].vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'[~MACRO:ViB'; If (temp_str <> ' ') then temp_str := temp_str+'~] '; ShowCStr(mn_environment.v_dest,INSCTRL_xshift+19,INSCTRL_yshift+26, ExpStrR(temp_str,21+1,#205), dialog_background+dialog_border, dialog_background+dialog_context); end; var temp: Byte; xstart,ystart: Byte; nope: Boolean; hpos,vpos: Byte; carrier: Boolean; inst: ^tADTRACK2_INS; type tSET_OF_CHARS = Set of Char; tBYTE_PTR = ^Byte; function _4op_conn_to_idx(str: String): Byte; var idx,result: Byte; temps: String; begin temps := FilterStr1(str,'~'); result := 2; For idx := 0 to 3 do If (temps = _4op_connection_str[idx]) then begin Inc(result,idx); BREAK; end; _4op_conn_to_idx := result; end; procedure _show_conn_scheme(xstart,ystart,conn: Byte; hi_op: tSET_OF_CHARS); var idx,idx2: Byte; result: array[1..6] of String; begin For idx2 := 1 to 6 do begin result[idx2] := ''; idx := 1; While (idx <= 17) do If (inst_con_scheme[conn][idx2][idx] = #219) and (inst_con_scheme[conn][idx2][idx+1] in ['1'..'4']) then begin If (inst_con_scheme[conn][idx2][idx+1] in hi_op) then result[idx2] := result[idx2]+'`'#219'`^'+inst_con_scheme[conn][idx2][idx+1]+'^`'#219'`' else result[idx2] := result[idx2]+#219'~'+inst_con_scheme[conn][idx2][idx+1]+'~'#219; Inc(idx,3); end else begin result[idx2] := result[idx2]+inst_con_scheme[conn][idx2][idx]; Inc(idx); end; end; For idx := 1 to 6 do ShowC4Str(ptr_temp_screen,xstart,ystart+idx-1,result[idx], instrument_bckg+instrument_glob, instrument_glob SHL 4, instrument_bckg+instrument_hi_glob, instrument_hi_glob SHL 4); end; function _get_feedback_val: Byte; begin If NOT (get_4op_to_test <> 0) then _get_feedback_val := (songdata.instr_data[current_inst].fm_data.FEEDBACK_FM SHR 1) AND 7 else _get_feedback_val := (songdata.instr_data[LO(get_4op_to_test)].fm_data.FEEDBACK_FM SHR 1) AND 7; end; procedure _inc_feedback_val; var feedb_ptr: tBYTE_PTR; begin If NOT (get_4op_to_test <> 0) then feedb_ptr := tBYTE_PTR(Addr(songdata.instr_data[current_inst].fm_data.FEEDBACK_FM)) else feedb_ptr := tBYTE_PTR(Addr(songdata.instr_data[LO(get_4op_to_test)].fm_data.FEEDBACK_FM)); If ((feedb_ptr^ SHR 1) AND 7 < 7) then feedb_ptr^ := feedb_ptr^ AND 1+((feedb_ptr^ SHR 1) AND 7 +1) SHL 1; end; procedure _dec_feedback_val; var feedb_ptr: tBYTE_PTR; begin If NOT (get_4op_to_test <> 0) then feedb_ptr := tBYTE_PTR(Addr(songdata.instr_data[current_inst].fm_data.FEEDBACK_FM)) else feedb_ptr := tBYTE_PTR(Addr(songdata.instr_data[LO(get_4op_to_test)].fm_data.FEEDBACK_FM)); If ((feedb_ptr^ SHR 1) AND 7 > 0) then feedb_ptr^ := feedb_ptr^ AND 1+((feedb_ptr^ SHR 1) AND 7 -1) SHL 1; end; function _get_finetune_val: Shortint; begin If NOT (get_4op_to_test <> 0) then _get_finetune_val := songdata.instr_data[current_inst].fine_tune else _get_finetune_val := songdata.instr_data[LO(get_4op_to_test)].fine_tune; end; procedure _inc_finetune_val; begin If NOT (get_4op_to_test <> 0) then songdata.instr_data[current_inst].fine_tune := max(songdata.instr_data[current_inst].fine_tune+1,127) else songdata.instr_data[LO(get_4op_to_test)].fine_tune := max(songdata.instr_data[LO(get_4op_to_test)].fine_tune+1,127); end; procedure _dec_finetune_val; begin If NOT (get_4op_to_test <> 0) then songdata.instr_data[current_inst].fine_tune := min(songdata.instr_data[current_inst].fine_tune-1,-127) else songdata.instr_data[LO(get_4op_to_test)].fine_tune := min(songdata.instr_data[LO(get_4op_to_test)].fine_tune-1,-127); end; var _curr_connection_str: String; _status_shift_pos: Byte; _4op_conn_str: String; _4op_slot_str: String; _4op_slot_chr: tSET_OF_CHARS; _col_mod,_col_hi_mod: Byte; procedure _page_build; var temp,nm_slots: Byte; temp_str: String; _pan_4op: String; _feedb_4op: String; _ftune_4op: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_edit:page_build'; {$ENDIF} ShowStr(ptr_temp_screen,xstart+45,ystart, byte2hex(instrum_page), instrument_bckg+instrument_title); If NOT is_default_screen_mode then ShowStr(ptr_temp_screen,xstart-1,ystart+24, #204+ExpStrL('',70,#205)+#185, instrument_bckg+instrument_border); If NOT (inst^.perc_voice in [2..5]) and (get_4op_to_test <> 0) then begin If (LO(get_4op_to_test) = HI(get_4op_to_test)) then _4op_conn_str := connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'/'+ connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1] else If (current_inst = HI(get_4op_to_test)) then _4op_conn_str := '~'+connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'~/'+ connection_str[pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1] else _4op_conn_str := connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'/~'+ connection_str[pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'~'; If (current_inst = LO(get_4op_to_test)) then If NOT carrier then If (HI(get_4op_to_test) <> LO(get_4op_to_test)) then begin _4op_slot_str := '~1~`'#27'`2`'#27'`3`'#27'`4'; _4op_slot_chr := ['1']; end else begin _4op_slot_str := '~1~`'#27'`2`'#27'`~3~`'#27'`4'; _4op_slot_chr := ['1','3'] end else If (HI(get_4op_to_test) <> LO(get_4op_to_test)) then begin _4op_slot_str := '1`'#27'`~2~`'#27'`3`'#27'`4'; _4op_slot_chr := ['2']; end else begin _4op_slot_str := '1`'#27'`~2~`'#27'`3`'#27'`~4~'; _4op_slot_chr := ['2','4']; end else If NOT carrier then If (HI(get_4op_to_test) <> LO(get_4op_to_test)) then begin _4op_slot_str := '1`'#27'`2`'#27'`~3~`'#27'`4'; _4op_slot_chr := ['3']; end else begin _4op_slot_str := '~1~`'#27'`2`'#27'`~3~`'#27'`4'; _4op_slot_chr := ['1','3']; end else If (HI(get_4op_to_test) <> LO(get_4op_to_test)) then begin _4op_slot_str := '1`'#27'`2`'#27'`3`'#27'`~4~'; _4op_slot_chr := ['4']; end else begin _4op_slot_str := '1`'#27'`~2~`'#27'`3`'#27'`~4~'; _4op_slot_chr := ['2','4']; end; end; If (inst^.perc_voice in [2..5]) then begin Move(inst_text_ext_perc,inst_text[9],SizeOf(inst_text_ext_perc)); Move(inst_hpos_ext_perc,inst_hpos[12],SizeOf(inst_hpos_ext_perc)); end else If NOT (get_4op_to_test <> 0) then begin Move(inst_text_ext_2op,inst_text[9],SizeOf(inst_text_ext_2op)); Move(inst_hpos_ext_2op,inst_hpos[12],SizeOf(inst_hpos_ext_2op)); end else begin Move(inst_text_ext_4op,inst_text[9],SizeOf(inst_text_ext_4op)); Move(inst_hpos_ext_4op,inst_hpos[12],SizeOf(inst_hpos_ext_4op)); end; If NOT (inst^.perc_voice in [2..5]) and ((NOT (get_4op_to_test <> 0) and carrier) or ((get_4op_to_test <> 0) and (('2' in _4op_slot_chr) or ('4' in _4op_slot_chr)))) then For temp := 1 to 24 do ShowC4Str(ptr_temp_screen,xstart+1,ystart+temp,inst_text[temp], instrument_bckg+instrument_text, instrument_bckg+instrument_car, instrument_bckg+instrument_glob, instrument_bckg+instrument_hid) else For temp := 1 to 24 do ShowC4Str(ptr_temp_screen,xstart+1,ystart+temp,inst_text[temp], instrument_bckg+instrument_text, instrument_bckg+instrument_mod, instrument_bckg+instrument_glob, instrument_bckg+instrument_hid); If (inst^.perc_voice in [2..5]) then _status_shift_pos := 5 else If NOT (get_4op_to_test <> 0) then _status_shift_pos := 9 else _status_shift_pos := 19; If NOT (inst^.perc_voice in [2..5]) and (get_4op_to_test <> 0) then begin If (LO(get_4op_to_test) = HI(get_4op_to_test)) then ShowC3Str(ptr_temp_screen,xstart,ystart+24, ' `[`'#244+byte2hex(HI(get_4op_to_test))+ ','#245+byte2hex(HI(get_4op_to_test))+' '+_4op_conn_str+'`]` ', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border) else If (current_inst = HI(get_4op_to_test)) then ShowC3Str(ptr_temp_screen,xstart,ystart+24, ' `[`~'#244+byte2hex(HI(get_4op_to_test))+ '~,'#245+byte2hex(LO(get_4op_to_test))+' '+_4op_conn_str+'`]` ', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border) else ShowC3Str(ptr_temp_screen,xstart,ystart+24, ' `[`'#244+byte2hex(HI(get_4op_to_test))+ ',~'#245+byte2hex(LO(get_4op_to_test))+'~ '+_4op_conn_str+'`]` ', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border); _show_conn_scheme(xstart+32,ystart+11,_4op_conn_to_idx(_4op_conn_str),_4op_slot_chr); ShowC3Str(ptr_temp_screen,xstart+17,ystart+24,'`[`'#4#3':'+_4op_slot_str+'`]` ', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border); end else begin If NOT (inst^.perc_voice in [2..5]) then _show_conn_scheme(xstart+32,ystart+11,inst^.fm_data.FEEDBACK_FM AND 1,[CHR(BYTE(carrier)+ORD('1'))]) else _show_conn_scheme(xstart+32,ystart+11,6,['1']); Case inst^.perc_voice of 0: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~MELODiC~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 1: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:BD~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 2: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:SD~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 3: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:TT~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 4: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:TC~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 5: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:HH~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); end; If (inst^.perc_voice in [2..5]) then ShowCStr(ptr_temp_screen,xstart+10,ystart+24, ' [~'#1#3'~] ', instrument_bckg+instrument_border, instrument_bckg+instrument_context) else If NOT carrier then ShowC3Str(ptr_temp_screen,xstart+10,ystart+24,' `[`'#2#3':~1~`'#27'`2`]`', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border) else ShowC3Str(ptr_temp_screen,xstart+10,ystart+24,' `[`'#2#3':1`'#27'`~2~`]`', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border); end; If (songdata.instr_macros[instrum_page].length <> 0) then temp_str := ' [~MACRO:FM' else temp_str := ' '; With songdata.macro_table[ songdata.instr_macros[instrum_page].arpeggio_table].arpeggio do If (songdata.instr_macros[instrum_page].arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'[~MACRO:ARP'; With songdata.macro_table[ songdata.instr_macros[instrum_page].vibrato_table].vibrato do If (songdata.instr_macros[instrum_page].vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'[~MACRO:ViB'; If (temp_str <> ' ') then temp_str := temp_str+'~] '; ShowCStr(ptr_temp_screen, xstart+10+_status_shift_pos,ystart+24, ExpStrR(temp_str,39,#205), instrument_bckg+instrument_border, instrument_bckg+instrument_context); If (inst^.perc_voice in [2..5]) then begin temp_str := '```` '; nm_slots := 1; end else If NOT (get_4op_to_test <> 0) then begin temp_str := ' `[`12`]` '; nm_slots := 2; end else begin temp_str := ' `[`1234`]` '; nm_slots := 4; end; temp_str := temp_str+'[~SPEED:'+Num2str(songdata.tempo*songdata.macro_speedup,10)+#174+'~] '; ShowC3Str(ptr_temp_screen,xstart+48,ystart+24, ExpStrL(temp_str,28,#205), instrument_bckg+instrument_border, instrument_bckg+instrument_context, instrument_bckg+instrument_con_dis); If (nm_slots > 1) then For temp := 1 to nm_slots do If (NOT _operator_enabled[temp]) then ShowStr(ptr_temp_screen,xstart+72-C3StrLen(temp_str)-1+temp,ystart+24, #250, instrument_bckg+instrument_border); If (inst_hpos[vpos,hpos] = 0) then begin vpos := 1; hpos := 1; end; If NOT (get_4op_to_test <> 0) then begin _pan_4op := ' '; _feedb_4op := ' '; _ftune_4op := ' '; end else begin If (current_inst = HI(get_4op_to_test)) then _pan_4op := '('#244#2#3')' else _pan_4op := '('#245#2#3')'; _feedb_4op := '['#4#3']'; _ftune_4op := '['#4#3']' end; If NOT (inst^.perc_voice in [2..5]) then begin _col_mod := instrument_mod; _col_hi_mod := instrument_hi_mod; end else begin _col_mod := instrument_glob; _col_hi_mod := instrument_hi_glob; end; If NOT ((vpos = 1) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+1,'~A~TTACK RATE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+1,'~A~TTACK RATE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos = 2) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+2,'~D~ECAY RATE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+2,'~D~ECAY RATE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos in [3,6,8,9]) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+51,ystart+1,'~W~AVEFORM TYPE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+51,ystart+1,'~W~AVEFORM TYPE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos = 4) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+4,'~S~USTAiN LEVEL', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+4,'~S~USTAiN LEVEL', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos = 5) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+5,'~R~ELEASE RATE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+5,'~R~ELEASE RATE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos = 7) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+7,'~O~UTPUT LEVEL', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+7,'~O~UTPUT LEVEL', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos in [10..13]) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+9,'~K~EY SCALiNG LEVEL', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+9,'~K~EY SCALiNG LEVEL', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT (inst^.perc_voice in [2..5]) then begin If NOT (((vpos in [12,13]) and (hpos = 2)) or ((vpos in [14,15]) and (hpos = 1)) or ((vpos = 17) and (hpos = 4))) then ShowCStr(ptr_temp_screen,xstart+21,ystart+11,'~C~ONNECTiON', instrument_bckg+instrument_glob, instrument_bckg+instrument_hi_glob); If NOT ((vpos = 12) and (hpos = 3)) then ShowCStr(ptr_temp_screen,xstart+51,ystart+11,'~F~EEDBACK '+_feedb_4op, instrument_bckg+instrument_glob, instrument_bckg+instrument_hi_glob); end; If NOT ((vpos = 16) and (hpos = 2)) then ShowCStr(ptr_temp_screen,xstart+51,ystart+15,'F-~T~UNE '+_ftune_4op, instrument_bckg+instrument_glob, instrument_bckg+instrument_hi_glob); If NOT ((vpos = 17) and (hpos in [1..3])) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+15,'~P~ANNiNG '+_pan_4op, instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+15,'~P~ANNiNG '+_pan_4op, instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos in [18..21]) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+19,'~E~NVELOPE TYPE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+19,'~E~NVELOPE TYPE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos in [18..20]) and (hpos > 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+28,ystart+19,'FREQUENCY DATA ~M~ULTiPLiER', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+28,ystart+19,'FREQUENCY DATA ~M~ULTiPLiER', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); Case hpos of 1: Case vpos of 1: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+1,'ATTACK RATE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+1,'ATTACK RATE', instrument_bckg+_col_hi_mod); 2: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+2,'DECAY RATE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+2,'DECAY RATE', instrument_bckg+_col_hi_mod); 3,6,8, 9: If carrier then ShowStr(ptr_temp_screen,xstart+51,ystart+1,'WAVEFORM TYPE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+51,ystart+1,'WAVEFORM TYPE', instrument_bckg+_col_hi_mod); 4: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+4,'SUSTAiN LEVEL', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+4,'SUSTAiN LEVEL', instrument_bckg+_col_hi_mod); 5: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+5,'RELEASE RATE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+5,'RELEASE RATE', instrument_bckg+_col_hi_mod); 7: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+7,'OUTPUT LEVEL', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+7,'OUTPUT LEVEL', instrument_bckg+_col_hi_mod); 10..17: If (vpos in [10..13]) and (hpos = 1) then If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+9,'KEY SCALiNG LEVEL', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+9,'KEY SCALiNG LEVEL', instrument_bckg+_col_hi_mod) else If (vpos <> 17) then ShowStr(ptr_temp_screen,xstart+21,ystart+11,'CONNECTiON', instrument_bckg+instrument_hi_glob) else If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+15,'PANNiNG '+_pan_4op, instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+15,'PANNiNG '+_pan_4op, instrument_bckg+_col_hi_mod); 18,19,20, 21: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+19,'ENVELOPE TYPE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+19,'ENVELOPE TYPE', instrument_bckg+_col_hi_mod); end; 2,3,4,5,6, 7: Case vpos of 2,4,5, 7: If carrier then ShowStr(ptr_temp_screen,xstart+51,ystart+1,'WAVEFORM TYPE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+51,ystart+1,'WAVEFORM TYPE', instrument_bckg+_col_hi_mod); 12..17: If (vpos = 12) and (hpos = 3) then ShowStr(ptr_temp_screen,xstart+51,ystart+11,'FEEDBACK '+_feedb_4op, instrument_bckg+instrument_hi_glob) else If (vpos = 16) and (hpos = 2) then ShowStr(ptr_temp_screen,xstart+51,ystart+15,'F-TUNE '+_ftune_4op, instrument_bckg+instrument_hi_glob) else If (vpos = 17) and (hpos in [1..3]) then If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+15,'PANNiNG '+_pan_4op, instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+15,'PANNiNG '+_pan_4op, instrument_bckg+_col_hi_mod) else ShowStr(ptr_temp_screen,xstart+21,ystart+11,'CONNECTiON', instrument_bckg+instrument_hi_glob); 18,19,20, 21: If carrier then ShowStr(ptr_temp_screen,xstart+28,ystart+19,'FREQUENCY DATA MULTiPLiER', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+28,ystart+19,'FREQUENCY DATA MULTiPLiER', instrument_bckg+_col_hi_mod); end; end; end; procedure _page_refresh; var temp,x0,y0: Byte; temps1,temps2: String; adsr_vpos: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_edit:page_refresh'; {$ENDIF} x0 := xstart; y0 := ystart; If is_default_screen_mode then begin adsr_vpos := y0+9; adsr_bckg := instrument_adsr; end else begin adsr_vpos := y0+24; adsr_bckg := instrument_bckg; end; If (NOT ((vpos in [1,2,4,5,7,21]) and (hpos = 1)) or NOT _ADSR_preview_flag) then begin _show_adsr(ptr_temp_screen,x0+3,adsr_vpos, BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL, adsr_bckg,adsr_bckg, TRUE); _page_build; end; If carrier then temp := inst^.fm_data.ATTCK_DEC_carrier else temp := inst^.fm_data.ATTCK_DEC_modulator; ShowCStr(ptr_temp_screen,x0+inst_hpos[1,1],y0+inst_vpos[1],'~'+ ExpStrL('', (temp SHR 4),#14)+'~'+ ExpStrL('',15-(temp SHR 4),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowCStr(ptr_temp_screen,x0+inst_hpos[2,1],y0+inst_vpos[2],'~'+ ExpStrL('', (temp AND $0f),#14)+'~'+ ExpStrL('',15-(temp AND $0f),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowStr(ptr_temp_screen,x0+inst_hpos[1,1]+16,y0+inst_vpos[1], ExpStrR(Num2str(temp SHR 4,16),1,' '), instrument_bckg+instrument_text); ShowStr(ptr_temp_screen,x0+inst_hpos[2,1]+16,y0+inst_vpos[2], ExpStrR(Num2str(temp AND $0f,16),1,' '), instrument_bckg+instrument_text); If carrier then temp := inst^.fm_data.SUSTN_REL_carrier else temp := inst^.fm_data.SUSTN_REL_modulator; ShowCStr(ptr_temp_screen,x0+inst_hpos[4,1],y0+inst_vpos[4],'~'+ ExpStrL('', (temp SHR 4),#14)+'~'+ ExpStrL('',15-(temp SHR 4),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowCStr(ptr_temp_screen,x0+inst_hpos[5,1],y0+inst_vpos[5],'~'+ ExpStrL('', (temp AND $0f),#14)+'~'+ ExpStrL('',15-(temp AND $0f),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowStr(ptr_temp_screen,x0+inst_hpos[4,1]+16,y0+inst_vpos[4], ExpStrR(Num2str(temp SHR 4,16),1,' '), instrument_bckg+instrument_text); ShowStr(ptr_temp_screen,x0+inst_hpos[5,1]+16,y0+inst_vpos[5], ExpStrR(Num2str(temp AND $0f,16),1,' '), instrument_bckg+instrument_text); If carrier then temp := inst^.fm_data.WAVEFORM_carrier else temp := inst^.fm_data.WAVEFORM_modulator; ShowVStr(ptr_temp_screen,x0+inst_hpos[2,2],y0+inst_vpos[2], ExpStrL('',temp AND 7,' ')+#11+ExpStrL('',7-temp AND 7,' '), instrument_bckg+instrument_hi_text); If carrier then temp := inst^.fm_data.KSL_VOLUM_carrier else temp := inst^.fm_data.KSL_VOLUM_modulator; ShowCStr(ptr_temp_screen,x0+inst_hpos[7,1],y0+inst_vpos[7],'~'+ ExpStrL('', ((63-(temp AND $3f)) DIV 2),#14)+'~'+ ExpStrL('',31-((63-(temp AND $3f)) DIV 2),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowStr(ptr_temp_screen,x0+inst_hpos[7,1]+32,y0+inst_vpos[7], ExpStrR(Num2str(63-(temp AND $3f),16),2,' '), instrument_bckg+instrument_text); temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; ShowVStr(ptr_temp_screen,x0+inst_hpos[10,1],y0+inst_vpos[10], ExpStrL('',temp,' ')+#11+ExpStrL('',3-temp,' '), instrument_bckg+instrument_hi_text); ShowCStr(ptr_temp_screen,x0+inst_hpos[17,1],y0+inst_vpos[17],ins_pan_str1[inst^.panning], instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); If NOT (inst^.perc_voice in [2..5]) then begin temp := inst^.fm_data.FEEDBACK_FM; ShowCStr(ptr_temp_screen,x0+inst_hpos[12,3],y0+inst_vpos[12],'~'+ ExpStrL('', ROUND(_get_feedback_val*(17/7)),#14)+'~'+ ExpStrL('',17-ROUND(_get_feedback_val*(17/7)),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowStr(ptr_temp_screen,x0+inst_hpos[12,3]+16,y0+inst_vpos[12]-1, ExpStrR(Num2str(_get_feedback_val,16),2,' '), instrument_bckg+instrument_text); _curr_connection_str := ExpStrR('',6,' '); If NOT (get_4op_to_test <> 0) then If (temp AND 1 = 0) then _curr_connection_str[1] := #11 else _curr_connection_str[2] := #11 else _curr_connection_str[_4op_conn_to_idx(_4op_conn_str)+1] := #11; If NOT (get_4op_to_test <> 0) then ShowVStr(ptr_temp_screen,x0+inst_hpos[12,2],y0+inst_vpos[12],_curr_connection_str, instrument_bckg+instrument_hi_text) else ShowVStr(ptr_temp_screen,x0+inst_hpos[14,1],y0+inst_vpos[12],_curr_connection_str, instrument_bckg+instrument_hi_text); end; If (_get_finetune_val >= 0) then temp := _get_finetune_val else temp := 0-_get_finetune_val; temps1 := ExpStrL('',17,#14); If (vpos = 16) and (hpos = 2) then temps2 := #15'~'#15'~'#15 else temps2 := #15'`'#15'`'#15; If (_get_finetune_val > 0) then begin Delete(temps1,1+7+(temp DIV 18),3); Insert(temps2,temps1,1+7+(temp DIV 18)); end else begin Delete(temps1,1+7-(temp DIV 18),3); Insert(temps2,temps1,1+7-(temp DIV 18)); end; If (_get_finetune_val > 0) then temps2 := '+' else If (_get_finetune_val < 0) then temps2 := '-' else temps2 := ''; ShowStr(ptr_temp_screen,x0+inst_hpos[16,2]+14,y0+inst_vpos[16]-1, ExpStrL(temps2+ExpStrL(Num2str(temp,16),2,'0'),3,' '), instrument_bckg+instrument_text); ShowC3Str(ptr_temp_screen,x0+inst_hpos[16,2],y0+inst_vpos[16],temps1, instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text, instrument_bckg+instrument_glob); If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier else temp := inst^.fm_data.AM_VIB_EG_modulator; If (temp SHR 7 = 0) then temps1 := ' ' else temps1 := #251; If ((temp SHR 6) AND 1 = 0) then temps1 := temps1+' ' else temps1 := temps1+#251; If ((temp SHR 4) AND 1 = 0) then temps1 := temps1+' ' else temps1 := temps1+#251; If ((temp SHR 5) AND 1 = 0) then temps1 := temps1+' ' else temps1 := temps1+#251; ShowVStr(ptr_temp_screen,x0+inst_hpos[18,1],y0+inst_vpos[18],temps1, instrument_bckg+instrument_hi_text); temps1 := ExpStrL('',16,' '); temps1[(temp AND $0f)+1] := '.'; If ((vpos in [19..21]) and (hpos in [2..7])) then ShowStr(ptr_temp_screen,x0+inst_hpos[21,2]-1,y0+inst_vpos[19]-1, ExpStrR(inst_mult_hint[(vpos-19)*6+hpos-2],34,' '), instrument_bckg+instrument_hi_text) else ShowStr(ptr_temp_screen,x0+inst_hpos[21,2]-1,y0+inst_vpos[19]-1, ExpStrR(inst_mult_hint[temp AND $0f],34,' '), instrument_bckg+instrument_hi_text); For temp := 1 to 6 do If (temps1[temp] = ' ') then ShowStr(ptr_temp_screen,x0+inst_hpos[19,2+temp-1],y0+inst_vpos[19],' ', instrument_bckg+instrument_hi_text) else ShowStr(ptr_temp_screen,x0+inst_hpos[19,2+temp-1],y0+inst_vpos[19],#11, instrument_bckg+instrument_hi_text); For temp := 1 to 6 do If (temps1[6+temp] = ' ') then ShowStr(ptr_temp_screen,x0+inst_hpos[20,2+temp-1],y0+inst_vpos[20],' ', instrument_bckg+instrument_hi_text) else ShowStr(ptr_temp_screen,x0+inst_hpos[20,2+temp-1],y0+inst_vpos[20],#11, instrument_bckg+instrument_hi_text); For temp := 1 to 4 do If (temps1[12+temp] = ' ') then ShowStr(ptr_temp_screen,x0+inst_hpos[21,2+temp-1],y0+inst_vpos[21],' ', instrument_bckg+instrument_hi_text) else ShowStr(ptr_temp_screen,x0+inst_hpos[21,2+temp-1],y0+inst_vpos[21],#11, instrument_bckg+instrument_hi_text); If NOT is_default_screen_mode or ((vpos in [1,2,4,5,7,21]) and (hpos = 1) and _ADSR_preview_flag) then If NOT carrier or (inst^.perc_voice in [2..5]) then _show_adsr(ptr_temp_screen,x0+3,adsr_vpos, inst^.fm_data.ATTCK_DEC_modulator SHR 4, inst^.fm_data.ATTCK_DEC_modulator AND $0f, inst^.fm_data.SUSTN_REL_modulator SHR 4, inst^.fm_data.SUSTN_REL_modulator AND $0f, inst^.fm_data.KSL_VOLUM_modulator AND $3f, inst^.fm_data.AM_VIB_EG_modulator SHR 5 AND 1, adsr_bckg+_col_mod, adsr_bckg+_col_hi_mod,FALSE) else _show_adsr(ptr_temp_screen,x0+3,adsr_vpos, inst^.fm_data.ATTCK_DEC_carrier SHR 4, inst^.fm_data.ATTCK_DEC_carrier AND $0f, inst^.fm_data.SUSTN_REL_carrier SHR 4, inst^.fm_data.SUSTN_REL_carrier AND $0f, inst^.fm_data.KSL_VOLUM_carrier AND $3f, inst^.fm_data.AM_VIB_EG_carrier SHR 5 AND 1, adsr_bckg+instrument_car, adsr_bckg+instrument_hi_car,FALSE); move2screen_alt; end; procedure _sync_radio_buttons; var temp: Byte; begin If ((vpos in [1,2,4,5,7]) and (hpos = 2)) or (vpos in [3,6,8,9]) then // sync WAVEFORM begin If carrier then vpos := 2+songdata.instr_data[current_inst].fm_data.WAVEFORM_carrier else vpos := 2+songdata.instr_data[current_inst].fm_data.WAVEFORM_modulator; If (vpos in [1,2,4,5,7]) then hpos := 2 else If (vpos in [3,6,8,9]) then hpos := 1; end; If (vpos in [10..13]) and (hpos = 1) then // sync SCALING LEVEL begin If carrier then temp := songdata.instr_data[current_inst].fm_data.KSL_VOLUM_carrier else temp := songdata.instr_data[current_inst].fm_data.KSL_VOLUM_modulator; temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; vpos := 10+temp; hpos := 1; end; If (vpos = 17) and (hpos in [1..3]) then // sync PANNING Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end; If ((vpos in [12,13]) and (hpos = 2)) or ((vpos in [14,15,16]) and (hpos = 1)) or ((vpos = 17) and (hpos = 4)) then // sync CONNECTION Case Pos(#11,_curr_connection_str) of 1: begin vpos := 12; hpos := 2; end; 2: begin vpos := 13; hpos := 2; end; 3: begin vpos := 14; hpos := 1; end; 4: begin vpos := 15; hpos := 1; end; 5: begin vpos := 16; hpos := 1; end; 6: begin vpos := 17; hpos := 3; end; end; If (vpos in [19..21]) and (hpos > 1) then // sync FREQ. DATA MULT. begin If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier AND $0f else temp := inst^.fm_data.AM_VIB_EG_modulator AND $0f; hpos := 2+(temp MOD 6); vpos := 19+(temp DIV 6); end; end; procedure INSTRUMENT_CONTROL_edit; function min0(number: Integer): Integer; begin If (number > 0) then min0 := number else min0 := 0; end; function _ftune(ftune: Integer): Integer; var temp: Integer; begin If (ftune DIV 18 = 0) and (ftune <> 0) then temp := 0 else temp := ABS(ftune) DIV 18; _ftune := (ftune DIV min(ABS(ftune),1))*temp; end; function _check_hpos_idx_l(vpos: Byte): Byte; var idx: Byte; begin _check_hpos_idx_l := 0; For idx := 1 to inst_hpos_max do If (inst_hpos[vpos,idx] <> 0) then begin _check_hpos_idx_l := idx; BREAK; end; end; function _check_hpos_idx_r(vpos: Byte): Byte; var idx: Byte; begin _check_hpos_idx_r := 0; For idx := inst_hpos_max downto 1 do If (inst_hpos[vpos,idx] <> 0) then begin _check_hpos_idx_r := idx; BREAK; end; end; procedure _set_operator_flag(operator: Byte; toggle: Boolean); var _temp_operator_enabled: array[1..4] of Boolean; begin If (inst^.perc_voice in [2..5]) or (NOT (get_4op_to_test <> 0) and NOT (operator in [1..2])) or (NOT (operator in [1..4])) then EXIT; If NOT toggle then begin FillChar(_operator_enabled,SizeOf(_operator_enabled),FALSE); _operator_enabled[operator] := TRUE; EXIT; end; Move(_operator_enabled,_temp_operator_enabled,SizeOf(_temp_operator_enabled)); If NOT (get_4op_to_test <> 0) and (operator in [1,2]) then begin _temp_operator_enabled[operator] := NOT _temp_operator_enabled[operator]; If NOT ((_temp_operator_enabled[1] = FALSE) and (_temp_operator_enabled[2] = FALSE)) then Move(_temp_operator_enabled,_operator_enabled,SizeOf(_operator_enabled)); end else If (get_4op_to_test <> 0) and (operator in [1,2,3,4]) then begin _temp_operator_enabled[operator] := NOT _temp_operator_enabled[operator]; If NOT ((_temp_operator_enabled[1] = FALSE) and (_temp_operator_enabled[2] = FALSE) and (_temp_operator_enabled[3] = FALSE) and (_temp_operator_enabled[4] = FALSE)) then Move(_temp_operator_enabled,_operator_enabled,SizeOf(_operator_enabled)); end; end; const KSL_volume: array[0..3] of Byte = (0,$80,$40,$0c0); AM_Vibrato_EG: array[0..3] of Byte = ($80,$40,$10,$20); panning_pos: array[0..2] of Byte = (1,0,2); label _jmp1,_end; begin { INSTRUMENT_CONTROL_edit } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_edit'; {$ENDIF} inst := Addr(songdata.instr_data[instrum_page]); FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); If NOT (inst^.perc_voice in [2..5]) then If remember_ins_pos then begin temp := get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier',-1); If (temp <> 2) then carrier := TRUE else carrier := FALSE; end else carrier := TRUE else carrier := FALSE; If NOT remember_ins_pos then begin hpos := 1; vpos := 1; end else If carrier then begin hpos := min(get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?hpos',-1),1); vpos := min(get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?vpos',-1),1); end else begin hpos := min(get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?hpos',-1),1); vpos := min(get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?vpos',-1),1); end; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,71,24+INSEDIT_yshift,' iNSTRUMENT EDiTOR (iNS_ ) ', instrument_bckg+instrument_border, instrument_bckg+instrument_title, frame_double); centered_frame_vdest := screen_ptr; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen_alt; move_to_screen_area[1] := xstart+1; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+70; move_to_screen_area[4] := ystart+24+INSEDIT_yshift; Inc(xstart); _page_build; _sync_radio_buttons; If NOT _force_program_quit then Repeat keyboard_poll_input; _page_build; _page_refresh; If ((vpos in [1,2,4,5,7]) and (hpos = 1)) or ((vpos = 12) and (hpos = 3)) or ((vpos = 16) and (hpos = 2)) then With songdata.instr_data[current_inst] do begin Case vpos of 1: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.ATTCK_DEC_carrier SHR 4-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.ATTCK_DEC_modulator SHR 4-1), ystart+inst_vpos[vpos]); 2: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.ATTCK_DEC_carrier AND $0f-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.ATTCK_DEC_modulator AND $0f-1), ystart+inst_vpos[vpos]); 4: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.SUSTN_REL_carrier SHR 4-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.SUSTN_REL_modulator SHR 4-1), ystart+inst_vpos[vpos]); 5: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.SUSTN_REL_carrier AND $0f-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.SUSTN_REL_modulator AND $0f-1), ystart+inst_vpos[vpos]); 7: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0((63-fm_data.KSL_VOLUM_carrier AND $3f) DIV 2-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0((63-fm_data.KSL_VOLUM_modulator AND $3f) DIV 2-1), ystart+inst_vpos[vpos]); 12: GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(ROUND(_get_feedback_val*(17/7))-1), ystart+inst_vpos[vpos]); 16: If (_get_finetune_val > 0) then GotoXY(xstart+inst_hpos[vpos,hpos]+7+_ftune(_get_finetune_val)+1, ystart+inst_vpos[vpos]) else If (_get_finetune_val < 0) then GotoXY(xstart+inst_hpos[vpos,hpos]+1+7+_ftune(_get_finetune_val)-1, ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+1+7+_ftune(_get_finetune_val), ystart+inst_vpos[vpos]); end; SetCursorShape($010c); end else begin ThinCursor; GotoXY(xstart+inst_hpos[vpos,hpos],ystart+inst_vpos[vpos]); end; nope := FALSE; If keypressed then fkey := getkey else GOTO _end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then If (get_4op_to_test <> 0) then INSTRUMENT_test(LO(get_4op_to_test),HI(get_4op_to_test),count_channel(pattern_hpos),fkey,TRUE) else INSTRUMENT_test(instrum_page,0,count_channel(pattern_hpos),fkey,TRUE); Case fkey of kAlt0: FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); kAlt1: If shift_pressed then _set_operator_flag(1,TRUE) else _set_operator_flag(1,FALSE); kAlt2: If shift_pressed then _set_operator_flag(2,TRUE) else _set_operator_flag(2,FALSE); kAlt3: If shift_pressed then _set_operator_flag(3,TRUE) else _set_operator_flag(3,FALSE); kAlt4: If shift_pressed then _set_operator_flag(4,TRUE) else _set_operator_flag(4,FALSE); kAltA: begin hpos := 1; vpos := 1; end; kAltD: begin hpos := 1; vpos := 2; end; kAltS: begin hpos := 1; vpos := 4; end; kAltR: begin hpos := 1; vpos := 5; end; kAltO: begin hpos := 1; vpos := 7; end; kAltW: begin If carrier then vpos := 2+inst^.fm_data.WAVEFORM_carrier else vpos := 2+inst^.fm_data.WAVEFORM_modulator; If (vpos in [2,4,5,7]) then hpos := 2 else hpos := 1; end; kAltK: begin If carrier then temp := inst^.fm_data.KSL_VOLUM_carrier else temp := inst^.fm_data.KSL_VOLUM_modulator; temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; vpos := 10+temp; hpos := 1; end; kAltP: Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end; kAltC: If NOT (inst^.perc_voice in [2..5]) then Case Pos(#11,_curr_connection_str) of 1: begin vpos := 12; hpos := 2; end; 2: begin vpos := 13; hpos := 2; end; 3: begin vpos := 14; hpos := 1; end; 4: begin vpos := 15; hpos := 1; end; 5: begin vpos := 16; hpos := 1; end; 6: begin vpos := 17; hpos := 4; end; end; kAltF: If NOT (inst^.perc_voice in [2..5]) then begin vpos := 12; hpos := 3; end; kAltT: begin vpos := 16; hpos := 2; end; kAltE: begin vpos := 18; hpos := 1; end; kAltM: begin If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier AND $0f else temp := inst^.fm_data.AM_VIB_EG_modulator AND $0f; hpos := 2+(temp MOD 6); vpos := 19+(temp DIV 6); end; kLEFT: If (hpos-1 >= 1) and (inst_hpos[vpos,hpos-1] <> 0) then Dec(hpos) else If (hpos-2 >= 1) and (inst_hpos[vpos,hpos-2] <> 0) then Dec(hpos,2) else If (vpos > 1) then begin Repeat Dec(vpos) until (_check_hpos_idx_r(vpos) <> 0); hpos := _check_hpos_idx_r(vpos); end else begin vpos := inst_vpos_max; hpos := inst_hpos_max; While (hpos > 1) and (inst_hpos[vpos,hpos] = 0) do Dec(hpos); end; kRIGHT: If (hpos+1 <= inst_hpos_max) and (inst_hpos[vpos,hpos+1] <> 0) then Inc(hpos) else If (hpos+2 <= inst_hpos_max) and (inst_hpos[vpos,hpos+2] <> 0) then Inc(hpos,2) else If (vpos < inst_vpos_max) then begin Repeat Inc(vpos) until (_check_hpos_idx_l(vpos) <> 0); hpos := _check_hpos_idx_l(vpos); end else begin vpos := 1; hpos := 1; end; kUP: If (vpos > 1) then begin Repeat Dec(vpos) until (inst_hpos[vpos,1] <> 0); temp := hpos; hpos := inst_hpos_max; While (hpos > 1) and ((inst_hpos[vpos,hpos] = 0) or (inst_hpos[vpos,hpos] > inst_hpos[vpos+1,temp])) do Dec(hpos); end else begin vpos := inst_vpos_max; temp := hpos; hpos := inst_hpos_max; While (hpos > 1) and ((inst_hpos[vpos,hpos] = 0) or (inst_hpos[vpos,hpos] > inst_hpos[vpos+1,temp])) do Dec(hpos); end; kDOWN: If (vpos < inst_vpos_max) then begin Repeat Inc(vpos) until (inst_hpos[vpos,1] <> 0); temp := hpos; hpos := inst_hpos_max; While (hpos > 1) and ((inst_hpos[vpos,hpos] = 0) or (inst_hpos[vpos,hpos] > inst_hpos[vpos-1,temp])) do Dec(hpos); end else begin vpos := 1; temp := hpos; hpos := inst_hpos_max; While (hpos > 1) and ((inst_hpos[vpos,hpos] = 0) or (inst_hpos[vpos,hpos] > inst_hpos[vpos-1,temp])) do Dec(hpos) end; kHOME: begin vpos := 1; hpos := 1; end; kEND: begin vpos := inst_vpos_max; hpos := inst_hpos_max; While (hpos > 1) and (inst_hpos[vpos,hpos] = 0) do Dec(hpos); end; kTAB: Case vpos of 1: begin vpos := 2; hpos := 1; end; // ATTACK RATE -> DECAY RATE 2: If (hpos = 1) then begin vpos := 4; hpos := 1; end // DECAY RATE -> SUSTAIN LEVEL else begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 3: begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 4: If (hpos = 1) then begin vpos := 5; hpos := 1; end // SUSTAIN LEVEL -> RELEASE RATE else begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 5: If (hpos = 1) then // RELEASE RATE -> WAVEFORM TYPE begin If carrier then vpos := 2+inst^.fm_data.WAVEFORM_carrier else vpos := 2+inst^.fm_data.WAVEFORM_modulator; If (vpos in [2,4,5,7]) then hpos := 2 else hpos := 1; end else begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 6: begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 7: If (hpos = 1) then // OUTPUT LEVEL -> KEY SCALiNG LEVEL begin If carrier then temp := inst^.fm_data.KSL_VOLUM_carrier else temp := inst^.fm_data.KSL_VOLUM_modulator; temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; vpos := 10+temp; hpos := 1; end else begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 8, 9: begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 10,11,12, 13: If (hpos = 1) then // KEY SCALING LEVEL -> PANNING Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end else If (vpos in [12,13]) and (hpos = 2) then // CONNECTION -> FEEDBACK begin vpos := 12; hpos := 3; end else begin vpos := 16; hpos := 2; end; // FEEDBACK -> F-TUNE 14,15, 16: If (hpos = 1) then // CONNECTION -> FEEDBACK begin vpos := 12; hpos := 3; end else begin vpos := 18; hpos := 1; end; // F-TUNE -> AM/VIB/EG/KSR 17: If (hpos in [1,2,3]) then If NOT (inst^.perc_voice in [2..5]) then // PANNING -> CONNECTION Case Pos(#11,_curr_connection_str) of 1: begin vpos := 12; hpos := 2; end; 2: begin vpos := 13; hpos := 2; end; 3: begin vpos := 14; hpos := 1; end; 4: begin vpos := 15; hpos := 1; end; 5: begin vpos := 16; hpos := 1; end; 6: begin vpos := 17; hpos := 3; end; end else begin vpos := 16; hpos := 2; end // PERC:SD/TT/TC/HH == PANNING -> F-TUNE else begin vpos := 12; hpos := 3; end; // CONNECTION -> FEEDBACK 18,19,20, 21: If (vpos = 18) or (hpos = 1) then // AM/VIB/EG/KSR -> FREQ. DATA MULT. begin If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier AND $0f else temp := inst^.fm_data.AM_VIB_EG_modulator AND $0f; hpos := 2+(temp MOD 6); vpos := 19+(temp DIV 6); end else begin // *NEXT SLOT* vpos := 1; hpos := 1; If NOT (inst^.perc_voice in [2..5]) then begin carrier := NOT carrier; If carrier and (get_4op_to_test <> 0) then begin If (current_inst = LO(get_4op_to_test)) then current_inst := HI(get_4op_to_test) else current_inst := LO(get_4op_to_test); instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); _page_build; _page_refresh; end; end; end; end; kShTAB: Case vpos of 1: begin // *PREVIOUS SLOT* If NOT (inst^.perc_voice in [2..5]) then begin carrier := NOT carrier; If NOT carrier and (get_4op_to_test <> 0) then begin If (current_inst = LO(get_4op_to_test)) then current_inst := HI(get_4op_to_test) else current_inst := LO(get_4op_to_test); instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); _page_build; _page_refresh; end; end; If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier AND $0f else temp := inst^.fm_data.AM_VIB_EG_modulator AND $0f; hpos := 2+(temp MOD 6); vpos := 19+(temp DIV 6); end; 2: If (hpos = 1) then begin vpos := 1; hpos := 1; end // DECAY RATE -> ATTACK RATE else begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 3: begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 4: If (hpos = 1) then begin vpos := 2; hpos := 1; end else begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 5: If (hpos = 1) then begin vpos := 4; hpos := 1; end else begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 6: begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 7: If (hpos = 1) then // OUTPUT LEVEL -> WAVEFORM TYPE begin If carrier then vpos := 2+inst^.fm_data.WAVEFORM_carrier else vpos := 2+inst^.fm_data.WAVEFORM_modulator; If (vpos in [2,4,5,7]) then hpos := 2 else hpos := 1; end else begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 8, 9: begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 10,11,12, 13: If (hpos = 1) then // KEY SCALING RATE -> OUTPUT LEVEL begin vpos := 7; hpos := 1; end else If (hpos = 2) then // CONNECTION -> PANNING Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end else Case Pos(#11,_curr_connection_str) of // FEEDBACK -> CONNECTION 1: begin vpos := 12; hpos := 2; end; 2: begin vpos := 13; hpos := 2; end; 3: begin vpos := 14; hpos := 1; end; 4: begin vpos := 15; hpos := 1; end; 5: begin vpos := 16; hpos := 1; end; 6: begin vpos := 17; hpos := 3; end; end; 14,15, 16: If (hpos = 1) then // CONNECTION -> PANNING Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end else If NOT (inst^.perc_voice in [2..5]) then // F-TUNE -> FEEDBACK begin vpos := 12; hpos := 3; end else Case inst^.panning of // PERC:SD/TT/TC/HH == F-TUNE -> PANNING 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end; 17: If (hpos in [1,2,3]) then // PANNING -> KEY SCALING LEVEL begin If carrier then temp := inst^.fm_data.KSL_VOLUM_carrier else temp := inst^.fm_data.KSL_VOLUM_modulator; temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; vpos := 10+temp; hpos := 1; end else Case inst^.panning of // CONNECTION -> PANNING 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end; 18,19,20, 21: If (vpos = 18) or (hpos = 1) then begin vpos := 16; hpos := 2; end // AM/VIB/EG/KSR -> F-TUNE else begin vpos := 18; hpos := 1; end; // FREQ. DATA MULT. -> AM/VIB/EG/KSR end; kSPACE: If ctrl_pressed then _ADSR_preview_flag := NOT _ADSR_preview_flag else begin Case vpos of 2: If (hpos = 2) then If carrier then inst^.fm_data.WAVEFORM_carrier := 0 else inst^.fm_data.WAVEFORM_modulator := 0; 3: If carrier then inst^.fm_data.WAVEFORM_carrier := 1 else inst^.fm_data.WAVEFORM_modulator := 1; 4: If (hpos = 2) then If carrier then inst^.fm_data.WAVEFORM_carrier := 2 else inst^.fm_data.WAVEFORM_modulator := 2; 5: If (hpos = 2) then If carrier then inst^.fm_data.WAVEFORM_carrier := 3 else inst^.fm_data.WAVEFORM_modulator := 3; 6: If carrier then inst^.fm_data.WAVEFORM_carrier := 4 else inst^.fm_data.WAVEFORM_modulator := 4; 7: If (hpos = 2) then If carrier then inst^.fm_data.WAVEFORM_carrier := 5 else inst^.fm_data.WAVEFORM_modulator := 5; 8: If carrier then inst^.fm_data.WAVEFORM_carrier := 6 else inst^.fm_data.WAVEFORM_modulator := 6; 9: If carrier then inst^.fm_data.WAVEFORM_carrier := 7 else inst^.fm_data.WAVEFORM_modulator := 7; 10..16, 17: If (vpos in [10..13]) and (hpos = 1) then If carrier then inst^.fm_data.KSL_VOLUM_carrier := inst^.fm_data.KSL_VOLUM_carrier AND $3f+KSL_volume[vpos-10] else inst^.fm_data.KSL_VOLUM_modulator := inst^.fm_data.KSL_VOLUM_modulator AND $3f+KSL_volume[vpos-10] else If ((vpos in [12,13]) and (hpos = 2)) or ((vpos in [14,15,16]) and (hpos = 1)) or ((vpos = 17) and (hpos = 4)) then Case vpos of 12,13: If NOT (get_4op_to_test <> 0) then inst^.fm_data.FEEDBACK_FM := vpos-12+inst^.fm_data.FEEDBACK_FM AND $0e; 14: If (get_4op_to_test <> 0) then begin pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] := 0+ pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] := 0+ pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; end; 15: If (get_4op_to_test <> 0) then begin pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] := 0+ pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] := 1+ pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; end; 16: If (get_4op_to_test <> 0) then begin pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] := 1+ pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] := 0+ pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; end; 17: If (get_4op_to_test <> 0) then begin pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] := 1+ pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] := 1+ pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; end; end else If (vpos = 17) and (hpos in [1..3]) then inst^.panning := panning_pos[hpos-1]; 18,19,20, 21: If (vpos = 18) or (hpos = 1) then begin If carrier then inst^.fm_data.AM_VIB_EG_carrier := inst^.fm_data.AM_VIB_EG_carrier XOR AM_Vibrato_EG[vpos-18] else inst^.fm_data.AM_VIB_EG_modulator := inst^.fm_data.AM_VIB_EG_modulator XOR AM_Vibrato_EG[vpos-18]; end else begin If carrier then inst^.fm_data.AM_VIB_EG_carrier := inst^.fm_data.AM_VIB_EG_carrier AND $0f0+ (vpos-19)*6+hpos-2 else inst^.fm_data.AM_VIB_EG_modulator := inst^.fm_data.AM_VIB_EG_modulator AND $0f0+ (vpos-19)*6+hpos-2; end; end; reset_instrument_preview; end; kPgUP, kCHplus, kNPplus: begin If carrier then begin If (vpos = 1) and (inst^.fm_data.ATTCK_DEC_carrier SHR 4 < $0f) then inst^.fm_data.ATTCK_DEC_carrier := inst^.fm_data.ATTCK_DEC_carrier AND $0f+ (inst^.fm_data.ATTCK_DEC_carrier SHR 4 +1) SHL 4; If (vpos = 2) and (hpos = 1) and (inst^.fm_data.ATTCK_DEC_carrier AND $0f < $0f) then Inc(inst^.fm_data.ATTCK_DEC_carrier); If (vpos = 4) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_carrier SHR 4 < $0f) then inst^.fm_data.SUSTN_REL_carrier := inst^.fm_data.SUSTN_REL_carrier AND $0f+ (inst^.fm_data.SUSTN_REL_carrier SHR 4 +1) SHL 4; If (vpos = 5) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_carrier AND $0f < $0f) then Inc(inst^.fm_data.SUSTN_REL_carrier); If (vpos = 7) and (hpos = 1) and (inst^.fm_data.KSL_VOLUM_carrier AND $3f > 0) then Dec(inst^.fm_data.KSL_VOLUM_carrier); end else begin If (vpos = 1) and (inst^.fm_data.ATTCK_DEC_modulator SHR 4 < $0f) then inst^.fm_data.ATTCK_DEC_modulator := inst^.fm_data.ATTCK_DEC_modulator AND $0f+ (inst^.fm_data.ATTCK_DEC_modulator SHR 4 +1) SHL 4; If (vpos = 2) and (hpos = 1) and (inst^.fm_data.ATTCK_DEC_modulator AND $0f < $0f) then Inc(inst^.fm_data.ATTCK_DEC_modulator); If (vpos = 4) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_modulator SHR 4 < $0f) then inst^.fm_data.SUSTN_REL_modulator := inst^.fm_data.SUSTN_REL_modulator AND $0f+ (inst^.fm_data.SUSTN_REL_modulator SHR 4 +1) SHL 4; If (vpos = 5) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_modulator AND $0f < $0f) then Inc(inst^.fm_data.SUSTN_REL_modulator); If (vpos = 7) and (hpos = 1) and (inst^.fm_data.KSL_VOLUM_modulator AND $3f > 0) then Dec(inst^.fm_data.KSL_VOLUM_modulator); end; If (vpos = 12) and (hpos = 3) then _inc_feedback_val; If (vpos = 16) and (hpos = 2) then _inc_finetune_val; reset_instrument_preview; end; kPgDOWN, kCHmins, kNPmins: begin If carrier then begin If (vpos = 1) and (inst^.fm_data.ATTCK_DEC_carrier SHR 4 > 0) then inst^.fm_data.ATTCK_DEC_carrier := inst^.fm_data.ATTCK_DEC_carrier AND $0f+ (inst^.fm_data.ATTCK_DEC_carrier SHR 4 -1) SHL 4; If (vpos = 2) and (hpos = 1) and (inst^.fm_data.ATTCK_DEC_carrier AND $0f > 0) then Dec(inst^.fm_data.ATTCK_DEC_carrier); If (vpos = 4) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_carrier SHR 4 > 0) then inst^.fm_data.SUSTN_REL_carrier := inst^.fm_data.SUSTN_REL_carrier AND $0f+ (inst^.fm_data.SUSTN_REL_carrier SHR 4 -1) SHL 4; If (vpos = 5) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_carrier AND $0f > 0) then Dec(inst^.fm_data.SUSTN_REL_carrier); If (vpos = 7) and (hpos = 1) and (inst^.fm_data.KSL_VOLUM_carrier AND $3f < $3f) then Inc(inst^.fm_data.KSL_VOLUM_carrier); end else begin If (vpos = 1) and (inst^.fm_data.ATTCK_DEC_modulator SHR 4 > 0) then inst^.fm_data.ATTCK_DEC_modulator := inst^.fm_data.ATTCK_DEC_modulator AND $0f+ (inst^.fm_data.ATTCK_DEC_modulator SHR 4 -1) SHL 4; If (vpos = 2) and (hpos = 1) and (inst^.fm_data.ATTCK_DEC_modulator AND $0f > 0) then Dec(inst^.fm_data.ATTCK_DEC_modulator); If (vpos = 4) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_modulator SHR 4 > 0) then inst^.fm_data.SUSTN_REL_modulator := inst^.fm_data.SUSTN_REL_modulator AND $0f+ (inst^.fm_data.SUSTN_REL_modulator SHR 4 -1) SHL 4; If (vpos = 5) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_modulator AND $0f > 0) then Dec(inst^.fm_data.SUSTN_REL_modulator); If (vpos = 7) and (hpos = 1) and (inst^.fm_data.KSL_VOLUM_modulator AND $3f < $3f) then Inc(inst^.fm_data.KSL_VOLUM_modulator); end; If (vpos = 12) and (hpos = 3) then _dec_feedback_val; If (vpos = 16) and (hpos = 2) then _dec_finetune_val; reset_instrument_preview; end; kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If (current_inst > 1) then begin Dec(current_inst); reset_marked_instruments; instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); If NOT (inst^.perc_voice in [2..5]) then carrier := TRUE else carrier := FALSE; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); _page_build; _page_refresh; _sync_radio_buttons; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If (current_inst < 255) then begin Inc(current_inst); reset_marked_instruments; instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); If NOT (inst^.perc_voice in [2..5]) then carrier := TRUE else carrier := FALSE; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); _page_build; _page_refresh; _sync_radio_buttons; end; kF1: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; HELP('instrument_editor'); GOTO _jmp1; end; kF2, kCtrlS: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; quick_cmd := FALSE; FILE_save('a2i'); GOTO _jmp1; end; kShF2: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; quick_cmd := FALSE; FILE_save('a2f'); GOTO _jmp1; end; kF3, kCtrlL: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); quick_cmd := FALSE; FILE_open('*.a2i$*.a2f$*.a2b$*.a2w$'+ '*.bnk$*.cif$*.fib$*.fin$*.ibk$*.ins$*.sbi$*.sgi$',FALSE);// load bank is not possible reset_instrument_preview; GOTO _jmp1; end; kF7: For temp := 1 to 20 do reset_chan_data(temp); kCtrlO: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; OCTAVE_CONTROL; GOTO _jmp1; end; kCtrlQ: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; MACRO_EDITOR(current_inst,FALSE); GOTO _jmp1; end; kCtrlE: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; MACRO_EDITOR(current_inst,TRUE); GOTO _jmp1; end; kENTER: If NOT (inst^.perc_voice in [2..5]) then If NOT shift_pressed then begin If remember_ins_pos then If carrier then begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?hpos',-1,hpos); add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?vpos',-1,vpos); end else begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?hpos',-1,hpos); add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?vpos',-1,vpos); end; carrier := NOT carrier; If carrier and (get_4op_to_test <> 0) then begin If (current_inst = LO(get_4op_to_test)) then current_inst := HI(get_4op_to_test) else current_inst := LO(get_4op_to_test); instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); _page_build; _page_refresh; end; _sync_radio_buttons; end else With songdata.instr_data[instrum_page].fm_data do If carrier then begin ATTCK_DEC_carrier := ATTCK_DEC_modulator; AM_VIB_EG_carrier := AM_VIB_EG_modulator; KSL_VOLUM_carrier := KSL_VOLUM_modulator; SUSTN_REL_carrier := SUSTN_REL_modulator; WAVEFORM_carrier := WAVEFORM_modulator; end else begin AM_VIB_EG_modulator := AM_VIB_EG_carrier; KSL_VOLUM_modulator := KSL_VOLUM_carrier; ATTCK_DEC_modulator := ATTCK_DEC_carrier; SUSTN_REL_modulator := SUSTN_REL_carrier; WAVEFORM_modulator := WAVEFORM_carrier; end; else nope := TRUE; end; If shift_pressed and (UpCase(CHR(LO(fkey))) in ['M','O','B','S','T','C','H']) then begin If (UpCase(CHR(LO(fkey))) = 'O') then begin songdata.instr_data[instrum_page].perc_voice := 0; If (instrum_page <> 255) then songdata.instr_data[SUCC(instrum_page)].perc_voice := 0 else songdata.instr_data[PRED(instrum_page)].perc_voice := 0; If (instrum_page <> 255) then If check_4op_flag(instrum_page) then reset_4op_flag(instrum_page) else set_4op_flag(instrum_page) else If check_4op_flag(PRED(instrum_page)) then reset_4op_flag(PRED(instrum_page)) else set_4op_flag(PRED(instrum_page)); update_4op_flag_marks; end else If NOT check_4op_flag(instrum_page) then Case UpCase(CHR(LO(fkey))) of 'M': inst^.perc_voice := 0; 'B': inst^.perc_voice := 1; 'S': inst^.perc_voice := 2; 'T': inst^.perc_voice := 3; 'C': inst^.perc_voice := 4; 'H': inst^.perc_voice := 5; end; update_4op_flag_marks; end; _end: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (nope and (fkey = kESC)) or _force_program_quit; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); If remember_ins_pos then begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier',-1,_carrier_flag[carrier]); If carrier then begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?hpos',-1,hpos); add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?vpos',-1,vpos); end else begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?hpos',-1,hpos); add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?vpos',-1,vpos); end; end; Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; end; procedure copy_object; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:copy_object'; {$ENDIF} Case clipboard.object_type of objInstrument: begin clipboard.instrument.names[1] := Copy(songdata.instr_names[instrum_page],10,32); clipboard.instrument.data[1] := songdata.instr_data[instrum_page]; end; objInstrumentWithMacros: begin clipboard.instrument.names[1] := Copy(songdata.instr_names[instrum_page],10,32); clipboard.instrument.data[1] := songdata.instr_data[instrum_page]; clipboard.instrument.macros[1] := songdata.instr_macros[instrum_page]; clipboard.instrument.dis_fmreg_col[1] := songdata.dis_fmreg_col[instrum_page]; end; objInstrumentBank: For temp := 1 to 255 do begin clipboard.instrument.names[temp] := Copy(songdata.instr_names[temp],10,32); clipboard.instrument.data[temp] := songdata.instr_data[temp]; clipboard.instrument.macros[temp] := songdata.instr_macros[temp]; clipboard.instrument.arpvib[temp] := songdata.macro_table[temp]; clipboard.instrument.dis_fmreg_col[temp] := songdata.dis_fmreg_col[temp]; end; end; end; procedure paste_object(mode: Byte); var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:paste_object'; {$ENDIF} Case clipboard.object_type of objInstrument: Case mode of 0: begin songdata.instr_names[instrum_page] := Copy(songdata.instr_names[instrum_page],1,9)+ clipboard.instrument.names[1]; songdata.instr_data[instrum_page] := clipboard.instrument.data[1]; reset_instrument_preview; end; 1: begin songdata.instr_data[instrum_page] := clipboard.instrument.data[1]; reset_instrument_preview; end; 2: songdata.instr_names[instrum_page] := Copy(songdata.instr_names[instrum_page],1,9)+ clipboard.instrument.names[1]; end; objInstrumentWithMacros: Case mode of 0: begin songdata.instr_names[instrum_page] := Copy(songdata.instr_names[instrum_page],1,9)+ clipboard.instrument.names[1]; songdata.instr_data[instrum_page] := clipboard.instrument.data[1]; songdata.instr_macros[instrum_page] := clipboard.instrument.macros[1]; songdata.dis_fmreg_col[instrum_page] := clipboard.instrument.dis_fmreg_col[1]; reset_instrument_preview; end; 1: begin songdata.instr_data[instrum_page] := clipboard.instrument.data[1]; songdata.instr_macros[instrum_page] := clipboard.instrument.macros[1]; songdata.dis_fmreg_col[instrum_page] := clipboard.instrument.dis_fmreg_col[1]; reset_instrument_preview; end; 2: songdata.instr_names[instrum_page] := Copy(songdata.instr_names[instrum_page],1,9)+ clipboard.instrument.names[1]; end; objInstrumentBank: For temp := 1 to 255 do Case mode of 0: begin songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ clipboard.instrument.names[temp]; songdata.instr_data[temp] := clipboard.instrument.data[temp]; songdata.instr_macros[temp] := clipboard.instrument.macros[temp]; songdata.macro_table[temp] := clipboard.instrument.arpvib[temp]; songdata.dis_fmreg_col[temp] := clipboard.instrument.dis_fmreg_col[temp]; update_instr_data(temp); end; 1: begin songdata.instr_data[temp] := clipboard.instrument.data[temp]; songdata.instr_macros[temp] := clipboard.instrument.macros[temp]; songdata.macro_table[temp] := clipboard.instrument.arpvib[temp]; songdata.dis_fmreg_col[temp] := clipboard.instrument.dis_fmreg_col[temp]; update_instr_data(temp); end; 2: songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ clipboard.instrument.names[temp]; end; end; end; procedure instr_control_ai; var temp,temp2: Byte; iflag: array[1..18] of Byte; istr: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:instr_control_ai'; {$ENDIF} istr := ''; For temp := 1 to 18 do iflag[temp] := ai_table[mn_environment.curr_page+temp-1]; For temp2 := 1 to 18 do begin For temp := 1 to songdata.nm_tracks do If (event_table[temp].instr_def = mn_environment.curr_page+temp2-1) then If channel_flag[temp] then If event_new[temp] and (iflag[temp] < 2) then iflag[temp2] := 2 else If (iflag[temp2] < 1) then iflag[temp2] := 1; Case iflag[temp2] of 0: istr := istr+#28; 1: istr := istr+'~'#28'~'; 2: istr := istr+'`'#11'`'; end; end; For temp := 1 to 18 do If (iflag[temp] <> 0) then ai_table[mn_environment.curr_page+temp-1] := 1; ShowVC3Str(mn_environment.v_dest, INSCTRL_xshift+37, INSCTRL_yshift+07, istr, dialog_background+instrument_ai_off, dialog_background+instrument_ai_on, dialog_background+instrument_ai_trig); end; procedure instr_control_proc; var temp,temp2,ins1,ins2: Byte; temps: String; ins_4op,ins_4op_2: Word; temp_inst: Record name: String; data: tADTRACK2_INS; macros: tREGISTER_TABLE; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:instr_control_proc'; {$ENDIF} Case mn_environment.keystroke of kCtLEFT: If NOT debugging and (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If NOT debugging and (play_status = isPlaying) then fast_forward := TRUE; kCHmins, kNPmins, kCtHOME: If (play_status <> isStopped) then If NOT mn_environment.is_editing then If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp > 0) and NOT (songdata.pattern_order[temp-1] < $80) do begin Dec(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp > 0) then begin Dec(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (mn_environment.keystroke = kCtHOME) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCHplus, kNPplus, kCtEND: If (play_status <> isStopped) then If NOT mn_environment.is_editing then If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp < $7f) and (songdata.pattern_order[SUCC(temp)] > $80) do begin Inc(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp < $7f) then begin Inc(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (mn_environment.keystroke = kCtEND) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kF5: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; isStopped: begin If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; start_playing; end; end; kF6: Case play_status of isPlaying: begin If NOT debugging then begin replay_forbidden := TRUE; play_status := isPaused; end; debugging := FALSE; end; isPaused: begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; end; end; kF7: If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else For temp := 1 to 20 do reset_chan_data(temp); kF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; isStopped: begin start_playing; debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; end; kCtrlC: begin If NOT shift_pressed then clipboard.object_type := objInstrument else clipboard.object_type := objInstrumentWithMacros; copy_object; end; kAltP: begin paste_object(0); mn_environment.do_refresh := TRUE; mn_environment.refresh; end; kCtrlV: begin If NOT shift_pressed then paste_object(0) else paste_object(1); mn_environment.do_refresh := TRUE; mn_environment.refresh; end; kAltV: begin If NOT shift_pressed then paste_object(2); mn_environment.do_refresh := TRUE; mn_environment.refresh; end; kCtrlW: If (marked_instruments = 2) then begin ins1 := 1; While (songdata.instr_names[ins1][1] <> _ins_mark_chr) do Inc(ins1); ins2 := SUCC(ins1); While (songdata.instr_names[ins2][1] <> _ins_mark_chr) do Inc(ins2); ins_4op := check_4op_instrument(ins1); ins_4op_2 := check_4op_instrument(ins2); If NOT ((ins_4op <> 0) and (ins_4op_2 <> 0)) then begin temp_inst.name := songdata.instr_names[ins1]; temp_inst.data := songdata.instr_data[ins1]; temp_inst.macros := songdata.instr_macros[ins1]; songdata.instr_macros[ins1] := songdata.instr_macros[ins2]; songdata.instr_macros[ins2] := temp_inst.macros; songdata.instr_data[ins1] := songdata.instr_data[ins2]; update_instr_data(ins1); songdata.instr_data[ins2] := temp_inst.data; update_instr_data(ins2); If NOT shift_pressed then begin songdata.instr_names[ins1] := Copy(songdata.instr_names[ins1],1,9)+ Copy(songdata.instr_names[ins2],10,32); songdata.instr_names[ins2] := Copy(songdata.instr_names[ins2],1,9)+ Copy(temp_inst.name,10,32); end; end else begin // 4OP 1/2 temp_inst.name := songdata.instr_names[HI(ins_4op)]; temp_inst.data := songdata.instr_data[HI(ins_4op)]; temp_inst.macros := songdata.instr_macros[HI(ins_4op)]; songdata.instr_macros[HI(ins_4op)] := songdata.instr_macros[HI(ins_4op_2)]; songdata.instr_macros[HI(ins_4op_2)] := temp_inst.macros; songdata.instr_data[HI(ins_4op)] := songdata.instr_data[HI(ins_4op_2)]; update_instr_data(HI(ins_4op)); songdata.instr_data[HI(ins_4op_2)] := temp_inst.data; update_instr_data(HI(ins_4op_2)); If NOT shift_pressed then begin songdata.instr_names[HI(ins_4op)] := Copy(songdata.instr_names[HI(ins_4op)],1,9)+ Copy(songdata.instr_names[HI(ins_4op_2)],10,32); songdata.instr_names[HI(ins_4op_2)] := Copy(songdata.instr_names[HI(ins_4op_2)],1,9)+ Copy(temp_inst.name,10,32); end; // 4OP 2/2 temp_inst.name := songdata.instr_names[LO(ins_4op)]; temp_inst.data := songdata.instr_data[LO(ins_4op)]; temp_inst.macros := songdata.instr_macros[LO(ins_4op)]; songdata.instr_macros[LO(ins_4op)] := songdata.instr_macros[LO(ins_4op_2)]; songdata.instr_macros[LO(ins_4op_2)] := temp_inst.macros; songdata.instr_data[LO(ins_4op)] := songdata.instr_data[LO(ins_4op_2)]; update_instr_data(LO(ins_4op)); songdata.instr_data[LO(ins_4op_2)] := temp_inst.data; update_instr_data(LO(ins_4op_2)); If NOT shift_pressed then begin songdata.instr_names[LO(ins_4op)] := Copy(songdata.instr_names[LO(ins_4op)],1,9)+ Copy(songdata.instr_names[LO(ins_4op_2)],10,32); songdata.instr_names[LO(ins_4op_2)] := Copy(songdata.instr_names[LO(ins_4op_2)],1,9)+ Copy(temp_inst.name,10,32); end; end; mn_environment.do_refresh := TRUE; mn_environment.refresh; end; kTAB: reset_marked_instruments; kSPACE: begin If (songdata.instr_names[instrum_page][1] <> _ins_mark_chr) then If (marked_instruments < 2) then songdata.instr_names[instrum_page][1] := _ins_mark_chr else begin reset_marked_instruments; songdata.instr_names[instrum_page][1] := _ins_mark_chr; end else reset_marked_instruments; mn_environment.do_refresh := TRUE; mn_environment.refresh; end; end; instrum_page := mn_environment.curr_pos; current_inst := instrum_page; If shift_pressed and (UpCase(CHR(LO(mn_environment.keystroke))) in ['M','O','B','S','T','C','H']) then If (UpCase(CHR(LO(mn_environment.keystroke))) = 'O') then begin songdata.instr_data[current_inst].perc_voice := 0; If (current_inst <> 255) then songdata.instr_data[SUCC(current_inst)].perc_voice := 0 else songdata.instr_data[PRED(current_inst)].perc_voice := 0; If (current_inst <> 255) then If check_4op_flag(current_inst) then reset_4op_flag(current_inst) else set_4op_flag(current_inst) else If check_4op_flag(PRED(current_inst)) then reset_4op_flag(PRED(current_inst)) else set_4op_flag(PRED(current_inst)); update_4op_flag_marks; mn_environment.do_refresh := TRUE; mn_environment.refresh; end else If NOT check_4op_flag(current_inst) then Case UpCase(CHR(LO(mn_environment.keystroke))) of 'M': songdata.instr_data[current_inst].perc_voice := 0; 'B': songdata.instr_data[current_inst].perc_voice := 1; 'S': songdata.instr_data[current_inst].perc_voice := 2; 'T': songdata.instr_data[current_inst].perc_voice := 3; 'C': songdata.instr_data[current_inst].perc_voice := 4; 'H': songdata.instr_data[current_inst].perc_voice := 5; end; INSTRUMENT_CONTROL_page_refresh(instrum_page); If (get_4op_to_test <> 0) and (songdata.flag_4op <> 0) then begin temps := connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'/'+ connection_str[pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]; ShowCStr(mn_environment.v_dest,INSCTRL_xshift+39,INSCTRL_yshift+26, ' ~[~'#244+byte2hex(HI(get_4op_to_test))+ ','#245+byte2hex(LO(get_4op_to_test))+' '+temps+'~]~ ', dialog_background+dialog_context, dialog_background+dialog_border); end else If (check_4op_to_test <> 0) then ShowCStr(mn_environment.v_dest,INSCTRL_xshift+39,INSCTRL_yshift+26, ExpStrR(' ~[~'#2#3' MODE~]~ ',17,#205), dialog_background+dialog_context, dialog_background+dialog_border) else ShowStr(mn_environment.v_dest,INSCTRL_xshift+39,INSCTRL_yshift+26, ExpStrL('',17,#205), dialog_background+dialog_border); If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then If (get_4op_to_test <> 0) then INSTRUMENT_test(LO(get_4op_to_test),HI(get_4op_to_test),count_channel(pattern_hpos),mn_environment.keystroke,TRUE) else INSTRUMENT_test(instrum_page,0,count_channel(pattern_hpos),mn_environment.keystroke,TRUE); end; function INSTRUMENT_CONTROL: Byte; const new_keys: array[1..20] of Word = (kESC,kENTER,kTAB,kShTAB,kCtrlO,kCtrlM,kAltC,kCtrlA,kCtrlQ,kCtrlE, kF1,kF2,kF4,kAltF2,kCtrlF2,kCtrlS,kShF2,kF3,kCtrlL,kShF3); var old_keys: array[1..20] of Word; temp: Byte; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL'; {$ENDIF} update_4op_flag_marks; songdata_crc := Update32(songdata,SizeOf(songdata),0); _jmp1: If _force_program_quit then EXIT; keyboard_reset_buffer; ScreenMemCopy(screen_ptr,ptr_screen_backup); mn_environment.v_dest := ptr_temp_screen; ScreenMemCopy(screen_ptr,mn_environment.v_dest); mn_setting.center_box := FALSE; mn_setting.cycle_moves := FALSE; mn_environment.edit_pos := 9; mn_environment.ext_proc := instr_control_proc; mn_environment.ext_proc_rt := instr_control_ai; mn_environment.context := ' TAB '#196#16' EDiTOR '; Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); Frame(ptr_temp_screen,INSCTRL_xshift+07,INSCTRL_yshift+05, INSCTRL_xshift+83,INSCTRL_yshift+26, dialog_background+dialog_border, ' iNSTRUMENT CONTROL (iNS_ ) ', dialog_background+dialog_title, frame_double); fr_setting.update_area := FALSE; fr_setting.shadow_enabled := FALSE; Frame(ptr_temp_screen,INSCTRL_xshift+09,INSCTRL_yshift+06, INSCTRL_xshift+34,INSCTRL_yshift+25, dialog_background+dialog_border, '', dialog_background+dialog_title, frame_single); Frame(ptr_temp_screen,INSCTRL_xshift+36,INSCTRL_yshift+06, INSCTRL_xshift+81,INSCTRL_yshift+25, dialog_background+dialog_border, '', dialog_background+dialog_title, frame_single); ShowStr(ptr_temp_screen,INSCTRL_xshift+66,INSCTRL_yshift+25, ' TAB '#196#16' EDITOR ', dialog_background+dialog_context); ShowStr(ptr_temp_screen,INSCTRL_xshift+58,INSCTRL_yshift+26, ' [SHiFT] TAB '#196#16' MACROS ', dialog_background+dialog_context); ShowVStr(mn_environment.v_dest,INSCTRL_xshift+37,INSCTRL_yshift+07, ExpStrL('',18,#28), dialog_background+instrument_ai_off); ShowVStr(mn_environment.v_dest,INSCTRL_xshift+38,INSCTRL_yshift+06, #194+ExpStrL('',18,#179)+#193, dialog_background+dialog_border); fr_setting.shadow_enabled := TRUE; color_table[1] := dialog_background+dialog_context_dis; color_table[2] := dialog_background+dialog_mod_text; color_table[3] := dialog_background+dialog_car_text; If (ins_parameter(instrum_page,10) AND 1 <> 1) then For temp := 1 to 18 do ShowCStr(ptr_temp_screen,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm1[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm1[temp].colr]) else For temp := 1 to 18 do ShowCStr(ptr_temp_screen,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm2[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm2[temp].colr]); mn_setting.edit_contents := TRUE; mn_setting.shadow_enabled := FALSE; mn_setting.frame_enabled := FALSE; mn_environment.unpolite := FALSE; mn_environment.preview := TRUE; mn_environment.hlight_chrs := 1; If NOT _force_program_quit then Menu(songdata.instr_names,INSCTRL_xshift+38,INSCTRL_yshift+06,instrum_page,42,18,255,''); INSTRUMENT_CONTROL_page_refresh(instrum_page); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := INSCTRL_xshift+7; move_to_screen_area[2] := INSCTRL_yshift+5; move_to_screen_area[3] := INSCTRL_xshift+83+2; move_to_screen_area[4] := INSCTRL_yshift+26+1; move2screen_alt; mn_environment.v_dest := screen_ptr; If NOT _force_program_quit then temp := Menu(songdata.instr_names,INSCTRL_xshift+38,INSCTRL_yshift+06,instrum_page,42,18,255,''); reset_marked_instruments; mn_environment.unpolite := FALSE; mn_environment.preview := FALSE; mn_setting.frame_enabled := TRUE; mn_setting.shadow_enabled := TRUE; fr_setting.update_area := TRUE; mn_setting.center_box := TRUE; mn_environment.context := ''; Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_setting.edit_contents := FALSE; mn_environment.ext_proc := NIL; mn_environment.ext_proc_rt := NIL; mn_environment.hlight_chrs := 0; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := INSCTRL_xshift+7; move_to_screen_area[2] := INSCTRL_yshift+5; move_to_screen_area[3] := INSCTRL_xshift+83+2; move_to_screen_area[4] := INSCTRL_yshift+26+1; move2screen; Case mn_environment.keystroke of kAltC: begin mn_setting.cycle_moves := TRUE; temp := Menu(copy_menu_str1,01,01,copypos1,30,15,15,' COPY OBJECT '); If (mn_environment.keystroke <> kESC) then begin copypos1 := temp; clipboard.object_type := tCOPY_OBJECT(temp); copy_object; end; GOTO _jmp1; end; kTAB: begin If (get_4op_to_test <> 0) then begin If (songdata.instr_data[HI(get_4op_to_test)].perc_voice <> 0) then songdata.instr_data[HI(get_4op_to_test)].perc_voice := 0; If (songdata.instr_data[LO(get_4op_to_test)].perc_voice <> 0) then songdata.instr_data[LO(get_4op_to_test)].perc_voice := 0; end; INSTRUMENT_CONTROL_edit; GOTO _jmp1; end; kCtrlQ, kShTAB: begin MACRO_EDITOR(instrum_page,FALSE); GOTO _jmp1; end; kCtrlO: begin OCTAVE_CONTROL; mn_environment.keystroke := BYTE_NULL; GOTO _jmp1; end; kCtrlE: begin MACRO_EDITOR(current_inst,TRUE); GOTO _jmp1; end; kCtrlM: begin MACRO_BROWSER(TRUE,TRUE); GOTO _jmp1; end; kF1: begin HELP('instrument_control'); GOTO _jmp1; end; kF2, kCtrlS: begin quick_cmd := FALSE; FILE_save('a2i'); GOTO _jmp1; end; kAltF2: begin quick_cmd := FALSE; FILE_save('a2b'); GOTO _jmp1; end; kShF2: begin quick_cmd := FALSE; FILE_save('a2f'); GOTO _jmp1; end; kCtrlF2: begin quick_cmd := FALSE; FILE_save('a2w'); GOTO _jmp1; end; kF3, kShF3, kCtrlL: begin If (mn_environment.keystroke = kShF3) then quick_cmd := TRUE; FILE_open('*.a2i$*.a2f$*.a2b$*.a2w$'+ '*.bnk$*.cif$*.fib$*.fin$*.ibk$*.ins$*.sbi$*.sgi$',TRUE);// load bank is possible reset_instrument_preview; update_4op_flag_marks; quick_cmd := FALSE; GOTO _jmp1; end; kF4, kCtrlA: begin NUKE; GOTO _jmp1; end; end; If (Update32(songdata,SizeOf(songdata),0) <> songdata_crc) then module_archived := FALSE; If (mn_environment.keystroke = kENTER) then INSTRUMENT_CONTROL := instrum_page else INSTRUMENT_CONTROL := 0; end; procedure instr_control_proc_alt; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:instr_control_proc_alt'; {$ENDIF} INSTRUMENT_CONTROL_page_refresh_alt(mn_environment.curr_pos); If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then If (get_4op_to_test <> 0) then INSTRUMENT_test(LO(get_4op_to_test),HI(get_4op_to_test),count_channel(pattern_hpos),mn_environment.keystroke,FALSE) else INSTRUMENT_test(mn_environment.curr_pos,0,count_channel(pattern_hpos),mn_environment.keystroke,FALSE); end; function INSTRUMENT_CONTROL_alt(instr: Byte; title: String): Byte; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_alt'; {$ENDIF} keyboard_reset_buffer; ScreenMemCopy(screen_ptr,ptr_screen_backup); mn_environment.v_dest := ptr_temp_screen; ScreenMemCopy(screen_ptr,mn_environment.v_dest); mn_setting.center_box := FALSE; mn_setting.cycle_moves := FALSE; mn_environment.ext_proc := instr_control_proc_alt; mn_environment.ext_proc_rt := instr_control_ai; Frame(ptr_temp_screen,INSCTRL_xshift+07,INSCTRL_yshift+05, INSCTRL_xshift+83,INSCTRL_yshift+26, dialog_background+dialog_border, ' '+title+' ', dialog_background+dialog_title, frame_double); fr_setting.update_area := FALSE; fr_setting.shadow_enabled := FALSE; Frame(ptr_temp_screen,INSCTRL_xshift+09,INSCTRL_yshift+06, INSCTRL_xshift+34,INSCTRL_yshift+25, instrument_bckg+instrument_border, '', instrument_bckg+instrument_title, frame_single); Frame(ptr_temp_screen,INSCTRL_xshift+36,INSCTRL_yshift+06, INSCTRL_xshift+81,INSCTRL_yshift+25, instrument_bckg+instrument_border, '', instrument_bckg+instrument_title, frame_single); ShowVStr(mn_environment.v_dest,INSCTRL_xshift+37,INSCTRL_yshift+07, ExpStrL('',18,#28), dialog_background+instrument_ai_off); ShowVStr(mn_environment.v_dest,INSCTRL_xshift+38,INSCTRL_yshift+06, #194+ExpStrL('',18,#179)+#193, dialog_background+dialog_border); fr_setting.shadow_enabled := TRUE; color_table[1] := instrument_bckg+instrument_text; color_table[2] := instrument_bckg+instrument_hi_mod; color_table[3] := instrument_bckg+instrument_hi_car; If (ins_parameter(instr,10) AND 1 <> 1) then For temp := 1 to 18 do ShowCStr(ptr_temp_screen,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm1[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm1[temp].colr]) else For temp := 1 to 18 do ShowCStr(ptr_temp_screen,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm2[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm2[temp].colr]); mn_setting.shadow_enabled := FALSE; mn_setting.frame_enabled := FALSE; mn_environment.unpolite := FALSE; mn_environment.preview := TRUE; If NOT _force_program_quit then Menu(songdata.instr_names,INSCTRL_xshift+38,INSCTRL_yshift+06,instr,42,18,255,''); INSTRUMENT_CONTROL_page_refresh_alt(instr); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := INSCTRL_xshift+7; move_to_screen_area[2] := INSCTRL_yshift+5; move_to_screen_area[3] := INSCTRL_xshift+83+2; move_to_screen_area[4] := INSCTRL_yshift+26+1; move2screen_alt; mn_environment.v_dest := screen_ptr; If NOT _force_program_quit then temp := Menu(songdata.instr_names,INSCTRL_xshift+38,INSCTRL_yshift+06,instr,42,18,255,''); reset_marked_instruments; mn_environment.unpolite := FALSE; mn_environment.preview := FALSE; mn_setting.frame_enabled := TRUE; mn_setting.shadow_enabled := TRUE; fr_setting.update_area := TRUE; mn_setting.center_box := TRUE; mn_environment.context := ''; mn_environment.ext_proc := NIL; mn_environment.ext_proc_rt := NIL; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := INSCTRL_xshift+7; move_to_screen_area[2] := INSCTRL_yshift+5; move_to_screen_area[3] := INSCTRL_xshift+83+2; move_to_screen_area[4] := INSCTRL_yshift+26+1; move2screen; If (mn_environment.keystroke = kENTER) then INSTRUMENT_CONTROL_alt := temp else INSTRUMENT_CONTROL_alt := 0; end; adlibtracker2-2.4.23/adt2data.pas0000644000000000000000000007400313176573533015223 0ustar rootrootunit AdT2data; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const font8x16: array[0..1023] of Dword = ( $00000000,$00000000,$00000000,$00000000,$71300000,$313131F1,$FC313131,$00000000, $CD780000,$31190DCD,$FCCDC161,$00000000,$29CE0000,$2E292929,$C8282828,$00000000, $19080000,$FDD97939,$3C191919,$00000000,$00000000,$06361C00,$BE32180C,$00000000, $00000000,$18181F00,$9E33031E,$00000000,$00000000,$28440000,$44281010,$00000000, $E7E70000,$E7E7E7E7,$E7E7E7E7,$000000E7,$FFFF0000,$C3C7CFDF,$FFDFCFC7,$000000FF, $38100000,$1010107C,$10387C10,$00000000,$00000000,$7E7E7E3C,$00003C7E,$00000000, $991F0000,$1818385F,$70793A1C,$00000000,$191F0000,$1818181F,$70783818,$00000000, $55555500,$55555555,$55555555,$00000055,$7F7F7F00,$7F7F7F7F,$7F7F7F7F,$0000007F, $60400000,$7E7C7870,$6070787C,$00000040,$06020000,$7E3E1E0E,$060E1E3E,$00000002, $38100000,$1010107C,$10001000,$00000000,$82FE0000,$32128282,$3070FE72,$00000010, $00000000,$AA000000,$00000000,$00000000,$28140000,$50505050,$14285050,$00000000, $14280000,$0A0A0A0A,$28140A0A,$00000000,$00100000,$10100010,$10387C10,$00000000, $38100000,$1010107C,$10101010,$00000000,$10100000,$10101010,$10387C10,$00000000, $00000000,$FF0E0C08,$00080C0E,$00000000,$00000000,$FF703010,$00103070,$00000000, $00000000,$3C3C1800,$00000018,$00000000,$F3FE0000,$81FFF3F3,$FF81FF81,$00000000, $00000000,$7C383810,$00FEFE7C,$00000000,$00000000,$7C7CFEFE,$00103838,$00000000, $00000000,$00000000,$00000000,$00000000,$3C180000,$18183C3C,$18180018,$00000000, $28282800,$00002828,$00000000,$00000000,$28000000,$28287C28,$28287C28,$00000000, $D67C1010,$167CD0D2,$7CD69616,$00001010,$00000000,$08C4C200,$86462010,$00000000, $6C380000,$DC76386C,$76CCCCCC,$00000000,$10101000,$00000020,$00000000,$00000000, $10080000,$20202020,$08102020,$00000000,$08100000,$04040404,$10080404,$00000000, $00000000,$FE385410,$00105438,$00000000,$00000000,$7C101000,$00001010,$00000000, $00000000,$00000000,$10101000,$00000020,$00000000,$7C000000,$00000000,$00000000, $00000000,$00000000,$10000000,$00000000,$00000000,$08040200,$80402010,$00000000, $6C380000,$D6D6C6C6,$386CC6C6,$00000000,$38180000,$18181878,$7E181818,$00000000, $C67C0000,$30180C06,$FEC6C060,$00000000,$C67C0000,$063C0606,$7CC60606,$00000000, $1C0C0000,$FECC6C3C,$1E0C0C0C,$00000000,$C0FE0000,$06FCC0C0,$7CC60606,$00000000, $60380000,$C6FCC0C0,$7CC6C6C6,$00000000,$C6FE0000,$180C0606,$30303030,$00000000, $C67C0000,$C67CC6C6,$7CC6C6C6,$00000000,$C67C0000,$067EC6C6,$780C0606,$00000000, $00000000,$00001000,$00001000,$00000000,$00000000,$00001000,$20101000,$00000000, $04000000,$40201008,$04081020,$00000000,$00000000,$00003C00,$0000003C,$00000000, $20000000,$02040810,$20100804,$00000000,$C67C0000,$18180CC6,$18180018,$00000000, $7C000000,$DEDEC6C6,$7CC0DCDE,$00000000,$38100000,$FEC6C66C,$C6C6C6C6,$00000000, $66FC0000,$667C6666,$FC666666,$00000000,$663C0000,$C0C0C0C2,$3C66C2C0,$00000000, $6CF80000,$66666666,$F86C6666,$00000000,$66FE0000,$68786862,$FE666260,$00000000, $66FE0000,$68786862,$F0606060,$00000000,$663C0000,$DEC0C0C2,$3A66C6C6,$00000000, $C6C60000,$C6FEC6C6,$C6C6C6C6,$00000000,$183C0000,$18181818,$3C181818,$00000000, $0C1E0000,$0C0C0C0C,$78CCCCCC,$00000000,$66E60000,$78786C66,$E666666C,$00000000, $60F00000,$60606060,$FE666260,$00000000,$EEC60000,$C6D6FEFE,$C6C6C6C6,$00000000, $E6C60000,$CEDEFEF6,$C6C6C6C6,$00000000,$C67C0000,$C6C6C6C6,$7CC6C6C6,$00000000, $66FC0000,$607C6666,$F0606060,$00000000,$C67C0000,$C6C6C6C6,$7CDED6C6,$00000E0C, $66FC0000,$6C7C6666,$E6666666,$00000000,$C67C0000,$0C3860C6,$7CC6C606,$00000000, $7E7E0000,$1818185A,$3C181818,$00000000,$C6C60000,$C6C6C6C6,$7CC6C6C6,$00000000, $C6C60000,$C6C6C6C6,$10386CC6,$00000000,$C6C60000,$D6D6C6C6,$6CEEFED6,$00000000, $C6C60000,$38387C6C,$C6C66C7C,$00000000,$66660000,$183C6666,$3C181818,$00000000, $C6FE0000,$30180C86,$FEC6C260,$00000000,$20380000,$20202020,$38202020,$00000000, $00000000,$20408000,$02040810,$00000000,$041C0000,$04040404,$1C040404,$00000000, $6C381000,$000000C6,$00000000,$00000000,$00000000,$00000000,$00000000,$0000FF00, $00081010,$00000000,$00000000,$00000000,$00000000,$7C0C7800,$76CCCCCC,$00000000, $60E00000,$666C7860,$7C666666,$00000000,$00000000,$C0C67C00,$7CC6C0C0,$00000000, $0C1C0000,$CC6C3C0C,$76CCCCCC,$00000000,$00000000,$FEC67C00,$7CC6C0C0,$00000000, $6C380000,$60F06064,$F0606060,$00000000,$00000000,$CCCC7600,$7CCCCCCC,$0078CC0C, $60E00000,$66766C60,$E6666666,$00000000,$18000000,$18183800,$3C181818,$00000000, $06000000,$06060E00,$06060606,$003C6666,$60E00000,$786C6660,$E6666C78,$00000000, $18380000,$18181818,$3C181818,$00000000,$00000000,$D6FEEC00,$C6D6D6D6,$00000000, $00000000,$6666DC00,$66666666,$00000000,$00000000,$C6C67C00,$7CC6C6C6,$00000000, $00000000,$6666DC00,$7C666666,$00F06060,$00000000,$CCCC7600,$7CCCCCCC,$001E0C0C, $00000000,$6676DC00,$F0606060,$00000000,$00000000,$60C67C00,$7CC60C38,$00000000, $30100000,$3030FC30,$1C363030,$00000000,$00000000,$CCCCCC00,$76CCCCCC,$00000000, $00000000,$66666600,$183C6666,$00000000,$00000000,$D6C6C600,$6CFED6D6,$00000000, $00000000,$386CC600,$C66C3838,$00000000,$00000000,$C6C6C600,$7EC6C6C6,$00F80C06, $00000000,$18CCFE00,$FEC66030,$00000000,$100C0000,$10601010,$0C101010,$00000000, $10100000,$10001010,$10101010,$00000000,$08300000,$08060808,$30080808,$00000000, $DC760000,$00000000,$00000000,$00000000,$023E0000,$12020202,$10307E32,$00000000, $00000000,$00000000,$00000000,$FF000000,$00000000,$00000000,$00000000,$FFFF0000, $00000000,$00000000,$00000000,$FFFFFF00,$00000000,$00000000,$00000000,$FFFFFFFF, $00000000,$00000000,$FF000000,$FFFFFFFF,$00000000,$00000000,$FFFF0000,$FFFFFFFF, $00000000,$00000000,$FFFFFF00,$FFFFFFFF,$00000000,$00000000,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFF0000,$FFFFFFFF,$FFFFFFFF, $00000000,$FFFFFF00,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FF000000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFF0000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FFFFFF00,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$00FFFFFF, $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$0000FFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$000000FF, $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$00FFFFFF,$00000000, $FFFFFFFF,$FFFFFFFF,$0000FFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$000000FF,$00000000, $FFFFFFFF,$FFFFFFFF,$00000000,$00000000,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $FFFFFFFF,$0000FFFF,$00000000,$00000000,$FFFFFFFF,$000000FF,$00000000,$00000000, $FFFFFFFF,$00000000,$00000000,$00000000,$00FFFFFF,$00000000,$00000000,$00000000, $0000FFFF,$00000000,$00000000,$00000000,$000000FF,$00000000,$00000000,$00000000, $10101010,$10101010,$10101010,$7C101010,$00000000,$0A110000,$110A0404,$00000000, $AACC0000,$AACAAAAA,$CCAAAAAA,$00000000,$AA4C0000,$4A8A8AAA,$4CAA2A2A,$00000000, $44EE0000,$44444444,$44444444,$00000000,$4AE40000,$4848484A,$444A4848,$00000000, $AAAA0000,$AAEEAAAA,$AAAAAAAA,$00000000,$00000000,$FFFFFF00,$80808000,$00808080, $00000000,$FFFFFF00,$A0A0A000,$00A0A0A0,$00000000,$FFFFFF00,$A8A8A800,$00A8A8A8, $00000000,$FFFFFF00,$AAAAAA00,$00AAAAAA,$10101010,$FFFFFF10,$AAAAAA00,$00AAAAAA, $00000000,$60606000,$7E606060,$00000000,$00000000,$C6C6FC00,$C6C6CCFC,$00000000, $00100015,$1C0C0010,$0C7E6C3C,$001E0C0C,$96959566,$10006494,$10001000,$00001500, $90900000,$F7F09090,$97949291,$00000000,$00100010,$38000010,$00003838,$00000000, $44114411,$44114411,$44114411,$44114411,$AA55AA55,$AA55AA55,$AA55AA55,$AA55AA55, $77DD77DD,$77DD77DD,$77DD77DD,$77DD77DD,$10101010,$10101010,$10101010,$10101010, $10101010,$F0101010,$10101010,$10101010,$10101010,$F0F0F010,$10101010,$10101010, $3C3C3C3C,$FC3C3C3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FC000000,$3C3C3C3C,$3C3C3C3C, $00000000,$F0F0F000,$10101010,$10101010,$3C3C3C3C,$FCFCFC3C,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FCFCFC00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$FCFCFC3C,$00000000,$00000000,$3C3C3C3C,$FC3C3C3C,$00000000,$00000000, $10101010,$F0F0F010,$00000000,$00000000,$00000000,$F0000000,$10101010,$10101010, $10101010,$1F101010,$00000000,$00000000,$10101010,$FF101010,$00000000,$00000000, $00000000,$FF000000,$10101010,$10101010,$10101010,$1F101010,$10101010,$10101010, $00000000,$FF000000,$00000000,$00000000,$10101010,$FF101010,$10101010,$10101010, $10101010,$1F1F1F10,$10101010,$10101010,$3C3C3C3C,$3F3C3C3C,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3F3F3F3C,$00000000,$00000000,$00000000,$3F3F3F00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$FFFFFF3C,$00000000,$00000000,$00000000,$FFFFFF00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3F3F3F3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FFFFFF00,$00000000,$00000000, $3C3C3C3C,$FFFFFF3C,$3C3C3C3C,$3C3C3C3C,$10101010,$FFFFFF10,$00000000,$00000000, $3C3C3C3C,$FF3C3C3C,$00000000,$00000000,$00000000,$FFFFFF00,$10101010,$10101010, $00000000,$FF000000,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$3F3C3C3C,$00000000,$00000000, $10101010,$1F1F1F10,$00000000,$00000000,$00000000,$1F1F1F00,$10101010,$10101010, $00000000,$3F000000,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$FF3C3C3C,$3C3C3C3C,$3C3C3C3C, $10101010,$FFFFFF10,$10101010,$10101010,$10101010,$F0101010,$00000000,$00000000, $00000000,$1F000000,$10101010,$10101010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0, $0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $00100010,$00920010,$00100010,$00920010,$00100010,$00920010,$00100010,$FF100010, $00100010,$00920010,$00100010,$FFFF0010,$00100010,$00920010,$00100010,$FFFFFF10, $00100010,$00920010,$00100010,$FFFFFFFF,$00100010,$00920010,$FF100010,$FFFFFFFF, $00100010,$00920010,$FFFF0010,$FFFFFFFF,$00100010,$00920010,$FFFFFF10,$FFFFFFFF, $00100010,$00920010,$FFFFFFFF,$FFFFFFFF,$00100010,$FF920010,$FFFFFFFF,$FFFFFFFF, $00100010,$FFFF0010,$FFFFFFFF,$FFFFFFFF,$00100010,$FFFFFF10,$FFFFFFFF,$FFFFFFFF, $00100010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FF100010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FFFF0010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFF10,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $01010101,$01010101,$01010101,$01010101,$10000000,$10101010,$10101010,$00000000, $00000000,$FF000000,$00100010,$00920010,$00100010,$FF100010,$00000000,$00000000, $18783818,$10081C1A,$00000020,$00000000,$186C6C38,$10087C32,$00000020,$00000000, $00100010,$00100010,$00100010,$00100010,$00010001,$00010001,$00010001,$00010001, $00100015,$00100010,$00100010,$00100010,$00000000,$28281000,$00001028,$00000000, $00000000,$10000000,$00000000,$00000000,$03010000,$CC040602,$307058C8,$00000000, $3E1C0800,$FFFFFF7F,$00000000,$00000000,$00000000,$FFFFFF00,$081C3E7F,$00000000, $00000000,$7C7C7C7C,$007C7C7C,$00000000,$00000000,$00000000,$00000000,$00000000); const vga_font8x16: array[0..1023] of Dword = ( $00000000,$00000000,$00000000,$00000000,$817E0000,$BD8181A5,$7E818199,$00000000, $FF7E0000,$C3FFFFDB,$7EFFFFE7,$00000000,$00000000,$FEFEFE6C,$10387CFE,$00000000, $00000000,$FE7C3810,$0010387C,$00000000,$18000000,$E7E73C3C,$3C1818E7,$00000000, $18000000,$FFFF7E3C,$3C18187E,$00000000,$00000000,$3C180000,$0000183C,$00000000, $FFFFFFFF,$C3E7FFFF,$FFFFE7C3,$FFFFFFFF,$00000000,$42663C00,$003C6642,$00000000, $FFFFFFFF,$BD99C3FF,$FFC399BD,$FFFFFFFF,$0E1E0000,$CC78321A,$78CCCCCC,$00000000, $663C0000,$3C666666,$18187E18,$00000000,$333F0000,$3030303F,$E0F07030,$00000000, $637F0000,$6363637F,$E6E76763,$000000C0,$18000000,$E73CDB18,$1818DB3C,$00000000, $E0C08000,$F8FEF8F0,$80C0E0F0,$00000000,$0E060200,$3EFE3E1E,$02060E1E,$00000000, $3C180000,$1818187E,$00183C7E,$00000000,$66660000,$66666666,$66660066,$00000000, $DB7F0000,$1B7BDBDB,$1B1B1B1B,$00000000,$60C67C00,$C6C66C38,$C60C386C,$0000007C, $00000000,$00000000,$FEFEFEFE,$00000000,$3C180000,$1818187E,$7E183C7E,$00000000, $3C180000,$1818187E,$18181818,$00000000,$18180000,$18181818,$183C7E18,$00000000, $00000000,$FE0C1800,$0000180C,$00000000,$00000000,$FE603000,$00003060,$00000000, $00000000,$C0C00000,$0000FEC0,$00000000,$00000000,$FF662400,$00002466,$00000000, $00000000,$7C383810,$00FEFE7C,$00000000,$00000000,$7C7CFEFE,$00103838,$00000000, $00000000,$00000000,$00000000,$00000000,$3C180000,$18183C3C,$18180018,$00000000, $66666600,$00000024,$00000000,$00000000,$6C000000,$6C6CFE6C,$6C6CFE6C,$00000000, $C67C1818,$067CC0C2,$7CC68606,$00001818,$00000000,$180CC6C2,$86C66030,$00000000, $6C380000,$DC76386C,$76CCCCCC,$00000000,$30303000,$00000060,$00000000,$00000000, $180C0000,$30303030,$0C183030,$00000000,$18300000,$0C0C0C0C,$30180C0C,$00000000, $00000000,$FF3C6600,$0000663C,$00000000,$00000000,$7E181800,$00001818,$00000000, $00000000,$00000000,$18181800,$00000030,$00000000,$FE000000,$00000000,$00000000, $00000000,$00000000,$18180000,$00000000,$00000000,$180C0602,$80C06030,$00000000, $663C0000,$DBDBC3C3,$3C66C3C3,$00000000,$38180000,$18181878,$7E181818,$00000000, $C67C0000,$30180C06,$FEC6C060,$00000000,$C67C0000,$063C0606,$7CC60606,$00000000, $1C0C0000,$FECC6C3C,$1E0C0C0C,$00000000,$C0FE0000,$06FCC0C0,$7CC60606,$00000000, $60380000,$C6FCC0C0,$7CC6C6C6,$00000000,$C6FE0000,$180C0606,$30303030,$00000000, $C67C0000,$C67CC6C6,$7CC6C6C6,$00000000,$C67C0000,$067EC6C6,$780C0606,$00000000, $00000000,$00001818,$00181800,$00000000,$00000000,$00001818,$30181800,$00000000, $06000000,$6030180C,$060C1830,$00000000,$00000000,$00007E00,$0000007E,$00000000, $60000000,$060C1830,$6030180C,$00000000,$C67C0000,$18180CC6,$18180018,$00000000, $7C000000,$DEDEC6C6,$7CC0DCDE,$00000000,$38100000,$FEC6C66C,$C6C6C6C6,$00000000, $66FC0000,$667C6666,$FC666666,$00000000,$663C0000,$C0C0C0C2,$3C66C2C0,$00000000, $6CF80000,$66666666,$F86C6666,$00000000,$66FE0000,$68786862,$FE666260,$00000000, $66FE0000,$68786862,$F0606060,$00000000,$663C0000,$DEC0C0C2,$3A66C6C6,$00000000, $C6C60000,$C6FEC6C6,$C6C6C6C6,$00000000,$183C0000,$18181818,$3C181818,$00000000, $0C1E0000,$0C0C0C0C,$78CCCCCC,$00000000,$66E60000,$78786C66,$E666666C,$00000000, $60F00000,$60606060,$FE666260,$00000000,$E7C30000,$C3DBFFFF,$C3C3C3C3,$00000000, $E6C60000,$CEDEFEF6,$C6C6C6C6,$00000000,$C67C0000,$C6C6C6C6,$7CC6C6C6,$00000000, $66FC0000,$607C6666,$F0606060,$00000000,$C67C0000,$C6C6C6C6,$7CDED6C6,$00000E0C, $66FC0000,$6C7C6666,$E6666666,$00000000,$C67C0000,$0C3860C6,$7CC6C606,$00000000, $DBFF0000,$18181899,$3C181818,$00000000,$C6C60000,$C6C6C6C6,$7CC6C6C6,$00000000, $C3C30000,$C3C3C3C3,$183C66C3,$00000000,$C3C30000,$DBC3C3C3,$6666FFDB,$00000000, $C3C30000,$18183C66,$C3C3663C,$00000000,$C3C30000,$183C66C3,$3C181818,$00000000, $C3FF0000,$30180C86,$FFC3C160,$00000000,$303C0000,$30303030,$3C303030,$00000000, $80000000,$3870E0C0,$02060E1C,$00000000,$0C3C0000,$0C0C0C0C,$3C0C0C0C,$00000000, $C66C3810,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$0000FF00, $00183030,$00000000,$00000000,$00000000,$00000000,$7C0C7800,$76CCCCCC,$00000000, $60E00000,$666C7860,$7C666666,$00000000,$00000000,$C0C67C00,$7CC6C0C0,$00000000, $0C1C0000,$CC6C3C0C,$76CCCCCC,$00000000,$00000000,$FEC67C00,$7CC6C0C0,$00000000, $6C380000,$60F06064,$F0606060,$00000000,$00000000,$CCCC7600,$7CCCCCCC,$0078CC0C, $60E00000,$66766C60,$E6666666,$00000000,$18180000,$18183800,$3C181818,$00000000, $06060000,$06060E00,$06060606,$003C6666,$60E00000,$786C6660,$E6666C78,$00000000, $18380000,$18181818,$3C181818,$00000000,$00000000,$DBFFE600,$DBDBDBDB,$00000000, $00000000,$6666DC00,$66666666,$00000000,$00000000,$C6C67C00,$7CC6C6C6,$00000000, $00000000,$6666DC00,$7C666666,$00F06060,$00000000,$CCCC7600,$7CCCCCCC,$001E0C0C, $00000000,$6676DC00,$F0606060,$00000000,$00000000,$60C67C00,$7CC60C38,$00000000, $30100000,$3030FC30,$1C363030,$00000000,$00000000,$CCCCCC00,$76CCCCCC,$00000000, $00000000,$C3C3C300,$183C66C3,$00000000,$00000000,$C3C3C300,$66FFDBDB,$00000000, $00000000,$3C66C300,$C3663C18,$00000000,$00000000,$C6C6C600,$7EC6C6C6,$00F80C06, $00000000,$18CCFE00,$FEC66030,$00000000,$180E0000,$18701818,$0E181818,$00000000, $18180000,$18001818,$18181818,$00000000,$18700000,$180E1818,$70181818,$00000000, $DC760000,$00000000,$00000000,$00000000,$00000000,$C66C3810,$00FEC6C6,$00000000, $663C0000,$C0C0C0C2,$0C3C66C2,$00007C06,$00CC0000,$CCCCCC00,$76CCCCCC,$00000000, $30180C00,$FEC67C00,$7CC6C0C0,$00000000,$6C381000,$7C0C7800,$76CCCCCC,$00000000, $00CC0000,$7C0C7800,$76CCCCCC,$00000000,$18306000,$7C0C7800,$76CCCCCC,$00000000, $386C3800,$7C0C7800,$76CCCCCC,$00000000,$00000000,$6060663C,$060C3C66,$0000003C, $6C381000,$FEC67C00,$7CC6C0C0,$00000000,$00C60000,$FEC67C00,$7CC6C0C0,$00000000, $18306000,$FEC67C00,$7CC6C0C0,$00000000,$00660000,$18183800,$3C181818,$00000000, $663C1800,$18183800,$3C181818,$00000000,$18306000,$18183800,$3C181818,$00000000, $1000C600,$C6C66C38,$C6C6C6FE,$00000000,$00386C38,$C6C66C38,$C6C6C6FE,$00000000, $00603018,$7C6066FE,$FE666060,$00000000,$00000000,$1B3B6E00,$77DCD87E,$00000000, $6C3E0000,$CCFECCCC,$CECCCCCC,$00000000,$6C381000,$C6C67C00,$7CC6C6C6,$00000000, $00C60000,$C6C67C00,$7CC6C6C6,$00000000,$18306000,$C6C67C00,$7CC6C6C6,$00000000, $CC783000,$CCCCCC00,$76CCCCCC,$00000000,$18306000,$CCCCCC00,$76CCCCCC,$00000000, $00C60000,$C6C6C600,$7EC6C6C6,$00780C06,$7C00C600,$C6C6C6C6,$7CC6C6C6,$00000000, $C600C600,$C6C6C6C6,$7CC6C6C6,$00000000,$7E181800,$C0C0C0C3,$18187EC3,$00000000, $646C3800,$6060F060,$FCE66060,$00000000,$66C30000,$18FF183C,$181818FF,$00000000, $6666FC00,$6F66627C,$F3666666,$00000000,$181B0E00,$187E1818,$18181818,$000070D8, $60301800,$7C0C7800,$76CCCCCC,$00000000,$30180C00,$18183800,$3C181818,$00000000, $60301800,$C6C67C00,$7CC6C6C6,$00000000,$60301800,$CCCCCC00,$76CCCCCC,$00000000, $DC760000,$6666DC00,$66666666,$00000000,$C600DC76,$DEFEF6E6,$C6C6C6CE,$00000000, $6C6C3C00,$007E003E,$00000000,$00000000,$6C6C3800,$007C0038,$00000000,$00000000, $30300000,$60303000,$7CC6C6C0,$00000000,$00000000,$C0FE0000,$00C0C0C0,$00000000, $00000000,$06FE0000,$00060606,$00000000,$C2C0C000,$3018CCC6,$069BCE60,$00001F0C, $C2C0C000,$3018CCC6,$3E96CE66,$00000606,$18180000,$18181800,$183C3C3C,$00000000, $00000000,$D86C3600,$0000366C,$00000000,$00000000,$366CD800,$0000D86C,$00000000, $44114411,$44114411,$44114411,$44114411,$AA55AA55,$AA55AA55,$AA55AA55,$AA55AA55, $77DD77DD,$77DD77DD,$77DD77DD,$77DD77DD,$18181818,$18181818,$18181818,$18181818, $18181818,$F8181818,$18181818,$18181818,$18181818,$F818F818,$18181818,$18181818, $36363636,$F6363636,$36363636,$36363636,$00000000,$FE000000,$36363636,$36363636, $00000000,$F818F800,$18181818,$18181818,$36363636,$F606F636,$36363636,$36363636, $36363636,$36363636,$36363636,$36363636,$00000000,$F606FE00,$36363636,$36363636, $36363636,$FE06F636,$00000000,$00000000,$36363636,$FE363636,$00000000,$00000000, $18181818,$F818F818,$00000000,$00000000,$00000000,$F8000000,$18181818,$18181818, $18181818,$1F181818,$00000000,$00000000,$18181818,$FF181818,$00000000,$00000000, $00000000,$FF000000,$18181818,$18181818,$18181818,$1F181818,$18181818,$18181818, $00000000,$FF000000,$00000000,$00000000,$18181818,$FF181818,$18181818,$18181818, $18181818,$1F181F18,$18181818,$18181818,$36363636,$37363636,$36363636,$36363636, $36363636,$3F303736,$00000000,$00000000,$00000000,$37303F00,$36363636,$36363636, $36363636,$FF00F736,$00000000,$00000000,$00000000,$F700FF00,$36363636,$36363636, $36363636,$37303736,$36363636,$36363636,$00000000,$FF00FF00,$00000000,$00000000, $36363636,$F700F736,$36363636,$36363636,$18181818,$FF00FF18,$00000000,$00000000, $36363636,$FF363636,$00000000,$00000000,$00000000,$FF00FF00,$18181818,$18181818, $00000000,$FF000000,$36363636,$36363636,$36363636,$3F363636,$00000000,$00000000, $18181818,$1F181F18,$00000000,$00000000,$00000000,$1F181F00,$18181818,$18181818, $00000000,$3F000000,$36363636,$36363636,$36363636,$FF363636,$36363636,$36363636, $18181818,$FF18FF18,$18181818,$18181818,$18181818,$F8181818,$00000000,$00000000, $00000000,$1F000000,$18181818,$18181818,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0, $0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $00000000,$D8DC7600,$76DCD8D8,$00000000,$CC780000,$CCD8CCCC,$CCC6C6C6,$00000000, $C6FE0000,$C0C0C0C6,$C0C0C0C0,$00000000,$00000000,$6C6C6CFE,$6C6C6C6C,$00000000, $FE000000,$183060C6,$FEC66030,$00000000,$00000000,$D8D87E00,$70D8D8D8,$00000000, $00000000,$66666666,$60607C66,$000000C0,$00000000,$1818DC76,$18181818,$00000000, $7E000000,$66663C18,$7E183C66,$00000000,$38000000,$FEC6C66C,$386CC6C6,$00000000, $6C380000,$6CC6C6C6,$EE6C6C6C,$00000000,$301E0000,$663E0C18,$3C666666,$00000000, $00000000,$DBDB7E00,$00007EDB,$00000000,$03000000,$DBDB7E06,$C0607EF3,$00000000, $301C0000,$607C6060,$1C306060,$00000000,$7C000000,$C6C6C6C6,$C6C6C6C6,$00000000, $00000000,$FE0000FE,$00FE0000,$00000000,$00000000,$187E1818,$FF000018,$00000000, $30000000,$0C060C18,$7E003018,$00000000,$0C000000,$30603018,$7E000C18,$00000000, $1B0E0000,$1818181B,$18181818,$18181818,$18181818,$18181818,$70D8D8D8,$00000000, $00000000,$7E001818,$00181800,$00000000,$00000000,$00DC7600,$0000DC76,$00000000, $6C6C3800,$00000038,$00000000,$00000000,$00000000,$18000000,$00000018,$00000000, $00000000,$00000000,$00000018,$00000000,$0C0C0F00,$EC0C0C0C,$1C3C6C6C,$00000000, $6C6CD800,$006C6C6C,$00000000,$00000000,$30D87000,$00F8C860,$00000000,$00000000, $00000000,$7C7C7C7C,$007C7C7C,$00000000,$00000000,$00000000,$00000000,$00000000); {$IFNDEF GO32V2} const adt2_icon_bitmap: array[0..782] of Dword = ( $0C364D42,$00000000,$00360000,$00280000,$00200000,$00200000,$00010000,$00000018, $0C000000,$00000000,$00000000,$00000000,$00000000,$CAFF0000,$77CAFF77,$FF7ACDFF, $CDFF7ACD,$7ACDFF7A,$FF77CAFF,$CDFF77CA,$7ACDFF7A,$FF77CAFF,$CDFF77CA,$7ACDFF7A, $FF77CAFF,$CDFF77CA,$7ACDFF7A,$FF7ACDFF,$CDFF7ACD,$7ACDFF7A,$FF7ACCFF,$CDFF7ACC, $7ACDFF7A,$EA81CFFA,$C4F681C7,$79CCFF77,$FF7ACDFF,$C9FF7ACD,$76C9FF77,$FF76C9FF, $C9FF76C9,$77C9FF77,$FF77CAFF,$CAFF77CA,$77CAFF77,$FF77CAFF,$CAFF77CA,$77CAFF77, $FF77CAFF,$CAFF77CA,$77CAFF77,$FF77CAFF,$C9FF77CA,$77C9FF77,$FF77CAFF,$C9FF77CA, $76C9FF77,$19D4E397,$5366A487,$76C9FF53,$FF77C9FF,$C4FF76C5,$76C5FF74,$FF76C5FF, $C5FF76C5,$76C5FF76,$FF76C5FF,$C5FF76C5,$76C5FF76,$FF76C5FF,$C5FF76C5,$76C5FF76, $FF76C5FF,$C5FF76C5,$76C5FF76,$FF76C5FF,$C5FF76C5,$76C5FF76,$FF76C5FF,$C4FF76C5, $74C4FF74,$1AEFF47E,$45578571,$74C4FF48,$FF74C4FF,$BFFF74C1,$73C1FF73,$FF73BFFF, $BFFF73BF,$73BFFF73,$FF74C1FF,$C1FF74C1,$74C1FF74,$FF73C1FF,$C1FF73C1,$74C1FF74, $FF73BFFF,$C1FF73BF,$73C1FF73,$FF74C1FF,$C1FF74C1,$74C1FF74,$FF73C1FF,$C1FF73C1, $73BFFF74,$1AECF27D,$40528773,$73BFFF44,$FF73C1FF,$BBFF73BF,$71BBFF6E,$FF71BBFF, $BBFF71BB,$71BBFF71,$FF71BBFF,$BBFF71BB,$6EBBFF6E,$FF71BBFF,$BCFF71BB,$71BCFF71, $FF71BCFF,$BCFF71BC,$71BCFF71,$FF71BCFF,$BBFF71BC,$71BBFF71,$FF71BCFF,$BBFF71BC, $6EBBFF71,$16ECF07B,$4052836E,$6EBBFF45,$FF71BBFF,$B1FF6EB9,$6BB1FF6B,$FF6CB5FF, $B5FF6CB5,$6CB5FF6C,$FF6CB5FF,$B6FF6CB5,$6CB6FF6C,$FF6CB6FF,$B6FF6CB6,$6CB6FF6C, $FF6CB5FF,$B5FF6CB5,$6CB5FF6C,$FF6EB6FF,$B6FF6EB6,$6CB6FF6C,$FF6CB5FF,$B5FF6CB5, $6BB5FF6B,$16EAEF79,$4452836E,$6BB1FF47,$FF6BB1FF,$ADFF6BB1,$68ABFF68,$FF68ADFF, $ABFF68AD,$68ABFF68,$FF68ADFF,$ADFF68AD,$69ADFF69,$FF69ADFF,$ADFF69AD,$69ADFF69, $FF69ADFF,$ADFF69AD,$69ADFF69,$FF69B0FF,$ADFF69B0,$68ADFF68,$FF69B0FF,$ADFF69B0, $68ADFF68,$26F0F380,$45539080,$68ABFF4B,$FF68ADFF,$A5FF68AB,$63A5FF63,$FF63A5FF, $A5FF63A5,$63A5FF63,$FF63A7FF,$A5FF63A7,$63A5FF63,$FF63A5FF,$A5FF63A5,$63A5FF63, $FF63A5FF,$A5FF63A5,$63A5FF63,$FF66A7FF,$A5FF66A7,$63A5FF63,$FF63A5FF,$A5FF63A5, $62A2FF63,$28F0F381,$404D9382,$63A5FF47,$FF63A5FF,$99FF62A2,$5F9CFF5F,$FF5F9CFF, $9CFF5F9C,$5F9CFF5F,$FF5F99FF,$9EFF5F9C,$609EFF60,$FF5F9CFF,$9CFF5F9C,$5F9CFF5F, $FF5F9CFF,$9CFF5F9C,$5F9CFF5F,$FF609EFF,$9EFF609E,$609EFF60,$FF609CFF,$9CFF609C, $5F9CFF60,$28F1F480,$3B489382,$5F9CFF44,$FF5F99FF,$8EF45D99,$5891F457,$AB588EF4, $3D328299,$3B191058,$F55891F4,$91F55891,$5891F558,$F55891F5,$91F55891,$5891F558, $F55891F5,$91F55891,$5891F558,$F75893F7,$91F55893,$5891F558,$F55891F5,$91F55891, $578EF458,$2AF0F27F,$404A9585,$578EF447,$F4578EF4,$82E3578E,$5283E64F,$A44F83E6, $7619D2E3,$2D00009A,$E6350F05,$83E65283,$5283E74F,$E65283E6,$85E75283,$5485E754, $E65283E6,$83E75283,$5283E752,$E65283E6,$85E75283,$5485E754,$E65283E6,$85E75283, $5283E652,$33F0F27F,$47529D8F,$4F82E650,$E34F82E3,$74D24F82,$4B76D549,$9E4971D2, $FF96D2E0,$9F7D1EFF,$012F0000,$74D3350F,$4974D349,$D54B76D5,$76D54B76,$4B76D54B, $D54B76D5,$76D54B76,$4B76D54B,$D34B74D3,$74D34B74,$4B74D34B,$D54B76D5,$76D54B76, $4B76D54B,$3AF2F37F,$444CA294,$4974D34D,$D34B74D3,$65BF4B74,$4166C141,$B64165BF, $FF907693,$FFFF85FF,$00967113,$07002D00,$4165C130,$C14165BF,$65C14166,$4165C141, $C14165C1,$65C14165,$4165C141,$C14166C1,$65C14166,$4165C141,$C14166C1,$65BF4166, $4062BF40,$2FF1F27E,$29339988,$4062BF3A,$BE4165BF,$51AA4062,$3752AB37,$A73751AA, $82A23551,$FDFF7D6B,$07FFFF71,$00008B65,$27000023,$AA3752AA,$52AA3751,$3752AA37, $AA3752AA,$52AA3752,$3752AA37,$AA3752AA,$51AA3752,$3751AA37,$AA3751AA,$52AB3751, $3752AB38,$23EDED79,$1B238F7C,$3751AA32,$A73751AA,$3D90354E,$2C3D912A,$902C3D90, $3D902C3D,$2C3D902C,$65F8F876,$5A00FFFF,$1C000082,$90210000,$3A902A3A,$2C3D902A, $912C3D91,$3D902C3D,$2A3D902A,$902C3D90,$3D912C3D,$2C3D912C,$902A3D90,$3D912A3D, $2C3D902C,$2DEEED78,$262B9988,$2A3A903B,$8E2C3D90,$23712A3A,$1E26741C,$741E2674, $24741E26,$1C24711E,$761C2471,$FF62FDFB,$7C5100FF,$00180000,$24711C00,$1C24711C, $711C2471,$24741C24,$1C24741C,$741C2371,$24741C24,$1C24741C,$741C2474,$24711C24, $1C24711C,$40F1F07A,$2F30A89D,$1C247445,$711C2474,$13601C24,$12136210,$60101360, $13621013,$12136212,$60101360,$F8741013,$FFFF69FA,$007D5200,$00001300,$10136019, $62101360,$13621215,$12136212,$24101360,$06041901,$33120B26,$1A402711,$3517503B, $31200E49,$2CD5CA63,$0B109887,$10136029,$62121562,$05571213,$04055704,$57040557, $05570405,$04055704,$55040557,$05550402,$FFFF7C04,$00FFFF6F,$00008057,$16000012, $55040255,$05570402,$04055704,$34040557,$F5676E5D,$FAF46DF9,$72F9F36D,$F875F9F5, $FCFA73FB,$3BFCFA7C,$0209AA9F,$04025521,$57040557,$004E0405,$00004E00,$4E00004E, $004E0000,$00004E00,$4E00004E,$004E0000,$00004F00,$71FFFF7C,$5100FFFF,$1000007C, $4E100000,$004E0000,$00004F00,$4E00004E,$6B542F2D,$6C6B546C,$51716F57,$69506B69, $7877586C,$49F8F778,$0B10B4AD,$00004E28,$4E00004F,$00470000,$00004600,$47000047, $00470000,$00004700,$46000046,$00470000,$00004600,$7C000046,$FF7CFFFF,$B3961BFF, $00120000,$00461600,$00004700,$47000047,$00470000,$00004700,$47000047,$00470000, $00004600,$3BE1DF71,$060FA89C,$00004623,$47000047,$00400000,$00004000,$40000040, $00410000,$00004100,$41000041,$00410000,$00004100,$40000040,$FF820000,$FFFF96FF, $00CFB63A,$00001600,$00003D12,$40000040,$00410000,$00004100,$41000041,$00400000, $00004000,$33DFDD6E,$0004A093,$00004017,$40000041,$003A0000,$00003A00,$3B00003B, $003B0000,$00003B00,$3A00003A,$003A0000,$00003A00,$3A00003B,$003A0000,$D0D88800, $47FFFFB6,$0000DBC5,$07000012,$3A00003A,$003A0000,$00003A00,$3A00003A,$003A0000, $00003A00,$32E3E170,$00009F92,$00003B0F,$3B00003B,$00350000,$00003500,$35000035, $00350000,$00003500,$35000035,$00350000,$00003500,$35000035,$00340000,$00003400, $B6CCD383,$AD32FFFF,$0D0000C7,$34050000,$00350000,$00003500,$35000035,$00350000, $00003500,$33E6E573,$0000A293,$0000350C,$35000035,$00320000,$00003200,$32000032, $00320000,$00003200,$32000032,$00320000,$00003200,$2F00002F,$00320000,$00002F00, $7700002F,$FF9FC1C5,$CCB135FF,$0C120000,$002F0000,$00002F00,$32000032,$00320000, $00002F00,$3FE7E675,$0000ADA0,$00002F10,$2F000032,$002C0000,$00002D00,$2D00002D, $002D0000,$00002D00,$2C00002C,$002D0000,$00002D00,$2C00002C,$002C0000,$00002C00, $2C00002D,$C4770000,$FFFFABBE,$15D2BB38,$002D0200,$00002D00,$2D00002D,$002C0000, $00002C00,$46E7E675,$0006B2A7,$00002D19,$2D00002D,$00290000,$00002900,$29000029, $002C0000,$00002C00,$2C00002C,$00290000,$00002900,$29000029,$00290000,$00002900, $29000029,$00290000,$09073200,$3A525140,$00291010,$00002900,$2C00002C,$00290000, $00002900,$46E6E574,$010BB2A7,$0000291B,$29000029,$00260000,$00002700,$27000027, $00270000,$00002700,$27000027,$00260000,$00002600,$26000026,$00270000,$00002700, $27000027,$00270000,$00002700,$26000026,$00260000,$00002600,$27000027,$00260000, $00002600,$47E5E373,$0009B1A8,$00002619,$26000027,$00240000,$00002600,$26000026, $00240000,$00002400,$26000026,$00240000,$00002400,$26000026,$00240000,$00002400, $26000026,$00240000,$00002400,$26000026,$00240000,$00002400,$26000026,$00240000, $00002400,$4FEBEB7D,$0004BAB2,$00002414,$24000026,$00210000,$00002100,$24000024, $00210000,$00002100,$24000024,$00210000,$00002100,$24000024,$00240000,$00002400, $24000024,$00210000,$00002100,$21000021,$00240000,$00002400,$24000024,$00240000, $00002100,$3CD5D564,$0001A79D,$00002110,$24000024,$00210000,$00002100,$21000021, $00200000,$00002000,$20000020,$00210000,$00002100,$21000021,$00210000,$00002100, $21000021,$00200000,$00002000,$20000020,$00200000,$00002000,$21000021,$00210000, $00002000,$39E0E068,$0000A599,$0000200F,$20000021,$00200000,$00002000,$1E00001E, $00200000,$00002000,$1E00001E,$001E0000,$00001E00,$1E00001E,$00200000,$00002000, $20000020,$00200000,$00002000,$1E00001E,$00200000,$00002000,$20000020,$00200000, $00001E00,$38D9D967,$0000AB9C,$0000200C,$20000020,$001B0000,$00001E00,$1E00001E, $001E0000,$00001E00,$1E00001E,$001E0000,$00001E00,$1E00001E,$001E0000,$00001E00, $1E00001E,$001E0000,$00001E00,$1E00001E,$001E0000,$00001E00,$1E00001E,$001B0000, $00001B00,$2BD6D667,$0000867A,$00001E09,$1E00001E,$00000000,$00000000); {$ENDIF} implementation end. adlibtracker2-2.4.23/utils/0000755000000000000000000000000013176573533014166 5ustar rootrootadlibtracker2-2.4.23/utils/checksrc.pas0000644000000000000000000000407713176573533016470 0ustar rootrootuses DOS; function check_extra_chars(var data; size: Dword): String; var temp: Dword; xchars: String; begin xchars := ''; If (size = 0) then EXIT; For temp := 0 to PRED(size) do begin If (temp < PRED(size)) and (pBYTE(@data)[temp] = $0d) and (pBYTE(@data)[SUCC(temp)] = $0a) then CONTINUE; If (temp > 0) and (pBYTE(@data)[PRED(temp)] = $0d) and (pBYTE(@data)[temp] = $0a) then CONTINUE; If (pBYTE(@data)[temp] <= $1f) or (pBYTE(@data)[temp] >= $7f) then If (Pos(CHR(pBYTE(@data)[temp]),xchars) = 0) then xchars := xchars+CHR(pBYTE(@data)[temp]); end; check_extra_chars := xchars; end; function byte2hex(value: Byte): String; const data: array[0..15] of char = '0123456789ABCDEF'; begin asm mov edi,@RESULT lea ebx,[data] mov al,2 stosb mov al,value xor ah,ah mov cl,16 div cl xlat stosb mov al,ah xlat stosb end; end; procedure check_file(filename: String); var f: File; buf: Pointer; size: Dword; idx: Byte; xchars: String; begin Assign(f,'..\'+filename); Reset(f,1); size := FileSize(f); GetMem(buf,size); BlockRead(f,buf^,size); Close(f); xchars := check_extra_chars(buf^,size); If (xchars <> '') then begin WriteLn(filename,':'); For idx := 1 to Length(xchars) do If (idx < Length(xchars)) then Write(byte2hex(ORD(xchars[idx])),', ') else WriteLn(byte2hex(ORD(xchars[idx]))); WriteLn; end; end; var search: SearchRec; begin FindFirst('..\*.pas',anyfile-volumeid-directory,search); While (DOSerror = 0) do begin check_file(search.name); FindNext(search); end; FindFirst('..\*.inc',anyfile-volumeid-directory,search); While (DOSerror = 0) do begin check_file(search.name); FindNext(search); end; end. adlibtracker2-2.4.23/adt2unit.pas0000644000000000000000000062325013176573533015275 0ustar rootrootunit AdT2unit; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface {$IFDEF GO32V2} const ___UNIT_DATA_START___: Dword = 0; {$ENDIF} const MAX_IRQ_FREQ = 1000; {$i typcons1.inc} {$i typcons2.inc} const IRQ_freq: Longint = 50; tempo: Byte = 50; speed: Byte = 6; macro_speedup: Word = 1; timer_initialized: Boolean = FALSE; repeat_pattern: Boolean = FALSE; fast_forward: Boolean = FALSE; rewind: Boolean = FALSE; pattern_break: Boolean = FALSE; pattern_delay: Boolean = FALSE; next_line: Byte = 0; start_order: Byte = BYTE_NULL; start_pattern: Byte = BYTE_NULL; start_line: Byte = BYTE_NULL; replay_forbidden: Boolean = TRUE; single_play: Boolean = FALSE; calibrating: Boolean = FALSE; no_status_refresh: Boolean = FALSE; do_synchronize: Boolean = FALSE; space_pressed: Boolean = FALSE; module_archived: Boolean = FALSE; force_scrollbars: Boolean = FALSE; no_sync_playing: Boolean = FALSE; no_step_debugging: Boolean = FALSE; play_single_patt: Boolean = FALSE; no_trace_pattord: Boolean = FALSE; skip_macro_flag: Boolean = FALSE; max_patterns: Byte = 128; jump_mark_mode: Boolean = FALSE; force_macro_keyon: Boolean = FALSE; ins_trailing_flag: Boolean = FALSE; const def_vibtrem_speed_factor: Byte = 1; def_vibtrem_table_size: Byte = 32; def_vibtrem_table: array[0..255] of Byte = ( 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24, 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253,255, 253,250,244,235,224,212,197,180,161,141,120,97,74,49,24); var vibtrem_speed_factor: Byte; vibtrem_table_size: Byte; vibtrem_table: array[0..255] of Byte; type tVIBRATO_TREMOLO_TABLE = array[1..20] of Record pos: Byte; dir: Byte; speed: Byte; depth: Byte; fine: Boolean; end; var vibr_table: tVIBRATO_TREMOLO_TABLE; vibr_table2: tVIBRATO_TREMOLO_TABLE; trem_table: tVIBRATO_TREMOLO_TABLE; trem_table2: tVIBRATO_TREMOLO_TABLE; const macro_preview_indic_proc: procedure(state: Byte) = NIL; seconds_counter: Longint = 0; hundereds_counter: Longint = 0; really_no_status_refresh: Boolean = FALSE; const keyoff_flag = $080; fixed_note_flag = $090; pattern_loop_flag = $0e0; pattern_break_flag = $0f0; var fmpar_table: array[1..20] of tFM_PARAMETER_TABLE; volume_lock: array[1..20] of Boolean; vol4op_lock: array[1..20] of Boolean; volume_table: array[1..20] of Word; vscale_table: array[1..20] of Word; peak_lock: array[1..20] of Boolean; pan_lock: array[1..20] of Boolean; modulator_vol: array[1..20] of Byte; carrier_vol: array[1..20] of Byte; decay_bar: array[1..20] of tDECAY_BAR; volum_bar: array[1..20] of tVOLUM_BAR; channel_flag: array[1..20] of Boolean; event_table: array[1..20] of tCHUNK; voice_table: array[1..20] of Byte; freq_table: array[1..20] of Word; zero_fq_table: array[1..20] of Word; effect_table: array[1..20] of Word; effect_table2: array[1..20] of Word; fslide_table: array[1..20] of Byte; fslide_table2: array[1..20] of Byte; glfsld_table: array[1..20] of Word; glfsld_table2: array[1..20] of Word; porta_table: array[1..20] of Record freq: Word; speed: Byte; end; porta_table2: array[1..20] of Record freq: Word; speed: Byte; end; portaFK_table: array[1..20] of Boolean; arpgg_table: array[1..20] of Record state,note,add1,add2: Byte; end; arpgg_table2: array[1..20] of Record state,note,add1,add2: Byte; end; retrig_table: array[1..20] of Byte; retrig_table2: array[1..20] of Byte; tremor_table: array[1..20] of Record pos: Integer; volume: Word; end; tremor_table2: array[1..20] of Record pos: Integer; volume: Word; end; panning_table: array[1..20] of Byte; last_effect: array[1..20] of Word; last_effect2: array[1..20] of Word; volslide_type: array[1..20] of Byte; event_new: array[1..20] of Boolean; freqtable2: array[1..20] of Word; notedel_table: array[1..20] of Byte; notecut_table: array[1..20] of Byte; ftune_table: array[1..20] of Shortint; keyoff_loop: array[1..20] of Boolean; macro_table: array[1..20] of Record fmreg_pos,arpg_pos,vib_pos: Word; fmreg_count,fmreg_duration,arpg_count, vib_count,vib_delay: Byte; vib_paused: Boolean; fmreg_table,arpg_table,vib_table: Byte; arpg_note: Byte; vib_freq: Word; end; loopbck_table: array[1..20] of Byte; loop_table: array[1..20,0..255] of Byte; misc_register: Byte; ai_table: array[1..255] of Byte; const overall_volume: Byte = 63; global_volume: Byte = 63; fade_out_volume: Byte = 63; play_status: tPLAY_STATUS = isStopped; chan_pos: Byte = 1; chpos: Byte = 1; transpos: Byte = 1; track_chan_start: Byte = 1; nm_track_chan: Byte = 1; play_pos_buf: array[1..9] of Word = (0,0,0,0,0,0,0,0,0); rec_correction: Byte = 0; const MACRO_NOTE_RETRIG_FLAG = $80; MACRO_ENVELOPE_RESTART_FLAG = $40; MACRO_ZERO_FREQ_FLAG = $20; const current_order: Byte = 0; current_pattern: Byte = 0; current_line: Byte = 0; current_tremolo_depth: Byte = 0; current_vibrato_depth: Byte = 0; current_inst: Byte = 1; current_octave: Byte = 4; var adt2_title: array[0..36] of String[18]; var songdata_source: String; instdata_source: String; songdata_title: String; var songdata_crc,songdata_crc_ord: Longint; temp_instrument: tADTRACK2_INS; temp_instrument2: tADTRACK2_INS; temp_instrument_macro: tREGISTER_TABLE; temp_instrument_macro2: tREGISTER_TABLE; temp_instrument_dis_fmreg_col: tDIS_FMREG_COL; temp_instrument_dis_fmreg_col2: tDIS_FMREG_COL; temp_ins_type: Byte; pattord_page,pattord_hpos,pattord_vpos: Byte; instrum_page: Byte; pattern_patt,pattern_page,pattern_hpos: Byte; limit_exceeded: Boolean; load_flag,load_flag_alt: Byte; reset_chan: array[1..20] of Boolean; reset_adsrw: array[1..20] of Boolean; ignore_note_once: array[1..20] of Boolean; track_notes_ins: Boolean; seek_pattern_break: Boolean; var speed_update,lockvol,panlock,lockVP: Boolean; tremolo_depth,vibrato_depth: Byte; volume_scaling,percussion_mode: Boolean; last_order: Byte; var buf1: tGENERIC_IO_BUFFER; buf2: tGENERIC_IO_BUFFER; buf3: array[WORD] of Byte; buf4: array[WORD] of Byte; const pattdata: ^tPATTERN_DATA = NIL; var old_hash_buffer: tOLD_VARIABLE_DATA1; hash_buffer: tOLD_VARIABLE_DATA2; old_songdata: tOLD_FIXED_SONGDATA; dos_memavail: Word; var songdata: tFIXED_SONGDATA; songdata_bak: tFIXED_SONGDATA; temp_songdata: tFIXED_SONGDATA; clipboard: tCLIPBOARD; const ptr_songdata: Pointer = Addr(songdata); ptr_songdata_bak: Pointer = Addr(songdata_bak); ptr_temp_songdata: Pointer = Addr(ptr_temp_songdata); ptr_clipboard: Pointer = Addr(clipboard); var song_timer,timer_temp: Longint; song_timer_tenths: Longint; ticks,tick0,tickD,tickXF: Longint; time_playing,time_playing0: Real; const {$IFDEF GO32V2} timer_determinator: Longint = 1; timer_det2: Longint = 1; scr_scroll_x: Word = 0; old_scr_scroll_x: Word = 0; scr_scroll_y: Word = 0; old_scr_scroll_y: Word = 0; {$ELSE} screen_scroll_offset: Word = 0; {$ENDIF} var common_flag_backup: Byte; volume_scaling_backup: Boolean; event_table_backup: array[1..20] of tCHUNK; freq_table_backup,freqtable2_backup: array[1..20] of Word; keyoff_loop_backup: array[1..20] of Boolean; channel_flag_backup: array[1..20] of Boolean; fmpar_table_backup: array[1..20] of tFM_PARAMETER_TABLE; volume_table_backup: array[1..20] of Word; pan_lock_backup: array[1..20] of Boolean; volume_lock_backup: array[1..20] of Boolean; peak_lock_backup: array[1..20] of Boolean; panning_table_backup: array[1..20] of Byte; voice_table_backup: array[1..20] of Byte; flag_4op_backup: Byte; status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; function nFreq(note: Byte): Word; procedure change_freq(chan: Byte; freq: Word); function calc_pattern_pos(pattern: Byte): Byte; function concw(lo,hi: Byte): Word; function ins_parameter(ins,param: Byte): Byte; function is_chan_adsr_data_empty(chan: Byte): Boolean; function is_ins_adsr_data_empty(ins: Byte): Boolean; function scale_volume(volume,scale_factor: Byte): Byte; function _macro_speedup: Word; procedure calibrate_player(order,line: Byte; status_filter: Boolean; line_dependent: Boolean); procedure update_timer(Hz: Longint); procedure key_on(chan: Byte); procedure key_off(chan: Byte); procedure release_sustaining_sound(chan: Byte); procedure init_macro_table(chan,note,ins: Byte; freq: Word); procedure set_ins_volume(modulator,carrier,chan: Byte); procedure update_modulator_adsrw(chan: Byte); procedure update_carrier_adsrw(chan: Byte); procedure update_fmpar(chan: Byte); procedure reset_chan_data(chan: Byte); procedure poll_proc; procedure macro_poll_proc; procedure init_buffers; procedure init_player; procedure reset_player; procedure start_playing; procedure stop_playing; procedure update_song_position; procedure change_frequency(chan: Byte; freq: Word); procedure set_global_volume; procedure set_ins_data(ins,chan: Byte); procedure init_timer_proc; procedure done_timer_proc; procedure realtime_gfx_poll_proc; procedure decay_bars_refresh; procedure status_refresh; procedure trace_update_proc; function hscroll_bar(x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Byte; function vscroll_bar(x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Byte; procedure centered_frame(var xstart,ystart: Byte; hsize,vsize: Byte; name: String; atr1,atr2: Byte; border: String); procedure get_chunk(pattern,line,channel: Byte; var chunk: tCHUNK); procedure put_chunk(pattern,line,channel: Byte; chunk: tCHUNK); function get_chanpos(var data; channels,scancode: Byte): Byte; function get_chanpos2(var data; channels,scancode: Byte): Byte; function count_channel(hpos: Byte): Byte; function count_pos(hpos: Byte): Byte; function calc_max_speedup(tempo: Byte): Word; function calc_order_jump: Integer; function calc_following_order(order: Byte): Integer; function is_4op_chan(chan: Byte): Boolean; procedure count_order(var entries: Byte); procedure count_patterns(var patterns: Byte); procedure count_instruments(var instruments: Byte); procedure init_old_songdata; procedure init_songdata; procedure update_instr_data(ins: Byte); procedure load_instrument(var data; chan: Byte); procedure output_note(note,ins,chan: Byte; restart_macro,restart_adsr: Boolean); function min(value: Longint; minimum: Longint): Longint; function max(value: Longint; maximum: Longint): Longint; function asciiz_string(str: String): String; const block_xstart: Byte = 1; block_ystart: Byte = 0; const block_x0: Byte = 0; block_y0: Byte = 1; block_x1: Byte = 0; block_y1: Byte = 1; function is_in_block(x0,y0,x1,y1: Byte): Boolean; procedure fade_out_playback(fade_screen: Boolean); const ticklooper: Longint = 0; macro_ticklooper: Longint = 0; const {$IFDEF GO32V2} MAX_NUM_BANK_POSITIONS = 1000; {$ELSE} MAX_NUM_BANK_POSITIONS = 500; {$ENDIF} const bank_position_list_size: Longint = 0; var bank_position_list: array[1..MAX_NUM_BANK_POSITIONS] of Record {$IFDEF GO32V2} bank_name: String[50]; {$ELSE} bank_name: String; {$ENDIF} bank_size: Longint; bank_position: Longint; end; function get_bank_position(bank_name: String; bank_size: Longint): Longint; procedure add_bank_position(bank_name: String; bank_size: Longint; bank_position: Longint); {$IFDEF GO32V2} const ___UNIT_DATA_END___: Dword = 0; {$ENDIF} implementation uses {$IFDEF GO32V2} CRT,DOS,GO32,ISS_Tim, {$ELSE} DOS,SDL_Types,SDL_Timer, {$ENDIF} AdT2opl3,AdT2sys,AdT2extn,AdT2ext2,AdT2keyb, TxtScrIO,StringIO,DialogIO,ParserIO; {$IFDEF GO32V2} const ___IRQ_DATA_START___: Dword = 0; procedure ___IRQ_CODE_START___; begin end; {$ENDIF} const FreqStart = $156; FreqEnd = $2ae; FreqRange = FreqEnd-FreqStart; function nFreq(note: Byte): Word; const Fnum: array[0..11] of Word = ( $157,$16b,$181,$198,$1b0,$1ca,$1e5,$202,$220,$241,$263,$287); var result: Word; begin asm xor ebx,ebx mov al,[note] xor ah,ah cmp ax,12*8 jae @@1 push eax mov bl,12 div bl mov bl,ah xor bh,bh shl bx,1 pop eax mov cl,12 div cl xor ah,ah shl ax,10 add ax,word ptr [Fnum+ebx] jmp @@2 @@1: mov ax,7 shl ax,10 add ax,FreqEnd @@2: mov result,ax end; nFreq := result; end; function calc_freq_shift_up(freq,shift: Word): Word; var result: Word; begin asm mov cx,freq mov ax,shift mov bx,cx and bx,0000001111111111b mov dx,cx and dx,0001110000000000b add bx,ax and cx,1110000000000000b shr dx,10 cmp bx,FreqEnd jb @@2 cmp dx,7 jnz @@1 mov bx,FreqEnd jmp @@2 @@1: sub bx,FreqRange inc dx @@2: mov ax,cx shl dx,10 add ax,dx add ax,bx mov result,ax end; calc_freq_shift_up := result; end; function calc_freq_shift_down(freq,shift: Word): Word; var result: Word; begin asm mov cx,freq mov ax,shift mov bx,cx and bx,0000001111111111b mov dx,cx and dx,0001110000000000b sub bx,ax and cx,1110000000000000b shr dx,10 cmp bx,FreqStart ja @@2 or dx,dx jnz @@1 mov bx,FreqStart jmp @@2 @@1: add bx,FreqRange dec dx @@2: mov ax,cx shl dx,10 add ax,dx add ax,bx mov result,ax end; calc_freq_shift_down := result; end; function calc_vibtrem_shift(chan: Byte; var table_data): Word; var pos,dir,depth: Byte; result: Word; begin pos := tVIBRATO_TREMOLO_TABLE(table_data)[chan].pos; depth := tVIBRATO_TREMOLO_TABLE(table_data)[chan].depth; asm xor ebx,ebx mov al,depth xor ah,ah mov bl,pos xor bh,bh mov dh,bl mov cl,byte ptr [vibtrem_table_size] dec cl and bl,cl mov dl,byte ptr [vibtrem_table+ebx] mul dl rol ax,1 xchg ah,al and ah,1 mov dir,1 mov dl,byte ptr [vibtrem_table_size] test dh,dl jne @@1 mov dir,0 @@1: mov result,ax end; tVIBRATO_TREMOLO_TABLE(table_data)[chan].dir := dir; calc_vibtrem_shift := result; end; procedure change_freq(chan: Byte; freq: Word); begin If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin freq_table[SUCC(chan)] := freq_table[chan]; freqtable2[SUCC(chan)] := freqtable2[chan]; chan := SUCC(chan); end; asm xor ebx,ebx mov bl,chan dec ebx shl ebx,1 mov ax,freq and ax,1fffh mov dx,word ptr [freq_table+ebx] and dx,NOT 1fffh add ax,dx mov word ptr [freq_table+ebx],ax mov word ptr [freqtable2+ebx],ax shr ebx,1 cmp byte ptr [channel_flag+ebx],TRUE jnz @@1 shl ebx,1 xor edx,edx mov dx,word ptr [_chan_n+ebx] add dx,0a0h push edx xor edx,edx mov dl,al push edx mov dx,word ptr [_chan_n+ebx] add dx,0b0h push edx xor edx,edx mov dl,ah push edx call opl3out call opl3out @@1: end; If is_4op_chan(chan) then begin freq_table[PRED(chan)] := freq_table[chan]; freqtable2[PRED(chan)] := freqtable2[chan]; end; end; function ins_parameter(ins,param: Byte): Byte; var result: Byte; begin asm xor ebx,ebx lea esi,[songdata.instr_data] mov bl,ins dec ebx mov eax,INSTRUMENT_SIZE mul ebx add esi,eax mov bl,param add esi,ebx lodsb mov result,al end; ins_parameter := result; end; function is_chan_adsr_data_empty(chan: Byte): Boolean; begin is_chan_adsr_data_empty := (fmpar_table[chan].adsrw_car.attck = 0) and (fmpar_table[chan].adsrw_mod.attck = 0) and (fmpar_table[chan].adsrw_car.dec = 0) and (fmpar_table[chan].adsrw_mod.dec = 0) and (fmpar_table[chan].adsrw_car.sustn = 0) and (fmpar_table[chan].adsrw_mod.sustn = 0) and (fmpar_table[chan].adsrw_car.rel = 0) and (fmpar_table[chan].adsrw_mod.rel = 0); end; function is_ins_adsr_data_empty(ins: Byte): Boolean; begin is_ins_adsr_data_empty := (ins_parameter(ins,5) SHR 4 = 0) and (ins_parameter(ins,4) SHR 4 = 0) and (ins_parameter(ins,5) AND $0f = 0) and (ins_parameter(ins,4) AND $0f = 0) and (ins_parameter(ins,7) SHR 4 = 0) and (ins_parameter(ins,6) SHR 4 = 0) and (ins_parameter(ins,7) AND $0f = 0) and (ins_parameter(ins,6) AND $0f = 0); end; function is_data_empty(var buf; size: Longint): Boolean; var result: Boolean; begin asm xor edx,edx mov eax,size cmp eax,16 jb @@3 mov ecx,4 div ecx mov ecx,eax jecxz @@1 mov edi,[buf] xor eax,eax repz scasd jnz @@2 mov ecx,edx jecxz @@1 repz scasb jnz @@2 @@1: mov result,TRUE jmp @@6 @@2: mov result,FALSE jmp @@6 @@3: mov ecx,size jecxz @@4 mov edi,[buf] xor eax,eax repz scasb jnz @@5 @@4: mov result,TRUE jmp @@6 @@5: mov result,FALSE @@6: end; is_data_empty := result; end; function min(value: Longint; minimum: Longint): Longint; begin If (value > minimum) then min := value else min := minimum; end; function max(value: Longint; maximum: Longint): Longint; begin If (value < maximum) then max := value else max := maximum; end; function asciiz_string(str: String): String; begin If (Pos(#0,str) <> 0) then asciiz_string := Copy(str,1,Pos(#0,str)-1) else asciiz_string := ''; end; function concw(lo,hi: Byte): Word; begin concw := lo+(hi SHL 8); end; procedure synchronize_song_timer; begin song_timer := TRUNC(time_playing); song_timer_tenths := TRUNC(time_playing*100) MOD 100; timer_temp := song_timer_tenths; end; procedure change_frequency(chan: Byte; freq: Word); begin macro_table[chan].vib_paused := TRUE; change_freq(chan,freq); If is_4op_chan(chan) then If (chan in _4op_tracks_hi) then begin macro_table[SUCC(chan)].vib_count := 1; macro_table[SUCC(chan)].vib_pos := 0; macro_table[SUCC(chan)].vib_freq := freq; macro_table[SUCC(chan)].vib_paused := FALSE; end else begin macro_table[PRED(chan)].vib_count := 1; macro_table[PRED(chan)].vib_pos := 0; macro_table[PRED(chan)].vib_freq := freq; macro_table[PRED(chan)].vib_paused := FALSE; end; macro_table[chan].vib_count := 1; macro_table[chan].vib_pos := 0; macro_table[chan].vib_freq := freq; macro_table[chan].vib_paused := FALSE; end; procedure TimerSetup(Hz: Longint); forward; procedure update_timer(Hz: Longint); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:update_timer'; {$ENDIF} If (Hz = 0) then begin TimerSetup(18); EXIT end else tempo := Hz; If (tempo = 18) and timer_fix then IRQ_freq := TRUNC((tempo+0.2)*20) else IRQ_freq := 250; While (IRQ_freq MOD (tempo*_macro_speedup) <> 0) do Inc(IRQ_freq); If (IRQ_freq > MAX_IRQ_FREQ) then IRQ_freq := MAX_IRQ_FREQ; TimerSetup(IRQ_freq); end; procedure key_on(chan: Byte); begin If NOT (is_4op_chan(chan) and (chan in _4op_tracks_hi)) then opl3out($0b0+_chan_n[chan],0) else opl3out($0b0+_chan_n[SUCC(chan)],0); end; procedure key_off(chan: Byte); begin freq_table[chan] := LO(freq_table[chan])+ (HI(freq_table[chan]) AND NOT $20) SHL 8; change_freq(chan,freq_table[chan]); event_table[chan].note := event_table[chan].note OR keyoff_flag; end; procedure release_sustaining_sound(chan: Byte); begin opl3out(_instr[02]+_chan_m[chan],63); opl3out(_instr[03]+_chan_c[chan],63); FillChar(fmpar_table[chan].adsrw_car, SizeOf(fmpar_table[chan].adsrw_car),0); FillChar(fmpar_table[chan].adsrw_mod, SizeOf(fmpar_table[chan].adsrw_mod),0); key_on(chan); opl3out(_instr[04]+_chan_m[chan],BYTE_NULL); opl3out(_instr[05]+_chan_c[chan],BYTE_NULL); opl3out(_instr[06]+_chan_m[chan],BYTE_NULL); opl3out(_instr[07]+_chan_c[chan],BYTE_NULL); key_off(chan); event_table[chan].instr_def := 0; reset_chan[chan] := TRUE; end; function scale_volume(volume,scale_factor: Byte): Byte; begin scale_volume := 63-Round((63-volume)/63* (63-scale_factor)); end; function _4op_data_flag(chan: Byte): Dword; var _4op_conn: Byte; _4op_mode: Boolean; _4op_ch1,_4op_ch2: Byte; _4op_ins1,_4op_ins2: Byte; begin _4op_mode := FALSE; If is_4op_chan(chan) then begin _4op_mode := TRUE; If (chan in _4op_tracks_hi) then begin _4op_ch1 := chan; _4op_ch2 := SUCC(chan); end else begin _4op_ch1 := PRED(chan); _4op_ch2 := chan; end; _4op_ins1 := event_table[_4op_ch1].instr_def; If (_4op_ins1 = 0) then _4op_ins1 := voice_table[_4op_ch1]; _4op_ins2 := event_table[_4op_ch2].instr_def; If (_4op_ins2 = 0) then _4op_ins2 := voice_table[_4op_ch2]; If (_4op_ins1 <> 0) and (_4op_ins2 <> 0) then begin _4op_mode := TRUE; _4op_conn := (pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[_instr_data_ofs[11]] AND 1) SHL 1 + (pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[_instr_data_ofs[11]] AND 1); end; end; {------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---} { BIT |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0 } {------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---} { DATA |..|..|..|..|..|F7|F6|F5|F4|F3|F2|F1|F0|E7|E6|E5|E4|E3|E2|E1|E0|D3|D2|D1|D0|C3|C2|C1|C0|B1|B0|A0 } {------+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+---} _4op_data_flag := ORD(_4op_mode) + {1-bit: A0} (_4op_conn AND 3) SHL 1 + {2-bit: B1-B0} (_4op_ch1 AND 15) SHL 3 + {4-bit: C3-C0} (_4op_ch2 AND 15) SHL 7 + {4-bit: D3-D0} _4op_ins1 SHL 11 + {8-bit: E7-E0} _4op_ins2 SHL 19; {8-bit: F7-F0} end; function _4op_vol_valid_chan(chan: Byte): Boolean; var _4op_flag: Dword; begin _4op_flag := _4op_data_flag(chan); _4op_vol_valid_chan := BOOLEAN(_4op_flag AND 1) and vol4op_lock[chan] and (BYTE(_4op_flag SHR 11) <> 0) and (BYTE(_4op_flag SHR 19) <> 0); end; procedure set_ins_volume(modulator,carrier,chan: Byte); var temp: Byte; begin {$IFNDEF GO32V2} // ** OPL3 emulation workaround ** // force muted instrument volume with missing channel ADSR data // when there is additionally no FM-reg macro defined for this instrument If is_chan_adsr_data_empty(chan) and NOT (songdata.instr_macros[voice_table[chan]].length <> 0) then begin modulator := 63; carrier := 63; end; {$ENDIF} If (modulator <> BYTE_NULL) then begin temp := modulator; If volume_scaling then If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator); If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then opl3out(_instr[02]+_chan_m[chan], scale_volume(scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+LO(vscale_table[chan])) else opl3out(_instr[02]+_chan_m[chan], temp+LO(vscale_table[chan])); volume_table[chan] := concw(temp,HI(volume_table[chan])); If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then modulator_vol[chan] := 63-scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)) else modulator_vol[chan] := 63-modulator; end; If (carrier <> BYTE_NULL) then begin temp := carrier; If volume_scaling then carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier); opl3out(_instr[03]+_chan_c[chan], scale_volume(scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+HI(vscale_table[chan])); volume_table[chan] := concw(LO(volume_table[chan]),temp); carrier_vol[chan] := 63-scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)); end; end; procedure set_ins_volume_4op(volume,chan: Byte); var _4op_flag: Dword; _4op_conn: Byte; _4op_ch1,_4op_ch2: Byte; procedure set_volume(modulator,carrier,chan: Byte); var temp: Byte; begin {$IFNDEF GO32V2} // ** OPL3 emulation workaround ** // force muted instrument volume with missing channel ADSR data // when there is additionally no FM-reg macro defined for this instrument If is_chan_adsr_data_empty(chan) and NOT (songdata.instr_macros[voice_table[chan]].length <> 0) then begin modulator := 63; carrier := 63; end; {$ENDIF} If (modulator <> BYTE_NULL) then begin temp := modulator; modulator := scale_volume(ins_parameter(voice_table[chan],2) AND $3f,modulator); opl3out(_instr[02]+_chan_m[chan], scale_volume(scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+LO(vscale_table[chan])); volume_table[chan] := concw(temp,HI(volume_table[chan])); modulator_vol[chan] := 63-scale_volume(modulator,scale_volume(63-global_volume,63-fade_out_volume)) end; If (carrier <> BYTE_NULL) then begin temp := carrier; carrier := scale_volume(ins_parameter(voice_table[chan],3) AND $3f,carrier); opl3out(_instr[03]+_chan_c[chan], scale_volume(scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)),63-overall_volume)+HI(vscale_table[chan])); volume_table[chan] := concw(LO(volume_table[chan]),temp); carrier_vol[chan] := 63-scale_volume(carrier,scale_volume(63-global_volume,63-fade_out_volume)); end; end; begin _4op_flag := _4op_data_flag(chan); _4op_conn := (_4op_flag SHR 1) AND 3; _4op_ch1 := (_4op_flag SHR 3) AND 15; _4op_ch2 := (_4op_flag SHR 7) AND 15; If _4op_vol_valid_chan(chan) then Case _4op_conn of // FM/FM 0: If (volume = BYTE_NULL) then set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1) else set_volume(BYTE_NULL,volume,_4op_ch1); // FM/AM 1: If (volume = BYTE_NULL) then begin set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1); set_volume(LO(volume_table[_4op_ch2]),BYTE_NULL,_4op_ch2); end else begin set_volume(BYTE_NULL,volume,_4op_ch1); set_volume(volume,BYTE_NULL,_4op_ch2); end; // AM/FM 2: If (volume = BYTE_NULL) then begin set_volume(BYTE_NULL,HI(volume_table[_4op_ch1]),_4op_ch1); set_volume(BYTE_NULL,HI(volume_table[_4op_ch2]),_4op_ch2); end else begin set_volume(BYTE_NULL,volume,_4op_ch1); set_volume(BYTE_NULL,volume,_4op_ch2); end; // AM/AM 3: If (volume = BYTE_NULL) then begin set_volume(LO(volume_table[_4op_ch1]),HI(volume_table[_4op_ch1]),_4op_ch1); set_volume(LO(volume_table[_4op_ch2]),BYTE_NULL,_4op_ch2); end else begin set_volume(volume,volume,_4op_ch1); set_volume(volume,BYTE_NULL,_4op_ch2); end; end; end; procedure reset_ins_volume(chan: Byte); begin If NOT volume_scaling then set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f, ins_parameter(voice_table[chan],3) AND $3f,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(ins_parameter(voice_table[chan],2) AND $3f,0,chan) else set_ins_volume(0,0,chan); end; procedure set_ins_data(ins,chan: Byte); var old_ins: Byte; begin If (ins <> event_table[chan].instr_def) or reset_chan[chan] then begin opl3out(_instr[02]+_chan_m[chan],63); opl3out(_instr[03]+_chan_c[chan],63); If NOT pan_lock[chan] then panning_table[chan] := ins_parameter(ins,11) else panning_table[chan] := songdata.lock_flags[chan] AND 3; opl3out(_instr[00]+_chan_m[chan],ins_parameter(ins,0)); opl3out(_instr[01]+_chan_c[chan],ins_parameter(ins,1)); opl3out(_instr[04]+_chan_m[chan],ins_parameter(ins,4)); opl3out(_instr[05]+_chan_c[chan],ins_parameter(ins,5)); opl3out(_instr[06]+_chan_m[chan],ins_parameter(ins,6)); opl3out(_instr[07]+_chan_c[chan],ins_parameter(ins,7)); opl3out(_instr[08]+_chan_m[chan],ins_parameter(ins,8)); opl3out(_instr[09]+_chan_c[chan],ins_parameter(ins,9)); opl3out(_instr[10]+_chan_n[chan],ins_parameter(ins,10) OR _panning[panning_table[chan]]); fmpar_table[chan].connect := ins_parameter(ins,10) AND 1; fmpar_table[chan].feedb := ins_parameter(ins,10) SHR 1 AND 7; fmpar_table[chan].multipM := ins_parameter(ins,0) AND $0f; fmpar_table[chan].kslM := ins_parameter(ins,2) SHR 6; fmpar_table[chan].tremM := ins_parameter(ins,0) SHR 7; fmpar_table[chan].vibrM := ins_parameter(ins,0) SHR 6 AND 1; fmpar_table[chan].ksrM := ins_parameter(ins,0) SHR 4 AND 1; fmpar_table[chan].sustM := ins_parameter(ins,0) SHR 5 AND 1; fmpar_table[chan].multipC := ins_parameter(ins,1) AND $0f; fmpar_table[chan].kslC := ins_parameter(ins,3) SHR 6; fmpar_table[chan].tremC := ins_parameter(ins,1) SHR 7; fmpar_table[chan].vibrC := ins_parameter(ins,1) SHR 6 AND 1; fmpar_table[chan].ksrC := ins_parameter(ins,1) SHR 4 AND 1; fmpar_table[chan].sustC := ins_parameter(ins,1) SHR 5 AND 1; fmpar_table[chan].adsrw_car.attck := ins_parameter(ins,5) SHR 4; fmpar_table[chan].adsrw_mod.attck := ins_parameter(ins,4) SHR 4; fmpar_table[chan].adsrw_car.dec := ins_parameter(ins,5) AND $0f; fmpar_table[chan].adsrw_mod.dec := ins_parameter(ins,4) AND $0f; fmpar_table[chan].adsrw_car.sustn := ins_parameter(ins,7) SHR 4; fmpar_table[chan].adsrw_mod.sustn := ins_parameter(ins,6) SHR 4; fmpar_table[chan].adsrw_car.rel := ins_parameter(ins,7) AND $0f; fmpar_table[chan].adsrw_mod.rel := ins_parameter(ins,6) AND $0f; fmpar_table[chan].adsrw_car.wform := ins_parameter(ins,9) AND $07; fmpar_table[chan].adsrw_mod.wform := ins_parameter(ins,8) AND $07; If NOT reset_chan[chan] then keyoff_loop[chan] := FALSE; If reset_chan[chan] then begin voice_table[chan] := ins; reset_ins_volume(chan); reset_chan[chan] := FALSE; end; If (event_table[chan].note AND $7f in [1..12*8+1]) then init_macro_table(chan,event_table[chan].note AND $7f,ins,freq_table[chan]) else init_macro_table(chan,0,ins,freq_table[chan]); end; vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6, fmpar_table[chan].kslC SHL 6); voice_table[chan] := ins; old_ins := event_table[chan].instr_def; event_table[chan].instr_def := ins; If NOT volume_lock[chan] or (ins <> old_ins) then reset_ins_volume(chan); ai_table[ins] := 1; end; procedure update_modulator_adsrw(chan: Byte); begin opl3out(_instr[04]+_chan_m[chan], fmpar_table[chan].adsrw_mod.attck SHL 4+ fmpar_table[chan].adsrw_mod.dec); opl3out(_instr[06]+_chan_m[chan], fmpar_table[chan].adsrw_mod.sustn SHL 4+ fmpar_table[chan].adsrw_mod.rel); opl3out(_instr[08]+_chan_m[chan], fmpar_table[chan].adsrw_mod.wform); end; procedure update_carrier_adsrw(chan: Byte); begin opl3out(_instr[05]+_chan_c[chan], fmpar_table[chan].adsrw_car.attck SHL 4+ fmpar_table[chan].adsrw_car.dec); opl3out(_instr[07]+_chan_c[chan], fmpar_table[chan].adsrw_car.sustn SHL 4+ fmpar_table[chan].adsrw_car.rel); opl3out(_instr[09]+_chan_c[chan], fmpar_table[chan].adsrw_car.wform); end; procedure update_fmpar(chan: Byte); begin opl3out(_instr[00]+_chan_m[chan],fmpar_table[chan].multipM+ fmpar_table[chan].ksrM SHL 4+ fmpar_table[chan].sustM SHL 5+ fmpar_table[chan].vibrM SHL 6+ fmpar_table[chan].tremM SHL 7); opl3out(_instr[01]+_chan_c[chan],fmpar_table[chan].multipC+ fmpar_table[chan].ksrC SHL 4+ fmpar_table[chan].sustC SHL 5+ fmpar_table[chan].vibrC SHL 6+ fmpar_table[chan].tremC SHL 7); opl3out(_instr[10]+_chan_n[chan],(fmpar_table[chan].connect+ fmpar_table[chan].feedb SHL 1) OR _panning[panning_table[chan]]); vscale_table[chan] := concw(fmpar_table[chan].kslM SHL 6, fmpar_table[chan].kslC SHL 6); set_ins_volume(LO(volume_table[chan]), HI(volume_table[chan]),chan); end; procedure reset_chan_data(chan: Byte); begin If (percussion_mode and (chan in [17..20])) then If channel_flag[chan] then reset_ins_volume(chan) else set_ins_volume(0,0,chan) else begin opl3out(_instr[02]+_chan_m[chan],63); opl3out(_instr[03]+_chan_c[chan],63); key_on(chan); opl3out(_instr[04]+_chan_m[chan],BYTE_NULL); opl3out(_instr[05]+_chan_c[chan],BYTE_NULL); opl3out(_instr[06]+_chan_m[chan],BYTE_NULL); opl3out(_instr[07]+_chan_c[chan],BYTE_NULL); key_off(chan); update_fmpar(chan); end; reset_adsrw[chan] := TRUE; If (play_status <> isStopped) then If (event_table[chan].note AND $7f in [1..12*8+1]) then init_macro_table(chan,event_table[chan].note AND $7f,voice_table[chan],freq_table[chan]) else init_macro_table(chan,0,voice_table[chan],freq_table[chan]); end; procedure init_macro_table(chan,note,ins: Byte; freq: Word); begin macro_table[chan].fmreg_count := 1; macro_table[chan].fmreg_pos := 0; macro_table[chan].fmreg_duration := 0; macro_table[chan].fmreg_table := ins; macro_table[chan].arpg_count := 1; macro_table[chan].arpg_pos := 0; macro_table[chan].arpg_table := songdata.instr_macros[ins].arpeggio_table; macro_table[chan].arpg_note := note; macro_table[chan].vib_count := 1; macro_table[chan].vib_paused := FALSE; macro_table[chan].vib_pos := 0; macro_table[chan].vib_table := songdata.instr_macros[ins].vibrato_table; macro_table[chan].vib_freq := freq; macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; zero_fq_table[chan] := 0; end; procedure output_note(note,ins,chan: Byte; restart_macro,restart_adsr: Boolean); var freq: Word; begin If (note = 0) and (ftune_table[chan] = 0) then EXIT; If NOT (note in [1..12*8+1]) then freq := freq_table[chan] else begin freq := nFreq(note-1)+SHORTINT(ins_parameter(ins,12)); If restart_adsr then key_on(chan); freq_table[chan] := concw(LO(freq_table[chan]), HI(freq_table[chan]) OR $20); If channel_flag[chan] then If is_4op_chan(chan) then begin If NOT (percussion_mode and (chan in [17..20])) then If (ins_parameter(voice_table[chan],10) AND 1 = 1) then If (volum_bar[chan].lvl < (carrier_vol[chan]+modulator_vol[chan]) DIV 2) then volum_bar[chan].dir := 1 else else If (volum_bar[chan].lvl < carrier_vol[chan]) then volum_bar[chan].dir := 1 else else If (volum_bar[chan].lvl < modulator_vol[chan]) then volum_bar[chan].dir := 1; If NOT (percussion_mode and (PRED(chan) in [17..20])) then If (ins_parameter(voice_table[PRED(chan)],10) AND 1 = 1) then If (volum_bar[PRED(chan)].lvl < (carrier_vol[PRED(chan)]+modulator_vol[PRED(chan)]) DIV 2) then volum_bar[PRED(chan)].dir := 1 else else If (volum_bar[PRED(chan)].lvl < carrier_vol[PRED(chan)]) then volum_bar[PRED(chan)].dir := 1 else else If (volum_bar[PRED(chan)].lvl < modulator_vol[PRED(chan)]) then volum_bar[PRED(chan)].dir := 1; If (decay_bar[chan].lvl1 < carrier_vol[chan]) then decay_bar[chan].dir1 := 1; If (decay_bar[chan].lvl2 < modulator_vol[chan]) then decay_bar[chan].dir2 := 1; If (decay_bar[PRED(chan)].lvl1 < carrier_vol[PRED(chan)]) then decay_bar[PRED(chan)].dir1 := 1; If (decay_bar[PRED(chan)].lvl2 < modulator_vol[PRED(chan)]) then decay_bar[PRED(chan)].dir2 := 1; If (play_status <> isPlaying) then begin volum_bar[chan].dir := -1; decay_bar[chan].dir1 := -1; decay_bar[chan].dir2 := -1; decay_bar[PRED(chan)].dir1 := -1; decay_bar[PRED(chan)].dir2 := -1; end; end else begin If NOT (percussion_mode and (chan in [17..20])) then If (ins_parameter(voice_table[chan],10) AND 1 = 1) then If (volum_bar[chan].lvl < (carrier_vol[chan]+modulator_vol[chan]) DIV 2) then volum_bar[chan].dir := 1 else else If (volum_bar[chan].lvl < carrier_vol[chan]) then volum_bar[chan].dir := 1 else else If (volum_bar[chan].lvl < modulator_vol[chan]) then volum_bar[chan].dir := 1; If (decay_bar[chan].lvl1 < carrier_vol[chan]) then decay_bar[chan].dir1 := 1; If (decay_bar[chan].lvl2 < modulator_vol[chan]) then decay_bar[chan].dir2 := 1; If (play_status <> isPlaying) then begin volum_bar[chan].dir := -1; decay_bar[chan].dir1 := -1; decay_bar[chan].dir2 := -1; end; end; end; If (ftune_table[chan] = -127) then ftune_table[chan] := 0; freq := freq+ftune_table[chan]; change_frequency(chan,freq); If (note <> 0) then begin event_table[chan].note := note; If is_4op_chan(chan) then event_table[PRED(chan)].note := note; If restart_macro then With event_table[chan] do If NOT (((effect_def = ef_Extended) and (effect DIV 16 = ef_ex_ExtendedCmd2) and (effect MOD 16 = ef_ex_cmd2_NoRestart)) or ((effect_def2 = ef_Extended) and (effect2 DIV 16 = ef_ex_ExtendedCmd2) and (effect2 MOD 16 = ef_ex_cmd2_NoRestart))) then init_macro_table(chan,note,ins,freq) else macro_table[chan].arpg_note := note; end; end; procedure generate_custom_vibrato(value: Byte); const vibtab_size: array[0..15] of Byte = ( 16,16,16,16,32,32,32,32,64,64,64,64,128,128,128,128); var mul_r: Real; mul_b: Byte; idx,idx2: Byte; function min0(value: Longint): Longint; begin If (value >= 0) then min0 := value else min0 := 0; end; begin Case value of // set default speed table 0: begin vibtrem_table_size := def_vibtrem_table_size; Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table)); end; // set custom speed table (fixed size = 32) 1..239: begin vibtrem_table_size := def_vibtrem_table_size; mul_r := value/16; For idx2 := 0 to 7 do begin vibtrem_table[idx2*32] := 0; For idx := 1 to 16 do vibtrem_table[idx2*32+idx] := ROUND(idx*mul_r); For idx := 17 to 31 do vibtrem_table[idx2*32+idx] := ROUND((32-idx)*mul_r); end; end; // set custom speed table (speed factor = 1-4) 240..255: begin vibtrem_speed_factor := SUCC((value-240) MOD 4); vibtrem_table_size := 2*vibtab_size[value-240]; mul_b := 256 DIV (vibtab_size[value-240]); For idx2 := 0 to PRED(128 DIV vibtab_size[value-240]) do begin vibtrem_table[2*vibtab_size[value-240]*idx2] := 0; For idx := 1 to vibtab_size[value-240] do vibtrem_table[2*vibtab_size[value-240]*idx2+idx] := min0(idx*mul_b-1); For idx := vibtab_size[value-240]+1 to 2*vibtab_size[value-240]-1 do vibtrem_table[2*vibtab_size[value-240]*idx2+idx] := min0((2*vibtab_size[value-240]-idx)*mul_b-1); end; end; end; end; procedure update_fine_effects(chan: Byte); forward; procedure play_line; var chan,idx: Byte; event: array[1..20] of tCHUNK; eLo,eHi,eLo2,eHi2: array[1..20] of Byte; tporta_flag: Boolean; function no_loop(current_chan,current_line: Byte): Boolean; var result: Boolean; chan: Byte; begin result := TRUE; For chan := 1 to PRED(current_chan) do If (loop_table[chan][current_line] <> 0) and (loop_table[chan][current_line] <> BYTE_NULL) then begin result := FALSE; BREAK; end; no_loop := result; end; begin If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and (current_order <> last_order) then begin FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); last_order := current_order; end; For chan := 1 to songdata.nm_tracks do If channel_flag[chan] and reset_adsrw[chan] then begin update_modulator_adsrw(chan); update_carrier_adsrw(chan); reset_adsrw[chan] := FALSE; end; For chan := 1 to songdata.nm_tracks do begin event[chan] := pattdata^[current_pattern DIV 8][current_pattern MOD 8] [chan][current_line]; If (effect_table[chan] <> 0) then last_effect[chan] := effect_table[chan]; If (glfsld_table[chan] <> 0) then effect_table[chan] := glfsld_table[chan] else effect_table[chan] := effect_table[chan] AND $0ff00; If (effect_table2[chan] <> 0) then last_effect2[chan] := effect_table2[chan]; If (glfsld_table2[chan] <> 0) then effect_table2[chan] := glfsld_table2[chan] else effect_table2[chan] := effect_table2[chan] AND $0ff00; ftune_table[chan] := 0; If (event[chan].note = BYTE_NULL) then event[chan].note := event_table[chan].note OR keyoff_flag else If (event[chan].note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then event[chan].note := event[chan].note-fixed_note_flag; If (event[chan].note <> 0) or (event[chan].effect_def <> 0) or (event[chan].effect_def2 <> 0) or ((event[chan].effect_def = 0) and (event[chan].effect <> 0)) or ((event[chan].effect_def2 = 0) and (event[chan].effect2 <> 0)) then event_new[chan] := TRUE else event_new[chan] := FALSE; If (event[chan].note <> 0) or (event[chan].instr_def <> 0) or (event[chan].effect_def+event[chan].effect <> 0) or (event[chan].effect_def2+event[chan].effect2 <> 0) then begin event_table[chan].effect_def := event[chan].effect_def; event_table[chan].effect := event[chan].effect; event_table[chan].effect_def2 := event[chan].effect_def2; event_table[chan].effect2 := event[chan].effect2; end; If (event[chan].instr_def <> 0) then If NOT is_data_empty(songdata.instr_data[event[chan].instr_def], INSTRUMENT_SIZE) then set_ins_data(event[chan].instr_def,chan) else begin release_sustaining_sound(chan); set_ins_data(event[chan].instr_def,chan); end; If NOT (event[chan].effect_def in [ef_Vibrato,ef_ExtraFineVibrato, ef_VibratoVolSlide,ef_VibratoVSlideFine]) then FillChar(vibr_table[chan],SizeOf(vibr_table[chan]),0); If NOT (event[chan].effect_def2 in [ef_Vibrato,ef_ExtraFineVibrato, ef_VibratoVolSlide,ef_VibratoVSlideFine]) then FillChar(vibr_table2[chan],SizeOf(vibr_table2[chan]),0); If NOT (event[chan].effect_def in [ef_RetrigNote,ef_MultiRetrigNote]) then FillChar(retrig_table[chan],SizeOf(retrig_table[chan]),0); If NOT (event[chan].effect_def2 in [ef_RetrigNote,ef_MultiRetrigNote]) then FillChar(retrig_table2[chan],SizeOf(retrig_table2[chan]),0); If NOT (event[chan].effect_def in [ef_Tremolo,ef_ExtraFineTremolo]) then FillChar(trem_table[chan],SizeOf(trem_table[chan]),0); If NOT (event[chan].effect_def2 in [ef_Tremolo,ef_ExtraFineTremolo]) then FillChar(trem_table2[chan],SizeOf(trem_table2[chan]),0); If NOT (((event[chan].effect_def = ef_Arpeggio) and (event[chan].effect <> 0)) or (event[chan].effect_def = ef_ExtraFineArpeggio)) and (arpgg_table[chan].note <> 0) and (arpgg_table[chan].state <> 1) then begin arpgg_table[chan].state := 1; change_frequency(chan,nFreq(arpgg_table[chan].note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end else If NOT (((event[chan].effect_def2 = ef_Arpeggio) and (event[chan].effect2 <> 0)) or (event[chan].effect_def2 = ef_ExtraFineArpeggio)) and (arpgg_table2[chan].note <> 0) and (arpgg_table2[chan].state <> 1) then begin arpgg_table2[chan].state := 1; change_frequency(chan,nFreq(arpgg_table2[chan].note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end; end; For chan := 1 to songdata.nm_tracks do begin If event_new[chan] and is_4op_chan(chan) then If (chan in _4op_tracks_hi) then event_new[SUCC(chan)] := TRUE else event_new[PRED(chan)] := TRUE; If (tremor_table[chan].pos <> 0) and (event[chan].effect_def <> ef_Tremor) then begin tremor_table[chan].pos := 0; set_ins_volume(LO(tremor_table[chan].volume), HI(tremor_table[chan].volume),chan); end; If (tremor_table2[chan].pos <> 0) and (event[chan].effect_def2 <> ef_Tremor) then begin tremor_table2[chan].pos := 0; set_ins_volume(LO(tremor_table2[chan].volume), HI(tremor_table2[chan].volume),chan); end; eLo[chan] := LO(last_effect[chan]); eHi[chan] := HI(last_effect[chan]); eLo2[chan] := LO(last_effect2[chan]); eHi2[chan] := HI(last_effect2[chan]); end; For chan := 1 to songdata.nm_tracks do Case event[chan].effect_def of ef_Arpeggio, ef_ExtraFineArpeggio, ef_ArpggVSlide, ef_ArpggVSlideFine: If (event[chan].effect_def <> ef_Arpeggio) or (event[chan].effect <> 0) then begin Case event[chan].effect_def of ef_Arpeggio: effect_table[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect); ef_ExtraFineArpeggio: effect_table[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect); ef_ArpggVSlide, ef_ArpggVSlideFine: If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := effect_table[chan] AND $0ff00; end; If (event[chan].note AND $7f in [1..12*8+1]) then begin arpgg_table[chan].state := 0; arpgg_table[chan].note := event[chan].note AND $7f; If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then begin arpgg_table[chan].add1 := event[chan].effect DIV 16; arpgg_table[chan].add2 := event[chan].effect MOD 16; end; end else If (event[chan].note = 0) and (event_table[chan].note AND $7f in [1..12*8+1]) then begin If NOT (eLo[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio, ef_ArpggVSlide,ef_ArpggVSlideFine]) then arpgg_table[chan].state := 0; arpgg_table[chan].note := event_table[chan].note AND $7f; If (event[chan].effect_def in [ef_Arpeggio,ef_ExtraFineArpeggio]) then begin arpgg_table[chan].add1 := event[chan].effect DIV 16; arpgg_table[chan].add2 := event[chan].effect MOD 16; end; end else effect_table[chan] := 0; end; ef_FSlideUp, ef_FSlideDown, ef_FSlideUpFine, ef_FSlideDownFine: begin effect_table[chan] := concw(event[chan].effect_def,event[chan].effect); fslide_table[chan] := event[chan].effect; end; ef_GlobalFSlideUp, ef_GlobalFSlideDown: begin If (event[chan].effect_def = ef_GlobalFSlideUp) then begin If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, event[chan].effect) else If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then effect_table[chan] := concw(ef_FSlideUpFine,event[chan].effect) else effect_table[chan] := concw(ef_FSlideUp,event[chan].effect); end else begin If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, event[chan].effect) else If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then effect_table[chan] := concw(ef_FSlideDownFine,event[chan].effect) else effect_table[chan] := concw(ef_FSlideDown,event[chan].effect); end; For idx := chan to songdata.nm_tracks do begin fslide_table[idx] := event[chan].effect; glfsld_table[idx] := effect_table[chan]; end; end; ef_FSlideUpVSlide, ef_FSlUpVSlF, ef_FSlideDownVSlide, ef_FSlDownVSlF, ef_FSlUpFineVSlide, ef_FSlUpFineVSlF, ef_FSlDownFineVSlide, ef_FSlDownFineVSlF: If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide, ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF, ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := effect_table[chan] AND $0ff00; ef_TonePortamento: If (event[chan].note in [1..12*8+1]) then begin If (event[chan].effect <> 0) then effect_table[chan] := concw(ef_TonePortamento,event[chan].effect) else If (eLo[chan] = ef_TonePortamento) and (eHi[chan] <> 0) then effect_table[chan] := concw(ef_TonePortamento,eHi[chan]) else effect_table[chan] := ef_TonePortamento; porta_table[chan].speed := HI(effect_table[chan]); porta_table[chan].freq := nFreq(event[chan].note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12)); end else If (eLo[chan] = ef_TonePortamento) then begin If (event[chan].effect <> 0) then effect_table[chan] := concw(ef_TonePortamento,event[chan].effect) else If (eLo[chan] = ef_TonePortamento) and (eHi[chan] <> 0) then effect_table[chan] := concw(ef_TonePortamento,eHi[chan]) else effect_table[chan] := ef_TonePortamento; porta_table[chan].speed := HI(effect_table[chan]); end; ef_TPortamVolSlide, ef_TPortamVSlideFine: If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := effect_table[chan] AND $0ff00; ef_Vibrato, ef_ExtraFineVibrato: begin If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := event[chan].effect_def; If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then vibr_table[chan].fine := TRUE; vibr_table[chan].speed := HI(effect_table[chan]) DIV 16; vibr_table[chan].depth := HI(effect_table[chan]) MOD 16; end; ef_Tremolo, ef_ExtraFineTremolo: begin If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and (eHi[chan] <> 0) then effect_table[chan] := concw(event[chan].effect_def,eHi[chan]) else effect_table[chan] := event[chan].effect_def; If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then trem_table[chan].fine := TRUE; trem_table[chan].speed := HI(effect_table[chan]) DIV 16; trem_table[chan].depth := HI(effect_table[chan]) MOD 16; end; ef_VibratoVolSlide, ef_VibratoVSlideFine: begin If (event[chan].effect <> 0) then effect_table[chan] := concw(event[chan].effect_def,event[chan].effect) else If (eLo[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and (HI(effect_table[chan]) <> 0) then effect_table[chan] := concw(event[chan].effect_def,HI(effect_table[chan])) else effect_table[chan] := effect_table[chan] AND $0ff00; If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then vibr_table[chan].fine := TRUE; end; ef_SetCarrierVol: set_ins_volume(BYTE_NULL,63-event[chan].effect,chan); ef_SetModulatorVol: set_ins_volume(63-event[chan].effect,BYTE_NULL,chan); ef_SetInsVolume: If _4op_vol_valid_chan(chan) then set_ins_volume_4op(63-event[chan].effect,chan) else If percussion_mode and (chan in [17..20]) then set_ins_volume(63-event[chan].effect,BYTE_NULL,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(BYTE_NULL,63-event[chan].effect,chan) else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan); ef_ForceInsVolume: If percussion_mode and (chan in [17..20]) then set_ins_volume(63-event[chan].effect,BYTE_NULL,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect),63-event[chan].effect,chan) else set_ins_volume(63-event[chan].effect,63-event[chan].effect,chan); ef_PositionJump: If no_loop(chan,current_line) then begin pattern_break := TRUE; next_line := pattern_break_flag+chan; end; ef_PatternBreak: If no_loop(chan,current_line) then begin pattern_break := TRUE; seek_pattern_break := TRUE; next_line := max(event[chan].effect,PRED(songdata.patt_len)); end; ef_SetSpeed: speed := event[chan].effect; ef_SetTempo: update_timer(event[chan].effect); ef_SetWaveform: begin If (event[chan].effect DIV 16 in [0..7]) then begin fmpar_table[chan].adsrw_car.wform := event[chan].effect DIV 16; update_carrier_adsrw(chan); end; If (event[chan].effect MOD 16 in [0..7]) then begin fmpar_table[chan].adsrw_mod.wform := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; end; ef_VolSlide: effect_table[chan] := concw(ef_VolSlide,event[chan].effect); ef_VolSlideFine: effect_table[chan] := concw(ef_VolSlideFine,event[chan].effect); ef_RetrigNote: If (event[chan].effect <> 0) then begin If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then retrig_table[chan] := 1; effect_table[chan] := concw(ef_RetrigNote,event[chan].effect); end; ef_SetGlobalVolume: begin global_volume := event[chan].effect; set_global_volume; end; ef_MultiRetrigNote: If (event[chan].effect DIV 16 <> 0) then begin If NOT (eLo[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then retrig_table[chan] := 1; effect_table[chan] := concw(ef_MultiRetrigNote,event[chan].effect); end; ef_Tremor: If (event[chan].effect DIV 16 <> 0) and (event[chan].effect MOD 16 <> 0) then begin If (eLo[chan] <> ef_Tremor) then begin tremor_table[chan].pos := 0; tremor_table[chan].volume := volume_table[chan]; end; effect_table[chan] := concw(ef_Tremor,event[chan].effect); end; ef_Extended: Case (event[chan].effect DIV 16) of ef_ex_SetTremDepth: Case (event[chan].effect MOD 16) of 0: begin opl3out(_instr[11],misc_register AND $07f); current_tremolo_depth := 0; end; 1: begin opl3out(_instr[11],misc_register OR $080); current_tremolo_depth := 1; end; end; ef_ex_SetVibDepth: Case (event[chan].effect MOD 16) of 0: begin opl3out(_instr[11],misc_register AND $0bf); current_vibrato_depth := 0; end; 1: begin opl3out(_instr[11],misc_register OR $040); current_vibrato_depth := 1; end; end; ef_ex_SetAttckRateM: begin fmpar_table[chan].adsrw_mod.attck := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetDecayRateM: begin fmpar_table[chan].adsrw_mod.dec := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetSustnLevelM: begin fmpar_table[chan].adsrw_mod.sustn := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetRelRateM: begin fmpar_table[chan].adsrw_mod.rel := event[chan].effect MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetAttckRateC: begin fmpar_table[chan].adsrw_car.attck := event[chan].effect MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetDecayRateC: begin fmpar_table[chan].adsrw_car.dec := event[chan].effect MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetSustnLevelC: begin fmpar_table[chan].adsrw_car.sustn := event[chan].effect MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetRelRateC: begin fmpar_table[chan].adsrw_car.rel := event[chan].effect MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetFeedback: begin fmpar_table[chan].feedb := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex_SetPanningPos: begin panning_table[chan] := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex_PatternLoop, ef_ex_PatternLoopRec: If (event[chan].effect MOD 16 = 0) then loopbck_table[chan] := current_line else If (loopbck_table[chan] <> BYTE_NULL) then begin If (loop_table[chan][current_line] = BYTE_NULL) then loop_table[chan][current_line] := event[chan].effect MOD 16; If (loop_table[chan][current_line] <> 0) then begin pattern_break := TRUE; next_line := pattern_loop_flag+chan; end else If (event[chan].effect DIV 16 = ef_ex_PatternLoopRec) then loop_table[chan][current_line] := BYTE_NULL; end; ef_ex_ExtendedCmd: Case (event[chan].effect MOD 16) of ef_ex_cmd_MKOffLoopDi: keyoff_loop[chan] := FALSE; ef_ex_cmd_MKOffLoopEn: keyoff_loop[chan] := TRUE; ef_ex_cmd_TPortaFKdis: portaFK_table[chan] := FALSE; ef_ex_cmd_TPortaFKenb: portaFK_table[chan] := TRUE; ef_ex_cmd_RestartEnv: begin key_on(chan); change_freq(chan,freq_table[chan]); end; ef_ex_cmd_4opVlockOff: If is_4op_chan(chan) then begin vol4op_lock[chan] := FALSE; If (chan in _4op_tracks_hi) then vol4op_lock[SUCC(chan)] := FALSE else vol4op_lock[PRED(chan)] := FALSE; end; ef_ex_cmd_4opVlockOn: If is_4op_chan(chan) then begin vol4op_lock[chan] := TRUE; If (chan in _4op_tracks_hi) then vol4op_lock[SUCC(chan)] := TRUE else vol4op_lock[PRED(chan)] := TRUE; end; end; ef_ex_ExtendedCmd2: Case (event[chan].effect MOD 16) of ef_ex_cmd2_RSS: release_sustaining_sound(chan); ef_ex_cmd2_ResetVol: reset_ins_volume(chan); ef_ex_cmd2_LockVol: volume_lock [chan] := TRUE; ef_ex_cmd2_UnlockVol: volume_lock [chan] := FALSE; ef_ex_cmd2_LockVP: peak_lock [chan] := TRUE; ef_ex_cmd2_UnlockVP: peak_lock [chan] := FALSE; ef_ex_cmd2_VSlide_def: volslide_type[chan] := 0; ef_ex_cmd2_LockPan: pan_lock [chan] := TRUE; ef_ex_cmd2_UnlockPan: pan_lock [chan] := FALSE; ef_ex_cmd2_VibrOff: change_frequency(chan,freq_table[chan]); ef_ex_cmd2_TremOff: If is_4op_chan(chan) then set_ins_volume_4op(BYTE_NULL,chan) else set_ins_volume(LO(volume_table[chan]), HI(volume_table[chan]),chan); ef_ex_cmd2_VSlide_car: If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ ef_ex_cmd2_VSlide_mod) then volslide_type[chan] := 3 else volslide_type[chan] := 1; ef_ex_cmd2_VSlide_mod: If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 = ef_ex_ExtendedCmd2*16+ ef_ex_cmd2_VSlide_car) then volslide_type[chan] := 3 else volslide_type[chan] := 2; end; end; ef_Extended2: Case (event[chan].effect DIV 16) of ef_ex2_PatDelayFrame, ef_ex2_PatDelayRow: begin pattern_delay := TRUE; If (event[chan].effect DIV 16 = ef_ex2_PatDelayFrame) then tickD := (event[chan].effect MOD 16) else tickD := speed*(event[chan].effect MOD 16); end; ef_ex2_NoteDelay: begin effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0); notedel_table[chan] := event[chan].effect MOD 16; end; ef_ex2_NoteCut: begin effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0); notecut_table[chan] := event[chan].effect MOD 16; end; ef_ex2_FineTuneUp: Inc(ftune_table[chan],event[chan].effect MOD 16); ef_ex2_FineTuneDown: Dec(ftune_table[chan],event[chan].effect MOD 16); ef_ex2_GlVolSlideUp: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp, event[chan].effect MOD 16); ef_ex2_GlVolSlideDn: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn, event[chan].effect MOD 16); ef_ex2_GlVolSlideUpF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF, event[chan].effect MOD 16); ef_ex2_GlVolSlideDnF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF, event[chan].effect MOD 16); ef_ex2_GlVolSldUpXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF, event[chan].effect MOD 16); ef_ex2_GlVolSldDnXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF, event[chan].effect MOD 16); ef_ex2_VolSlideUpXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF, event[chan].effect MOD 16); ef_ex2_VolSlideDnXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF, event[chan].effect MOD 16); ef_ex2_FreqSlideUpXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, event[chan].effect MOD 16); ef_ex2_FreqSlideDnXF: effect_table[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, event[chan].effect MOD 16); end; ef_Extended3: Case (event[chan].effect DIV 16) of ef_ex3_SetConnection: begin fmpar_table[chan].connect := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetMultipM: begin fmpar_table[chan].multipM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetKslM: begin fmpar_table[chan].kslM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetTremoloM: begin fmpar_table[chan].tremM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetVibratoM: begin fmpar_table[chan].vibrM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetKsrM: begin fmpar_table[chan].ksrM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetSustainM: begin fmpar_table[chan].sustM := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetMultipC: begin fmpar_table[chan].multipC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetKslC: begin fmpar_table[chan].kslC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetTremoloC: begin fmpar_table[chan].tremC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetVibratoC: begin fmpar_table[chan].vibrC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetKsrC: begin fmpar_table[chan].ksrC := event[chan].effect MOD 16; update_fmpar(chan); end; ef_ex3_SetSustainC: begin fmpar_table[chan].sustC := event[chan].effect MOD 16; update_fmpar(chan); end; end; end; For chan := 1 to songdata.nm_tracks do Case event[chan].effect_def2 of ef_Arpeggio, ef_ExtraFineArpeggio, ef_ArpggVSlide, ef_ArpggVSlideFine: If (event[chan].effect_def2 <> ef_Arpeggio) or (event[chan].effect2 <> 0) then begin Case event[chan].effect_def2 of ef_Arpeggio: effect_table2[chan] := concw(ef_Arpeggio+ef_fix1,event[chan].effect2); ef_ExtraFineArpeggio: effect_table2[chan] := concw(ef_ExtraFineArpeggio,event[chan].effect2); ef_ArpggVSlide, ef_ArpggVSlideFine: If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_ArpggVSlide,ef_ArpggVSlideFine]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := effect_table2[chan] AND $0ff00; end; If (event[chan].note AND $7f in [1..12*8+1]) then begin arpgg_table2[chan].state := 0; arpgg_table2[chan].note := event[chan].note AND $7f; If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then begin arpgg_table2[chan].add1 := event[chan].effect2 DIV 16; arpgg_table2[chan].add2 := event[chan].effect2 MOD 16; end; end else If (event[chan].note = 0) and (event_table[chan].note AND $7f in [1..12*8+1]) then begin If NOT (eLo2[chan] in [ef_Arpeggio+ef_fix1,ef_ExtraFineArpeggio, ef_ArpggVSlide,ef_ArpggVSlideFine]) then arpgg_table2[chan].state := 0; arpgg_table2[chan].note := event_table[chan].note AND $7f; If (event[chan].effect_def2 in [ef_Arpeggio,ef_ExtraFineArpeggio]) then begin arpgg_table2[chan].add1 := event[chan].effect2 DIV 16; arpgg_table2[chan].add2 := event[chan].effect2 MOD 16; end; end else effect_table2[chan] := 0; end; ef_FSlideUp, ef_FSlideDown, ef_FSlideUpFine, ef_FSlideDownFine: begin effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2); fslide_table2[chan] := event[chan].effect2; end; ef_GlobalFSlideUp, ef_GlobalFSlideDown: begin If (event[chan].effect_def2 = ef_GlobalFSlideUp) then begin If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, event[chan].effect2) else If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then effect_table2[chan] := concw(ef_FSlideUpFine,event[chan].effect2) else effect_table2[chan] := concw(ef_FSlideUp,event[chan].effect2); end else begin If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, event[chan].effect2) else If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then effect_table2[chan] := concw(ef_FSlideDownFine,event[chan].effect2) else effect_table2[chan] := concw(ef_FSlideDown,event[chan].effect2); end; For idx := chan to songdata.nm_tracks do begin fslide_table2[idx] := event[chan].effect2; glfsld_table2[idx] := effect_table2[chan]; end; end; ef_FSlideUpVSlide, ef_FSlUpVSlF, ef_FSlideDownVSlide, ef_FSlDownVSlF, ef_FSlUpFineVSlide, ef_FSlUpFineVSlF, ef_FSlDownFineVSlide, ef_FSlDownFineVSlF: If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_FSlideUpVSlide,ef_FSlUpVSlF,ef_FSlideDownVSlide, ef_FSlDownVSlF,ef_FSlUpFineVSlide,ef_FSlUpFineVSlF, ef_FSlDownFineVSlide,ef_FSlDownFineVSlF]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := effect_table2[chan] AND $0ff00; ef_TonePortamento: If (event[chan].note in [1..12*8+1]) then begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2) else If (eLo2[chan] = ef_TonePortamento) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan]) else effect_table2[chan] := ef_TonePortamento; porta_table2[chan].speed := HI(effect_table2[chan]); porta_table2[chan].freq := nFreq(event[chan].note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12)); end else If (eLo2[chan] = ef_TonePortamento) then begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(ef_TonePortamento,event[chan].effect2) else If (eLo2[chan] = ef_TonePortamento) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(ef_TonePortamento,eHi2[chan]) else effect_table2[chan] := ef_TonePortamento; porta_table2[chan].speed := HI(effect_table2[chan]); end; ef_TPortamVolSlide, ef_TPortamVSlideFine: If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_TPortamVolSlide,ef_TPortamVSlideFine]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := effect_table2[chan] AND $0ff00; ef_Vibrato, ef_ExtraFineVibrato: begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_Vibrato,ef_ExtraFineVibrato]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := event[chan].effect_def2; If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then vibr_table2[chan].fine := TRUE; vibr_table2[chan].speed := HI(effect_table2[chan]) DIV 16; vibr_table2[chan].depth := HI(effect_table2[chan]) MOD 16; end; ef_Tremolo, ef_ExtraFineTremolo: begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_Tremolo,ef_ExtraFineTremolo]) and (eHi2[chan] <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,eHi2[chan]) else effect_table2[chan] := event[chan].effect_def2; If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FTrm_XFGFS) then trem_table2[chan].fine := TRUE; trem_table2[chan].speed := HI(effect_table2[chan]) DIV 16; trem_table2[chan].depth := HI(effect_table2[chan]) MOD 16; end; ef_VibratoVolSlide, ef_VibratoVSlideFine: begin If (event[chan].effect2 <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,event[chan].effect2) else If (eLo2[chan] in [ef_VibratoVolSlide,ef_VibratoVSlideFine]) and (HI(effect_table2[chan]) <> 0) then effect_table2[chan] := concw(event[chan].effect_def2,HI(effect_table2[chan])) else effect_table2[chan] := effect_table2[chan] AND $0ff00; If (event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ef_ex_cmd2_FVib_FGFS) then vibr_table2[chan].fine := TRUE; end; ef_SetCarrierVol: set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan); ef_SetModulatorVol: set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan); ef_SetInsVolume: If _4op_vol_valid_chan(chan) then set_ins_volume_4op(63-event[chan].effect2,chan) else If percussion_mode and (chan in [17..20]) then set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(BYTE_NULL,63-event[chan].effect2,chan) else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan); ef_ForceInsVolume: If percussion_mode and (chan in [17..20]) then set_ins_volume(63-event[chan].effect2,BYTE_NULL,chan) else If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(scale_volume(ins_parameter(voice_table[chan],2) AND $3f,63-event[chan].effect2),63-event[chan].effect2,chan) else set_ins_volume(63-event[chan].effect2,63-event[chan].effect2,chan); ef_PositionJump: If no_loop(chan,current_line) then begin pattern_break := TRUE; next_line := pattern_break_flag+chan; end; ef_PatternBreak: If no_loop(chan,current_line) then begin pattern_break := TRUE; seek_pattern_break := TRUE; next_line := max(event[chan].effect2,PRED(songdata.patt_len)); end; ef_SetSpeed: speed := event[chan].effect2; ef_SetTempo: update_timer(event[chan].effect2); ef_SetWaveform: begin If (event[chan].effect2 DIV 16 in [0..7]) then begin fmpar_table[chan].adsrw_car.wform := event[chan].effect2 DIV 16; update_carrier_adsrw(chan); end; If (event[chan].effect2 MOD 16 in [0..7]) then begin fmpar_table[chan].adsrw_mod.wform := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; end; ef_VolSlide: effect_table2[chan] := concw(ef_VolSlide,event[chan].effect2); ef_VolSlideFine: effect_table2[chan] := concw(ef_VolSlideFine,event[chan].effect2); ef_RetrigNote: If (event[chan].effect2 <> 0) then begin If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then retrig_table2[chan] := 1; effect_table2[chan] := concw(ef_RetrigNote,event[chan].effect2); end; ef_SetGlobalVolume: begin global_volume := event[chan].effect2; set_global_volume; end; ef_MultiRetrigNote: If (event[chan].effect2 DIV 16 <> 0) then begin If NOT (eLo2[chan] in [ef_RetrigNote,ef_MultiRetrigNote]) then retrig_table2[chan] := 1; effect_table2[chan] := concw(ef_MultiRetrigNote,event[chan].effect2); end; ef_Tremor: If (event[chan].effect2 DIV 16 <> 0) and (event[chan].effect2 MOD 16 <> 0) then begin If (eLo2[chan] <> ef_Tremor) then begin tremor_table2[chan].pos := 0; tremor_table2[chan].volume := volume_table[chan]; end; effect_table2[chan] := concw(ef_Tremor,event[chan].effect2); end; ef_Extended: Case (event[chan].effect2 DIV 16) of ef_ex_SetTremDepth: Case (event[chan].effect2 MOD 16) of 0: begin opl3out(_instr[11],misc_register AND $07f); current_tremolo_depth := 0; end; 1: begin opl3out(_instr[11],misc_register OR $080); current_tremolo_depth := 1; end; end; ef_ex_SetVibDepth: Case (event[chan].effect2 MOD 16) of 0: begin opl3out(_instr[11],misc_register AND $0bf); current_vibrato_depth := 0; end; 1: begin opl3out(_instr[11],misc_register OR $040); current_vibrato_depth := 1; end; end; ef_ex_SetAttckRateM: begin fmpar_table[chan].adsrw_mod.attck := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetDecayRateM: begin fmpar_table[chan].adsrw_mod.dec := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetSustnLevelM: begin fmpar_table[chan].adsrw_mod.sustn := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetRelRateM: begin fmpar_table[chan].adsrw_mod.rel := event[chan].effect2 MOD 16; update_modulator_adsrw(chan); end; ef_ex_SetAttckRateC: begin fmpar_table[chan].adsrw_car.attck := event[chan].effect2 MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetDecayRateC: begin fmpar_table[chan].adsrw_car.dec := event[chan].effect2 MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetSustnLevelC: begin fmpar_table[chan].adsrw_car.sustn := event[chan].effect2 MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetRelRateC: begin fmpar_table[chan].adsrw_car.rel := event[chan].effect2 MOD 16; update_carrier_adsrw(chan); end; ef_ex_SetFeedback: begin fmpar_table[chan].feedb := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex_SetPanningPos: begin panning_table[chan] := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex_PatternLoop, ef_ex_PatternLoopRec: If (event[chan].effect2 MOD 16 = 0) then loopbck_table[chan] := current_line else If (loopbck_table[chan] <> BYTE_NULL) then begin If (loop_table[chan][current_line] = BYTE_NULL) then loop_table[chan][current_line] := event[chan].effect2 MOD 16; If (loop_table[chan][current_line] <> 0) then begin pattern_break := TRUE; next_line := pattern_loop_flag+chan; end else If (event[chan].effect2 DIV 16 = ef_ex_PatternLoopRec) then loop_table[chan][current_line] := BYTE_NULL; end; ef_ex_ExtendedCmd: Case (event[chan].effect2 MOD 16) of ef_ex_cmd_MKOffLoopDi: keyoff_loop[chan] := FALSE; ef_ex_cmd_MKOffLoopEn: keyoff_loop[chan] := TRUE; ef_ex_cmd_TPortaFKdis: portaFK_table[chan] := FALSE; ef_ex_cmd_TPortaFKenb: portaFK_table[chan] := TRUE; ef_ex_cmd_RestartEnv: begin key_on(chan); change_freq(chan,freq_table[chan]); end; ef_ex_cmd_4opVlockOff: If is_4op_chan(chan) then begin vol4op_lock[chan] := FALSE; If (chan in _4op_tracks_hi) then vol4op_lock[SUCC(chan)] := FALSE else vol4op_lock[PRED(chan)] := FALSE; end; ef_ex_cmd_4opVlockOn: If is_4op_chan(chan) then begin vol4op_lock[chan] := TRUE; If (chan in _4op_tracks_hi) then vol4op_lock[SUCC(chan)] := TRUE else vol4op_lock[PRED(chan)] := TRUE; end; end; ef_ex_ExtendedCmd2: Case (event[chan].effect2 MOD 16) of ef_ex_cmd2_RSS: release_sustaining_sound(chan); ef_ex_cmd2_ResetVol: reset_ins_volume(chan); ef_ex_cmd2_LockVol: volume_lock [chan] := TRUE; ef_ex_cmd2_UnlockVol: volume_lock [chan] := FALSE; ef_ex_cmd2_LockVP: peak_lock [chan] := TRUE; ef_ex_cmd2_UnlockVP: peak_lock [chan] := FALSE; ef_ex_cmd2_VSlide_def: volslide_type[chan] := 0; ef_ex_cmd2_LockPan: pan_lock [chan] := TRUE; ef_ex_cmd2_UnlockPan: pan_lock [chan] := FALSE; ef_ex_cmd2_VibrOff: change_frequency(chan,freq_table[chan]); ef_ex_cmd2_TremOff: If _4op_vol_valid_chan(chan) then set_ins_volume_4op(BYTE_NULL,chan) else set_ins_volume(LO(volume_table[chan]), HI(volume_table[chan]),chan); ef_ex_cmd2_VSlide_car: If NOT ((event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ ef_ex_cmd2_VSlide_mod)) then volslide_type[chan] := 1; ef_ex_cmd2_VSlide_mod: If NOT ((event[chan].effect_def = ef_Extended) and (event[chan].effect = ef_ex_ExtendedCmd2*16+ ef_ex_cmd2_VSlide_car)) then volslide_type[chan] := 2; end; end; ef_Extended2: Case (event[chan].effect2 DIV 16) of ef_ex2_PatDelayFrame, ef_ex2_PatDelayRow: begin pattern_delay := TRUE; If (event[chan].effect2 DIV 16 = ef_ex2_PatDelayFrame) then tickD := (event[chan].effect2 MOD 16) else tickD := speed*(event[chan].effect2 MOD 16); end; ef_ex2_NoteDelay: begin effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteDelay,0); notedel_table[chan] := event[chan].effect2 MOD 16; end; ef_ex2_NoteCut: begin effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_NoteCut,0); notecut_table[chan] := event[chan].effect2 MOD 16; end; ef_ex2_FineTuneUp: Inc(ftune_table[chan],event[chan].effect2 MOD 16); ef_ex2_FineTuneDown: Dec(ftune_table[chan],event[chan].effect2 MOD 16); ef_ex2_GlVolSlideUp: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp, event[chan].effect2 MOD 16); ef_ex2_GlVolSlideDn: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn, event[chan].effect2 MOD 16); ef_ex2_GlVolSlideUpF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF, event[chan].effect2 MOD 16); ef_ex2_GlVolSlideDnF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF, event[chan].effect2 MOD 16); ef_ex2_GlVolSldUpXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF, event[chan].effect2 MOD 16); ef_ex2_GlVolSldDnXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF, event[chan].effect2 MOD 16); ef_ex2_VolSlideUpXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF, event[chan].effect2 MOD 16); ef_ex2_VolSlideDnXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF, event[chan].effect2 MOD 16); ef_ex2_FreqSlideUpXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF, event[chan].effect2 MOD 16); ef_ex2_FreqSlideDnXF: effect_table2[chan] := concw(ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF, event[chan].effect2 MOD 16); end; ef_Extended3: Case (event[chan].effect2 DIV 16) of ef_ex3_SetConnection: begin fmpar_table[chan].connect := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetMultipM: begin fmpar_table[chan].multipM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetKslM: begin fmpar_table[chan].kslM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetTremoloM: begin fmpar_table[chan].tremM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetVibratoM: begin fmpar_table[chan].vibrM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetKsrM: begin fmpar_table[chan].ksrM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetSustainM: begin fmpar_table[chan].sustM := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetMultipC: begin fmpar_table[chan].multipC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetKslC: begin fmpar_table[chan].kslC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetTremoloC: begin fmpar_table[chan].tremC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetVibratoC: begin fmpar_table[chan].vibrC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetKsrC: begin fmpar_table[chan].ksrC := event[chan].effect2 MOD 16; update_fmpar(chan); end; ef_ex3_SetSustainC: begin fmpar_table[chan].sustC := event[chan].effect2 MOD 16; update_fmpar(chan); end; end; end; For chan := 1 to songdata.nm_tracks do begin tporta_flag := (event[chan].effect_def in [ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine]) or (event[chan].effect_def2 in [ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine]); If (event[chan].effect_def+event[chan].effect = 0) then If (glfsld_table[chan] = 0) then effect_table[chan] := 0 else begin event_table[chan].effect_def := event[chan].effect_def; event_table[chan].effect := event[chan].effect; end; If (event[chan].effect_def2+event[chan].effect2 = 0) then If (glfsld_table2[chan] = 0) then effect_table2[chan] := 0 else begin event_table[chan].effect_def2 := event[chan].effect_def2; event_table[chan].effect2 := event[chan].effect2; end; // treat Tone Portamento based effects // vs. note Key-Off's // vs. step-playing with Spacebar in Pattern Editor window If (event[chan].note = event[chan].note OR keyoff_flag) then key_off(chan) else If NOT (LO(effect_table[chan]) in [ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine, ef_extended2+ef_fix2+ef_ex2_NoteDelay]) and NOT (LO(effect_table2[chan]) in [ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine, ef_extended2+ef_fix2+ef_ex2_NoteDelay]) then If NOT (((event[chan].effect_def2 = ef_SwapArpeggio) or (event[chan].effect_def2 = ef_SwapVibrato)) and (event[chan].effect_def = ef_Extended) and (event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart)) and NOT (((event[chan].effect_def = ef_SwapArpeggio) or (event[chan].effect_def = ef_SwapVibrato)) and (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart)) then If NOT ignore_note_once[chan] then output_note(event[chan].note,voice_table[chan],chan,TRUE,TRUE) else else output_note(event[chan].note,voice_table[chan],chan,TRUE,FALSE) else If NOT single_play and (event[chan].note <> 0) and tporta_flag then If (event_table[chan].note = event_table[chan].note OR keyoff_flag) then If NOT ignore_note_once[chan] then output_note(event_table[chan].note AND NOT keyoff_flag,voice_table[chan],chan,FALSE,TRUE) else else If portaFK_table[chan] then output_note(event_table[chan].note AND NOT keyoff_flag,voice_table[chan],chan,FALSE,TRUE) else If (event[chan].note <> 0) then event_table[chan].note := event[chan].note else else If single_play and NOT (event[chan].note = event[chan].note OR keyoff_flag) and NOT (event_table[chan].note <> 0) and (event[chan].instr_def <> 0) and tporta_flag then output_note(event[chan].note,event[chan].instr_def,chan,FALSE,TRUE) else If (event[chan].note <> 0) then If portaFK_table[chan] and tporta_flag then output_note(event[chan].note,event[chan].instr_def,chan,FALSE,TRUE) else event_table[chan].note := event[chan].note; Case event[chan].effect_def of ef_SwapArpeggio: begin If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart) then begin If (macro_table[chan].arpg_pos > songdata.macro_table[event[chan].effect].arpeggio.length) then macro_table[chan].arpg_pos := songdata.macro_table[event[chan].effect].arpeggio.length; macro_table[chan].arpg_table := event[chan].effect; end else begin macro_table[chan].arpg_count := 1; macro_table[chan].arpg_pos := 0; macro_table[chan].arpg_table := event[chan].effect; macro_table[chan].arpg_note := event_table[chan].note; end; end; ef_SwapVibrato: begin If (event[chan].effect_def2 = ef_Extended) and (event[chan].effect2 DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect2 MOD 16 = ef_ex_cmd2_NoRestart) then begin If (macro_table[chan].vib_table > songdata.macro_table[event[chan].effect].vibrato.length) then macro_table[chan].vib_pos := songdata.macro_table[event[chan].effect].vibrato.length; macro_table[chan].vib_table := event[chan].effect; end else begin macro_table[chan].vib_count := 1; macro_table[chan].vib_pos := 0; macro_table[chan].vib_table := event[chan].effect; macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; end; end; ef_SetCustomSpeedTab: generate_custom_vibrato(event[chan].effect); end; Case event[chan].effect_def2 of ef_SwapArpeggio: begin If (event[chan].effect_def = ef_Extended) and (event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart) then begin If (macro_table[chan].arpg_pos > songdata.macro_table[event[chan].effect2].arpeggio.length) then macro_table[chan].arpg_pos := songdata.macro_table[event[chan].effect2].arpeggio.length; macro_table[chan].arpg_table := event[chan].effect2; end else begin macro_table[chan].arpg_count := 1; macro_table[chan].arpg_pos := 0; macro_table[chan].arpg_table := event[chan].effect2; macro_table[chan].arpg_note := event_table[chan].note; end; end; ef_SwapVibrato: begin If (event[chan].effect_def = ef_Extended) and (event[chan].effect DIV 16 = ef_ex_ExtendedCmd2) and (event[chan].effect MOD 16 = ef_ex_cmd2_NoRestart) then begin If (macro_table[chan].vib_table > songdata.macro_table[event[chan].effect2].vibrato.length) then macro_table[chan].vib_pos := songdata.macro_table[event[chan].effect2].vibrato.length; macro_table[chan].vib_table := event[chan].effect2; end else begin macro_table[chan].vib_count := 1; macro_table[chan].vib_pos := 0; macro_table[chan].vib_table := event[chan].effect2; macro_table[chan].vib_delay := songdata.macro_table[macro_table[chan].vib_table].vibrato.delay; end; end; ef_SetCustomSpeedTab: generate_custom_vibrato(event[chan].effect2); end; update_fine_effects(chan); end; If pattern_delay then begin time_playing := time_playing+1/tempo*tickD; If (time_playing > 3600-1) then time_playing := 0; end else begin time_playing := time_playing+1/tempo*speed; If (time_playing > 3600-1) then time_playing := 0; end; end; procedure portamento_up(chan: Byte; slide: Word; limit: Word); var freq: Word; begin freq := calc_freq_shift_up(freq_table[chan] AND $1fff,slide); If (freq <= limit) then change_frequency(chan,freq) else change_frequency(chan,limit); end; procedure portamento_down(chan: Byte; slide: Word; limit: Word); var freq: Word; begin freq := calc_freq_shift_down(freq_table[chan] AND $1fff,slide); If (freq >= limit) then change_frequency(chan,freq) else change_frequency(chan,limit); end; procedure macro_vibrato__porta_up(chan: Byte; depth: Byte); var freq: Word; begin freq := calc_freq_shift_up(macro_table[chan].vib_freq AND $1fff,depth); If (freq <= nFreq(12*8+1)) then change_freq(chan,freq) else change_freq(chan,nFreq(12*8+1)); end; procedure macro_vibrato__porta_down(chan: Byte; depth: Byte); var freq: Word; begin freq := calc_freq_shift_down(macro_table[chan].vib_freq AND $1fff,depth); If (freq >= nFreq(0)) then change_freq(chan,freq) else change_freq(chan,nFreq(0)); end; procedure tone_portamento(chan: Byte); begin If (freq_table[chan] AND $1fff > porta_table[chan].freq) then portamento_down(chan,porta_table[chan].speed,porta_table[chan].freq) else If (freq_table[chan] AND $1fff < porta_table[chan].freq) then portamento_up(chan,porta_table[chan].speed,porta_table[chan].freq); end; procedure tone_portamento2(chan: Byte); begin If (freq_table[chan] AND $1fff > porta_table2[chan].freq) then portamento_down(chan,porta_table2[chan].speed,porta_table2[chan].freq) else If (freq_table[chan] AND $1fff < porta_table2[chan].freq) then portamento_up(chan,porta_table2[chan].speed,porta_table2[chan].freq); end; procedure slide_carrier_volume_up(chan: Byte; slide,limit: Byte); var vol: Word; vLo,vHi: Byte; begin vLo := LO(volume_table[chan]); vHi := HI(volume_table[chan]); If (vHi-slide >= limit) then vol := concw(vLo,vHi-slide) else vol := concw(vLo,limit); set_ins_volume(BYTE_NULL,HI(vol),chan); volume_table[chan] := vol; end; procedure slide_modulator_volume_up(chan: Byte; slide,limit: Byte); var vol: Word; vLo,vHi: Byte; begin vLo := LO(volume_table[chan]); vHi := HI(volume_table[chan]); If (vLo-slide >= limit) then vol := concw(vLo-slide,vHi) else vol := concw(limit,vHi); set_ins_volume(LO(vol),BYTE_NULL,chan); volume_table[chan] := vol; end; procedure slide_volume_up(chan,slide: Byte); var limit1,limit2: Byte; limit1_4op,limit2_4op: Word; _4op_flag: Dword; _4op_conn: Byte; _4op_ch1,_4op_ch2: Byte; _4op_ins1,_4op_ins2: Byte; begin _4op_flag := _4op_data_flag(chan); _4op_conn := (_4op_flag SHR 1) AND 3; _4op_ch1 := (_4op_flag SHR 3) AND 15; _4op_ch2 := (_4op_flag SHR 7) AND 15; _4op_ins1 := BYTE(_4op_flag SHR 11); _4op_ins2 := BYTE(_4op_flag SHR 19); If _4op_vol_valid_chan(chan) then begin If NOT peak_lock[_4op_ch1] then limit1_4op := 0 else limit1_4op := ins_parameter(_4op_ins1,3) AND $3f SHL 16 + ins_parameter(_4op_ins1,2) AND $3f; If NOT peak_lock[_4op_ch2] then limit2_4op := 0 else limit2_4op := ins_parameter(_4op_ins2,3) AND $3f SHL 16 + ins_parameter(_4op_ins2,2) AND $3f; end else begin If NOT peak_lock[chan] then limit1 := 0 else limit1 := ins_parameter(event_table[chan].instr_def,3) AND $3f; If NOT peak_lock[chan] then limit2 := 0 else limit2 := ins_parameter(event_table[chan].instr_def,2) AND $3f; end; Case volslide_type[chan] of 0: begin If NOT _4op_vol_valid_chan(chan) then begin slide_carrier_volume_up(chan,slide,limit1); If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then slide_modulator_volume_up(chan,slide,limit2); end else Case _4op_conn of // FM/FM 0: slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op)); // FM/AM 1: begin slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op)); slide_modulator_volume_up(_4op_ch2,slide,LO(limit2_4op)); end; // AM/FM 2: begin slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op)); slide_carrier_volume_up(_4op_ch2,slide,HI(limit2_4op)); end; // AM/AM 3: begin slide_carrier_volume_up(_4op_ch1,slide,HI(limit1_4op)); slide_modulator_volume_up(_4op_ch1,slide,LO(limit1_4op)); slide_modulator_volume_up(_4op_ch2,slide,LO(limit2_4op)); end; end; end; 1: slide_carrier_volume_up(chan,slide,limit1); 2: slide_modulator_volume_up(chan,slide,limit2); 3: begin slide_carrier_volume_up(chan,slide,limit1); slide_modulator_volume_up(chan,slide,limit2); end; end; end; procedure slide_carrier_volume_down(chan: Byte; slide: Byte); var vol: Word; vLo,vHi: Byte; begin vLo := LO(volume_table[chan]); vHi := HI(volume_table[chan]); If (vHi+slide <= 63) then vol := concw(vLo,vHi+slide) else vol := concw(vLo,63); set_ins_volume(BYTE_NULL,HI(vol),chan); volume_table[chan] := vol; end; procedure slide_modulator_volume_down(chan: Byte; slide: Byte); var vol: Word; vLo,vHi: Byte; begin vLo := LO(volume_table[chan]); vHi := HI(volume_table[chan]); If (vLo+slide <= 63) then vol := concw(vLo+slide,vHi) else vol := concw(63,vHi); set_ins_volume(LO(vol),BYTE_NULL,chan); volume_table[chan] := vol; end; procedure slide_volume_down(chan,slide: Byte); var _4op_flag: Dword; _4op_conn: Byte; _4op_ch1,_4op_ch2: Byte; begin _4op_flag := _4op_data_flag(chan); _4op_conn := (_4op_flag SHR 1) AND 3; _4op_ch1 := (_4op_flag SHR 3) AND 15; _4op_ch2 := (_4op_flag SHR 7) AND 15; Case volslide_type[chan] of 0: begin If NOT _4op_vol_valid_chan(chan) then begin slide_carrier_volume_down(chan,slide); If (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then slide_modulator_volume_down(chan,slide); end else Case _4op_conn of // FM/FM 0: slide_carrier_volume_down(_4op_ch1,slide); // FM/AM 1: begin slide_carrier_volume_down(_4op_ch1,slide); slide_modulator_volume_down(_4op_ch2,slide); end; // AM/FM 2: begin slide_carrier_volume_down(_4op_ch1,slide); slide_carrier_volume_down(_4op_ch2,slide); end; // AM/AM 3: begin slide_carrier_volume_down(_4op_ch1,slide); slide_modulator_volume_down(_4op_ch1,slide); slide_modulator_volume_down(_4op_ch2,slide); end; end; end; 1: slide_carrier_volume_down(chan,slide); 2: slide_modulator_volume_down(chan,slide); 3: begin slide_carrier_volume_down(chan,slide); slide_modulator_volume_down(chan,slide); end; end; end; procedure volume_slide(chan,up_speed,down_speed: Byte); begin If (up_speed <> 0) then slide_volume_up(chan,up_speed) else If (down_speed <> 0) then slide_volume_down(chan,down_speed); end; procedure global_volume_slide(up_speed,down_speed: Byte); begin If (up_speed <> BYTE_NULL) then global_volume := max(global_volume+up_speed,63); If (down_speed <> BYTE_NULL) then If (global_volume >= down_speed) then Dec(global_volume,down_speed) else global_volume := 0; set_global_volume; end; procedure arpeggio(chan: Byte); const arpgg_state: array[0..2] of Byte = (1,2,0); var freq: Word; begin Case arpgg_table[chan].state of 0: freq := nFreq(arpgg_table[chan].note-1); 1: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add1); 2: freq := nFreq(arpgg_table[chan].note-1 +arpgg_table[chan].add2); end; arpgg_table[chan].state := arpgg_state[arpgg_table[chan].state]; change_frequency(chan,freq+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end; procedure arpeggio2(chan: Byte); const arpgg_state: array[0..2] of Byte = (1,2,0); var freq: Word; begin Case arpgg_table2[chan].state of 0: freq := nFreq(arpgg_table2[chan].note-1); 1: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add1); 2: freq := nFreq(arpgg_table2[chan].note-1 +arpgg_table2[chan].add2); end; arpgg_table2[chan].state := arpgg_state[arpgg_table2[chan].state]; change_frequency(chan,freq+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end; procedure vibrato(chan: Byte); var freq,old_freq: Word; begin Inc(vibr_table[chan].pos,vibr_table[chan].speed*vibtrem_speed_factor); freq := calc_vibtrem_shift(chan,vibr_table); old_freq := freq_table[chan]; If (vibr_table[chan].dir = 0) then portamento_down(chan,freq,nFreq(0)) else portamento_up(chan,freq,nFreq(12*8+1)); freq_table[chan] := old_freq; end; procedure vibrato2(chan: Byte); var freq,old_freq: Word; begin Inc(vibr_table2[chan].pos,vibr_table2[chan].speed*vibtrem_speed_factor); freq := calc_vibtrem_shift(chan,vibr_table2); old_freq := freq_table[chan]; If (vibr_table2[chan].dir = 0) then portamento_down(chan,freq,nFreq(0)) else portamento_up(chan,freq,nFreq(12*8+1)); freq_table[chan] := old_freq; end; procedure tremolo(chan: Byte); var vol,old_vol: Word; begin Inc(trem_table[chan].pos,trem_table[chan].speed*vibtrem_speed_factor); vol := calc_vibtrem_shift(chan,trem_table); old_vol := volume_table[chan]; If (trem_table[chan].dir = 0) then slide_volume_down(chan,vol) else slide_volume_up(chan,vol); volume_table[chan] := old_vol; end; procedure tremolo2(chan: Byte); var vol,old_vol: Word; begin Inc(trem_table2[chan].pos,trem_table2[chan].speed*vibtrem_speed_factor); vol := calc_vibtrem_shift(chan,trem_table2); old_vol := volume_table[chan]; If (trem_table2[chan].pos = 0) then slide_volume_down(chan,vol) else slide_volume_up(chan,vol); volume_table[chan] := old_vol; end; procedure update_effects; var chan,eLo,eHi, eLo2,eHi2: Byte; function chanvol(chan: Byte): Byte; begin If (ins_parameter(voice_table[chan],10) AND 1 = 0) then chanvol := 63-HI(volume_table[chan]) else chanvol := 63-Round((LO(volume_table[chan])+HI(volume_table[chan]))/2); end; begin For chan := 1 to songdata.nm_tracks do begin eLo := LO(effect_table[chan]); eHi := HI(effect_table[chan]); eLo2 := LO(effect_table2[chan]); eHi2 := HI(effect_table2[chan]); Case eLo of ef_Arpeggio+ef_fix1: arpeggio(chan); ef_ArpggVSlide: begin volume_slide(chan,eHi DIV 16,eHi MOD 16); arpeggio(chan); end; ef_ArpggVSlideFine: arpeggio(chan); ef_FSlideUp: portamento_up(chan,eHi,nFreq(12*8+1)); ef_FSlideDown: portamento_down(chan,eHi,nFreq(0)); ef_FSlideUpVSlide: begin portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); volume_slide(chan,eHi DIV 16,eHi MOD 16); end; ef_FSlUpVSlF: portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); ef_FSlideDownVSlide: begin portamento_down(chan,fslide_table[chan],nFreq(0)); volume_slide(chan,eHi DIV 16,eHi MOD 16); end; ef_FSlDownVSlF: portamento_down(chan,fslide_table[chan],nFreq(0)); ef_FSlUpFineVSlide: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_FSlDownFineVSlide: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_TonePortamento: tone_portamento(chan); ef_TPortamVolSlide: begin volume_slide(chan,eHi DIV 16,eHi MOD 16); tone_portamento(chan); end; ef_TPortamVSlideFine: tone_portamento(chan); ef_Vibrato: If NOT vibr_table[chan].fine then vibrato(chan); ef_Tremolo: If NOT trem_table[chan].fine then tremolo(chan); ef_VibratoVolSlide: begin volume_slide(chan,eHi DIV 16,eHi MOD 16); If NOT vibr_table[chan].fine then vibrato(chan); end; ef_VibratoVSlideFine: If NOT vibr_table[chan].fine then vibrato(chan); ef_VolSlide: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_RetrigNote: If (retrig_table[chan] >= eHi) then begin retrig_table[chan] := 0; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Inc(retrig_table[chan]); ef_MultiRetrigNote: If (retrig_table[chan] >= eHi DIV 16) then begin Case eHi MOD 16 of 0,8: ; 1: slide_volume_down(chan,1); 2: slide_volume_down(chan,2); 3: slide_volume_down(chan,4); 4: slide_volume_down(chan,8); 5: slide_volume_down(chan,16); 9: slide_volume_up(chan,1); 10: slide_volume_up(chan,2); 11: slide_volume_up(chan,4); 12: slide_volume_up(chan,8); 13: slide_volume_up(chan,16); 6: slide_volume_down(chan,chanvol(chan)- Round(chanvol(chan)*2/3)); 7: slide_volume_down(chan,chanvol(chan)- Round(chanvol(chan)*1/2)); 14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)- chanvol(chan),63)); 15: slide_volume_up(chan,max(Round(chanvol(chan)*2)- chanvol(chan),63)); end; retrig_table[chan] := 0; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Inc(retrig_table[chan]); ef_Tremor: If (tremor_table[chan].pos >= 0) then begin If (SUCC(tremor_table[chan].pos) <= eHi DIV 16) then Inc(tremor_table[chan].pos) else begin slide_volume_down(chan,63); tremor_table[chan].pos := -1; end; end else If (PRED(tremor_table[chan].pos) >= -(eHi MOD 16)) then Dec(tremor_table[chan].pos) else begin set_ins_volume(LO(tremor_table[chan].volume), HI(tremor_table[chan].volume),chan); tremor_table[chan].pos := 1; end; ef_extended2+ef_fix2+ef_ex2_NoteDelay: If (notedel_table[chan] = 0) then begin notedel_table[chan] := BYTE_NULL; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Dec(notedel_table[chan]); ef_extended2+ef_fix2+ef_ex2_NoteCut: If (notecut_table[chan] = 0) then begin notecut_table[chan] := BYTE_NULL; key_off(chan); end else Dec(notecut_table[chan]); ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp: global_volume_slide(eHi,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn: global_volume_slide(BYTE_NULL,eHi); end; Case eLo2 of ef_Arpeggio+ef_fix1: arpeggio2(chan); ef_ArpggVSlide: begin volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); arpeggio2(chan); end; ef_ArpggVSlideFine: arpeggio2(chan); ef_FSlideUp: portamento_up(chan,eHi2,nFreq(12*8+1)); ef_FSlideDown: portamento_down(chan,eHi2,nFreq(0)); ef_FSlideUpVSlide: begin portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); end; ef_FSlUpVSlF: portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); ef_FSlideDownVSlide: begin portamento_down(chan,fslide_table2[chan],nFreq(0)); volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); end; ef_FSlDownVSlF: portamento_down(chan,fslide_table2[chan],nFreq(0)); ef_FSlUpFineVSlide: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_FSlDownFineVSlide: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_TonePortamento: tone_portamento2(chan); ef_TPortamVolSlide: begin volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); tone_portamento2(chan); end; ef_TPortamVSlideFine: tone_portamento2(chan); ef_Vibrato: If NOT vibr_table2[chan].fine then vibrato2(chan); ef_Tremolo: If NOT trem_table2[chan].fine then tremolo2(chan); ef_VibratoVolSlide: begin volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); If NOT vibr_table2[chan].fine then vibrato2(chan); end; ef_VibratoVSlideFine: If NOT vibr_table2[chan].fine then vibrato2(chan); ef_VolSlide: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_RetrigNote: If (retrig_table2[chan] >= eHi2) then begin retrig_table2[chan] := 0; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Inc(retrig_table2[chan]); ef_MultiRetrigNote: If (retrig_table2[chan] >= eHi2 DIV 16) then begin Case eHi2 MOD 16 of 0,8: ; 1: slide_volume_down(chan,1); 2: slide_volume_down(chan,2); 3: slide_volume_down(chan,4); 4: slide_volume_down(chan,8); 5: slide_volume_down(chan,16); 9: slide_volume_up(chan,1); 10: slide_volume_up(chan,2); 11: slide_volume_up(chan,4); 12: slide_volume_up(chan,8); 13: slide_volume_up(chan,16); 6: slide_volume_down(chan,chanvol(chan)- Round(chanvol(chan)*2/3)); 7: slide_volume_down(chan,chanvol(chan)- Round(chanvol(chan)*1/2)); 14: slide_volume_up(chan,max(Round(chanvol(chan)*3/2)- chanvol(chan),63)); 15: slide_volume_up(chan,max(Round(chanvol(chan)*2)- chanvol(chan),63)); end; retrig_table2[chan] := 0; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Inc(retrig_table2[chan]); ef_Tremor: If (tremor_table2[chan].pos >= 0) then begin If (SUCC(tremor_table2[chan].pos) <= eHi2 DIV 16) then Inc(tremor_table2[chan].pos) else begin slide_volume_down(chan,63); tremor_table2[chan].pos := -1; end; end else If (PRED(tremor_table2[chan].pos) >= -(eHi2 MOD 16)) then Dec(tremor_table2[chan].pos) else begin set_ins_volume(LO(tremor_table2[chan].volume), HI(tremor_table2[chan].volume),chan); tremor_table2[chan].pos := 1; end; ef_extended2+ef_fix2+ef_ex2_NoteDelay: If (notedel_table[chan] = 0) then begin notedel_table[chan] := BYTE_NULL; output_note(event_table[chan].note, event_table[chan].instr_def,chan,TRUE,TRUE); end else Dec(notedel_table[chan]); ef_extended2+ef_fix2+ef_ex2_NoteCut: If (notecut_table[chan] = 0) then begin notecut_table[chan] := BYTE_NULL; key_off(chan); end else Dec(notecut_table[chan]); ef_extended2+ef_fix2+ef_ex2_GlVolSlideUp: global_volume_slide(eHi2,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSlideDn: global_volume_slide(BYTE_NULL,eHi2); end; end; end; procedure update_fine_effects(chan: Byte); var eLo,eHi, eLo2,eHi2: Byte; begin eLo := LO(effect_table[chan]); eHi := HI(effect_table[chan]); eLo2 := LO(effect_table2[chan]); eHi2 := HI(effect_table2[chan]); Case eLo of ef_ArpggVSlideFine: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_FSlideUpFine: portamento_up(chan,eHi,nFreq(12*8+1)); ef_FSlideDownFine: portamento_down(chan,eHi,nFreq(0)); ef_FSlUpVSlF: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_FSlDownVSlF: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_FSlUpFineVSlide: portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); ef_FSlUpFineVSlF: begin portamento_up(chan,fslide_table[chan],nFreq(12*8+1)); volume_slide(chan,eHi DIV 16,eHi MOD 16); end; ef_FSlDownFineVSlide: portamento_down(chan,fslide_table[chan],nFreq(0)); ef_FSlDownFineVSlF: begin portamento_down(chan,fslide_table[chan],nFreq(0)); volume_slide(chan,eHi DIV 16,eHi MOD 16); end; ef_TPortamVSlideFine: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_Vibrato: If vibr_table[chan].fine then vibrato(chan); ef_Tremolo: If trem_table[chan].fine then tremolo(chan); ef_VibratoVolSlide: If vibr_table[chan].fine then vibrato(chan); ef_VibratoVSlideFine: begin volume_slide(chan,eHi DIV 16,eHi MOD 16); If vibr_table[chan].fine then vibrato(chan); end; ef_VolSlideFine: volume_slide(chan,eHi DIV 16,eHi MOD 16); ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF: global_volume_slide(eHi,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF: global_volume_slide(BYTE_NULL,eHi); end; Case eLo2 of ef_ArpggVSlideFine: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_FSlideUpFine: portamento_up(chan,eHi2,nFreq(12*8+1)); ef_FSlideDownFine: portamento_down(chan,eHi2,nFreq(0)); ef_FSlUpVSlF: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_FSlDownVSlF: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_FSlUpFineVSlide: portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); ef_FSlUpFineVSlF: begin portamento_up(chan,fslide_table2[chan],nFreq(12*8+1)); volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); end; ef_FSlDownFineVSlide: portamento_down(chan,fslide_table2[chan],nFreq(0)); ef_FSlDownFineVSlF: begin portamento_down(chan,fslide_table2[chan],nFreq(0)); volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); end; ef_TPortamVSlideFine: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_Vibrato: If vibr_table2[chan].fine then vibrato2(chan); ef_Tremolo: If trem_table2[chan].fine then tremolo2(chan); ef_VibratoVolSlide: If vibr_table2[chan].fine then vibrato2(chan); ef_VibratoVSlideFine: begin volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); If vibr_table2[chan].fine then vibrato2(chan); end; ef_VolSlideFine: volume_slide(chan,eHi2 DIV 16,eHi2 MOD 16); ef_extended2+ef_fix2+ef_ex2_GlVolSlideUpF: global_volume_slide(eHi2,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSlideDnF: global_volume_slide(BYTE_NULL,eHi2); end; end; procedure update_extra_fine_effects; var chan,eLo,eHi, eLo2,eHi2: Byte; begin For chan := 1 to songdata.nm_tracks do begin eLo := LO(effect_table[chan]); eHi := HI(effect_table[chan]); eLo2 := LO(effect_table2[chan]); eHi2 := HI(effect_table2[chan]); Case eLo of ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF: global_volume_slide(eHi,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF: global_volume_slide(BYTE_NULL,eHi); ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF: volume_slide(chan,eHi,0); ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF: volume_slide(chan,0,eHi); ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF: portamento_up(chan,eHi,nFreq(12*8+1)); ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF: portamento_down(chan,eHi,nFreq(0)); ef_ExtraFineArpeggio: arpeggio(chan); ef_ExtraFineVibrato: If NOT vibr_table[chan].fine then vibrato(chan); ef_ExtraFineTremolo: If NOT trem_table[chan].fine then tremolo(chan); end; Case eLo2 of ef_extended2+ef_fix2+ef_ex2_GlVolSldUpXF: global_volume_slide(eHi2,BYTE_NULL); ef_extended2+ef_fix2+ef_ex2_GlVolSldDnXF: global_volume_slide(BYTE_NULL,eHi2); ef_extended2+ef_fix2+ef_ex2_VolSlideUpXF: volume_slide(chan,eHi2,0); ef_extended2+ef_fix2+ef_ex2_VolSlideDnXF: volume_slide(chan,0,eHi2); ef_extended2+ef_fix2+ef_ex2_FreqSlideUpXF: portamento_up(chan,eHi2,nFreq(12*8+1)); ef_extended2+ef_fix2+ef_ex2_FreqSlideDnXF: portamento_down(chan,eHi2,nFreq(0)); ef_ExtraFineArpeggio: arpeggio2(chan); ef_ExtraFineVibrato: If NOT vibr_table2[chan].fine then vibrato2(chan); ef_ExtraFineTremolo: If NOT trem_table2[chan].fine then tremolo2(chan); end; end; end; function calc_following_order(order: Byte): Integer; var result: Integer; index,jump_count: Byte; begin result := -1; index := order; jump_count := 0; Repeat If (songdata.pattern_order[index] < $80) then result := index else begin index := songdata.pattern_order[index]-$80; Inc(jump_count); end; until (jump_count > $7f) or (result <> -1); calc_following_order := result; end; function calc_order_jump: Integer; var temp: Byte; result: Integer; begin result := 0; temp := 0; Repeat If (songdata.pattern_order[current_order] > $7f) then current_order := songdata.pattern_order[current_order]-$80; Inc(temp); until (temp > $7f) or (songdata.pattern_order[current_order] < $80); If (temp > $7f) then begin stop_playing; result := -1; end; calc_order_jump := result; end; procedure update_song_position; var temp: Byte; begin For temp := 9 downto 2 do play_pos_buf[temp] := play_pos_buf[temp-1]; play_pos_buf[1] := (current_pattern SHL 8)+current_line; If NOT rewind then begin If (current_line < PRED(songdata.patt_len)) and NOT pattern_break then Inc(current_line) else begin If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and repeat_pattern then begin FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); current_line := 0; pattern_break := FALSE; end else begin If NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag)) and (current_order < $7f) then begin FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); Inc(current_order); end; If pattern_break and (next_line AND $0f0 = pattern_loop_flag) then begin temp := next_line-pattern_loop_flag; next_line := loopbck_table[temp]; If (loop_table[temp][current_line] <> 0) then Dec(loop_table[temp][current_line]); end else If pattern_break and (next_line AND $0f0 = pattern_break_flag) then begin If (event_table[next_line-pattern_break_flag].effect_def2 = ef_PositionJump) then current_order := event_table[next_line-pattern_break_flag].effect2 else current_order := event_table[next_line-pattern_break_flag].effect; pattern_break := FALSE; end else If (current_order > $7f) then current_order := 0; If NOT play_single_patt then If (songdata.pattern_order[current_order] > $7f) then If (calc_order_jump = -1) then EXIT; If NOT play_single_patt then current_pattern := songdata.pattern_order[current_order]; If NOT pattern_break then current_line := 0 else begin pattern_break := FALSE; current_line := next_line; end; end; end; end else If (current_line > 0) then Dec(current_line); For temp := 1 to songdata.nm_tracks do begin ignore_note_once[temp] := FALSE; glfsld_table[temp] := 0; glfsld_table2[temp] := 0; end; If NOT play_single_patt then If (current_line = 0) and (current_order = calc_following_order(0)) and speed_update then begin tempo := songdata.tempo; speed := songdata.speed; update_timer(tempo); end; end; procedure poll_proc; var temp: Byte; factor: Real; {$IFDEF GO32V2} _debug_str_bak_: String; {$ENDIF} begin {$IFDEF GO32V2} _debug_str_bak_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:_poll_proc'; {$ENDIF} If (NOT pattern_delay and (ticks-tick0+1 >= speed)) or fast_forward or rewind or single_play then begin If debugging and NOT single_play and NOT pattern_break and (NOT space_pressed or no_step_debugging) then EXIT; If NOT single_play and NOT play_single_patt then begin If (songdata.pattern_order[current_order] > $7f) then If (calc_order_jump = -1) then EXIT; current_pattern := songdata.pattern_order[current_order]; end; play_line; If NOT single_play and NOT (fast_forward or rewind) then update_effects else For temp := 1 to speed do begin update_effects; If (temp MOD 4 = temp) then update_extra_fine_effects; Inc(ticks); end; tick0 := ticks; If NOT single_play and (fast_forward or rewind or NOT pattern_delay) then update_song_position; If fast_forward or rewind then If NOT pattern_delay then synchronize_song_timer; If (fast_forward or rewind) and pattern_delay then begin tickD := 0; pattern_delay := FALSE; end; If fast_forward or rewind then begin {$IFDEF GO32V2} keyboard_reset_buffer; {$ENDIF} If fast_forward then factor := 1/(5-fforward_factor+1) else factor := 1/(5-rewind_factor+1); If (Abs(time_playing-time_playing0) > factor*(1+(1/255*tempo))/speed) then begin fast_forward := FALSE; rewind := FALSE; time_playing0 := time_playing; synchronize_song_timer; end; end; end else begin update_effects; Inc(ticks); If NOT (debugging and NOT single_play and (NOT space_pressed or no_step_debugging)) then If pattern_delay and (tickD > 1) then Dec(tickD) else begin If pattern_delay and NOT single_play then begin tick0 := ticks; update_song_position; end; pattern_delay := FALSE; end; end; Inc(tickXF); If (tickXF MOD 4 = 0) then begin update_extra_fine_effects; Dec(tickXF,4); end; {$IFDEF GO32V2} _debug_str_ := _debug_str_bak_; {$ENDIF} end; procedure macro_poll_proc; const IDLE = $0fff; FINISHED = $0ffff; var chan: Byte; finished_flag: Word; {$IFDEF GO32V2} var _debug_str_bak_: String; {$ENDIF} begin {$IFDEF GO32V2} _debug_str_bak_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:macro_poll_proc'; {$ENDIF} For chan := 1 to songdata.nm_tracks do begin If NOT keyoff_loop[chan] then finished_flag := FINISHED else finished_flag := IDLE; With macro_table[chan] do begin With songdata.instr_macros[fmreg_table] do If (fmreg_table <> 0) and (speed <> 0) then If (fmreg_duration > 1) then Dec(fmreg_duration) else begin fmreg_count := 1; If (fmreg_pos <= length) then If (loop_begin <> 0) and (loop_length <> 0) then If (fmreg_pos = loop_begin+PRED(loop_length)) then fmreg_pos := loop_begin else If (fmreg_pos < length) then Inc(fmreg_pos) else fmreg_pos := finished_flag else If (fmreg_pos < length) then Inc(fmreg_pos) else fmreg_pos := finished_flag else fmreg_pos := finished_flag; If (freq_table[chan] OR $2000 = freq_table[chan]) and (keyoff_pos <> 0) and (fmreg_pos >= keyoff_pos) then fmreg_pos := IDLE else If (freq_table[chan] OR $2000 <> freq_table[chan]) and (fmreg_pos <> 0) and (keyoff_pos <> 0) and ((fmreg_pos < keyoff_pos) or (fmreg_pos = IDLE)) then fmreg_pos := keyoff_pos; If (fmreg_pos <> 0) and (fmreg_pos <> IDLE) and (fmreg_pos <> finished_flag) then begin fmreg_duration := data[fmreg_pos].duration; If (fmreg_duration <> 0) then With data[fmreg_pos] do begin // force KEY-ON with missing ADSR instrument data force_macro_keyon := FALSE; If (fmreg_pos = 1) then If is_ins_adsr_data_empty(voice_table[chan]) and NOT (songdata.dis_fmreg_col[fmreg_table][0] and songdata.dis_fmreg_col[fmreg_table][1] and songdata.dis_fmreg_col[fmreg_table][2] and songdata.dis_fmreg_col[fmreg_table][3] and songdata.dis_fmreg_col[fmreg_table][12] and songdata.dis_fmreg_col[fmreg_table][13] and songdata.dis_fmreg_col[fmreg_table][14] and songdata.dis_fmreg_col[fmreg_table][15]) then force_macro_keyon := TRUE; If NOT songdata.dis_fmreg_col[fmreg_table][0] then fmpar_table[chan].adsrw_mod.attck := fm_data.ATTCK_DEC_modulator SHR 4; If NOT songdata.dis_fmreg_col[fmreg_table][1] then fmpar_table[chan].adsrw_mod.dec := fm_data.ATTCK_DEC_modulator AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][2] then fmpar_table[chan].adsrw_mod.sustn := fm_data.SUSTN_REL_modulator SHR 4; If NOT songdata.dis_fmreg_col[fmreg_table][3] then fmpar_table[chan].adsrw_mod.rel := fm_data.SUSTN_REL_modulator AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][4] then fmpar_table[chan].adsrw_mod.wform := fm_data.WAVEFORM_modulator AND $07; If NOT songdata.dis_fmreg_col[fmreg_table][6] then fmpar_table[chan].kslM := fm_data.KSL_VOLUM_modulator SHR 6; If NOT songdata.dis_fmreg_col[fmreg_table][7] then fmpar_table[chan].multipM := fm_data.AM_VIB_EG_modulator AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][8] then fmpar_table[chan].tremM := fm_data.AM_VIB_EG_modulator SHR 7; If NOT songdata.dis_fmreg_col[fmreg_table][9] then fmpar_table[chan].vibrM := fm_data.AM_VIB_EG_modulator SHR 6 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][10] then fmpar_table[chan].ksrM := fm_data.AM_VIB_EG_modulator SHR 4 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][11] then fmpar_table[chan].sustM := fm_data.AM_VIB_EG_modulator SHR 5 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][12] then fmpar_table[chan].adsrw_car.attck := fm_data.ATTCK_DEC_carrier SHR 4; If NOT songdata.dis_fmreg_col[fmreg_table][13] then fmpar_table[chan].adsrw_car.dec := fm_data.ATTCK_DEC_carrier AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][14] then fmpar_table[chan].adsrw_car.sustn := fm_data.SUSTN_REL_carrier SHR 4; If NOT songdata.dis_fmreg_col[fmreg_table][15] then fmpar_table[chan].adsrw_car.rel := fm_data.SUSTN_REL_carrier AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][16] then fmpar_table[chan].adsrw_car.wform := fm_data.WAVEFORM_carrier AND $07; If NOT songdata.dis_fmreg_col[fmreg_table][18] then fmpar_table[chan].kslC := fm_data.KSL_VOLUM_carrier SHR 6; If NOT songdata.dis_fmreg_col[fmreg_table][19] then fmpar_table[chan].multipC := fm_data.AM_VIB_EG_carrier AND $0f; If NOT songdata.dis_fmreg_col[fmreg_table][20] then fmpar_table[chan].tremC := fm_data.AM_VIB_EG_carrier SHR 7; If NOT songdata.dis_fmreg_col[fmreg_table][21] then fmpar_table[chan].vibrC := fm_data.AM_VIB_EG_carrier SHR 6 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][22] then fmpar_table[chan].ksrC := fm_data.AM_VIB_EG_carrier SHR 4 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][23] then fmpar_table[chan].sustC := fm_data.AM_VIB_EG_carrier SHR 5 AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][24] then fmpar_table[chan].connect := fm_data.FEEDBACK_FM AND 1; If NOT songdata.dis_fmreg_col[fmreg_table][25] then fmpar_table[chan].feedb := fm_data.FEEDBACK_FM SHR 1 AND 7; If NOT songdata.dis_fmreg_col[fmreg_table][27] then If NOT pan_lock[chan] then panning_table[chan] := panning; If NOT songdata.dis_fmreg_col[fmreg_table][5] then set_ins_volume(63-fm_data.KSL_VOLUM_modulator AND $3f, BYTE_NULL,chan); If NOT songdata.dis_fmreg_col[fmreg_table][17] then set_ins_volume(BYTE_NULL, 63-fm_data.KSL_VOLUM_carrier AND $3f,chan); update_modulator_adsrw(chan); update_carrier_adsrw(chan); update_fmpar(chan); If force_macro_keyon or NOT (fm_data.FEEDBACK_FM OR MACRO_NOTE_RETRIG_FLAG <> fm_data.FEEDBACK_FM) then begin If NOT (is_4op_chan(chan) and (chan in _4op_tracks_hi)) then begin output_note(event_table[chan].note, event_table[chan].instr_def,chan,FALSE,TRUE); If (is_4op_chan(chan) and (chan in _4op_tracks_lo)) then init_macro_table(PRED(chan),0,voice_table[PRED(chan)],0); end; end else If NOT (fm_data.FEEDBACK_FM OR MACRO_ENVELOPE_RESTART_FLAG <> fm_data.FEEDBACK_FM) then begin key_on(chan); change_freq(chan,freq_table[chan]); end else If NOT (fm_data.FEEDBACK_FM OR MACRO_ZERO_FREQ_FLAG <> fm_data.FEEDBACK_FM) then If (freq_table[chan] <> 0) then begin zero_fq_table[chan] := freq_table[chan]; freq_table[chan] := freq_table[chan] AND NOT $1fff; change_freq(chan,freq_table[chan]); end else else If (zero_fq_table[chan] <> 0) then begin freq_table[chan] := zero_fq_table[chan]; zero_fq_table[chan] := 0; change_freq(chan,freq_table[chan]); end; If NOT songdata.dis_fmreg_col[fmreg_table][26] then If (freq_slide > 0) then portamento_up(chan,freq_slide,nFreq(12*8+1)) else If (freq_slide < 0) then portamento_down(chan,Abs(freq_slide),nFreq(0)); end; end; end; With songdata.macro_table[arpg_table].arpeggio do If (arpg_table <> 0) and (speed <> 0) then If (arpg_count = speed) then begin arpg_count := 1; If (arpg_pos <= length) then If (loop_begin <> 0) and (loop_length <> 0) then If (arpg_pos = loop_begin+PRED(loop_length)) then arpg_pos := loop_begin else If (arpg_pos < length) then Inc(arpg_pos) else arpg_pos := finished_flag else If (arpg_pos < length) then Inc(arpg_pos) else arpg_pos := finished_flag else arpg_pos := finished_flag; If (freq_table[chan] OR $2000 = freq_table[chan]) and (keyoff_pos <> 0) and (arpg_pos >= keyoff_pos) then arpg_pos := IDLE else If (freq_table[chan] OR $2000 <> freq_table[chan]) and (keyoff_pos <> 0) and (keyoff_pos <> 0) and ((arpg_pos < keyoff_pos) or (arpg_pos = IDLE)) then arpg_pos := keyoff_pos; If (arpg_pos <> 0) and (arpg_pos <> IDLE) and (arpg_pos <> finished_flag) then Case data[arpg_pos] of 0: change_frequency(chan, nFreq(arpg_note-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); 1..96: change_frequency(chan, nFreq(max(arpg_note+data[arpg_pos],97)-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); $80..$80+12*8+1: change_frequency(chan,nFreq(data[arpg_pos]-$80-1)+ SHORTINT(ins_parameter(event_table[chan].instr_def,12))); end; end else Inc(arpg_count); With songdata.macro_table[vib_table].vibrato do If NOT vib_paused and (vib_table <> 0) and (speed <> 0) then If (vib_count = speed) then If (vib_delay <> 0) then Dec(vib_delay) else begin vib_count := 1; If (vib_pos <= length) then If (loop_begin <> 0) and (loop_length <> 0) then If (vib_pos = loop_begin+PRED(loop_length)) then vib_pos := loop_begin else If (vib_pos < length) then Inc(vib_pos) else vib_pos := finished_flag else If (vib_pos < length) then Inc(vib_pos) else vib_pos := finished_flag else vib_pos := finished_flag; If (freq_table[chan] OR $2000 = freq_table[chan]) and (keyoff_pos <> 0) and (vib_pos >= keyoff_pos) then vib_pos := IDLE else If (freq_table[chan] OR $2000 <> freq_table[chan]) and (vib_pos <> 0) and (keyoff_pos <> 0) and ((vib_pos < keyoff_pos) or (vib_pos = IDLE)) then vib_pos := keyoff_pos; If (vib_pos <> 0) and (vib_pos <> IDLE) and (vib_pos <> finished_flag) then If (data[vib_pos] > 0) then macro_vibrato__porta_up(chan,data[vib_pos]) else If (data[vib_pos] < 0) then macro_vibrato__porta_down(chan,Abs(data[vib_pos])) else change_freq(chan,vib_freq); end else Inc(vib_count); end; end; {$IFDEF GO32V2} _debug_str_ := _debug_str_bak_; {$ENDIF} end; procedure set_global_volume; var chan: Byte; begin For chan := 1 to songdata.nm_tracks do If _4op_vol_valid_chan(chan) then set_ins_volume_4op(BYTE_NULL,chan) else If NOT ((carrier_vol[chan] = 0) and (modulator_vol[chan] = 0)) then If (ins_parameter(voice_table[chan],10) AND 1 = 0) then set_ins_volume(BYTE_NULL,HI(volume_table[chan]),chan) else set_ins_volume(LO(volume_table[chan]),HI(volume_table[chan]),chan); end; {$IFDEF GO32V2} var regs: tRealRegs; procedure update_mouse_position; begin If mouse_active then begin FillChar(regs,SizeOf(regs),0); regs.ax := $04; regs.cx := scr_scroll_x; regs.dx := scr_scroll_y; RealIntr($33,regs); end; end; {$ENDIF} procedure synchronize_screen; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:synchronize_screen'; If mouse_active then begin FillChar(regs,SizeOf(regs),0); regs.ax := $03; RealIntr($33,regs); scr_scroll_x := regs.cx; scr_scroll_y := regs.dx; end; If (scr_scroll_x <> old_scr_scroll_x) or (scr_scroll_y <> old_scr_scroll_y) then begin old_scr_scroll_x := scr_scroll_x; old_scr_scroll_y := scr_scroll_y; If (scr_scroll_x > scr_font_width*MaxCol-scr_font_width*hard_maxcol) then begin scr_scroll_x := scr_font_width*MaxCol-scr_font_width*hard_maxcol; update_mouse_position; end; If (scr_scroll_y > scr_font_height*MaxLn-scr_font_height*hard_maxln) then begin scr_scroll_y := scr_font_height*MaxLn-scr_font_height*hard_maxln; update_mouse_position; end; WaitRetrace; If NOT is_VESA_emulated_mode then SetTextDisp(scr_scroll_x,scr_scroll_y) else virtual_screen__first_row := scr_scroll_y*800; end; {$ELSE} If NOT is_default_screen_mode then EXIT; If (screen_scroll_offset > 16*MaxLn-16*hard_maxln) then screen_scroll_offset := 16*MaxLn-16*hard_maxln; virtual_screen__first_row := screen_scroll_offset*SCREEN_RES_X; {$ENDIF} end; function _macro_speedup: Word; begin If (macro_speedup > 0) then _macro_speedup := macro_speedup else _macro_speedup := macro_speedup+1; end; procedure timer_poll_proc; {$IFDEF GO32V2} var _debug_str_bak_: String; {$ENDIF} begin {$IFDEF GO32V2} _debug_str_bak_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:timer_poll_proc'; If (timer_determinator < IRQ_freq) then Inc(timer_determinator) else begin timer_determinator := 1; Inc(seconds_counter); end; If (timer_det2 < IRQ_freq DIV 100) then Inc(timer_det2) else begin timer_det2 := 1; Inc(hundereds_counter); Inc(_cursor_blink_pending_frames); Inc(_screen_refresh_pending_frames); end; {$ENDIF} {$IFDEF GO32V2} If NOT reset_gfx_ticks then Inc(gfx_ticks) else begin gfx_ticks := 0; reset_gfx_ticks := FALSE; end; scroll_ticks := scroll_ticks+1/IRQ_freq*100; If (scroll_ticks > 0.2) then begin If ctrl_tab_pressed then begin If scankey(SC_UP) then If (scr_scroll_y > 0) then begin Dec(scr_scroll_y); update_mouse_position; end; If scankey(SC_DOWN) then If (scr_scroll_y < scr_font_height*MaxLn-scr_font_height*hard_maxln) then begin Inc(scr_scroll_y); update_mouse_position; end; If scankey(SC_PAGEUP) then begin scr_scroll_y := 0; update_mouse_position; end; If scankey(SC_PAGEDOWN) then begin scr_scroll_y := scr_font_height*MaxLn-scr_font_height*hard_maxln; update_mouse_position; end; If scankey(SC_HOME) then begin scr_scroll_x := 0; update_mouse_position; end; If scankey(SC_END) then begin scr_scroll_x := scr_font_width*MaxCol-scr_font_width*hard_maxcol; update_mouse_position; end; If scankey(SC_LEFT) then If (scr_scroll_x > 0) then begin Dec(scr_scroll_x); update_mouse_position; end; If scankey(SC_RIGHT) then If (scr_scroll_x < scr_font_width*MaxCol-scr_font_width*hard_maxcol) then begin Inc(scr_scroll_x); update_mouse_position; end; end; scroll_ticks := 0; end; {$ELSE} Inc(blink_ticks); If ((fast_forward or rewind or (space_pressed and debugging) or (@macro_preview_indic_proc <> NIL)) and (blink_ticks > 50)) or (blink_ticks > 50) then begin _generic_blink_event_flag := NOT _generic_blink_event_flag; blink_flag := NOT blink_flag; blink_ticks := 0; end; If ctrl_tab_pressed then begin If scankey(SC_UP) then If (screen_scroll_offset > 0) then Dec(screen_scroll_offset,2); If scankey(SC_DOWN) then If (screen_scroll_offset < 16*MaxLn-16*hard_maxln) then Inc(screen_scroll_offset,2); If scankey(SC_PAGEUP) then screen_scroll_offset := 0; If scankey(SC_PAGEDOWN) then screen_scroll_offset := 16*MaxLn-16*hard_maxln; end; {$ENDIF} If (play_status = isPlaying) and NOT (debugging and (NOT space_pressed or no_step_debugging)) then begin {$IFDEF GO32V2} song_timer_tenths := Trunc(100/IRQ_freq*timer_temp); {$ELSE} song_timer_tenths := timer_temp; {$ENDIF} If (song_timer_tenths >= 100) then song_timer_tenths := 0; {$IFDEF GO32V2} If (timer_temp < IRQ_freq) then Inc(timer_temp) {$ELSE} If (timer_temp < 100) then Inc(timer_temp) {$ENDIF} else begin Inc(song_timer); timer_temp := 1; end; end else If debugging and (NOT space_pressed or no_step_debugging) then If NOT pattern_delay then synchronize_song_timer; If (song_timer > 3600-1) then begin song_timer := 0; timer_temp := 0; song_timer_tenths := 0; end; {$IFDEF GO32V2} If (ticklooper > 0) then If (fast_forward or rewind) and NOT replay_forbidden then poll_proc else else If NOT replay_forbidden then poll_proc; If (macro_ticklooper = 0) then macro_poll_proc; Inc(ticklooper); If (ticklooper >= IRQ_freq DIV tempo) then ticklooper := 0; Inc(macro_ticklooper); If (macro_ticklooper >= IRQ_freq DIV (tempo*_macro_speedup)) then macro_ticklooper := 0; _debug_str_ := _debug_str_bak_; {$ENDIF} end; {$IFDEF GO32V2} const ___IRQ_DATA_END___: Dword = 0; procedure ___IRQ_CODE_END___; begin end; procedure DisableTimerIRQ; begin asm in al,21h or al,1 out 21h,al end; end; procedure EnableTimerIRQ; begin asm in al,21h and al,0feh out 21h,al end; end; const timer_poll_proc_ptr: Pointer = NIL; procedure TimerSetup(Hz: Longint); begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:TimerSetup'; If (Hz < 19) then Hz := 19; If (Hz > 1193180) then Hz := 1193180; DisableTimerIRQ; If (timer_poll_proc_ptr <> NIL) then ISS_StopTimer(timer_poll_proc_ptr); timer_poll_proc_ptr := @timer_poll_proc; ISS_StartTimer(timer_poll_proc_ptr,ISS_TimerSpeed DIV Hz); EnableTimerIRQ; end; procedure TimerDone; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:TimerDone'; DisableTimerIRQ; If (timer_poll_proc_ptr <> NIL) then ISS_StopTimer(timer_poll_proc_ptr); timer_poll_proc_ptr := NIL; EnableTimerIRQ; end; procedure TimerInstallHandler(handler: Pointer); begin end; procedure TimerRemoveHandler; begin end; {$ELSE} const timer_handler: Procedure = NIL; TimerID: SDL_TimerID = NIL; _interval: longint = 1000 DIV 50; // 1000 ms / Hz function TimerCallback(interval: Uint32; param: Pointer):Uint32; cdecl; begin If (@timer_handler <> NIL) then timer_handler; TimerCallback := _interval; // trick to alter delay rate on the fly end; procedure TimerSetup(Hz: Longint); begin _interval := 1000 DIV Hz; // only activate timer once, later only alter delay rate If (TimerID = NIL) then begin TimerID := SDL_AddTimer(_interval,SDL_NewTimerCallback(@TimerCallBack),NIL); If (TimerID = NIL) then Writeln('SDL: Error creating timer'); end; snd_SetTimer(Hz); end; procedure TimerDone; begin end; procedure TimerInstallHandler(handler: Pointer); begin @timer_handler := handler; end; procedure TimerRemoveHandler; begin @timer_handler := NIL; end; {$ENDIF} procedure init_timer_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:init_timer_proc'; scroll_ticks := 0; {$ENDIF} Randomize; If timer_initialized then EXIT; timer_initialized := TRUE; {$IFNDEF GO32V2} TimerInstallHandler(@timer_poll_proc); {$ENDIF} TimerSetup(50); end; procedure done_timer_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:done_timer_proc'; {$ENDIF} If NOT timer_initialized then EXIT; timer_initialized := FALSE; TimerDone; TimerRemoveHandler; end; {$i realtime.inc} function calc_pattern_pos(pattern: Byte): Byte; var index: Integer; jump_count,pattern_pos: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:calc_pattern_pos'; {$ENDIF} pattern_pos := BYTE_NULL; jump_count := 0; index := calc_following_order(0); While (index <> -1) and (jump_count < $7f) do If (songdata.pattern_order[index] <> pattern) then If NOT (index < $7f) then BREAK else begin Inc(index); index := calc_following_order(index); Inc(jump_count); end else begin pattern_pos := index; BREAK; end; calc_pattern_pos := pattern_pos; end; procedure calibrate_player(order,line: Byte; status_filter: Boolean; line_dependent: Boolean); var temp_channel_flag: array[1..20] of Boolean; old_debugging, old_repeat_pattern: Boolean; jump_count,loop_count, temp,previous_order,previous_line: Byte; status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; procedure update_status; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:calibrate_player:update_status'; {$ENDIF} temp := songdata.pattern_order[current_order]; If NOT (temp <= $7f) then temp := 0; show_str(17,03,byte2hex(current_order),pattern_bckg+status_dynamic_txt); show_str(20,03,byte2hex(temp),pattern_bckg+status_dynamic_txt); show_str(17,04,'--',pattern_bckg+status_dynamic_txt); {$IFNDEF GO32V2} _draw_screen_without_delay := TRUE; {$ENDIF} draw_screen; end; var _pattern_page,_pattord_page, _pattord_hpos,_pattord_vpos: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:calibrate_player'; {$ENDIF} If (calc_following_order(0) = -1) then EXIT; calibrating := TRUE; status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; If status_filter then no_status_refresh := TRUE; nul_volume_bars; Move(channel_flag,temp_channel_flag,SizeOf(temp_channel_flag)); FillChar(channel_flag,SizeOf(channel_flag),BYTE(FALSE)); old_debugging := debugging; old_repeat_pattern := repeat_pattern; debugging := FALSE; repeat_pattern := FALSE; If (play_status = isStopped) or (order < current_order) or (order = calc_following_order(0)) then begin If NOT no_sync_playing then stop_playing else begin stop_playing; no_sync_playing := TRUE; end; init_player; speed := songdata.speed; macro_speedup := songdata.macro_speedup; update_timer(songdata.tempo); current_order := calc_following_order(0); current_pattern := songdata.pattern_order[current_order]; current_line := 0; pattern_break := FALSE; pattern_delay := FALSE; last_order := 0; next_line := 0; song_timer := 0; timer_temp := 0; song_timer_tenths := 0; time_playing := 0; ticklooper := 0; macro_ticklooper := 0; ticks := 0; tick0 := 0; end; If NOT no_sync_playing then begin show_str(13,07,' --:--.- ',status_background+status_border); {$IFNDEF GO32V2} _draw_screen_without_delay := TRUE; {$ENDIF} draw_screen; end; previous_order := current_order; previous_line := current_line; jump_count := 0; loop_count := 0; replay_forbidden := TRUE; seek_pattern_break := FALSE; If NOT no_sync_playing then While (current_line <> line) or (current_order <> order) do begin If scankey(SC_ESCAPE) then BREAK; If NOT ((previous_order = current_order) and (previous_line >= current_line) and NOT (pattern_break and (next_line AND $0f0 = pattern_loop_flag))) then loop_count := 0 else begin Inc(loop_count); If (loop_count > 15) then BREAK; end; If (current_order = order) and (current_line >= line) and NOT line_dependent then BREAK; previous_order := current_order; previous_line := current_line; fast_forward := TRUE; poll_proc; If (macro_ticklooper = 0) then macro_poll_proc; fast_forward := FALSE; Inc(ticklooper); If (ticklooper >= IRQ_freq DIV tempo) then ticklooper := 0; Inc(macro_ticklooper); If (macro_ticklooper >= IRQ_freq DIV (tempo*macro_speedup)) then macro_ticklooper := 0; If (previous_order <> current_order) then begin update_status; Inc(jump_count); If (jump_count > $7f) then BREAK; end; If seek_pattern_break then If (current_order > order) or ((current_order = order) and ((current_line <> 0) or (line = 0))) then BREAK else seek_pattern_break := FALSE; keyboard_reset_buffer; end else begin start_playing; current_order := order; current_pattern := songdata.pattern_order[order]; current_line := line; end; fade_out_volume := 63; Move(temp_channel_flag,channel_flag,SizeOf(channel_flag)); For temp := 1 to 20 do reset_chan_data(temp); If (status_backup.play_status <> isStopped) then begin replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end else begin replay_forbidden := FALSE; play_status := isPlaying; end; debugging := old_debugging; repeat_pattern := old_repeat_pattern; synchronize_song_timer; calibrating := FALSE; If status_filter then no_status_refresh := FALSE; _pattern_page := line; _pattord_page := 0; _pattord_hpos := 1; _pattord_vpos := 1; While (current_order <> _pattord_vpos+4*(_pattord_hpos+_pattord_page-1)-1) do If (_pattord_vpos < 4) then Inc(_pattord_vpos) else If (_pattord_hpos < MAX_ORDER_COLS) then begin Inc(_pattord_hpos); _pattord_vpos := 1; end else If (_pattord_page < 23-(MAX_ORDER_COLS-9)) then begin Inc(_pattord_page); _pattord_vpos := 1; end; If tracing then begin PATTERN_ORDER_page_refresh(_pattord_page); PATTERN_page_refresh(_pattern_page); end; keyboard_reset_buffer; end; procedure init_buffers; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:init_buffers'; {$ENDIF} FillChar(fmpar_table,SizeOf(fmpar_table),0); FillChar(pan_lock,SizeOf(pan_lock),BYTE(panlock)); FillChar(volume_table,SizeOf(volume_table),63); FillChar(vscale_table,SizeOf(vscale_table),0); FillChar(modulator_vol,SizeOf(modulator_vol),0); FillChar(carrier_vol,SizeOf(carrier_vol),0); FillChar(decay_bar,SizeOf(decay_bar),0); FillChar(volum_bar,SizeOf(volum_bar),0); FillChar(event_table,SizeOf(event_table),0); FillChar(freq_table,SizeOf(freq_table),0); FillChar(zero_fq_table,SizeOf(zero_fq_table),0); FillChar(effect_table,SizeOf(effect_table),0); FillChar(effect_table2,SizeOf(effect_table2),0); FillChar(fslide_table,SizeOf(fslide_table),0); FillChar(fslide_table2,SizeOf(fslide_table2),0); FillChar(glfsld_table,SizeOf(glfsld_table),0); FillChar(glfsld_table2,SizeOf(glfsld_table2),0); FillChar(porta_table,SizeOf(porta_table),0); FillChar(porta_table2,SizeOf(porta_table2),0); FillChar(portaFK_table,SizeOf(portaFK_table),BYTE(FALSE)); FillChar(arpgg_table,SizeOf(arpgg_table),0); FillChar(arpgg_table2,SizeOf(arpgg_table2),0); FillChar(vibr_table,SizeOf(vibr_table),0); FillChar(vibr_table2,SizeOf(vibr_table2),0); FillChar(trem_table,SizeOf(trem_table),0); FillChar(trem_table2,SizeOf(trem_table2),0); FillChar(retrig_table,SizeOf(retrig_table),0); FillChar(retrig_table2,SizeOf(retrig_table2),0); FillChar(tremor_table,SizeOf(tremor_table),0); FillChar(tremor_table2,SizeOf(tremor_table2),0); FillChar(last_effect,SizeOf(last_effect),0); FillChar(last_effect2,SizeOf(last_effect2),0); FillChar(voice_table,SizeOf(voice_table),0); FillChar(event_new,SizeOf(event_new),0); FillChar(freqtable2,SizeOf(freqtable2),0); FillChar(notedel_table,SizeOf(notedel_table),BYTE_NULL); FillChar(notecut_table,SizeOf(notecut_table),BYTE_NULL); FillChar(ftune_table,SizeOf(ftune_table),0); FillChar(loopbck_table,SizeOf(loopbck_table),BYTE_NULL); FillChar(loop_table,SizeOf(loop_table),BYTE_NULL); FillChar(reset_chan,SizeOf(reset_chan),BYTE(FALSE)); FillChar(reset_adsrw,SizeOf(reset_adsrw),BYTE(FALSE)); FillChar(keyoff_loop,SizeOf(keyoff_loop),BYTE(FALSE)); FillChar(macro_table,SizeOf(macro_table),0); FillChar(ignore_note_once,SizeOf(ignore_note_once),FALSE); If NOT lockvol then FillChar(volume_lock,SizeOf(volume_lock),0) else For temp := 1 to 20 do volume_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 4 AND 1); If NOT panlock then FillChar(panning_table,SizeOf(panning_table),0) else For temp := 1 to 20 do panning_table[temp] := songdata.lock_flags[temp] AND 3; If NOT lockVP then FillChar(peak_lock,SizeOf(peak_lock),0) else For temp := 1 to 20 do peak_lock[temp] := BOOLEAN(songdata.lock_flags[temp] SHR 5 AND 1); FillChar(vol4op_lock,SizeOf(vol4op_lock),BYTE(FALSE)); For temp := 1 to 6 do begin vol4op_lock[_4op_main_chan[temp]] := (songdata.lock_flags[_4op_main_chan[temp]] OR $40 = songdata.lock_flags[_4op_main_chan[temp]]); vol4op_lock[PRED(_4op_main_chan[temp])] := (songdata.lock_flags[PRED(_4op_main_chan[temp])] OR $40 = songdata.lock_flags[PRED(_4op_main_chan[temp])]); end; For temp := 1 to 20 do volslide_type[temp] := songdata.lock_flags[temp] SHR 2 AND 3; end; procedure init_player; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:init_player'; {$ELSE} opl3_init; {$ENDIF} FillChar(ai_table,SizeOf(ai_table),0); opl2out($01,0); For temp := 1 to 18 do opl2out($0b0+_chan_n[temp],0); For temp := $080 to $08d do opl2out(temp,BYTE_NULL); For temp := $090 to $095 do opl2out(temp,BYTE_NULL); misc_register := tremolo_depth SHL 7+ vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; opl2out($01,$20); opl2out($08,$40); opl3exp($0105); opl3exp($04+songdata.flag_4op SHL 8); key_off(17); key_off(18); opl2out(_instr[11],misc_register); init_buffers; current_tremolo_depth := tremolo_depth; current_vibrato_depth := vibrato_depth; global_volume := 63; macro_ticklooper := 0; vibtrem_speed_factor := def_vibtrem_speed_factor; vibtrem_table_size := def_vibtrem_table_size; Move(def_vibtrem_table,vibtrem_table,SizeOf(vibtrem_table)); For temp := 1 to 20 do begin arpgg_table[temp].state := 1; arpgg_table2[temp].state := 1; voice_table[temp] := temp; end; end; procedure reset_player; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:reset_player'; {$ENDIF} opl2out($01,0); For temp := 1 to 18 do opl2out($0b0+_chan_n[temp],0); For temp := $080 to $08d do opl2out(temp,BYTE_NULL); For temp := $090 to $095 do opl2out(temp,BYTE_NULL); misc_register := tremolo_depth SHL 7+ vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; opl2out($01,$20); opl2out($08,$40); opl3exp($0105); opl3exp($04+songdata.flag_4op SHL 8); key_off(17); key_off(18); opl2out(_instr[11],misc_register); For temp := 1 to 20 do reset_chan_data(temp); end; procedure start_playing; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:start_playing'; {$ENDIF} init_player; If (start_pattern = BYTE_NULL) then current_order := 0 else If (start_order = BYTE_NULL) then begin If (calc_pattern_pos(start_pattern) <> BYTE_NULL) then current_order := calc_pattern_pos(start_pattern) else If NOT play_single_patt then begin start_pattern := BYTE_NULL; current_order := 0; EXIT; end; end else begin current_order := start_order; current_pattern := start_pattern; end; If NOT play_single_patt then If (songdata.pattern_order[current_order] > $7f) then If (calc_order_jump = -1) then EXIT; If NOT play_single_patt then current_pattern := songdata.pattern_order[current_order] else current_pattern := start_pattern; If (start_line = BYTE_NULL) then current_line := 0 else current_line := start_line; pattern_break := FALSE; pattern_delay := FALSE; tickXF := 0; last_order := 0; next_line := 0; song_timer := 0; timer_temp := 0; song_timer_tenths := 0; time_playing := 0; ticklooper := 0; macro_ticklooper := 0; debugging := FALSE; ticks := 0; tick0 := 0; fade_out_volume := 63; replay_forbidden := FALSE; play_status := isPlaying; speed := songdata.speed; macro_speedup := songdata.macro_speedup; update_timer(songdata.tempo); no_status_refresh := FALSE; really_no_status_refresh := FALSE; FillChar(play_pos_buf,SizeOf(play_pos_buf),0); end; procedure stop_playing; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:stop_playing'; {$ELSE} flush_WAV_data; If NOT opl3_flushmode then renew_wav_files_flag := TRUE; {$ENDIF} replay_forbidden := TRUE; play_status := isStopped; fade_out_volume := 63; repeat_pattern := FALSE; global_volume := 63; no_sync_playing := FALSE; play_single_patt := FALSE; current_tremolo_depth := tremolo_depth; current_vibrato_depth := vibrato_depth; pattern_break := FALSE; current_order := 0; current_pattern := 0; current_line := 0; start_order := BYTE_NULL; start_pattern := BYTE_NULL; start_line := BYTE_NULL; song_timer := 0; timer_temp := 0; song_timer_tenths := 0; time_playing := 0; skip_macro_flag := TRUE; For temp := 1 to 20 do reset_chan_data(temp); opl2out(_instr[11],0); init_buffers; skip_macro_flag := FALSE; speed := songdata.speed; update_timer(songdata.tempo); end; function _partial(max,val: Byte; base: Byte): Byte; var temp1,temp2: Real; temp3: Byte; begin temp1 := max/base; temp2 := (max/base)/2; temp3 := 0; While (temp2 < val) do begin temp2 := temp2+temp1; Inc(temp3); end; _partial := temp3; end; function hscroll_bar(x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Byte; var temp: Byte; begin If (size > work_MaxCol-x) then size := work_MaxCol-x; If (size < 5) then size := 5; If (size-2-1 < 10) then temp := _partial(len1,len2,size-2-1) else temp := _partial(len1,len2,size-2-1-2); If (pos = temp) and NOT force_scrollbars then begin hscroll_bar := temp; EXIT; end; If (size < len1*4) and (len1 > 4) then begin pos := temp; show_str(x,y,#17+ExpStrL('',size-2,#176)+#16,atr1); If (size-2-1 < 10) then show_str(x+1+temp,y,#178,atr2) else show_str(x+1+temp,y,#178#178#178,atr2); end else show_Str(x,y,#17+ExpStrL('',size-2,#177)+#16,atr1); hscroll_bar := pos; end; function vscroll_bar(x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Byte; var temp: Byte; begin If (size > work_MaxLn-y) then size := work_MaxLn-y; If (size < 5) then size := 5; If (size-2-1 < 10) then temp := _partial(len1,len2,size-2-1) else temp := _partial(len1,len2,size-2-1-2); If (pos = temp) and NOT force_scrollbars then begin vscroll_bar := temp; EXIT; end; If (size < len1*4) and (len1 > 5) then begin pos := temp; show_vstr(x,y,#30+ExpStrL('',size-2,#176)+#31,atr1); If (size-2-1 < 10) then show_str(x,y+1+temp,#178,atr2) else show_vstr(x,y+1+temp,#178#178#178,atr2); end else show_vstr(x,y,#30+ExpStrL('',size-2,#177)+#31,atr1); vscroll_bar := pos; end; procedure centered_frame(var xstart,ystart: Byte; hsize,vsize: Byte; name: String; atr1,atr2: Byte; border: String); begin xstart := (work_MaxCol-hsize) DIV 2; ystart := (work_MaxLn -vsize) DIV 2+(work_MaxLn-vsize) MOD 2; Frame(centered_frame_vdest,xstart,ystart,xstart+hsize,ystart+vsize, atr1,name,atr2,border); end; procedure get_chunk(pattern,line,channel: Byte; var chunk: tCHUNK); begin asm mov esi,[pattdata] mov edi,[chunk] mov al,pattern inc al cmp al,max_patterns jbe @@1 mov ecx,CHUNK_SIZE xor al,al rep stosb jmp @@2 @@1: xor eax,eax mov al,line mov ebx,CHUNK_SIZE mul ebx mov ecx,eax xor eax,eax mov al,channel dec eax mov ebx,256*CHUNK_SIZE mul ebx add ecx,eax xor eax,eax mov al,pattern mov ebx,8 div ebx push eax mov eax,edx mov ebx,20*256*CHUNK_SIZE mul ebx add ecx,eax pop eax mov ebx,8*20*256*CHUNK_SIZE mul ebx add ecx,eax add esi,ecx mov ecx,CHUNK_SIZE rep movsb @@2: end; end; procedure put_chunk(pattern,line,channel: Byte; chunk: tCHUNK); begin asm lea esi,[chunk] mov edi,[pattdata] mov al,pattern inc al cmp al,max_patterns jbe @@1 mov limit_exceeded,TRUE jmp @@2 @@1: xor eax,eax mov al,line mov ebx,CHUNK_SIZE mul ebx mov ecx,eax xor eax,eax mov al,channel dec eax mov ebx,256*CHUNK_SIZE mul ebx add ecx,eax xor eax,eax mov al,pattern mov ebx,8 div ebx push eax mov eax,edx mov ebx,20*256*CHUNK_SIZE mul ebx add ecx,eax pop eax mov ebx,8*20*256*CHUNK_SIZE mul ebx add ecx,eax add edi,ecx mov ecx,CHUNK_SIZE rep movsb mov module_archived,FALSE @@2: end; end; function get_chanpos(var data; channels,scancode: Byte): Byte; var result: Byte; begin asm xor ebx,ebx @@1: mov edi,[data] add edi,ebx xor ecx,ecx mov cl,channels mov al,scancode sub ecx,ebx repnz scasb jnz @@2 xor eax,eax mov al,channels sub eax,ecx jmp @@3 @@2: xor eax,eax jmp @@5 @@3: pusha push eax call is_4op_chan or al,al jz @@4 popa inc ebx jmp @@1 @@4: popa @@5: mov result,al end; get_chanpos := result; end; function get_chanpos2(var data; channels,scancode: Byte): Byte; var result: Byte; begin asm mov edi,[data] xor ecx,ecx mov cl,channels mov al,scancode repnz scasb jnz @@1 xor eax,eax mov al,channels sub eax,ecx jmp @@2 @@1: xor eax,eax @@2: mov result,al end; get_chanpos2 := result; end; function count_channel(hpos: Byte): Byte; var result: Byte; begin asm mov al,_pattedit_lastpos xor ah,ah mov bl,MAX_TRACKS div bl mov bl,al mov al,hpos xor ah,ah div bl or ah,ah jz @@1 add al,chan_pos jmp @@2 @@1: add al,chan_pos dec al @@2: mov result,al end; count_channel := result; end; function count_pos(hpos: Byte): Byte; var result: Byte; begin asm mov al,_pattedit_lastpos xor ah,ah mov bl,MAX_TRACKS div bl mov bl,al mov al,hpos xor ah,ah div bl mov al,ah dec al or ah,ah jnz @@1 dec bl mov al,bl @@1: mov result,al end; count_pos := result; end; procedure count_order(var entries: Byte); var index, index2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:count_order'; {$ENDIF} index := 0; index2 := 0; Repeat If (songdata.pattern_order[index] <> $80) then begin If (songdata.pattern_order[index] > $80) then If (songdata.pattern_order[index]-$80 <> index2) then begin index := songdata.pattern_order[index]-$80; index2 := index; end else BREAK; end else BREAK; If (index < $80) then Inc(index); until (index > $7f); entries := index; end; procedure count_patterns(var patterns: Byte); var temp1: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:count_patterns'; {$ENDIF} patterns := 0; For temp1 := 0 to PRED(max_patterns) do begin realtime_gfx_poll_proc; If NOT is_data_empty(pattdata^[temp1 DIV 8][temp1 MOD 8],PATTERN_SIZE) then patterns := temp1+1; end; end; procedure count_instruments(var instruments: Byte); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:count_instruments'; {$ENDIF} instruments := 255; While (instruments > 0) and Empty(songdata.instr_data[instruments],INSTRUMENT_SIZE) do Dec(instruments); end; function calc_max_speedup(tempo: Byte): Word; var temp: Longint; result: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:calc_max_speedup'; {$ENDIF} result := MAX_IRQ_FREQ DIV tempo; Repeat If (tempo = 18) and timer_fix then temp := TRUNC((tempo+0.2)*20) else temp := 250; While (temp MOD (tempo*result) <> 0) do Inc(temp); If (temp <= MAX_IRQ_FREQ) then Inc(result); until NOT (temp <= MAX_IRQ_FREQ); calc_max_speedup := PRED(result); end; procedure init_old_songdata; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:init_old_songdata'; {$ENDIF} FillChar(old_songdata,SizeOf(old_songdata),0); FillChar(old_songdata.pattern_order,SizeOf(old_songdata.pattern_order),$080); FillChar(old_songdata.instr_data,SizeOf(old_songdata.instr_data),0); For temp := 1 to 250 do old_songdata.instr_names[temp] := ' iNS_'+byte2hex(temp)+#247' '; end; procedure init_songdata; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:init_songdata'; {$ENDIF} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end else init_buffers; FillChar(songdata,SizeOf(songdata),0); FillChar(songdata.pattern_order,SizeOf(songdata.pattern_order),$080); For temp := 1 to max_patterns DIV 8 do FillChar(pattdata^[PRED(temp)],8*PATTERN_SIZE,0); songdata.tempo := tempo; songdata.speed := speed; songdata.macro_speedup := init_macro_speedup; speed_update := FALSE; songdata.patt_len := patt_len; songdata.nm_tracks := nm_tracks; lockvol := FALSE; panlock := FALSE; lockVP := FALSE; tremolo_depth := 0; vibrato_depth := 0; volume_scaling := FALSE; old_chan_pos := 1; old_hpos := 1; old_page := 0; old_block_chan_pos := 1; old_block_patt_hpos := 1; old_block_patt_page := 0; marking := FALSE; If (nm_tracks <= 18) then begin percussion_mode := FALSE; _chan_n := _chmm_n; _chan_m := _chmm_m; _chan_c := _chmm_c; end else begin percussion_mode := TRUE; _chan_n := _chpm_n; _chan_m := _chpm_m; _chan_c := _chpm_c; end; For temp := 1 to 255 do songdata.instr_names[temp] := ' iNS_'+byte2hex(temp)+#247' '; For temp := 0 to $7f do songdata.pattern_names[temp] := ' PAT_'+byte2hex(temp)+' '#247' '; songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); module_archived := TRUE; end; procedure update_instr_data(ins: Byte); var temp: Byte; begin For temp := 1 to 20 do If (voice_table[temp] = ins) then begin reset_chan[temp] := TRUE; set_ins_data(ins,temp); change_frequency(temp,nFreq(PRED(event_table[temp].note AND $7f))+ SHORTINT(ins_parameter(ins,12))); end; end; procedure load_instrument(var data; chan: Byte); begin fmpar_table[chan].connect := pBYTE(@data)[10] AND 1; fmpar_table[chan].feedb := pBYTE(@data)[10] SHR 1 AND 7; fmpar_table[chan].multipM := pBYTE(@data)[0] AND $0f; fmpar_table[chan].kslM := pBYTE(@data)[2] SHR 6; fmpar_table[chan].tremM := pBYTE(@data)[0] SHR 7; fmpar_table[chan].vibrM := pBYTE(@data)[0] SHR 6 AND 1; fmpar_table[chan].ksrM := pBYTE(@data)[0] SHR 4 AND 1; fmpar_table[chan].sustM := pBYTE(@data)[0] SHR 5 AND 1; fmpar_table[chan].multipC := pBYTE(@data)[1] AND $0f; fmpar_table[chan].kslC := pBYTE(@data)[3] SHR 6; fmpar_table[chan].tremC := pBYTE(@data)[1] SHR 7; fmpar_table[chan].vibrC := pBYTE(@data)[1] SHR 6 AND 1; fmpar_table[chan].ksrC := pBYTE(@data)[1] SHR 4 AND 1; fmpar_table[chan].sustC := pBYTE(@data)[1] SHR 5 AND 1; fmpar_table[chan].adsrw_car.attck := pBYTE(@data)[5] SHR 4; fmpar_table[chan].adsrw_mod.attck := pBYTE(@data)[4] SHR 4; fmpar_table[chan].adsrw_car.dec := pBYTE(@data)[5] AND $0f; fmpar_table[chan].adsrw_mod.dec := pBYTE(@data)[4] AND $0f; fmpar_table[chan].adsrw_car.sustn := pBYTE(@data)[7] SHR 4; fmpar_table[chan].adsrw_mod.sustn := pBYTE(@data)[6] SHR 4; fmpar_table[chan].adsrw_car.rel := pBYTE(@data)[7] AND $0f; fmpar_table[chan].adsrw_mod.rel := pBYTE(@data)[6] AND $0f; fmpar_table[chan].adsrw_car.wform := pBYTE(@data)[9] AND $07; fmpar_table[chan].adsrw_mod.wform := pBYTE(@data)[8] AND $07; panning_table[chan] := pBYTE(@data)[11] AND 3; volume_table[chan] := concw(pBYTE(@data)[2] AND $3f, pBYTE(@data)[3] AND $3f); update_modulator_adsrw(chan); update_carrier_adsrw(chan); update_fmpar(chan); end; function is_4op_chan(chan: Byte): Boolean; var result: Boolean; begin asm mov al,byte ptr [songdata.flag_4op] mov ah,chan test al,1 jz @@1 cmp ah,1 jb @@1 cmp ah,2 ja @@1 mov result,TRUE jmp @@7 @@1: test al,2 jz @@2 cmp ah,3 jb @@2 cmp ah,4 ja @@2 mov result,TRUE jmp @@7 @@2: test al,4 jz @@3 cmp ah,5 jb @@3 cmp ah,6 ja @@3 mov result,TRUE jmp @@7 @@3: test al,8 jz @@4 cmp ah,10 jb @@4 cmp ah,11 ja @@4 mov result,TRUE jmp @@7 @@4: test al,10h jz @@5 cmp ah,12 jb @@5 cmp ah,13 ja @@5 mov result,TRUE jmp @@7 @@5: test al,20h jz @@6 cmp ah,14 jb @@6 cmp ah,15 ja @@6 mov result,TRUE jmp @@7 @@6: mov result,FALSE @@7: end; is_4op_chan := result; end; function is_in_block(x0,y0,x1,y1: Byte): Boolean; begin block_x1 := x1; block_x0 := block_xstart; If (block_x0 > block_x1) then begin block_x1 := block_x0; block_x0 := x1; end; block_y1 := y1; block_y0 := block_ystart; If (block_y0 > block_y1) then begin block_y1 := block_y0; block_y0 := y1; end; is_in_block := (x0 >= block_x0) and (x0 <= block_x1) and (y0 >= block_y0) and (y0 <= block_y1); end; procedure fade_out_playback(fade_screen: Boolean); var {$IFDEF GO32V2} idx,idx2: Byte; fade_buf: tFADE_BUF; {$ELSE} temp: Byte; temp2,temp3: Byte; factor: Byte; {$ENDIF} begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:fade_out_playback'; If fade_screen then begin draw_screen; fade_buf.action := first; fade_speed := 32; GetPalette(fade_buf.pal0,0,255); For idx := fade_speed downto 0 do begin For idx2 := 0 to 255 do begin fade_buf.pal1[idx2].r := fade_buf.pal0[idx2].r * idx DIV fade_speed; fade_buf.pal1[idx2].g := fade_buf.pal0[idx2].g * idx DIV fade_speed; fade_buf.pal1[idx2].b := fade_buf.pal0[idx2].b * idx DIV fade_speed; end; SetPalette(fade_buf.pal1,0,255); If (play_status <> isStopped) then begin fade_out_volume := idx*2; set_global_volume; CRT.Delay(fade_out_volume DIV 32); end else CRT.Delay(1); realtime_gfx_poll_proc; draw_screen; keyboard_reset_buffer; end; fade_buf.action := fadeIn; end else If (play_status <> isStopped) then For idx := 63 downto 0 do begin fade_out_volume := idx; set_global_volume; CRT.Delay(fade_out_volume DIV 32); realtime_gfx_poll_proc; keyboard_reset_buffer; end; {$ELSE} If fade_screen then factor := 255 else factor := 63; If (global_volume > 0) then temp2 := factor DIV global_volume else temp2 := 0; temp3 := 0; fade_out_volume := 63; If (play_status <> isStopped) then For temp := 1 to factor do begin Inc(temp3); If (temp3 > temp2) then begin temp3 := 0; Dec(fade_out_volume); set_global_volume; If fade_screen or (temp MOD 5 = 0) then begin _draw_screen_without_delay := TRUE; draw_screen; keyboard_reset_buffer; end; end; If fade_screen then begin vid_FadeOut; SDL_Delay(1); end; end else For fade_out_volume := 1 to 255 do If fade_screen then begin vid_FadeOut; SDL_Delay(1); end; {$ENDIF} end; procedure realtime_gfx_poll_proc; begin If _realtime_gfx_no_update then EXIT; {$IFDEF GO32V2} If NOT reset_gfx_ticks and (gfx_ticks > (IRQ_freq DIV 100)*SUCC(fps_down_factor)) then begin Inc(blink_ticks); If (blink_ticks = 40) then begin _generic_blink_event_flag := NOT _generic_blink_event_flag; blink_flag := NOT blink_flag; blink_ticks := 0; end; {$ENDIF} If blink_flag then begin If debugging and (play_status = isStopped) then status_layout[isStopped][9] := #9 else status_layout[isStopped][9] := ' '; If NOT debugging then status_layout[isPlaying][9] := #16 else status_layout[isPlaying][9] := #9; status_layout[isPaused][8] := #8; If (@macro_preview_indic_proc <> NIL) then macro_preview_indic_proc(1); end else begin status_layout[isPlaying][9] := ' '; status_layout[isPaused] [8] := ' '; status_layout[isStopped][9] := ' '; If (@macro_preview_indic_proc <> NIL) then macro_preview_indic_proc(2); end; decay_bars_refresh; {$IFNDEF GO32V2} If opl3_channel_recording_mode then update_recorded_channels; {$ENDIF} If do_synchronize then synchronize_screen; {$IFNDEF GO32V2} If (_name_scrl_pending_frames > 0) then Dec(_name_scrl_pending_frames); Inc(_cursor_blink_pending_frames); {$ENDIF} status_refresh; STATUS_LINE_refresh; {$IFDEF GO32V2} reset_gfx_ticks := TRUE; {$ENDIF} trace_update_proc; If (@mn_environment.ext_proc_rt <> NIL) then mn_environment.ext_proc_rt; {$IFDEF GO32V2} end; {$ENDIF} end; function get_bank_position(bank_name: String; bank_size: Longint): Longint; var idx: Longint; result: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:get_bank_position'; {$ENDIF} result := 0; bank_name := CutStr(Upper_filename(bank_name)); For idx := 1 to bank_position_list_size do If (bank_position_list[idx].bank_name = bank_name) and ((bank_position_list[idx].bank_size = bank_size) or (bank_size = -1)) then begin result := bank_position_list[idx].bank_position; BREAK; end; get_bank_position := result; end; procedure add_bank_position(bank_name: String; bank_size: Longint; bank_position: Longint); var idx,idx2: Longint; found_flag: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2UNIT.PAS:add_bank_position'; {$ENDIF} found_flag := FALSE; bank_name := CutStr(Upper_filename(bank_name)); For idx := 1 to bank_position_list_size do If (bank_position_list[idx].bank_name = bank_name) and ((bank_position_list[idx].bank_size = bank_size) or (bank_size = -1)) then begin found_flag := TRUE; idx2 := idx; BREAK; end; If found_flag then begin bank_position_list[idx2].bank_position := bank_position; EXIT; end; If (bank_position_list_size < MAX_NUM_BANK_POSITIONS) then Inc(bank_position_list_size) else begin bank_position_list_size := MAX_NUM_BANK_POSITIONS; For idx := 1 to PRED(bank_position_list_size) do bank_position_list[idx] := bank_position_list[idx+1]; end; bank_position_list[bank_position_list_size].bank_name := bank_name; bank_position_list[bank_position_list_size].bank_size := bank_size; bank_position_list[bank_position_list_size].bank_position := bank_position; end; {$IFDEF GO32V2} var old_exit_proc: procedure; procedure new_exit_proc; begin Unlock_Data(___UNIT_DATA_START___,DWORD(Addr(___UNIT_DATA_END___))-DWORD(Addr(___UNIT_DATA_START___))); Unlock_Data(___IRQ_DATA_START___,DWORD(Addr(___IRQ_DATA_END___))-DWORD(Addr(___IRQ_DATA_START___))); Unlock_Code(@___IRQ_CODE_START___,DWORD(@___IRQ_CODE_END___)-DWORD(@___IRQ_CODE_START___)); ExitProc := @old_exit_proc; end; begin Lock_Data(___UNIT_DATA_START___,DWORD(Addr(___UNIT_DATA_END___))-DWORD(Addr(___UNIT_DATA_START___))); Lock_Data(___IRQ_DATA_START___,DWORD(Addr(___IRQ_DATA_END___))-DWORD(Addr(___IRQ_DATA_START___))); Lock_Code(@___IRQ_CODE_START___,DWORD(@___IRQ_CODE_END___)-DWORD(@___IRQ_CODE_START___)); @old_exit_proc := ExitProc; ExitProc := @new_exit_proc; {$ENDIF} end. adlibtracker2-2.4.23/menulib1.pas0000644000000000000000000004503113176573533015252 0ustar rootrootunit MenuLib1; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface uses DOS, AdT2unit,AdT2sys,AdT2keyb,AdT2ext2, DialogIO,TxtScrIO,StringIO,ParserIO; const MenuLib1_mn_setting: Record frame_type: String; shadow_enabled: Boolean; posbar_enabled: Boolean; title_attr, menu_attr, text_attr, text2_attr, default_attr, short_attr, short2_attr, disbld_attr, contxt_attr, contxt2_attr: Byte; center_box: Boolean; cycle_moves: Boolean; edit_contents: Boolean; reverse_use: Boolean; fixed_len: Byte; terminate_keys: array[1..50] of Word; end = (frame_type: frame_single; shadow_enabled: TRUE; posbar_enabled: TRUE; title_attr: $0f; menu_attr: $07; text_attr: $07; text2_attr: $70; default_attr: $0f; short_attr: $0f; short2_attr: $70; disbld_attr: $07; contxt_attr: $0f; contxt2_attr: $07; center_box: TRUE; cycle_moves: TRUE; edit_contents: FALSE; reverse_use: FALSE; fixed_len: 0; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); var MenuLib1_mn_environment: Record v_dest: tSCREEN_MEM_PTR; keystroke: Word; context: String; unpolite: Boolean; winshade: Boolean; edit_pos: Byte; curr_pos: Word; ext_proc: procedure; refresh: procedure; do_refresh: Boolean; preview: Boolean; descr_len: Byte; descr: Pointer; end; function MenuLib1_Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure MenuLib1_Init; implementation type tDBUFFR = array[1.. 100] of Record str: String; pos: Byte; key: Char; use: Boolean; end; type tMBUFFR = array[1..16384] of Record key: Char; use: Boolean; end; var idx,idx2,max,len2b,page, first,last,temp,temp2,opage,opos: Word; old_fr_shadow_enabled: Boolean; key: Word; solid: Boolean; qflg: Boolean; mbuf: tMBUFFR; contxt: String; var mnu_x,mnu_y,mnu_len,mnu_len2: Byte; mnu_data: Pointer; mnu_count: Word; var vscrollbar_pos: Word; function OutKey(str: String): Char; var result: Char; begin If (SYSTEM.Pos('~',str) = 0) then result := '~' else If (str[SYSTEM.Pos('~',str)+2] <> '~') then result := '~' else result := str[SYSTEM.Pos('~',str)+1]; OutKey := result; end; function pstr(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:pstr'; {$ENDIF} Move(POINTER(Ptr(0,Ofs(mnu_data^)+(item-1)*(mnu_len+1)))^,temp,mnu_len+1); If NOT solid then pstr := ExpStrR(temp,mnu_len-2,' ') else pstr := ExpStrR(temp,mnu_len,' '); end; function pdes(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:pdes'; {$ENDIF} If (mn_environment.descr <> NIL) then Move(POINTER(Ptr(0,Ofs(mn_environment.descr^)+ (item-1)*(mn_environment.descr_len+1)))^,temp,mn_environment.descr_len+1) else temp := ''; pdes := ExpStrR(temp,mn_environment.descr_len,' '); end; procedure refresh; procedure ShowCStr_clone(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); var temp,len: Byte; highlighted: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:refresh:ShowCStr_clone'; {$ENDIF} If NOT (MenuLib1_mn_setting.fixed_len <> 0) then begin ShowCStr(dest,x,y,str,atr1,atr2); EXIT; end; highlighted := FALSE; len := 0; For temp := 1 to Length(str) do If (str[temp] = '~') then highlighted := NOT highlighted else begin If (len < MenuLib1_mn_setting.fixed_len) then begin If NOT highlighted then ShowStr(dest,x+len,y,str[temp],atr1) else ShowStr(dest,x+len,y,str[temp],atr2); Inc(len); end else begin If NOT highlighted then ShowStr(dest,x+len,y,str[temp],atr3) else ShowStr(dest,x+len,y,str[temp],atr4); Inc(len); end end; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:refresh'; {$ENDIF} If (page = opage) and (idx2 = opos) and NOT MenuLib1_mn_environment.do_refresh then EXIT else begin opage := page; opos := idx2; MenuLib1_mn_environment.do_refresh := FALSE; end; For idx := page to mnu_len2+page-1 do If (idx = idx2+page-1) then ShowCStr_clone(MenuLib1_mn_environment.v_dest,mnu_x+1,mnu_y+idx2, ExpStrR(pstr(idx2+page-1)+pdes(idx2+page-1), max+(Length(pstr(idx2+page-1))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx2+page-1)+pdes(idx2+page-1))),' '), MenuLib1_mn_setting.text2_attr,MenuLib1_mn_setting.short2_attr, MenuLib1_mn_setting.text_attr,MenuLib1_mn_setting.short_attr) else If mbuf[idx].use then ShowCStr(MenuLib1_mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(pstr(idx)+pdes(idx), max+(Length(pstr(idx))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx)+pdes(idx))),' '), MenuLib1_mn_setting.text_attr,MenuLib1_mn_setting.short_attr) else ShowCStr(MenuLib1_mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(pstr(idx)+pdes(idx), max+(Length(pstr(idx))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx)+pdes(idx))),' '), MenuLib1_mn_setting.disbld_attr,MenuLib1_mn_setting.disbld_attr); vscrollbar_pos := VScrollBar(MenuLib1_mn_environment.v_dest,mnu_x+max+1,mnu_y+1,temp2,mnu_count,idx2+page-1, vscrollbar_pos,MenuLib1_mn_setting.menu_attr,MenuLib1_mn_setting.menu_attr); end; function MenuLib1_Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure SubPos(var p: Word); var temp: Word; begin temp := p; If (temp > 1) and mbuf[temp+page-2].use then Dec(temp) else If (temp > 1) then begin Dec(temp); SubPos(temp); end else If (page > first) then Dec(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 > first) then SubPos(temp); end; procedure AddPos(var p: Word); var temp: Word; begin temp := p; If (temp < len2) and (temp < last) and mbuf[temp+page].use then Inc(temp) else If (temp < len2) and (temp < last) then begin Inc(temp); AddPos(temp); end else If (page+temp <= last) then Inc(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 < last) then AddPos(temp); end; function RetKey(code: Byte): Word; var temp: Byte; begin RetKey := 0; For temp := 1 to count do If (UpCase(mbuf[temp].key) = UpCase(CHR(code))) then begin RetKey := temp; BREAK; end; end; procedure edit_contents(item: Word); var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:MenuLib1_Menu:edit_contents'; {$ENDIF} is_setting.append_enabled := TRUE; is_setting.character_set := [#32..#255]; is_environment.locate_pos := 1; If (MenuLib1_mn_environment.edit_pos > 0) and (MenuLib1_mn_environment.edit_pos < max-2) then temp := Copy(pstr(item),MenuLib1_mn_environment.edit_pos+1, Length(pstr(item))-MenuLib1_mn_environment.edit_pos+1) else temp := CutStr(pstr(item)); While (temp <> '') and (temp[Length(temp)] = ' ') do Delete(temp,Length(temp),1); temp := InputStr(temp,x+1+MenuLib1_mn_environment.edit_pos,y+idx2, max-2-MenuLib1_mn_environment.edit_pos+1, max-2-MenuLib1_mn_environment.edit_pos+1, MenuLib1_mn_setting.text2_attr,MenuLib1_mn_setting.default_attr); If (is_environment.keystroke = kENTER) then begin If (MenuLib1_mn_environment.edit_pos > 0) and (MenuLib1_mn_environment.edit_pos < max-2) then temp := Copy(pstr(item),1,MenuLib1_mn_environment.edit_pos)+temp else temp := CutStr(temp); Move(temp,POINTER(Ptr(0,Ofs(data)+(item-1)*(len+1)))^,len+1); end; ShowCStr(MenuLib1_mn_environment.v_dest,x+1,y+idx2, ExpStrR(pstr(item),max+(Length(pstr(item)))- CStrLen(pstr(item)),' '), MenuLib1_mn_setting.text2_attr,MenuLib1_mn_setting.short2_attr); end; begin { MenuLib1_Menu } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:MenuLib1_Menu'; {$ENDIF} If (count = 0) then begin MenuLib1_Menu := 0; EXIT; end; max := Length(title); mnu_data := Addr(data); mnu_count := count; mnu_len := len; If NOT MenuLib1_mn_environment.unpolite then ScreenMemCopy(MenuLib1_mn_environment.v_dest,ptr_scr_backup); If (count < 1) then EXIT; vscrollbar_pos := BYTE_NULL; If NOT MenuLib1_mn_environment.preview then HideCursor; temp := 0; For idx := 1 to count do begin mbuf[idx].key := OutKey(pstr(idx)); If NOT MenuLib1_mn_setting.reverse_use then mbuf[idx].use := mbuf[idx].key <> '~' else mbuf[idx].use := NOT (mbuf[idx].key <> '~'); If mbuf[idx].use then temp := 1; end; solid := FALSE; If (temp = 0) then begin For temp := 1 to count do mbuf[temp].use := TRUE; solid := TRUE; end; For idx := 1 to count do If (max < CStrLen(pstr(idx))+MenuLib1_mn_environment.descr_len) then max := CStrLen(pstr(idx))+MenuLib1_mn_environment.descr_len; If MenuLib1_mn_setting.center_box then begin x := (work_MaxCol-max-2) DIV 2+(work_MaxCol-max-2) MOD 2; y := (work_MaxLn-len2-1) DIV 2+(work_MaxLn-len2-1) MOD 2; end; mnu_x := x; mnu_y := y; len2b := len2; If NOT MenuLib1_mn_environment.unpolite then begin old_fr_shadow_enabled := fr_setting.shadow_enabled; fr_setting.shadow_enabled := MenuLib1_mn_setting.shadow_enabled; fr_setting.update_area := FALSE; Frame(MenuLib1_mn_environment.v_dest,x,y,x+max+1,y+len2+1,MenuLib1_mn_setting.menu_attr, title,MenuLib1_mn_setting.title_attr,MenuLib1_mn_setting.frame_type); fr_setting.update_area := TRUE; fr_setting.shadow_enabled := old_fr_shadow_enabled; contxt := DietStr(MenuLib1_mn_environment.context,max+ (Length(MenuLib1_mn_environment.context)-CStrLen(MenuLib1_mn_environment.context))); ShowCStr(MenuLib1_mn_environment.v_dest,x+max+1-CStrLen(contxt),y+len2+1, contxt,MenuLib1_mn_setting.contxt_attr,MenuLib1_mn_setting.contxt2_attr); temp2 := len2; If (len2 > count) then len2 := count; If (len2 < 1) then len2 := 1; If (spos < 1) then spos := 1; If (spos > count) then spos := count; mnu_len2 := len2; MenuLib1_mn_environment.refresh := refresh; first := 1; last := count; While NOT mbuf[first].use do Inc(first); While NOT mbuf[last].use do Dec(last); If (spos < first) or (spos > last) then spos := first; idx2 := 1; page := 1; opage := WORD_NULL; opos := WORD_NULL; While (idx2+page-1 < spos) do AddPos(idx2); end; MenuLib1_mn_environment.curr_pos := idx2+page-1; MenuLib1_mn_environment.keystroke := WORD_NULL; If (Addr(MenuLib1_mn_environment.ext_proc) <> NIL) then MenuLib1_mn_environment.ext_proc; qflg := FALSE; If MenuLib1_mn_environment.preview then begin MenuLib1_mn_environment.preview := FALSE; MenuLib1_mn_environment.unpolite := TRUE; refresh; end else Repeat key := getkey; If LookUpKey(key,MenuLib1_mn_setting.terminate_keys,50) then If NOT ((key = MenuLib1_mn_setting.terminate_keys[2]) and MenuLib1_mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx2+page-1); If NOT qflg then If (LO(key) in [$20..$0ff]) then begin idx := RetKey(LO(key)); If (idx <> 0) then begin refresh; idx2 := idx; If NOT ((key = MenuLib1_mn_setting.terminate_keys[2]) and MenuLib1_mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx); end; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then Case key of kUP: If (page+idx2-1 > first) or NOT MenuLib1_mn_setting.cycle_moves then SubPos(idx2) else begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kDOWN: If (page+idx2-1 < last) or NOT MenuLib1_mn_setting.cycle_moves then AddPos(idx2) else begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kHOME: begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kEND: begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kPgUP: For temp := 1 to len2-1 do SubPos(idx2); kPgDOWN: For temp := 1 to len2-1 do AddPos(idx2); end; MenuLib1_mn_environment.curr_pos := idx2+page-1; refresh; MenuLib1_mn_environment.keystroke := key; If (Addr(MenuLib1_mn_environment.ext_proc) <> NIL) then MenuLib1_mn_environment.ext_proc; {$IFDEF GO32V2} // draw_screen; keyboard_reset_buffer_alt; {$ELSE} draw_screen; // keyboard_reset_buffer; {$ENDIF} until qflg or _force_program_quit; If MenuLib1_mn_environment.winshade and NOT MenuLib1_mn_environment.unpolite then begin If (Addr(move_to_screen_routine) <> NIL) then begin move_to_screen_data := ptr_scr_backup; move_to_screen_area[1] := x; move_to_screen_area[2] := y; move_to_screen_area[3] := x+max+1+2; move_to_screen_area[4] := y+len2b+1+1; move_to_screen_routine; end else ScreenMemCopy(ptr_scr_backup,MenuLib1_mn_environment.v_dest); end; MenuLib1_Menu := idx2+page-1; end; procedure MenuLib1_Init; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:MenuLib1_Init'; {$ENDIF} MenuLib1_mn_setting.frame_type := frame_single; MenuLib1_mn_setting.center_box := FALSE; MenuLib1_mn_setting.shadow_enabled := FALSE; MenuLib1_mn_setting.cycle_moves := FALSE; MenuLib1_mn_setting.title_attr := dialog_background+dialog_title; MenuLib1_mn_setting.menu_attr := dialog_background+dialog_text; MenuLib1_mn_setting.text_attr := dialog_background+dialog_item; MenuLib1_mn_setting.text2_attr := dialog_sel_itm_bck+dialog_sel_itm; MenuLib1_mn_setting.default_attr := dialog_def_bckg+dialog_def; MenuLib1_mn_setting.short_attr := dialog_background+dialog_short; MenuLib1_mn_setting.short2_attr := dialog_sel_itm_bck+dialog_sel_short; MenuLib1_mn_setting.disbld_attr := dialog_background+dialog_item_dis; MenuLib1_mn_setting.contxt_attr := dialog_background+dialog_context; MenuLib1_mn_setting.contxt2_attr := dialog_background+dialog_context_dis; MenuLib1_mn_setting.terminate_keys[3] := kTAB; MenuLib1_mn_setting.terminate_keys[4] := kLEFT; MenuLib1_mn_setting.terminate_keys[5] := kRIGHT; MenuLib1_mn_setting.terminate_keys[6] := kCtrlO; MenuLib1_mn_setting.terminate_keys[7] := kF1; MenuLib1_mn_setting.terminate_keys[8] := kShTAB; MenuLib1_mn_environment.v_dest := screen_ptr; MenuLib1_mn_environment.keystroke := $0000; MenuLib1_mn_environment.context := ''; MenuLib1_mn_environment.unpolite := FALSE; MenuLib1_mn_environment.winshade := TRUE; MenuLib1_mn_environment.ext_proc := NIL; MenuLib1_mn_environment.refresh := NIL; MenuLib1_mn_environment.do_refresh := FALSE; MenuLib1_mn_environment.preview := FALSE; MenuLib1_mn_environment.descr_len := 0; MenuLib1_mn_environment.descr := NIL; end; end. adlibtracker2-2.4.23/ipattern.inc0000644000000000000000000071665113176573533015367 0ustar rootroot{ procedure cancel_note_recorder; procedure PATTERN_tabs_refresh; procedure STATUS_LINE_refresh; function last_chan_pos: Byte; function last_hpos: Byte; procedure PATTERN_page_refresh(page: Byte); procedure PATTERN_position_preview(pattern,line,channel,mode: Byte); function PATTERN_trace: Word; procedure PATTERN_edit(var pattern,page,hpos: Byte); } const old_nm_track_chan: Byte = 0; old_track_chan_start: Byte = 0; const pattern_undo_flag: Boolean = FALSE; var pattern_undo_patt: Byte; pattern_undo_data: array[0..PRED(SizeOf(tPATTERN_DATA) DIV 16)] of Byte; procedure cancel_note_recorder; begin If track_notes then begin old_nm_track_chan := nm_track_chan; old_track_chan_start := track_chan_start; track_notes := FALSE; nm_track_chan := 1; end; end; procedure PATTERN_tabs_refresh; var temp: Byte; begin If (command_typing <> 0) then begin For temp := chan_pos to max(chan_pos+MAX_TRACKS-1,songdata.nm_tracks) do If (temp <> count_channel(pattern_hpos)) then show_str(08+(temp-PRED(chan_pos)-1)*15,10, patt_tab_str[0], pattern_bckg+pattern_border); Case count_pos(pattern_hpos) of 0, 1: show_cstr(08+(count_channel(pattern_hpos)-PRED(chan_pos)-1)*15,10, patt_tab_str[1], pattern_bckg+pattern_border, pattern_bckg+pattern_pos_indic); 2, 3: show_cstr(08+(count_channel(pattern_hpos)-PRED(chan_pos)-1)*15,10, patt_tab_str[2], pattern_bckg+pattern_border, pattern_bckg+pattern_pos_indic); 4,5, 6: show_cstr(08+(count_channel(pattern_hpos)-PRED(chan_pos)-1)*15,10, patt_tab_str[3], pattern_bckg+pattern_border, pattern_bckg+pattern_pos_indic); 7,8, 9: show_cstr(08+(count_channel(pattern_hpos)-PRED(chan_pos)-1)*15,10, patt_tab_str[4], pattern_bckg+pattern_border, pattern_bckg+pattern_pos_indic); end; end; end; procedure STATUS_LINE_refresh; var tracking_indicator_attr: array[Boolean] of Byte; attr: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:STATUS_LINE_refresh'; {$ENDIF} If really_no_status_refresh then EXIT; If (get_4op_to_test <> 0) then show_cstr(40,MAX_PATTERN_ROWS+12,'~[~'+byte2hex(HI(get_4op_to_test))+'~+~'+byte2hex(LO(get_4op_to_test))+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line) else show_cstr(40,MAX_PATTERN_ROWS+12,'~[~'+byte2hex(current_inst)+'~]~'#196#196#196, main_background+main_border, main_background+main_stat_line); If marking and NOT (discard_block or (tracing and (pattern_patt <> tracing_block_pattern))) then show_cstr(MAX_COLUMNS-39,MAX_PATTERN_ROWS+12,'~[M.BLOCK:~'+ byte2hex(block_y0)+','+byte2dec(block_x0)+'~'#196#16'~'+ byte2hex(block_y1)+','+byte2dec(block_x1)+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line) else begin show_cstr(MAX_COLUMNS-39,MAX_PATTERN_ROWS+12,'~[LN:~'+ExpStrL(Num2str(pattern_page,10),3,'0')+'/'+ExpStrL(Num2str(PRED(songdata.patt_len),10),3,'0')+'~;~', main_background+main_hi_stat_line, main_background+main_stat_line); show_cstr(MAX_COLUMNS-27,MAX_PATTERN_ROWS+12,'~TRK:~'+byte2dec(count_channel(pattern_hpos))+'/'+byte2dec(songdata.nm_tracks)+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line); end; If midiboard or (debugging and (play_status = isStopped)) then show_str(03,MAX_PATTERN_ROWS+12,'MBOARD',main_background+main_hi_stat_line) else show_str(03,MAX_PATTERN_ROWS+12,'MBOARD',main_background+main_stat_line); If NOT debugging and tracing and (play_status <> isStopped) then show_str(10,MAX_PATTERN_ROWS+12,'TRACE',main_background+main_hi_stat_line) else show_str(10,MAX_PATTERN_ROWS+12,'TRACE',main_background+main_stat_line); If debugging and (play_status <> isStopped) then show_str(16,MAX_PATTERN_ROWS+12,'DEBUG',main_background+main_hi_stat_line) else show_str(16,MAX_PATTERN_ROWS+12,'DEBUG',main_background+main_stat_line); tracking_indicator_attr[TRUE] := main_background+main_hi_stat_line; If (play_status = isPlaying) and tracing then If track_notes_ins then tracking_indicator_attr[FALSE] := main_behavior SHL 4 AND $0f0 else tracking_indicator_attr[FALSE] := main_hi_stat_line SHL 4 AND $0f0 else tracking_indicator_attr[FALSE] := main_background+main_stat_line; If track_notes then begin If jump_mark_mode and mark_lines then attr := main_background+main_dis_stat_line else attr := main_background+main_hi_stat_line; show_cstr(22,MAX_PATTERN_ROWS+12,'NRECM~:'#30+CHR(ORD('0')+rec_correction)+'~', tracking_indicator_attr[_generic_blink_event_flag], attr); end else If debugging and (play_status = isStopped) then show_str(22,MAX_PATTERN_ROWS+12,'TRACKiNG',main_background+main_hi_stat_line) else show_str(22,MAX_PATTERN_ROWS+12,'TRACKiNG',main_background+main_stat_line); If linefeed and NOT (command_typing = 0) then show_str(MAX_COLUMNS-16,MAX_PATTERN_ROWS+12,#127,main_background+main_behavior) else show_str(MAX_COLUMNS-16,MAX_PATTERN_ROWS+12,#127,main_background+main_behavior_dis); If jump_mark_mode then show_str(MAX_COLUMNS-15,MAX_PATTERN_ROWS+12,#23,main_background+main_behavior) else show_str(MAX_COLUMNS-15,MAX_PATTERN_ROWS+12,#23,main_background+main_behavior_dis); end; function last_chan_pos: Byte; begin If (songdata.nm_tracks > MAX_TRACKS) then last_chan_pos := max(16,songdata.nm_tracks-MAX_TRACKS+1) else last_chan_pos := 1; end; function last_hpos: Byte; begin last_hpos := max(_pattedit_lastpos,songdata.nm_tracks*(_pattedit_lastpos DIV MAX_TRACKS)); end; procedure PATTERN_page_refresh(page: Byte); var attr: Word; temp,temp1,temp2,temp3,attr2,attr3: Byte; chan_attr: Byte; {$IFNDEF GO32V2} chanrec_indicator_attr: array[Boolean] of Byte; {$ENDIF} temps: String; spos,epos: Byte; dummy_str: String[1]; dummy_atr: Byte; chunk: tCHUNK; _row_bckg, _row_bckg2, _row_fgnd: Byte; _no_block_tracing: Boolean; function PRED1(value: Longint): Longint; begin If (value > 1) then PRED1 := PRED(value) else PRED1 := 1; end; procedure _set_attr(chan: Byte; chunk: tCHUNK; _bckg,_fix_note,_note,_note0,_note_hid,_inst,_inst0: Byte; var attr: Word; var attr2: Byte); begin If (chunk.note <> 0) then If (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then attr := attr+(_bckg+_fix_note) SHL 8 else attr := attr+(_bckg+_note) SHL 8 else attr := attr+(_bckg+_note0) SHL 8; If (chunk.instr_def <> 0) then attr2 := _bckg+_inst else attr2 := _bckg+_inst0; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_page_refresh'; {$ENDIF} For temp := SUCC(songdata.nm_tracks) to MAX_TRACKS do begin show_str(08+(temp-1)*15,10,patt_tab_str[0], pattern_bckg+pattern_border); show_str(11+(temp-1)*15,09,ExpStrL('',10,' '), pattern_bckg+pattern_border); end; PATTERN_tabs_refresh; If (page > PRED(songdata.patt_len)) then page := PRED(songdata.patt_len); If (pattern_page > PRED(songdata.patt_len)) then pattern_page := PRED(songdata.patt_len); While NOT ((chan_pos <= last_chan_pos) and (pattern_hpos <= last_hpos)) do If (pattern_hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); If (pattern_hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(pattern_hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(pattern_hpos,temp); end else If (chan_pos > 1) then begin Dec(chan_pos); If (pattern_hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(pattern_hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(pattern_hpos,temp); end else If cycle_pattern then begin chan_pos := last_chan_pos; pattern_hpos := last_hpos; end; If (page < PRED(MAX_PATTERN_ROWS DIV 2)) then spos := PRED(MAX_PATTERN_ROWS DIV 2)-page else spos := 0; If (page > INTEGER(PRED(songdata.patt_len))-PRED(MAX_PATTERN_ROWS DIV 2)-1) then epos := page-(INTEGER(PRED(songdata.patt_len))-PRED(MAX_PATTERN_ROWS DIV 2)-1) else epos := 0; If (spos <> 0) or (epos <> 0) then For temp2 := chan_pos to chan_pos+MAX_TRACKS-1 do begin If (temp2-PRED(chan_pos) <> MAX_TRACKS) then dummy_str := #179 else dummy_str := ''; If (spos <> 0) then For temp3 := 1 to spos do begin show_str(03,10+temp3,ExpStrL('',4,' ')+#186,pattern_bckg+pattern_border); show_str(MAX_COLUMNS-8,10+temp3,#186+ExpStrL('',4,' '),pattern_bckg+pattern_border); show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp3,ExpStrL('',14,' ')+ dummy_str,pattern_bckg+pattern_border); end; If (epos <> 0) then For temp3 := MAX_PATTERN_ROWS downto MAX_PATTERN_ROWS-epos+1 do begin show_str(03,10+temp3,ExpStrL('',4,' ')+#186,pattern_bckg+pattern_border); show_str(MAX_COLUMNS-8,10+temp3,#186+ExpStrL('',4,' '),pattern_bckg+pattern_border); show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp3,ExpStrL('',14,' ')+ dummy_str,pattern_bckg+pattern_border); end; end; _no_block_tracing := discard_block or (tracing and (pattern_patt <> tracing_block_pattern)); show_str(17+(MAX_COLUMNS-19) DIV 2,08,byte2hex(pattern_patt),pattern_bckg+pattern_border); For temp1 := 1+spos to MAX_PATTERN_ROWS-epos do begin If tracing and (play_status <> isStopped) then begin If (temp1 <> MAX_PATTERN_ROWS DIV 2) then _row_bckg := BYTE_NULL else begin _row_bckg := pattern_row_bckg_p; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_line_p; end end else If NOT ((pattern_patt = current_pattern) and (page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1 = current_line) and (play_status <> isStopped)) then _row_bckg := BYTE_NULL else begin _row_bckg := pattern_row_bckg_p; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_line_p; end; If NOT ((mark_line <> 0) and mark_lines) then begin If (temp1 <> MAX_PATTERN_ROWS DIV 2) or (marking and (NOT _no_block_tracing or discard_block)) then begin If (temp1 <> MAX_PATTERN_ROWS DIV 2) then begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_line; end; show_cstr(03,10+temp1,' '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~ '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_border; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17+'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end; end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_row_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_hi_line; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17+'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end; end else begin If (temp1 <> MAX_PATTERN_ROWS DIV 2) or (marking and (NOT _no_block_tracing or discard_block)) then If ((page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1 = 0) or ((page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1) MOD mark_line = 0)) and (mark_line <> 0) then begin If NOT marking or (marking and NOT discard_block and _no_block_tracing) then begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_row_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_hi_line; end; show_cstr(03,10+temp1,' '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~ '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else If (temp1 <> MAX_PATTERN_ROWS DIV 2) then begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_hi_line; end; show_cstr(03,10+temp1,' '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~ '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_border; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17+'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end; end else If (temp1 <> MAX_PATTERN_ROWS DIV 2) then begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_line; end; show_cstr(03,10+temp1,' '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~ '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_border; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17+'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_row_bckg_m; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_hi_line_m; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end; end; For temp2 := chan_pos to chan_pos+MAX_TRACKS-1 do begin get_chunk(pattern_patt,page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1,temp2,chunk); If marking and ( (NOT tracing and is_in_block(temp2,page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1, count_channel(pattern_hpos),page)) or (NOT discard_block and tracing and NOT _no_block_tracing and is_in_block(temp2,page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1, tracing_block_xend,tracing_block_yend)) or (discard_block and (temp2 = block_xstart) and (page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1 = block_ystart))) then begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then attr := pattern_block_bckg+pattern_cmnd_b else attr := pattern_block_bckg+pattern_cmnd0_b; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then attr3 := pattern_block_bckg+pattern_cmnd_b else attr3 := pattern_block_bckg+pattern_cmnd0_b; _set_attr(temp2,chunk,pattern_block_bckg,pattern_fix_note_b, pattern_note_b,pattern_note0_b,pattern_note_hid_b, pattern_inst_b,pattern_inst0_b,attr,attr2); end else If (NOT marking or (marking and NOT discard_block and _no_block_tracing)) and (temp1 = 1+PRED(MAX_PATTERN_ROWS DIV 2)) then begin If NOT ((mark_line <> 0) and mark_lines) then begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then attr := pattern_row_bckg+pattern_hi_cmnd else attr := pattern_row_bckg+pattern_hi_cmnd0; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then attr3 := pattern_row_bckg+pattern_hi_cmnd else attr3 := pattern_row_bckg+pattern_hi_cmnd0; _set_attr(temp2,chunk,pattern_row_bckg,pattern_hi_fx_note, pattern_hi_note,pattern_hi_note0,pattern_hi_note_h, pattern_hi_inst,pattern_hi_inst0,attr,attr2); end else begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then attr := pattern_row_bckg_m+pattern_cmnd_m else attr := pattern_row_bckg_m+pattern_cmnd0_m; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then attr3 := pattern_row_bckg_m+pattern_cmnd_m else attr3 := pattern_row_bckg_m+pattern_cmnd0_m; _set_attr(temp2,chunk,pattern_row_bckg_m,pattern_fix_note_m, pattern_note_m,pattern_note0_m,pattern_note_hid_m, pattern_inst_m,pattern_inst0_m,attr,attr2); end; end else If ((page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1 = 0) or ((page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1) MOD mark_line = 0)) and (mark_line <> 0) and (NOT marking or (marking and NOT discard_block and _no_block_tracing)) and mark_lines then begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then attr := pattern_row_bckg+pattern_hi_cmnd else attr := pattern_row_bckg+pattern_hi_cmnd0; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then attr3 := pattern_row_bckg+pattern_hi_cmnd else attr3 := pattern_row_bckg+pattern_hi_cmnd0; _set_attr(temp2,chunk,pattern_row_bckg,pattern_hi_fx_note, pattern_hi_note,pattern_hi_note0,pattern_hi_note_h, pattern_hi_inst,pattern_hi_inst0,attr,attr2); end else begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then begin If NOT highlight_controls or NOT ((chunk.effect_def in [ef_PositionJump, ef_PatternBreak, ef_SetSpeed, ef_SetTempo]) or ((chunk.effect_def = ef_Extended) and (chunk.effect DIV 16 in [ef_ex_PatternLoop, ef_ex_PatternLoopRec]))) then attr := pattern_bckg+pattern_cmnd else attr := pattern_bckg+pattern_cmnd_ctrl end else attr := pattern_bckg+pattern_cmnd0; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then begin If NOT highlight_controls or NOT ((chunk.effect_def2 in [ef_PositionJump, ef_PatternBreak, ef_SetSpeed, ef_SetTempo]) or ((chunk.effect_def2 = ef_Extended) and (chunk.effect2 DIV 16 in [ef_ex_PatternLoop, ef_ex_PatternLoopRec]))) then attr3 := pattern_bckg+pattern_cmnd else attr3 := pattern_bckg+pattern_cmnd_ctrl end else attr3 := pattern_bckg+pattern_cmnd0; _set_attr(temp2,chunk,pattern_bckg,pattern_fix_note, pattern_note,pattern_note0,pattern_note_hid, pattern_inst,pattern_inst0,attr,attr2); end; dummy_atr := attr3 AND $0f0+pattern_border; If (temp2-PRED(chan_pos) <> MAX_TRACKS) and (NOT (marking and (temp2 >= block_x1)) or (marking and _no_block_tracing)) then begin dummy_str := #179; If marking and discard_block then dummy_atr := pattern_bckg+pattern_border; end else If marking and (temp2-PRED(chan_pos) <> MAX_TRACKS) and NOT _no_block_tracing then begin dummy_str := #179; dummy_atr := pattern_bckg+pattern_border; end else dummy_str := ''; If (temp2 > max(chan_pos+MAX_TRACKS-1,songdata.nm_tracks)) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,' ',HI(attr)) else Case pattern_layout of 0: Case chunk.note of 0: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#250#250#250' ',HI(attr)); 1..12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note]+' ',HI(attr)); fixed_note_flag+ 1.. fixed_note_flag+ 12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note-fixed_note_flag]+' ',HI(attr)); BYTE_NULL: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#254#254#254' ',HI(attr)); end; 1: Case chunk.note of 0: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#250#250#250' ',HI(attr)); 1..12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note]+' ',HI(attr)); fixed_note_flag+ 1.. fixed_note_flag+ 12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note-fixed_note_flag]+' ',HI(attr)); BYTE_NULL: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#205#205#205' ',HI(attr)); end; 2: Case chunk.note of 0: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#250#250#250' ',HI(attr)); 1..12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note]+' ',HI(attr)); fixed_note_flag+ 1.. fixed_note_flag+ 12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note-fixed_note_flag]+' ',HI(attr)); BYTE_NULL: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,'^^'#250' ',HI(attr)); end; end; If (temp2 > max(chan_pos+MAX_TRACKS-1,songdata.nm_tracks)) then begin show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1,' ',attr2); show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1,' ',LO(attr)); show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4], 10+temp1,' '+ #10+dummy_str+#10,attr3,dummy_atr); end else Case pattern_layout of 0: begin If (chunk.instr_def = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1,#249#249' ',attr2) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1, ExpStrL(Num2str(chunk.instr_def,16),2,#249)+' ',attr2); If (chunk.effect_def = 0) and (chunk.effect = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1,#250#250#250' ',LO(attr)) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1, fx_digits[chunk.effect_def]+byte2hex(chunk.effect)+' ',LO(attr)); If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1,#250#250#250+ #10+dummy_str+#10,attr3,dummy_atr) else show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1, fx_digits[chunk.effect_def2]+byte2hex(chunk.effect2)+ #10+dummy_str+#10,attr3,dummy_atr); end; 1: begin If (chunk.instr_def = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1,#250#250' ',attr2) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1, ExpStrL(Num2str(chunk.instr_def,16),2,#250)+' ',attr2); If (chunk.effect_def = 0) and (chunk.effect = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1,#249#249#249' ',LO(attr)) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1, fx_digits[chunk.effect_def]+byte2hex(chunk.effect)+' ',LO(attr)); If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1,#249#249#249+ #10+dummy_str+#10,attr3,dummy_atr) else show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1, fx_digits[chunk.effect_def2]+byte2hex(chunk.effect2)+ #10+dummy_str+#10,attr3,dummy_atr); end; 2: begin If (chunk.instr_def = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1,#250#250' ',attr2) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1, ExpStrL(Num2str(chunk.instr_def,16),2,#250)+' ',attr2); If (chunk.effect_def = 0) and (chunk.effect = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1,#250#249#249' ',LO(attr)) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1, fx_digits[chunk.effect_def]+byte2hex(chunk.effect)+' ',LO(attr)); If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1,#250#249#249+ #10+dummy_str+#10,attr3,dummy_atr) else show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1, fx_digits[chunk.effect_def2]+byte2hex(chunk.effect2)+ #10+dummy_str+#10,attr3,dummy_atr); end; end; end; end; {$IFNDEF GO32V2} chanrec_indicator_attr[TRUE] := main_behavior SHL 4 AND $0f0; If (play_status = isPlaying) then chanrec_indicator_attr[FALSE] := pattern_bckg+pattern_border else chanrec_indicator_attr[FALSE] := main_behavior SHL 4 AND $0f0; {$ENDIF} STATUS_LINE_refresh; For temp1 := chan_pos to chan_pos+MAX_TRACKS-1 do begin If NOT is_4op_chan(temp1) then temps := '~ ~'+ExpStrR(Num2str(temp1,10),2,' ')+'~ ~' else If (temp1 in _4op_tracks_hi) then temps := '~'#244'~'+ExpStrR(Num2str(temp1,10),2,' ')+'~ ~' else temps := '~'#245'~'+ExpStrR(Num2str(temp1,10),2,' ')+'~ ~'; {$IFNDEF GO32V2} If opl3_channel_recording_mode and opl3_record_channel[temp1] then chan_attr := chanrec_indicator_attr[_generic_blink_event_flag] else {$ENDIF} If track_notes and (temp1 >= track_chan_start) and (temp1 <= track_chan_start+nm_track_chan-1) then chan_attr := main_behavior SHL 4 and $0f0 else chan_attr := pattern_bckg+pattern_border; show_cstr(08+(temp1-PRED(chan_pos)-1)*15,09,temps, chan_attr, pattern_bckg+pattern_4op_indic); end; If scroll_bars then begin scroll_pos2 := vscroll_bar(MAX_COLUMNS-2,08,MAX_PATTERN_ROWS+4,PRED1(songdata.patt_len), page,scroll_pos2, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos3 := hscroll_bar(MAX_COLUMNS-14,MAX_PATTERN_ROWS+12,13,PRED1(songdata.nm_tracks),PRED(count_channel(pattern_hpos)), scroll_pos3, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); If (pattern_patt <= PRED(max_patterns)) then scroll_pos4 := vscroll_bar(MAX_COLUMNS-1,08,MAX_PATTERN_ROWS+4,PRED(max_patterns), pattern_patt,scroll_pos4, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_2nd_mark) else scroll_pos4 := vscroll_bar(MAX_COLUMNS-1,08,MAX_PATTERN_ROWS+4,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); end else begin scroll_pos2 := vscroll_bar(MAX_COLUMNS-2,08,MAX_PATTERN_ROWS+4,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos3 := hscroll_bar(MAX_COLUMNS-14,MAX_PATTERN_ROWS+12,13,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos4 := vscroll_bar(MAX_COLUMNS-1,08,MAX_PATTERN_ROWS+4,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); end; end; procedure PATTERN_position_preview(pattern,line,channel,mode: Byte); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_position_preview'; {$ENDIF} If (mode = 0) then begin old_pattern_patt := pattern_patt; old_pattern_page := pattern_page; old_pattern_hpos := pattern_hpos; old_chan_pos := chan_pos; old_block_xstart := block_xstart; old_block_ystart := block_ystart; old_marking := marking; end else If (mode = 1) then begin pattern_patt := pattern; pattern_page := line; If (channel > chan_pos+MAX_TRACKS-1) then While (channel > chan_pos+MAX_TRACKS-1) do Inc(chan_pos) else While (channel < chan_pos) do Dec(chan_pos); While (channel > chan_pos+MAX_TRACKS-1) and (chan_pos < last_chan_pos) do Inc(chan_pos); If (count_channel(pattern_hpos) < channel) then While (count_channel(pattern_hpos) <> channel) do Inc(pattern_hpos) else While (count_channel(pattern_hpos) <> channel) do Dec(pattern_hpos); While (count_pos(pattern_hpos) <> 0) do Dec(pattern_hpos); block_xstart := count_channel(pattern_hpos); block_ystart := line; marking := TRUE; cancel_note_recorder; discard_block := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (mode = BYTE_NULL) then begin pattern_patt := old_pattern_patt; pattern_page := old_pattern_page; pattern_hpos := old_pattern_hpos; chan_pos := old_chan_pos; block_xstart := old_block_xstart; block_ystart := old_block_ystart; marking := old_marking; discard_block := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; function PATTERN_trace: Word; var old_pattord_page,old_pattord_hpos,old_pattord_vpos: Byte; old_pattern_patt,old_pattern_page,old_pattern_hpos: Byte; nope,flag,reset_pos: Boolean; temp,temp2,fkey2: Word; idx,idx2,track_ch,curr_ch: Byte; patt_nm,line_nm,dif1,dif2: Byte; track_ch_key: array[1..20] of Byte; old_hpos: Byte; temps: String; chunk,chunk2: tCHUNK; procedure pause_debugging; begin If debugging then begin debugging := FALSE; replay_forbidden := TRUE; play_status := isPaused; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; label _end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_trace'; {$ENDIF} If (play_status = isStopped) then EXIT; _traceprc_last_order := BYTE_NULL; _traceprc_last_pattern := BYTE_NULL; _traceprc_last_line := BYTE_NULL; HideCursor; old_pattord_page := pattord_page; old_pattord_hpos := pattord_hpos; old_pattord_vpos := pattord_vpos; old_pattern_patt := pattern_patt; old_pattern_page := pattern_page; old_pattern_hpos := pattern_hpos; reset_pos := TRUE; tracing := TRUE; If marking then begin tracing_block_pattern := pattern_patt; tracing_block_xend := count_channel(pattern_hpos); tracing_block_yend := pattern_page; end; Repeat nope := FALSE; trace_update_proc; If ctrl_pressed and alt_pressed then begin DEBUG_INFO; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; old_hpos := pattern_hpos; If keypressed then fkey2 := getkey else If NOT (seconds_counter >= ssaver_time) then GOTO _end //CONTINUE else begin screen_saver; GOTO _end; //CONTINUE; end; If track_notes and midiboard then begin curr_ch := track_chan_start; track_ch := 0; flag := FALSE; FillChar(track_ch_key,SizeOf(track_ch_key),BYTE_NULL); If NOT ctrl_pressed and NOT alt_pressed then For idx := 1 to 29 do If (scankey(board_scancodes[idx])) then begin flag := TRUE; If (track_ch < nm_track_chan) then Inc(track_ch) else BREAK; track_ch_key[track_ch] := idx; end; If (fkey2 = kWeird) or (flag AND track_notes) then begin idx2 := 1; For idx := 1 to nm_track_chan do begin If (fkey2 = kWeird) or ((track_ch_key[idx2] <> BYTE_NULL) and (track_ch_key[idx2]+12*(current_octave-1) in [1..12*8+1])) then begin If NOT (jump_mark_mode and mark_lines) and (rec_correction <> 0) then begin patt_nm := HI(play_pos_buf[rec_correction]); line_nm := LO(play_pos_buf[rec_correction]); end else begin patt_nm := current_pattern; line_nm := current_line; end; If (jump_mark_mode and mark_lines and (line_nm MOD mark_line <> 0)) then begin dif1 := line_nm; While (dif1 MOD mark_line <> 0) and (dif1 <= songdata.patt_len) do Inc(dif1); If (dif1 > songdata.patt_len) then dif1 := 0; dif2 := line_nm; While (dif2 MOD mark_line <> 0) and (dif2 > 0) do Dec(dif2); If (Abs(dif1-line_nm) <= Abs(line_nm-dif2)) then line_nm := dif1 else line_nm := dif2; end; get_chunk(patt_nm,line_nm,curr_ch+idx-1,chunk); If (fkey2 <> kWeird) then begin If NOT right_shift_pressed then chunk.note := track_ch_key[idx2]+12*(current_octave-1) else chunk.note := track_ch_key[idx2]+12*(current_octave-1)+fixed_note_flag; If NOT (chunk.effect_def in [ef_TonePortamento, ef_TPortamVolSlide]) then begin If track_notes_ins then chunk.instr_def := current_inst else chunk.instr_def := min(voice_table[curr_ch+idx-1],1); If is_4op_chan(curr_ch+idx-1) and (curr_ch+idx-1 in _4op_tracks_lo) then begin get_chunk(patt_nm,line_nm,PRED(curr_ch)+idx-1,chunk2); chunk2.note := 0; If NOT track_notes or track_notes_ins then If (HI(get_4op_to_test) <> 0) then chunk2.instr_def := HI(get_4op_to_test) else chunk2.instr_def := current_inst else chunk2.instr_def := min(voice_table[PRED(curr_ch)+idx-1],1); If channel_flag[PRED(curr_ch)+idx-1] then put_chunk(patt_nm,line_nm,PRED(curr_ch)+idx-1,chunk2); end else If is_4op_chan(curr_ch+idx-1) and (curr_ch+idx-1 in _4op_tracks_hi) then begin get_chunk(patt_nm,line_nm,SUCC(curr_ch)+idx-1,chunk2); chunk2.note := 0; If NOT track_notes or track_notes_ins then If (LO(get_4op_to_test) <> 0) then chunk2.instr_def := LO(get_4op_to_test) else chunk2.instr_def := current_inst else chunk2.instr_def := min(voice_table[SUCC(curr_ch)+idx-1],1); If channel_flag[SUCC(curr_ch)+idx-1] then put_chunk(patt_nm,line_nm,SUCC(curr_ch)+idx-1,chunk2); end; end; end else begin chunk.note := BYTE_NULL; chunk.instr_def := 0; end; If channel_flag[curr_ch+idx-1] and NOT ignore_note_once[curr_ch+idx-1] then begin ignore_note_once[curr_ch+idx-1] := TRUE; put_chunk(patt_nm,line_nm,curr_ch+idx-1,chunk); If (patt_nm <> current_pattern) or (line_nm <= current_line) then begin If (chunk.instr_def <> 0) then load_instrument(songdata.instr_data[chunk.instr_def],curr_ch+idx-1); If is_4op_chan(curr_ch+idx-1) then If (curr_ch+idx-1 in _4op_tracks_lo) then begin get_chunk(patt_nm,line_nm,PRED(curr_ch)+idx-1,chunk2); load_instrument(songdata.instr_data[chunk2.instr_def],PRED(curr_ch)+idx-1); end else begin get_chunk(patt_nm,line_nm,SUCC(curr_ch)+idx-1,chunk2); load_instrument(songdata.instr_data[chunk2.instr_def],SUCC(curr_ch)+idx-1); end; If (chunk.note <> BYTE_NULL) then output_note(chunk.note AND $7f,chunk.instr_def,curr_ch+idx-1,TRUE,TRUE); end; Inc(idx2); end; If (play_status = isPaused) then begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; end; end; end; keyboard_reset_buffer; end; end; Case fkey2 of kCtLbr: If NOT shift_pressed then If (current_inst > 1) then begin If NOT (marked_instruments = 2) then begin Dec(current_inst); reset_marked_instruments; end else If NOT ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then Dec(current_inst) else While (current_inst > 1) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) do Dec(current_inst); instrum_page := current_inst; keyboard_reset_buffer; end; kCtRbr: If NOT shift_pressed then If (current_inst < 255) then begin If NOT (marked_instruments = 2) then begin Inc(current_inst); reset_marked_instruments; end else If NOT ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then Inc(current_inst) else While (current_inst < 255) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) do Inc(current_inst); instrum_page := current_inst; keyboard_reset_buffer; end; kAstrsk, kNPastr: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} For temp := 1 to songdata.nm_tracks do begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltL: begin pause_debugging; LINE_MARKING_SETUP; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltM: If (mark_line <> 0) then begin mark_lines := NOT mark_lines; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltS: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) and NOT track_notes then {$ELSE} If NOT track_notes then {$ENDIF} begin For temp := 1 to songdata.nm_tracks do channel_flag[temp] := FALSE; For temp := 1 to songdata.nm_tracks do If (temp = count_channel(pattern_hpos)) then begin channel_flag[temp] := TRUE; If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then channel_flag[SUCC(temp)] := TRUE else channel_flag[PRED(temp)] := TRUE; end; For temp := 1 to songdata.nm_tracks do If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltR: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} FillChar(channel_flag,songdata.nm_tracks,BYTE(TRUE)); kAlt1.. kAlt0: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} If (fkey2 <> kAlt0) then begin If shift_pressed then temp := HI(fkey2)-$77+10 else temp := HI(fkey2)-$77; If (temp <= songdata.nm_tracks) then begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then begin channel_flag[SUCC(temp)] := channel_flag[temp]; If NOT channel_flag[SUCC(temp)] then reset_chan_data(SUCC(temp)); end else begin channel_flag[PRED(temp)] := channel_flag[temp]; If NOT channel_flag[PRED(temp)] then reset_chan_data(PRED(temp)); end; end; end else If shift_pressed or (10 in [chan_pos..chan_pos+MAX_TRACKS-1]) or (songdata.nm_tracks = 10) then begin channel_flag[10] := NOT channel_flag[10]; If NOT channel_flag[10] then reset_chan_data(10); If is_4op_chan(10) then begin channel_flag[11] := channel_flag[10]; If NOT channel_flag[11] then reset_chan_data(11); end; end else begin If NOT percussion_mode then temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$1~6~$1~7~$1~8~$1~9~$2~0~$' else temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$16 ~B~D$17 ~S~D$18 ~T~T$19 T~C~$20 ~H~H$'; temps := FlipStr(temps); For temp := 10 to 20 do If (temp > songdata.nm_tracks) then begin Delete(temps,Pos('~',temps),1); Delete(temps,Pos('~',temps),1); end; temps := FlipStr(temps); If (Pos('~',temps) <> 0) then begin chpos := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO TOGGLE TRACK ON/OFF$', temps, ' TRACK ON/OFF ',chpos); If (dl_environment.keystroke <> kESC) then begin channel_flag[9+chpos] := NOT channel_flag[9+chpos]; If NOT channel_flag[9+chpos] then reset_chan_data(9+chpos); If is_4op_chan(9+chpos) then If (9+chpos in [10,12,14]) then begin channel_flag[SUCC(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[SUCC(9+chpos)] then reset_chan_data(SUCC(9+chpos)); end else If (9+chpos in [11,13,15]) then begin channel_flag[PRED(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[PRED(9+chpos)] then reset_chan_data(PRED(9+chpos)); end; end; end; end; kUP: If shift_pressed and track_notes then If NOT (jump_mark_mode and mark_lines) and (rec_correction < 9) then Inc(rec_correction) else else If NOT shift_pressed and (track_notes or (NOT debugging and (play_status = isPlaying))) then rewind := TRUE; kDOWN: If shift_pressed and track_notes then If NOT (jump_mark_mode and mark_lines) and (rec_correction > 0) then Dec(rec_correction) else else If NOT shift_pressed and (track_notes or (NOT debugging and (play_status = isPlaying))) then fast_forward := TRUE; kCtLEFT: If track_notes then If NOT debugging and (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If track_notes then If NOT debugging and (play_status = isPlaying) then fast_forward := TRUE; kLEFT, kShTAB: If NOT track_notes then If (chan_pos > 1) then begin Dec(chan_pos); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (pattern_hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kRIGHT, kTAB: If NOT track_notes then If (chan_pos < last_chan_pos) then begin Inc(chan_pos); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (pattern_hpos <= last_hpos-_pattedit_lastpos DIV MAX_TRACKS) then begin Inc(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kCHmins, kNPmins, kCtHOME: If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp > 0) and NOT (songdata.pattern_order[temp-1] < $80) do begin Dec(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp > 0) then begin Dec(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (fkey2 = kCtHOME) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCHplus, kNPplus, kCtEND: If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp < $7f) and (songdata.pattern_order[SUCC(temp)] > $80) do begin Inc(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp < $7f) then begin Inc(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (fkey2 = kCtEND) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCtENTR: If play_single_patt then begin current_line := 0; PATTERN_ORDER_page_refresh(0); PATTERN_page_refresh(0); end else begin no_status_refresh := TRUE; fade_out_playback(FALSE); If (current_order < $7f) and (play_status <> isStopped) then If (songdata.pattern_order[SUCC(current_order)] < $80) then calibrate_player(SUCC(current_order),0,FALSE,FALSE) else If (calc_following_order(SUCC(current_order)) <> -1) then calibrate_player(calc_following_order(SUCC(current_order)),0,FALSE,FALSE) else else If (calc_following_order(0) <> -1) then calibrate_player(calc_following_order(0),0,FALSE,FALSE); no_status_refresh := FALSE; end; kCtrlT: begin pause_debugging; TRANSPOSE; keyboard_reset_buffer; end; kCtrlR: begin pause_debugging; REMAP; keyboard_reset_buffer; end; kCtrlB: begin pause_debugging; MESSAGE_BOARD; keyboard_reset_buffer; end; kCtrlD: begin pause_debugging; DEBUG_INFO; keyboard_reset_buffer; end; kCtrlO: begin pause_debugging; OCTAVE_CONTROL; keyboard_reset_buffer; end; kCtrlP: begin pause_debugging; If NOT ((play_status <> isStopped) and tracing) then PATTERN_LIST(pattern_patt+1) else begin PATTERN_LIST(old_pattern_patt+1); old_pattern_patt := pattern_list__page-1; end; keyboard_reset_buffer; end; kCtrlF: begin cancel_note_recorder; pause_debugging; SONG_VARIABLES; keyboard_reset_buffer; end; kCtrlH: begin pause_debugging; REPLACE; keyboard_reset_buffer; end; kCtrlI: begin pause_debugging; INSTRUMENT_CONTROL; keyboard_reset_buffer; end; kCtrlE: begin pause_debugging; INSTRUMENT_CONTROL_edit; keyboard_reset_buffer; end; kCtrlQ: begin pause_debugging; MACRO_EDITOR(current_inst,FALSE); keyboard_reset_buffer; end; kCtrlG: begin pause_debugging; MACRO_EDITOR(current_inst,TRUE); keyboard_reset_buffer; end; kCtrlM: begin pause_debugging; MACRO_BROWSER(TRUE,TRUE); keyboard_reset_buffer; end; kCtrlX: begin pause_debugging; REARRANGE; keyboard_reset_buffer; end; kF1: begin pause_debugging; {$IFDEF GO32V2} If track_notes then HELP('note_recorder') {$ELSE} If (sdl_opl3_emulator = 1) and ((play_status = isPlaying) or opl3_channel_recording_mode) then HELP('wav_recorder') else If track_notes then HELP('note_recorder') {$ENDIF} else HELP('general'); keyboard_reset_buffer; end; kF2, kShF2, kCtrlS: begin pause_debugging; If (fkey2 = kShF2) then quick_cmd := TRUE; FILE_save('a2m'); quick_cmd := FALSE; keyboard_reset_buffer; end; kCtrlF2: begin pause_debugging; FILE_save('a2t'); keyboard_reset_buffer; end; kF3, kShF3, kCtrlL: begin pause_debugging; If (fkey2 = kShF3) then quick_cmd := TRUE; FILE_open('*.a2m$*.a2t$*.a2p$*.amd$*.cff$*.dfm$*.fmk$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); quick_cmd := FALSE; keyboard_reset_buffer; end; kF4, kCtrlA: NUKE; kSPACE: If ctrl_pressed then begin {$IFNDEF GO32V2} If NOT opl3_channel_recording_mode then {$ENDIF} If NOT track_notes then track_notes := TRUE else cancel_note_recorder; If track_notes then begin track_notes_ins := TRUE; If debugging then begin debugging := FALSE; stop_playing; end; track_chan_start := count_channel(pattern_hpos); midiboard := TRUE; end; fkey2 := WORD_NULL; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If track_notes then If alt_pressed then track_notes_ins := FALSE else track_notes_ins := TRUE else If (play_status = isPaused) and NOT track_notes then begin debugging := TRUE; replay_forbidden := FALSE; play_status := isPlaying; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kF10: begin QUIT_request; If (fkey = kESC) then begin fkey2 := kF10; nope := TRUE; end; end; kENTER, kESC: begin nope := TRUE; debugging := FALSE; If (fkey2 = kESC) and track_notes then cancel_note_recorder else begin If (fkey2 = kENTER) or (shift_pressed and (fkey2 = kESC)) then begin reset_pos := FALSE; If (fkey2 = kENTER) then begin replay_forbidden := TRUE; play_status := isPaused; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; end; kF5, kAltF5, kShF5: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; If (NOT nosync_by_default and (fkey2 = kAltF5)) or (nosync_by_default and (fkey2 = kF5)) then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey2 = kAltF5)) or (nosync_by_default and (fkey2 = kF5)) then no_sync_playing := TRUE; end; end; kF6: Case play_status of isPlaying: begin If NOT debugging then begin replay_forbidden := TRUE; play_status := isPaused; end; debugging := FALSE; end; isPaused: begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; end; end; kShF6: begin If track_notes then cancel_note_recorder; debugging := TRUE; replay_forbidden := FALSE; play_status := isPlaying; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kF7: begin fade_out_playback(FALSE); debugging := FALSE; stop_playing; nope := TRUE; If (play_status <> isStopped) then FillChar(ai_table,SizeOf(ai_table),0); end; kF8, kAltF8, kShF8: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := FALSE; If (NOT nosync_by_default and (fkey2 = kAltF8)) or (nosync_by_default and (fkey2 = kF8)) then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; repeat_pattern := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey2 = kAltF8)) or (nosync_by_default and (fkey2 = kF8)) then no_sync_playing := TRUE; end; end; kF9, kAltF9, kShF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If (NOT nosync_by_default and (fkey2 = kAltF9)) or (nosync_by_default and (fkey2 = kF8)) then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey2 = kAltF9)) or (nosync_by_default and (fkey2 = kF9)) then no_sync_playing := TRUE; end; end; end; If track_notes and (pattern_hpos <> old_hpos) then cancel_note_recorder; _end: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} If scankey(SC_F11) and NOT ctrl_pressed and NOT alt_pressed and NOT shift_pressed then begin If (command_typing <> 0) then Case command_typing of 1: If cycle_pattern then begin command_typing := 2; cycle_pattern := FALSE; end else cycle_pattern := TRUE; 2: begin command_typing := 1; cycle_pattern := FALSE; end; end; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; If scankey(SC_F12) and NOT ctrl_pressed and NOT alt_pressed then begin If NOT shift_pressed then linefeed := NOT linefeed else jump_mark_mode := NOT jump_mark_mode; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; until (nope or (play_status = isStopped)) or _force_program_quit; PATTERN_trace := fkey2; If (fkey2 = kF10) or _force_program_quit then EXIT; ThinCursor; tracing := FALSE; If (play_status <> isStopped) then cancel_note_recorder; If nope and reset_pos then begin pattord_page := old_pattord_page; pattord_hpos := old_pattord_hpos; pattord_vpos := old_pattord_vpos; pattern_patt := old_pattern_patt; pattern_page := old_pattern_page; pattern_hpos := old_pattern_hpos; end; debugging := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; procedure _save_pattern_to_undo; begin pattern_undo_flag := TRUE; pattern_undo_patt := pattern_patt; Move(pattdata^[pattern_undo_patt DIV 8][pattern_undo_patt MOD 8], pattern_undo_data, SizeOf(pattern_undo_data)); end; procedure _restore_pattern_from_undo; begin If pattern_undo_flag then begin Move(pattern_undo_data, pattdata^[pattern_undo_patt DIV 8][pattern_undo_patt MOD 8], SizeOf(pattern_undo_data)); pattern_undo_flag := FALSE; end; end; procedure PATTERN_edit(var pattern,page,hpos: Byte); var temp1,temp2,temp3,fkey_X: Word; temp,chan: Byte; tstr,temps: String; nope: Boolean; chunk,chunk2: tCHUNK; old_order,old_pattern,old_line: Byte; old_speed,old_tempo: Byte; old_patt_page: Byte; flag,flag2: Boolean; idx,idx2,track_ch,curr_ch: Byte; track_ch_key: array[1..20] of Byte; old_hpos: Byte; function correct_range(fxdef: Byte; var fxdata: Byte): Boolean; var result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit:correct_range'; {$ENDIF} result := FALSE; Case fxdef of ef_Arpeggio, ef_FSlideUp, ef_FSlideDown, ef_FSlideUpFine, ef_FSlideDownFine, ef_FSlideUpVSlide, ef_FSlUpVSlF, ef_FSlideDownVSlide, ef_FSlDownVSlF, ef_FSlUpFineVSlide, ef_FSlUpFineVSlF, ef_FSlDownFineVSlide, ef_FSlDownFineVSlF, ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine, ef_Vibrato, ef_VibratoVolSlide, ef_VibratoVSlideFine, ef_VolSlide, ef_VolSlideFine, ef_ArpggVSlide, ef_ArpggVSlideFine, ef_Tremolo, ef_Tremor, ef_ExtraFineVibrato, ef_ExtraFineTremolo, ef_SwapArpeggio, ef_SwapVibrato, ef_SetCustomSpeedTab, ef_GlobalFSlideUp, ef_GlobalFSlideDown: result := TRUE; ef_SetSpeed, ef_SetTempo, ef_ExtraFineArpeggio, ef_RetrigNote, ef_MultiRetrigNote: If (fxdata in [1..255]) then result := TRUE else If (command_typing <> 0) then begin If (fxdef <> ef_MultiRetrigNote) then fxdata := 1 else fxdata := $10; result := TRUE; end; ef_SetCarrierVol, ef_SetModulatorVol, ef_SetInsVolume, ef_ForceInsVolume, ef_SetGlobalVolume: If (fxdata in [0..63]) then result := TRUE else If (command_typing <> 0) then begin fxdata := 0; result := TRUE; end; ef_PatternBreak: result := TRUE; ef_PositionJump: If (fxdata in [0..127]) then result := TRUE else If (command_typing <> 0) then begin fxdata := 0; result := TRUE; end; ef_SetWaveform: If (fxdata DIV 16 in [0..7,$0f]) and (fxdata MOD 16 in [0..7,$0f]) then result := TRUE else If (command_typing <> 0) then begin If (fxdata DIV 16 in [0..7,$0f]) then fxdata := fxdata AND $f0 else If (fxdata MOD 16 in [0..7,$0f]) then fxdata := fxdata AND $0f else fxdata := 0; result := TRUE; end; ef_Extended: If (fxdata in [$00..$01,$10..$11, $20..$2f,$30..$3f, $40..$4f,$50..$5f, $60..$6f,$70..$7f, $80..$8f,$90..$9f, $a0..$a7,$b0..$b2, $c0..$cf,$d0..$df, $e0..$e6,$f0..$ff]) then result := TRUE else If (command_typing <> 0) then begin fxdata := fxdata AND $f0; result := TRUE; end; ef_Extended2: If (fxdata in [$01..$0f,$11..$1f, $21..$2f,$31..$3f, $41..$4f,$51..$5f, $61..$6f,$71..$7f, $81..$8f,$91..$9f, $a1..$af,$b1..$bf, $c1..$cf,$d1..$df, $e1..$ef,$f1..$ff]) then result := TRUE else If (command_typing <> 0) then begin fxdata := fxdata AND $f0+1; result := TRUE; end; ef_Extended3: If (fxdata in [$00..$01,$10..$1f, $20..$23,$30..$31, $40..$41,$50..$51, $60..$61,$70..$7f, $80..$83,$90..$91, $a0..$a1,$b0..$b1, $c0..$c1]) then result := TRUE else If (command_typing <> 0) then begin If (fxdata DIV 16 in [0..$0c]) then fxdata := fxdata AND $f0+1 else fxdata := 1; result := TRUE; end; end; correct_range := result; end; procedure copy_object; var chan: Byte; temp1,temp2: Word; temp3: tCOPY_OBJECT; chunk: tCHUNK; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit:copy_object'; {$ENDIF} chan := count_channel(hpos); If clipboard.object_type in [ objPatternDef,objPatternTable, objInstrument,objInstrumentBank, objNote,objInstrumentDef,objEffect,objEffect2, objLine,objTrack,objPattern,objMarkedBlock] then begin temp3 := clipboard.object_type; FillChar(clipboard,SizeOf(clipboard),0); clipboard.object_type := temp3; end; Case clipboard.object_type of objNote, objInstrumentDef, objEffect, objEffect2: begin get_chunk(pattern,page,chan,chunk); clipboard.pattern[1][0] := chunk; end; objLine: For temp1 := 1 to songdata.nm_tracks do begin get_chunk(pattern,page,temp1,chunk); clipboard.pattern[temp1][0] := chunk; end; objTrack: For temp1 := 0 to PRED(songdata.patt_len) do begin get_chunk(pattern,temp1,chan,chunk); clipboard.pattern[1][temp1] := chunk; end; objPattern: begin For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp2,temp1,chunk); clipboard.pattern[temp1][temp2] := chunk; end; clipboard._string := Copy(songdata.pattern_names[pattern],9,33); end; objMarkedBlock: begin clipboard.block_hsize := block_x1-block_x0; clipboard.block_vsize := block_y1-block_y0; For temp2 := block_y0 to block_y1 do For temp1 := block_x0 to block_x1 do begin get_chunk(pattern,temp2,temp1,chunk); clipboard.pattern[SUCC(temp1-block_x0)][temp2-block_y0] := chunk; end; end; end; end; procedure paste_object; var chan: Byte; temp1,temp2: Word; chunk: tCHUNK; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit:paste_object'; {$ENDIF} _save_pattern_to_undo; chan := count_channel(hpos); Case clipboard.object_type of objNote: begin get_chunk(pattern,page,chan,chunk); chunk.note := clipboard.pattern[1][0].note; put_chunk(pattern,page,chan,chunk); If linefeed then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; end; objInstrumentDef: begin get_chunk(pattern,page,chan,chunk); chunk.instr_def := clipboard.pattern[1][0].instr_def; put_chunk(pattern,page,chan,chunk); If linefeed then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; end; objEffect: begin get_chunk(pattern,page,chan,chunk); chunk.effect_def := clipboard.pattern[1][0].effect_def; chunk.effect := clipboard.pattern[1][0].effect; put_chunk(pattern,page,chan,chunk); If linefeed then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; end; objEffect2: begin get_chunk(pattern,page,chan,chunk); chunk.effect_def2 := clipboard.pattern[1][0].effect_def2; chunk.effect2 := clipboard.pattern[1][0].effect2; put_chunk(pattern,page,chan,chunk); If linefeed then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; end; objLine: begin For temp1 := 1 to songdata.nm_tracks do put_chunk(pattern,page,temp1, clipboard.pattern[temp1][0]); If linefeed then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; end; objTrack: For temp1 := 0 to PRED(songdata.patt_len) do put_chunk(pattern,temp1,chan, clipboard.pattern[1][temp1]); objPattern: begin For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do put_chunk(pattern,temp2,temp1, clipboard.pattern[temp1][temp2]); songdata.pattern_names[pattern] := Copy(songdata.pattern_names[pattern],1,8)+ clipboard._string; end; objMarkedBlock: If shift_pressed then begin For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do If (temp1 <= songdata.nm_tracks) and (temp2 <= PRED(songdata.patt_len)) then begin get_chunk(pattern,temp2,temp1,chunk); If (command_typing <> 0) then Case count_pos(hpos) of 0, 1: chunk.note := clipboard.pattern[SUCC(temp1-chan)][temp2-page].note; 2, 3: chunk.instr_def := clipboard.pattern[SUCC(temp1-chan)][temp2-page].instr_def; 4,5, 6: begin chunk.effect_def := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect_def; chunk.effect := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect; end; 7,8, 9: begin chunk.effect_def2 := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect_def2; chunk.effect2 := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect2; end; end else Case count_pos(hpos) of 0: chunk.note := clipboard.pattern[SUCC(temp1-chan)][temp2-page].note; 1: chunk.instr_def := clipboard.pattern[SUCC(temp1-chan)][temp2-page].instr_def; 2: begin chunk.effect_def := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect_def; chunk.effect := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect; end; 3: begin chunk.effect_def2 := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect_def2; chunk.effect2 := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect2; end; end; put_chunk(pattern,temp2,temp1,chunk); end; end else For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do If (temp1 <= songdata.nm_tracks) and (temp2 <= PRED(songdata.patt_len)) then put_chunk(pattern,temp2,temp1, clipboard.pattern[SUCC(temp1-chan)][temp2-page]); end; end; procedure paste_object_alt(pattern: Byte); var temp1,temp2: Word; chunk: tCHUNK; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit:paste_object_alt'; {$ENDIF} Case clipboard.object_type of objNote: begin get_chunk(pattern,page,chan,chunk); chunk.note := clipboard.pattern[1][0].note; put_chunk(pattern,page,chan,chunk); end; objInstrumentDef: begin get_chunk(pattern,page,chan,chunk); chunk.instr_def := clipboard.pattern[1][0].instr_def; put_chunk(pattern,page,chan,chunk); end; objEffect: begin get_chunk(pattern,page,chan,chunk); chunk.effect_def := clipboard.pattern[1][0].effect_def; chunk.effect := clipboard.pattern[1][0].effect; put_chunk(pattern,page,chan,chunk); end; objEffect2: begin get_chunk(pattern,page,chan,chunk); chunk.effect_def2 := clipboard.pattern[1][0].effect_def2; chunk.effect2 := clipboard.pattern[1][0].effect2; put_chunk(pattern,page,chan,chunk); end; objLine: begin For temp1 := 1 to songdata.nm_tracks do put_chunk(pattern,page,temp1, clipboard.pattern[temp1][0]); end; objTrack: For temp1 := 0 to PRED(songdata.patt_len) do put_chunk(pattern,temp1,chan, clipboard.pattern[1][temp1]); objPattern: For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do put_chunk(pattern,temp2,temp1, clipboard.pattern[temp1][temp2]); objMarkedBlock: For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do If (temp1 <= songdata.nm_tracks) and (temp2 <= PRED(songdata.patt_len)) then put_chunk(pattern,temp2,temp1, clipboard.pattern[SUCC(temp1-chan)][temp2-page]); end; end; function FX(chr: Char): Byte; begin FX := PRED(Pos(UpCase(chr),fx_digits)); end; function update_block_volume(block_x0,block_y0,block_x1,block_y1: Byte; volume_commands: tByteSet; shift: Integer; var fx_found_flag: Boolean; update_values: Boolean): Boolean; var temp1,temp2: Byte; begin _save_pattern_to_undo; fx_found_flag := FALSE; For temp2 := block_y0 to block_y1 do For temp1 := block_x0 to block_x1 do begin get_chunk(pattern,temp2,temp1,chunk); If (chunk.effect_def in volume_commands) then begin fx_found_flag := TRUE; If (shift >= 0) then If (chunk.effect+shift <= 63) then Inc(chunk.effect,shift) else begin update_block_volume := FALSE; EXIT; end else If (chunk.effect+shift >= 0) then Inc(chunk.effect,shift) else begin update_block_volume := FALSE; EXIT; end; end; If (chunk.effect_def2 in volume_commands) then begin fx_found_flag := TRUE; If (shift >= 0) then If (chunk.effect2+shift <= 63) then Inc(chunk.effect2,shift) else begin update_block_volume := FALSE; EXIT; end else If (chunk.effect2+shift >= 0) then Inc(chunk.effect2,shift) else begin update_block_volume := FALSE; EXIT; end; end; If update_values then put_chunk(pattern,temp2,temp1,chunk); end; update_block_volume := fx_found_flag; end; procedure enter_debug_mode(pattern,page: Byte); begin cancel_note_recorder; If NOT replay_forbidden then begin debugging := TRUE; play_status := isPlaying; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If NOT play_single_patt and (calc_pattern_pos(pattern) <> BYTE_NULL) then begin fade_out_playback(FALSE); calibrate_player(calc_pattern_pos(pattern),page,TRUE,TRUE); If (play_status <> isStopped) then begin debugging := TRUE; play_status := isPlaying; replay_forbidden := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else If (calc_pattern_pos(pattern) = BYTE_NULL) then begin fade_out_playback(FALSE); play_single_patt := TRUE; no_sync_playing := TRUE; start_pattern := pattern_patt; start_line := pattern_page; start_playing; debugging := TRUE; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; label _end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit'; {$ENDIF} fkey_X := WORD_NULL; chan := count_channel(hpos); Repeat If (page > PRED(songdata.patt_len)) then page := PRED(songdata.patt_len); While NOT ((chan_pos <= last_chan_pos) and (hpos <= last_hpos)) do If (hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(hpos,_pattedit_lastpos DIV MAX_TRACKS); If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end else If (chan_pos > 1) then begin Dec(chan_pos); If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end else If cycle_pattern then begin chan_pos := last_chan_pos; hpos := last_hpos; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(page); If (command_typing <> 0) then GotoXY(08+pos4[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)) else GotoXY(08+pos3[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)); If tracing then fkey := PATTERN_trace else ThinCursor; nope := FALSE; If ctrl_pressed and alt_pressed then begin DEBUG_INFO; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; old_patt_page := page; old_hpos := hpos; If keypressed then fkey := getkey else If NOT (seconds_counter >= ssaver_time) then GOTO _end //CONTINUE else begin screen_saver; GOTO _end; //CONTINUE; end; If (fkey <> kAltQ) then quick_mark_type := 0; If NOT shift_pressed and NOT (marking and ((fkey = kAltC) or (fkey = kCtrlN) or (fkey = kCtrlB) or (fkey = kCtrlD) or (fkey = kCtrlC) or (fkey = kCtrlV) or (fkey = kCtrlX) or (fkey = kCtPgUP) or (fkey = kCtrlM) or (fkey = kCtPgDN) or (fkey = kCtrlT) or (fkey = kCtrlR) or (fkey = kCtrlH) or (fkey = kAltQ) or (fkey = kCtrlD) or (fkey = kCtrlZ) or (fkey = kAltM) or (fkey = kAltL) or (fkey = kF5) or (fkey = kAltF5) or (fkey = kF6) or (fkey = kAltF6) or (fkey = kF7) or (fkey = kF8) or (fkey = kAltF8) or (fkey = kCtrlF8) or (fkey = kF9) or (fkey = kAltF9) or (fkey = kCtrlF9) or (fkey = kCtLeft) or (fkey = kCtRght) or (fkey = kCtENTR) or (fkey = kAltB) or (fkey = kAltV) or (fkey = kCHmins) or (fkey = kNPplus) or (fkey = kNPmins))) or (shift_pressed and NOT ((fkey = kLEFT) or (fkey = kRIGHT) or (fkey = kUP) or (fkey = kDOWN) or (fkey = kPgUP) or (fkey = kPgDOWN) or (fkey = kNPPgUP) or (fkey = kNPPgDN) or (fkey = kHOME) or (fkey = kEND) or (fkey = kNPHOME) or (fkey = kNPEND) or (marking and ((fkey = kAltF5) or (fkey = kShF5) or (fkey = kAltF6) or (fkey = kShF6) or (fkey = kAltF8) or (fkey = kShF8) or (fkey = kCtrlF8) or (fkey = kAltF9) or (fkey = kShF9) or (fkey = kCtrlF9) or (fkey = kCtLEFT) or (fkey = kCtRGHT) or (fkey = kCHplus))) or (fkey = kCtENTR))) then begin If marking and NOT (((fkey = kENTER) and shift_pressed) or (fkey = kF1)) then begin old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; fkey := WORD_NULL; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(page); If (command_typing <> 0) then GotoXY(08+pos4[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)) else GotoXY(08+pos3[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)); end; end else If NOT marking and NOT track_notes and (fkey <> kPgUP) and (fkey <> kPgDOWN) and (fkey <> kNPPgUP) and (fkey <> kNPPgDN) and (fkey <> kHOME) and (fkey <> kEND) and (fkey <> kNPHOME) and (fkey <> kNPEND) then begin old_chan_pos := chan_pos; old_hpos := hpos; old_page := page; marking := TRUE; cancel_note_recorder; fkey := WORD_NULL; block_xstart := chan; block_ystart := page; end; Case fkey of kCHlbrk, kCtLbr: If NOT shift_pressed then If (current_inst > 1) then begin If NOT (marked_instruments = 2) then begin Dec(current_inst); reset_marked_instruments; end else If NOT ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then Dec(current_inst) else While (current_inst > 1) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) do Dec(current_inst); instrum_page := current_inst; keyboard_reset_buffer; end; kCHrbrk, kCtRbr: If NOT shift_pressed then If (current_inst < 255) then begin If NOT (marked_instruments = 2) then begin Inc(current_inst); reset_marked_instruments; end else If NOT ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then Inc(current_inst) else While (current_inst < 255) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) do Inc(current_inst); instrum_page := current_inst; keyboard_reset_buffer; end; kLEFT: If marking then begin If (hpos > _pattedit_lastpos DIV MAX_TRACKS) then Dec(hpos,_pattedit_lastpos DIV MAX_TRACKS) else If (chan_pos > 1) then Dec(chan_pos); end else If hpos > 1 then Dec(hpos) else If (chan_pos > 1) then begin Dec(chan_pos); hpos := _pattedit_lastpos DIV MAX_TRACKS; end else If cycle_pattern then begin chan_pos := last_chan_pos; hpos := last_hpos; end; kRIGHT: If marking then begin If (hpos <= last_hpos-_pattedit_lastpos DIV MAX_TRACKS) then Inc(hpos,_pattedit_lastpos DIV MAX_TRACKS) else If (chan_pos < last_chan_pos) then Inc(chan_pos); end else If hpos < last_hpos then Inc(hpos) else If (chan_pos < last_chan_pos) then begin Inc(chan_pos); hpos := last_hpos-PRED(_pattedit_lastpos DIV MAX_TRACKS); end else If cycle_pattern then begin chan_pos := 1; hpos := 1; end; kUP: If shift_pressed and track_notes then If NOT (jump_mark_mode and mark_lines) and (rec_correction < 9) then Inc(rec_correction) else else If (page > 0) then Dec(page) else If NOT marking and cycle_pattern then page := PRED(songdata.patt_len); kDOWN: If shift_pressed and track_notes then If NOT (jump_mark_mode and mark_lines) and (rec_correction > 0) then Dec(rec_correction) else else If (page < PRED(songdata.patt_len)) then Inc(page) else If NOT marking and cycle_pattern then page := 0; kCHplus, kNPplus: If NOT marking then If pattern < PRED(max_patterns) then Inc(pattern) else else begin If update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetInsVolume,ef_ForceInsVolume],+1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetInsVolume,ef_ForceInsVolume],+1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetModulatorVol],+1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetModulatorVol],+1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetCarrierVol],+1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetCarrierVol],+1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetGlobalVolume],+1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetGlobalVolume],+1,flag2,TRUE); PATTERN_page_refresh(pattern_page); end; kCHmins, kNPmins: If NOT marking then If pattern > 0 then Dec(pattern) else else begin If update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetInsVolume,ef_ForceInsVolume],-1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetInsVolume,ef_ForceInsVolume],-1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetModulatorVol],-1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetModulatorVol],-1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetCarrierVol],-1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetCarrierVol],-1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetGlobalVolume],-1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetGlobalVolume],-1,flag2,TRUE); PATTERN_page_refresh(pattern_page); end; kPgUP: If NOT shift_pressed or marking then begin If page > max(16,songdata.patt_len) then Dec(page,max(16,songdata.patt_len)) else page := 0; end else If pattern > 0 then Dec(pattern); kPgDOWN: If NOT shift_pressed or marking then begin If page < PRED(songdata.patt_len)-max(16,songdata.patt_len) then Inc(page,max(16,songdata.patt_len)) else page := PRED(songdata.patt_len); end else If pattern < PRED(max_patterns) then Inc(pattern); kNPUp, kNPDown: If NumLock then nope := TRUE; kNPPgUP: If NumLock then nope := TRUE else If shift_pressed then If NOT marking and (pattern > 0) then Dec(pattern) else If marking then begin If page > max(16,songdata.patt_len) then Dec(page,max(16,songdata.patt_len)) else page := 0; end; kNPPgDN: If NumLock then nope := TRUE else If shift_pressed then If NOT marking and (pattern < PRED(max_patterns)) then Inc(pattern) else If marking then begin If page < PRED(songdata.patt_len)-max(16,songdata.patt_len) then Inc(page,max(16,songdata.patt_len)) else page := PRED(songdata.patt_len); end; kCtHOME: If pattern > 0 then begin Dec(pattern); page := PRED(songdata.patt_len); end; kCtEND: If pattern < PRED(max_patterns) then begin Inc(pattern); page := 0; end; kHOME: If NOT shift_pressed or marking then If (page <> 0) then page := 0 else begin chan_pos := 1; hpos := 1; end else If (chan_pos+hpos-1 <> 1) then begin chan_pos := 1; hpos := 1; end else If (page <> 0) then page := 0 else pattern := 0; kEND: If NOT shift_pressed or marking then If (page <> PRED(songdata.patt_len)) then page := PRED(songdata.patt_len) else begin chan_pos := last_chan_pos; hpos := last_hpos; end else If (chan_pos+hpos <> last_chan_pos+last_hpos) then begin chan_pos := last_chan_pos; hpos := last_hpos; end else If (page <> PRED(songdata.patt_len)) then page := PRED(songdata.patt_len) else pattern := PRED(max_patterns); kNPHOME: If NumLock then nope := TRUE else If shift_pressed then If NOT marking then begin If (chan_pos+hpos-1 <> 1) then begin chan_pos := 1; hpos := 1; end else If (page <> 0) then page := 0 else pattern := 0; end else If (page <> 0) then page := 0 else begin chan_pos := 1; hpos := 1; end; kNPEND: If NumLock then nope := TRUE else If shift_pressed then If NOT marking then begin If (chan_pos+hpos <> last_chan_pos+last_hpos) then begin chan_pos := last_chan_pos; hpos := last_hpos; end else If (page <> PRED(songdata.patt_len)) then page := PRED(songdata.patt_len) else pattern := PRED(max_patterns); end else If (page <> PRED(songdata.patt_len)) then page := PRED(songdata.patt_len) else begin chan_pos := last_chan_pos; hpos := last_hpos; end; kAstrsk, kNPastr: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} For temp1 := 1 to songdata.nm_tracks do begin channel_flag[temp1] := NOT channel_flag[temp1]; If NOT channel_flag[temp1] then reset_chan_data(temp1); end; kAltL: begin LINE_MARKING_SETUP; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltM: If (mark_line <> 0) then begin mark_lines := NOT mark_lines; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltS: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) and NOT track_notes then {$ELSE} If NOT track_notes then {$ENDIF} begin For temp := 1 to songdata.nm_tracks do channel_flag[temp] := FALSE; For temp := 1 to songdata.nm_tracks do If (temp = count_channel(pattern_hpos)) then begin channel_flag[temp] := TRUE; If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then channel_flag[SUCC(temp)] := TRUE else channel_flag[PRED(temp)] := TRUE; end; For temp := 1 to songdata.nm_tracks do If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltR: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} FillChar(channel_flag,songdata.nm_tracks,BYTE(TRUE)); kAlt1.. kAlt0: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} If (fkey <> kAlt0) then begin If shift_pressed then temp := HI(fkey)-$77+10 else temp := HI(fkey)-$77; If (temp <= songdata.nm_tracks) then begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then begin channel_flag[SUCC(temp)] := channel_flag[temp]; If NOT channel_flag[SUCC(temp)] then reset_chan_data(SUCC(temp)); end else begin channel_flag[PRED(temp)] := channel_flag[temp]; If NOT channel_flag[PRED(temp)] then reset_chan_data(PRED(temp)); end; end; end else If shift_pressed or (10 in [chan_pos..chan_pos+MAX_TRACKS-1]) or (songdata.nm_tracks = 10) then begin channel_flag[10] := NOT channel_flag[10]; If NOT channel_flag[10] then reset_chan_data(10); If is_4op_chan(10) then begin channel_flag[11] := channel_flag[10]; If NOT channel_flag[11] then reset_chan_data(11); end; end else begin If NOT percussion_mode then temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$1~6~$1~7~$1~8~$1~9~$2~0~$' else temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$16 ~B~D$17 ~S~D$18 ~T~T$19 T~C~$20 ~H~H$'; temps := FlipStr(temps); For temp := 10 to 20 do If (temp > songdata.nm_tracks) then begin Delete(temps,Pos('~',temps),1); Delete(temps,Pos('~',temps),1); end; temps := FlipStr(temps); If (Pos('~',temps) <> 0) then begin chpos := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO TOGGLE TRACK ON/OFF$', temps, ' TRACK ON/OFF ',chpos); If (dl_environment.keystroke <> kESC) then begin channel_flag[9+chpos] := NOT channel_flag[9+chpos]; If NOT channel_flag[9+chpos] then reset_chan_data(9+chpos); If is_4op_chan(9+chpos) then If (9+chpos in [10,12,14]) then begin channel_flag[SUCC(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[SUCC(9+chpos)] then reset_chan_data(SUCC(9+chpos)); end else If (9+chpos in [11,13,15]) then begin channel_flag[PRED(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[PRED(9+chpos)] then reset_chan_data(PRED(9+chpos)); end; end; end; end; kShTAB: If (hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(hpos,_pattedit_lastpos DIV MAX_TRACKS); If NOT keep_track_pos then begin If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end end else If (chan_pos > 1) then begin Dec(chan_pos); If NOT keep_track_pos then begin If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end end else If cycle_pattern then begin chan_pos := last_chan_pos; If NOT keep_track_pos then hpos := last_hpos; end; kTAB: If (hpos <= last_hpos-_pattedit_lastpos DIV MAX_TRACKS) then begin Inc(hpos,_pattedit_lastpos DIV MAX_TRACKS); If NOT keep_track_pos then begin If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end end else If (chan_pos < last_chan_pos) then begin Inc(chan_pos); If NOT keep_track_pos then begin If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end end else If cycle_pattern then begin chan_pos := 1; If NOT keep_track_pos then hpos := 1; end; kSPACE: If ctrl_pressed and NOT shift_pressed and NOT alt_pressed then begin {$IFNDEF GO32V2} If NOT opl3_channel_recording_mode then {$ENDIF} If NOT track_notes then track_notes := TRUE else cancel_note_recorder; If track_notes and (play_status <> isStopped) then stop_playing; If track_notes then begin track_notes_ins := TRUE; If debugging then begin debugging := FALSE; stop_playing; end; track_chan_start := chan; nm_track_chan := 1; midiboard := TRUE; end; fkey := WORD_NULL; end else If track_notes then If alt_pressed then track_notes_ins := FALSE else track_notes_ins := TRUE else If NOT ctrl_pressed and shift_pressed and NOT alt_pressed then begin midiboard := NOT midiboard; fkey := WORD_NULL; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then If NOT midiboard then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; kINSERT: If NOT shift_pressed then begin _save_pattern_to_undo; For temp1 := PRED(songdata.patt_len)-1 downto page do begin get_chunk(pattern,temp1,chan,chunk); put_chunk(pattern,temp1+1,chan,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,page,chan,chunk); end else begin _save_pattern_to_undo; For temp1 := PRED(songdata.patt_len)-1 downto page do For temp2 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp1,temp2,chunk); put_chunk(pattern,temp1+1,temp2,chunk); end; For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,page,temp1,chunk); end; end; kDELETE: If NOT shift_pressed then begin _save_pattern_to_undo; For temp1 := page to PRED(songdata.patt_len)-1 do begin get_chunk(pattern,temp1+1,chan,chunk); put_chunk(pattern,temp1,chan,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),chan,chunk); end else begin _save_pattern_to_undo; For temp1 := page to PRED(songdata.patt_len)-1 do For temp2 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp1+1,temp2,chunk); put_chunk(pattern,temp1,temp2,chunk); end; For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),temp1,chunk); end; end; kNPins: If NumLock then nope := TRUE else If shift_pressed then begin _save_pattern_to_undo; For temp1 := PRED(songdata.patt_len)-1 downto page do For temp2 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp1,temp2,chunk); put_chunk(pattern,temp1+1,temp2,chunk); end; For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,page,temp1,chunk); end; end; kNPdel: If NumLock then nope := TRUE else If shift_pressed then begin _save_pattern_to_undo; For temp1 := page to PRED(songdata.patt_len)-1 do For temp2 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp1+1,temp2,chunk); put_chunk(pattern,temp1,temp2,chunk); end; For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),temp1,chunk); end; end; kAltB: If marking then begin old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; chan_pos := old_chan_pos; hpos := old_hpos; page := old_page; marking := FALSE; end else begin old_chan_pos := chan_pos; old_hpos := hpos; old_page := page; hpos := old_block_patt_hpos; page := old_block_patt_page; chan_pos := old_block_chan_pos; marking := TRUE; cancel_note_recorder; end; kAltQ: If track_notes then If (old_nm_track_chan <> 0) and (old_track_chan_start <> 0) and (old_track_chan_start+old_nm_track_chan-1 <= songdata.nm_tracks) then begin nm_track_chan := old_nm_track_chan; track_chan_start := old_track_chan_start; chan_pos := track_chan_start; hpos := 1; While (chan < chan_pos) do Inc(hpos); old_hpos := hpos; end else else Case quick_mark_type of 0: begin old_chan_pos := chan_pos; old_hpos := hpos; old_page := page; page := 0; marking := TRUE; cancel_note_recorder; block_xstart := chan; block_ystart := PRED(songdata.patt_len); quick_mark_type := 1; end; 1: begin marking := TRUE; cancel_note_recorder; chan_pos := 1; hpos := 1; page := 0; block_xstart := songdata.nm_tracks; block_ystart := PRED(songdata.patt_len); quick_mark_type := 2; end; 2: begin old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; chan_pos := old_chan_pos; hpos := old_hpos; page := old_page; marking := FALSE; quick_mark_type := 0; end; end; kCtrlK: If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,pattern_page,track_chan_start+idx-1,chunk); chunk.note := BYTE_NULL; chunk.instr_def := 0; put_chunk(pattern,pattern_page,track_chan_start+idx-1,chunk); keyboard_reset_buffer; end; If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; end else begin get_chunk(pattern,pattern_page,chan,chunk); chunk.note := BYTE_NULL; chunk.instr_def := 0; put_chunk(pattern,pattern_page,chan,chunk); If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; end; kBkSPC: If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,pattern_page,track_chan_start+idx-1,chunk); If (command_typing <> 0) then Case count_pos(hpos) of 0, 1: begin chunk.note := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; If midiboard then begin chunk.instr_def := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; end; end; 2, 3: begin chunk.instr_def := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; end; 4,5, 6: begin chunk.effect_def := 0; chunk.effect := 0; end; 7,8, 9: begin chunk.effect_def2 := 0; chunk.effect2 := 0; end; end else Case count_pos(hpos) of 0: begin chunk.note := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; If midiboard then begin chunk.instr_def := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; end; end; 1: begin chunk.instr_def := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; end; 2: begin chunk.effect_def := 0; chunk.effect := 0; end; 3: begin chunk.effect_def2 := 0; chunk.effect2 := 0; end; end; put_chunk(pattern,pattern_page,track_chan_start+idx-1,chunk); end; Case backspace_dir of 1: If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; 2: If page > 0 then Dec(page) else If cycle_pattern then page := PRED(songdata.patt_len); end; end else begin get_chunk(pattern,pattern_page,chan,chunk); If (command_typing <> 0) then Case count_pos(hpos) of 0, 1: begin chunk.note := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; If midiboard then begin chunk.instr_def := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; end; end; 2, 3: begin chunk.instr_def := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; end; 4,5, 6: begin chunk.effect_def := 0; chunk.effect := 0; end; 7,8, 9: begin chunk.effect_def2 := 0; chunk.effect2 := 0; end; end else Case count_pos(hpos) of 0: begin chunk.note := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; If midiboard then begin chunk.instr_def := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; end; end; 1: begin chunk.instr_def := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; end; 2: begin chunk.effect_def := 0; chunk.effect := 0; end; 3: begin chunk.effect_def2 := 0; chunk.effect2 := 0; end; end; put_chunk(pattern,pattern_page,chan,chunk); Case backspace_dir of 1: If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; 2: If page > 0 then Dec(page) else If cycle_pattern then page := PRED(songdata.patt_len); end; end; kCtPgUP: begin _save_pattern_to_undo; If marking then transpose_custom_area(ttTransposeUp, ttTransposeAllIns, pattern,pattern,block_x0,block_x1,block_y0,block_y1, 1) else transpose_custom_area(ttTransposeUp, ttTransposeAllIns, pattern,pattern,chan,chan,page,page, 1); end; kCtPgDN: begin _save_pattern_to_undo; If marking then transpose_custom_area(ttTransposeDown, ttTransposeAllIns, pattern,pattern,block_x0,block_x1,block_y0,block_y1, 1) else transpose_custom_area(ttTransposeDown, ttTransposeAllIns, pattern,pattern,chan,chan,page,page, 1); end; kCtrlC: begin If marking then clipboard.object_type := objMarkedBlock else If (command_typing <> 0) then Case count_pos(hpos) of 0, 1: clipboard.object_type := objNote; 2, 3: clipboard.object_type := objInstrumentDef; 4,5, 6: clipboard.object_type := objEffect; 7,8, 9: clipboard.object_type := objEffect2; end else Case count_pos(hpos) of 0: clipboard.object_type := objNote; 1: clipboard.object_type := objInstrumentDef; 2: clipboard.object_type := objEffect; 3: clipboard.object_type := objEffect2; end; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; copy_object; end; kAltP: If shift_pressed then begin temp := PATTERN_LIST_alt(pattern_list__page); If (temp <> BYTE_NULL) then If (_patts_marked <> 0) then begin For temp := 0 to PRED(max_patterns) do If (songdata.pattern_names[temp][1] <> ' ') then paste_object_alt(temp); end else paste_object_alt(temp-1); end else paste_object; kCtrlV: paste_object; kAltV: If (clipboard.object_type = objMarkedBlock) then begin _save_pattern_to_undo; If NOT shift_pressed then For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do begin get_chunk(pattern,temp2,temp1,chunk); If (chunk.note = 0) then begin chunk.note := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].note; chunk.instr_def := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].instr_def; end; If (chunk.effect_def = 0) then chunk.effect_def := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].effect_def; If (chunk.effect = 0) then chunk.effect := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].effect; If (chunk.effect_def2 = 0) then chunk.effect_def2 := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].effect_def2; If (chunk.effect2 = 0) then chunk.effect2 := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].effect2; put_chunk(pattern,temp2,temp1,chunk); end else For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do put_chunk(pattern,temp2,temp1, clipboard.pattern[SUCC(temp1-chan)][clipboard.block_vsize-(temp2-page)]); end; kCtrlZ: _restore_pattern_from_undo; kCtrlX: If NOT marking then REARRANGE else begin _save_pattern_to_undo; clipboard.object_type := objMarkedBlock; clipboard.block_hsize := block_x1-block_x0; clipboard.block_vsize := block_y1-block_y0; For temp2 := block_y0 to block_y1 do For temp1 := block_x0 to block_x1 do begin get_chunk(pattern,temp2,temp1,chunk); clipboard.pattern[SUCC(temp1-block_x0)] [temp2-block_y0] := chunk; end; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; For temp2 := block_x0 to block_x1 do For temp1 := block_y0 to block_y1 do begin For temp3 := block_y0 to PRED(songdata.patt_len) do begin get_chunk(pattern,temp3+1,temp2,chunk); put_chunk(pattern,temp3,temp2,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),temp2,chunk); end; end; kCtrlN: If marking then begin _save_pattern_to_undo; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; For temp2 := block_y0 to block_y1 do For temp1 := block_x0 to block_x1 do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,temp2,temp1,chunk); end; end; kAltC: begin mn_setting.cycle_moves := TRUE; If NOT marking then copy_menu_str2[12] := copy_marked_str[1] else copy_menu_str2[12] := copy_marked_str[2]; temp1 := Menu(copy_menu_str2,01,01,copypos2,30,15,15,' COPY OBJECT '); If (mn_environment.keystroke <> kESC) then begin copypos2 := temp1; If marking and (tCOPY_OBJECT(temp1) = objMarkedBlock) then clipboard.object_type := objMarkedBlock else If (tCOPY_OBJECT(temp1) <> objMarkedBlock) then clipboard.object_type := tCOPY_OBJECT(temp1) else GOTO _end; //CONTINUE; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; copy_object; end; end; kCtrlB: If NOT marking then MESSAGE_BOARD else begin _save_pattern_to_undo; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; For temp2 := block_x0 to block_x1 do For temp1 := block_y0 to block_y1 do begin For temp3 := PRED(songdata.patt_len)-1 downto block_y0 do begin get_chunk(pattern,temp3,temp2,chunk); put_chunk(pattern,temp3+1,temp2,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,block_y0,temp2,chunk); end; end; kCtrlD: If NOT marking then DEBUG_INFO else begin _save_pattern_to_undo; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; For temp2 := block_x0 to block_x1 do For temp1 := block_y0 to block_y1 do begin For temp3 := block_y0 to PRED(songdata.patt_len)-1 do begin get_chunk(pattern,temp3+1,temp2,chunk); put_chunk(pattern,temp3,temp2,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),temp2,chunk); end; end; kCtrlT: TRANSPOSE; kCtrlR: REMAP; kCtrlO: OCTAVE_CONTROL; kCtrlP: If NOT ((play_status <> isStopped) and tracing) then PATTERN_LIST(pattern_patt+1) else begin PATTERN_LIST(old_pattern_patt+1); old_pattern_patt := pattern_list__page-1; end; kCtrlF: begin cancel_note_recorder; SONG_VARIABLES; end; kCtrlH: REPLACE; kCtrlI: INSTRUMENT_CONTROL; kCtrlE: INSTRUMENT_CONTROL_edit; kCtrlQ: MACRO_EDITOR(current_inst,FALSE); kCtrlG: MACRO_EDITOR(current_inst,TRUE); kCtrlM: MACRO_BROWSER(TRUE,TRUE); kCtLEFT: If track_notes then begin If (track_chan_start = chan) and (nm_track_chan > 1) then Dec(nm_track_chan) else If (track_chan_start > chan_pos) then begin Dec(track_chan_start); Inc(nm_track_chan); end; end else If NOT debugging and (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If track_notes then begin If (track_chan_start = chan) and (track_chan_start+nm_track_chan-chan_pos < max(MAX_TRACKS,songdata.nm_tracks)) then Inc(nm_track_chan) else If (track_chan_start < chan) then begin Inc(track_chan_start); Dec(nm_track_chan); end; end else If (play_status = isPlaying) then fast_forward := TRUE; kCtENTR: If play_single_patt then current_line := 0 else begin no_status_refresh := TRUE; fade_out_playback(FALSE); If (current_order < $7f) and (play_status <> isStopped) then If (songdata.pattern_order[SUCC(current_order)] < $80) then calibrate_player(SUCC(current_order),0,FALSE,FALSE) else If (calc_following_order(SUCC(current_order)) <> -1) then calibrate_player(calc_following_order(SUCC(current_order)),0,FALSE,FALSE) else else If debugging and (play_status = isStopped) then enter_debug_mode(SUCC(pattern),0); no_status_refresh := FALSE; end; kF1: begin If marking then temps := 'block_operations' else If NOT (command_typing <> 0) and (count_pos(hpos) in [2,3]) then temps := 'effects_page1' else If (command_typing <> 0) and (count_pos(hpos) in [4..9]) then temps := 'effects_page1' else If debugging and (play_status = isStopped) then temps := 'midiboard' else temps := 'pattern_editor'; {$IFDEF GO32V2} If track_notes then HELP('note_recorder') {$ELSE} If NOT marking and (sdl_opl3_emulator = 1) and opl3_channel_recording_mode then HELP('wav_recorder') else If track_notes then HELP('note_recorder') {$ENDIF} else begin get_chunk(pattern,page,chan,chunk); If NOT marking and ((NOT (command_typing <> 0) and (count_pos(hpos) = 2)) or ((command_typing <> 0) and (count_pos(hpos) in [4,5,6]))) then temp1 := chunk.effect_def+(chunk.effect DIV 16) SHL 8 else If NOT marking and ((NOT (command_typing <> 0) and (count_pos(hpos) = 3)) or ((command_typing <> 0) and (count_pos(hpos) in [7,8,9]))) then temp1 := chunk.effect_def2+(chunk.effect2 DIV 16) SHL 8 else temp1 := WORD_NULL; If (temp1 <> WORD_NULL) then Case LO(temp1) of ef_Arpeggio..ef_SetWaveform: temps := 'effects_page1'; ef_VolSlideFine..ef_FSlDownFineVSlF: temps := 'effects_page2'; ef_Extended: Case HI(temp1) of ef_ex_SetTremDepth..ef_ex_PatternLoopRec: temps := 'effects_page3' else temps := 'effects_page4'; end; ef_Extended3: temps := 'effects_page5'; ef_Extended2: temps := 'effects_page6'; else temps := 'effects_page7'; end; HELP(temps); end; end; kF2, kShF2, kCtrlS: begin If (fkey = kShF2) then quick_cmd := TRUE; FILE_save('a2m'); quick_cmd := FALSE; end; kAltF2: FILE_save('a2p'); kCtrlF2: FILE_save('a2t'); kF3, kShF3, kCtrlL: begin If (fkey = kShF3) then quick_cmd := TRUE; FILE_open('*.a2m$*.a2t$*.a2p$*.amd$*.cff$*.dfm$*.fmk$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); quick_cmd := FALSE; end; kF4, kCtrlA: NUKE; kF5, kAltF5, kShF5: begin cancel_note_recorder; If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; isStopped: begin If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; start_playing; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; end; kF6: Case play_status of isPlaying: begin replay_forbidden := TRUE; play_status := isPaused; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; end; end; kShF6: enter_debug_mode(pattern,page); kAltF6: If NOT play_single_patt then begin start_pattern := pattern; play_single_patt := TRUE; no_sync_playing := TRUE; start_playing; repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; kF7: begin fade_out_playback(FALSE); stop_playing; If (play_status <> isStopped) then FillChar(ai_table,SizeOf(ai_table),0); end; kF8, kAltF8, kShF8: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin stop_playing; debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; calibrate_player(calc_pattern_pos(pattern),0,TRUE,FALSE); repeat_pattern := FALSE; end; end; isStopped: If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; calibrate_player(calc_pattern_pos(pattern),0,TRUE,FALSE); repeat_pattern := FALSE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kCtrlF8: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := FALSE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin stop_playing; calibrate_player(calc_pattern_pos(pattern),pattern_page,TRUE,FALSE); end; end; isStopped: If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin debugging := FALSE; calibrate_player(calc_pattern_pos(pattern),pattern_page,TRUE,FALSE); repeat_pattern := FALSE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end end; isPaused: begin debugging := FALSE; repeat_pattern := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF9, kAltF9, kShF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin stop_playing; calibrate_player(calc_pattern_pos(pattern),0,TRUE,FALSE); repeat_pattern := TRUE; end; end; isStopped: If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; calibrate_player(calc_pattern_pos(pattern),0,TRUE,FALSE); repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kCtrlF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin stop_playing; calibrate_player(calc_pattern_pos(pattern),pattern_page,TRUE,FALSE); repeat_pattern := TRUE; end; end; isStopped: If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin debugging := FALSE; calibrate_player(calc_pattern_pos(pattern),pattern_page,TRUE,FALSE); repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF10, kESC: begin If (fkey = kESC) and track_notes then cancel_note_recorder else begin QUIT_request; If (fkey = kESC) then nope := TRUE; end; end; kENTER: If NOT shift_pressed then nope := TRUE else begin _save_pattern_to_undo; If marking then For temp2 := block_x0 to block_x1 do For temp1 := block_y0 to block_y1 do begin get_chunk(pattern,temp1,temp2,chunk); If (chunk.note in [1..12*8+1]) then chunk.note := chunk.note+fixed_note_flag else If (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then chunk.note := chunk.note-fixed_note_flag; put_chunk(pattern,temp1,temp2,chunk); end else begin get_chunk(pattern,page,chan,chunk); If (chunk.note in [1..12*8+1]) then chunk.note := chunk.note+fixed_note_flag else If (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then chunk.note := chunk.note-fixed_note_flag; put_chunk(pattern,page,chan,chunk); end; end; else If NOT scankey(SC_F11) and NOT scankey(SC_F12) then nope := TRUE; end; If (nope or (fkey = kSPACE) or (fkey = kWeird)) and midiboard then begin nope := FALSE; If track_notes then curr_ch := track_chan_start else curr_ch := chan; track_ch := 0; flag := FALSE; FillChar(track_ch_key,SizeOf(track_ch_key),BYTE_NULL); If NOT ctrl_pressed and NOT alt_pressed then For idx := 1 to 29 do If (scankey(board_scancodes[idx])) then begin flag := TRUE; If NOT track_notes or NOT (track_ch < nm_track_chan) then begin track_ch_key[1] := idx; BREAK; end else begin Inc(track_ch); track_ch_key[track_ch] := idx; end; end; fkey_X := fkey; If ((fkey = kSPACE) or (((fkey = kWeird) or (flag AND (count_pos(hpos) = 0))) and (NOT ((fkey = kWeird) and (count_pos(hpos) >= 2))) or track_notes)) then begin If track_notes then temp1 := nm_track_chan else temp1 := 1; idx2 := 1; If track_notes and NOT ((NOT (command_typing <> 0) and (count_pos(hpos) = 0)) or ((command_typing <> 0) and (count_pos(hpos) < 2))) then If (fkey <> kSPACE) and (fkey <> kENTER) then nope := TRUE; If NOT nope and (fkey <> kSPACE) then For idx := 1 to temp1 do If (fkey = kWeird) or ((track_ch_key[idx2] <> BYTE_NULL) and (track_ch_key[idx2]+12*(current_octave-1) in [1..12*8+1])) then begin If (fkey <> kSPACE) and NOT (track_notes and mark_lines and (pattern_page MOD mark_line <> 0)) then begin get_chunk(pattern,pattern_page,curr_ch+idx-1,chunk); If (fkey <> kWeird) then begin If NOT right_shift_pressed then chunk.note := track_ch_key[idx2]+12*(current_octave-1) else chunk.note := track_ch_key[idx2]+12*(current_octave-1)+fixed_note_flag; If NOT (chunk.effect_def in [ef_TonePortamento, ef_TPortamVolSlide]) then begin If NOT (get_4op_to_test <> 0) then chunk.instr_def := current_inst else If (curr_ch+idx-1 in _4op_tracks_lo) then chunk.instr_def := LO(get_4op_to_test) else chunk.instr_def := HI(get_4op_to_test); If is_4op_chan(curr_ch+idx-1) and (curr_ch+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(curr_ch)+idx-1,chunk2); chunk2.note := 0; If NOT track_notes or track_notes_ins then If (HI(get_4op_to_test) <> 0) then chunk2.instr_def := HI(get_4op_to_test) else chunk2.instr_def := current_inst else chunk2.instr_def := min(voice_table[PRED(curr_ch)+idx-1],1); If channel_flag[PRED(curr_ch)+idx-1] then put_chunk(pattern,pattern_page,PRED(curr_ch)+idx-1,chunk2); end else If is_4op_chan(curr_ch+idx-1) and (curr_ch+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(curr_ch)+idx-1,chunk2); chunk2.note := 0; If NOT track_notes or track_notes_ins then If (LO(get_4op_to_test) <> 0) then chunk2.instr_def := LO(get_4op_to_test) else chunk2.instr_def := current_inst else chunk2.instr_def := min(voice_table[SUCC(curr_ch)+idx-1],1); If channel_flag[SUCC(curr_ch)+idx-1] then put_chunk(pattern,pattern_page,SUCC(curr_ch)+idx-1,chunk2); end; end; end else begin chunk.note := BYTE_NULL; chunk.instr_def := 0; end; If channel_flag[curr_ch+idx-1] and NOT ignore_note_once[curr_ch+idx-1] then begin ignore_note_once[curr_ch+idx-1] := TRUE; put_chunk(pattern_patt,pattern_page,curr_ch+idx-1,chunk); If (chunk.instr_def <> 0) then load_instrument(songdata.instr_data[chunk.instr_def],curr_ch+idx-1); If is_4op_chan(curr_ch+idx-1) then If (curr_ch+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern_patt,pattern_page,PRED(curr_ch)+idx-1,chunk2); load_instrument(songdata.instr_data[chunk2.instr_def],PRED(curr_ch)+idx-1); end else begin get_chunk(pattern_patt,pattern_page,SUCC(curr_ch)+idx-1,chunk2); load_instrument(songdata.instr_data[chunk2.instr_def],SUCC(curr_ch)+idx-1); end; If (chunk.note <> BYTE_NULL) then output_note(chunk.note AND $7f,chunk.instr_def,curr_ch+idx-1,TRUE,TRUE); Inc(idx2); end; end; end; If NOT nope then begin fkey := kSPACE; If track_notes then begin If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin fade_out_playback(FALSE); calibrate_player(calc_pattern_pos(pattern),page,TRUE,TRUE); end else begin start_pattern := pattern; start_line := page; play_single_patt := TRUE; no_sync_playing := TRUE; start_playing; repeat_pattern := TRUE; end; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (songdata.pattern_order[pattern] <> BYTE_NULL) and NOT ((play_status <> isStopped) and (fkey_X = kSPACE)) then begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; If (status_backup.play_status <> isStopped) then begin replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; Move(event_table,event_table_backup,SizeOf(event_table)); Move(voice_table,voice_table_backup,SizeOf(voice_table)); Move(volume_table,volume_table_backup,SizeOf(volume_table)); Move(pan_lock,pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); reset_player; Move(fmpar_table,fmpar_table_backup,SizeOf(fmpar_table_backup)); Move(freq_table,freq_table_backup,SizeOf(freq_table)); Move(freqtable2,freqtable2_backup,SizeOf(freqtable2)); Move(keyoff_loop,keyoff_loop_backup,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); end; If NOT (debugging and (play_status = isStopped)) then begin init_player; debugging := TRUE; end; old_order := current_order; old_pattern := current_pattern; old_line := current_line; old_speed := speed; old_tempo := tempo; current_order := 0; current_pattern := pattern; current_line := page; single_play := TRUE; poll_proc; single_play := FALSE; current_order := old_order; current_pattern := old_pattern; current_line := old_line; speed := old_speed; tempo := old_tempo; play_status := isStopped; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(page); If (status_backup.play_status <> isStopped) then begin Move(event_table_backup,event_table,SizeOf(event_table)); Move(voice_table_backup,voice_table,SizeOf(voice_table)); Move(volume_table_backup,volume_table,SizeOf(volume_table)); Move(fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(panning_table_backup,panning_table,SizeOf(panning_table)); reset_player; Move(pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(peak_lock_backup,peak_lock,SizeOf(volume_lock)); Move(freq_table_backup,freq_table,SizeOf(freq_table)); Move(freqtable2_backup,freqtable2,SizeOf(freqtable2)); Move(keyoff_loop_backup,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; debugging := FALSE; end; If (page < PRED(songdata.patt_len)) then Inc(page) else If cycle_pattern then page := 0; If (left_shift_pressed or jump_mark_mode) and (mark_line <> 0) and mark_lines then begin old_line := page; While (page MOD mark_line <> 0) do If (page < PRED(songdata.patt_len)) then Inc(page) else If cycle_pattern then page := 0 else begin page := old_line; BREAK; end; end; end else If (page < PRED(songdata.patt_len)) then Inc(page) else If cycle_pattern then page := 0; end; end else If (fkey <> kUp) and (fkey <> kDown) and (fkey <> kHome) and (fkey <> kEnd) and (fkey <> kLeft) and (fkey <> kRight) and (fkey <> kPgUp) and (fkey <> kPgDown) and (fkey <> kCtPgUp) and (fkey <> kCtPgDn) and (fkey <> kTAB) and (fkey <> kShTAB) and (fkey <> kCtLbr) and (fkey <> kCtRbr) and (fkey <> kCHlbrk) and (fkey <> kCHrbrk) and (fkey <> kCtHome) and (fkey <> kCtEnd) and (fkey <> kAltM) and (fkey <> kAltL) and (fkey <> kCtEntr) and (fkey <> kF1) and NOT (shift_pressed and ((fkey = kHome) or (fkey = kNPHome) or (fkey = kPgUp) or (fkey = kNPPgUp) or (fkey = kEnd) or (fkey = kNPEnd) or (fkey = kPgDown) or (fkey = kNPPgDn))) then begin nope := TRUE; debugging := FALSE; end; end else If (fkey <> kUp) and (fkey <> kDown) and (fkey <> kHome) and (fkey <> kEnd) and (fkey <> kLeft) and (fkey <> kRight) and (fkey <> kPgUp) and (fkey <> kPgDown) and (fkey <> kCtPgUp) and (fkey <> kCtPgDn) and (fkey <> kTAB) and (fkey <> kShTAB) and (fkey <> kCtLbr) and (fkey <> kCtRbr) and (fkey <> kCHlbrk) and (fkey <> kCHrbrk) and (fkey <> kCtHome) and (fkey <> kCtEnd) and (fkey <> kAltM) and (fkey <> kAltL) and (fkey <> kCtEntr) and (fkey <> kF1) and NOT (shift_pressed and ((fkey = kHome) or (fkey = kNPHome) or (fkey = kPgUp) or (fkey = kNPPgUp) or (fkey = kEnd) or (fkey = kNPEnd) or (fkey = kPgDown) or (fkey = kNPPgDn))) then begin debugging := FALSE; end; If track_notes and (chan <> count_channel(old_hpos)) then cancel_note_recorder; If (page <> old_patt_page) then For idx := 1 to 20 do ignore_note_once[idx] := FALSE; chan := count_channel(hpos); If nope and NOT midiboard and (count_pos(hpos) = 0) and (UpCase(CHAR(LO(fkey))) in ['A',UpCase(b_note),'C'..'G']) then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['1'..'9','a',b_note,'c'..'g', 'A',UpCase(b_note),'C'..'F','#','-']; is_environment.locate_pos := 2; tstr := CHAR(LO(fkey)); is_setting.terminate_keys[3] := kTAB; Repeat tstr := InputStr(tstr,08+pos3[1+(chan-PRED(chan_pos)-1)*4], 11+PRED(MAX_PATTERN_ROWS DIV 2),3,3, pattern_input_bckg+pattern_input, pattern_input_warn+pattern_input); is_setting.append_enabled := TRUE; If (UpCase(tstr[1]) in ['A',UpCase(b_note),'C'..'G']) and ((is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB)) then begin nope := FALSE; If (Length(tstr) = 2) then If tstr[2] in ['1'..'9'] then Insert('-',tstr,2) else If tstr[2] in ['-','#'] then tstr := tstr+Num2str(current_octave,10); If (Length(tstr) = 1) then tstr := tstr+'-'+Num2str(current_octave,10); For temp1 := 1 to 12*8+1 do If (Upper(tstr) = note_layout[temp1]) then begin nope := TRUE; get_chunk(pattern,page,chan,chunk); chunk.note := temp1; put_chunk(pattern,page,chan,chunk); If is_4op_chan(chan) then If (chan in _4op_tracks_hi) then begin get_chunk(pattern,page,SUCC(chan),chunk2); chunk2.note := 0; put_chunk(pattern,page,SUCC(chan),chunk2); end else begin get_chunk(pattern,page,PRED(chan),chunk2); chunk2.note := 0; put_chunk(pattern,page,PRED(chan),chunk2); end; BREAK; end; If NOT nope and (Length(tstr) = 2) then For temp1 := 1 to 12*8+1 do If (Copy(Upper(tstr),1,2) = Copy(note_layout[temp1],1,2)) then begin nope := TRUE; get_chunk(pattern,page,chan,chunk); chunk.note := temp1; put_chunk(pattern,page,chan,chunk); If is_4op_chan(chan) then If (chan in _4op_tracks_hi) then begin get_chunk(pattern,page,SUCC(chan),chunk2); chunk2.note := 0; put_chunk(pattern,page,SUCC(chan),chunk2); end else begin get_chunk(pattern,page,PRED(chan),chunk2); chunk2.note := 0; put_chunk(pattern,page,PRED(chan),chunk2); end; BREAK; end; If nope and linefeed and (is_environment.keystroke = kENTER) then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; If (tstr = '') then nope := TRUE; If nope and (is_environment.keystroke = kTAB) and (hpos+1 <= last_hpos) then Inc(hpos); end; until (is_environment.keystroke = kESC) or nope; is_setting.terminate_keys[3] := 0; nope := FALSE; end; If NOT (command_typing <> 0) and nope and (count_pos(hpos) = 1) and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['0'..'9','a'..'f','A'..'F']; is_environment.locate_pos := 2; tstr := CHAR(LO(fkey)); is_setting.terminate_keys[3] := kTAB; If (pattern_layout = 1) then temp := 1 else temp := 0; Repeat tstr := InputStr(tstr,08+pos3[hpos]-temp,11+PRED(MAX_PATTERN_ROWS DIV 2),2,2, pattern_input_bckg+pattern_input, pattern_input_warn+pattern_input); is_setting.append_enabled := TRUE; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then If (tstr = '') then nope := TRUE else If Str2num(tstr,16) in [0..$0fa] then begin nope := TRUE; If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); chunk.instr_def := Str2num(tstr,16); put_chunk(pattern,page,track_chan_start+idx-1,chunk); If (chunk.instr_def <> 0) and update_ins then begin current_inst := chunk.instr_def; instrum_page := current_inst; reset_marked_instruments; end; end; end else begin get_chunk(pattern,page,chan,chunk); chunk.instr_def := Str2num(tstr,16); put_chunk(pattern,page,chan,chunk); If (chunk.instr_def <> 0) and update_ins then begin current_inst := chunk.instr_def; instrum_page := current_inst; reset_marked_instruments; end; end; end; If nope and linefeed and (is_environment.keystroke = kENTER) then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; If nope and (is_environment.keystroke = kTAB) and (hpos+1 <= last_hpos) then Inc(hpos); until (is_environment.keystroke = kESC) or nope; is_setting.terminate_keys[3] := 0; nope := FALSE; end; If NOT (command_typing <> 0) and nope and (count_pos(hpos) = 2) and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<']) then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['0'..'9','a'..'z','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<']; is_environment.locate_pos := 2; tstr := CHAR(LO(fkey)); is_setting.terminate_keys[3] := kTAB; Repeat tstr := InputStr(tstr,08+pos3[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2),3,3, pattern_input_bckg+pattern_input, pattern_input_warn+pattern_input); is_setting.append_enabled := TRUE; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then If (tstr = '') then nope := TRUE else begin If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then If (idx > 1) then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); get_chunk(pattern,page,track_chan_start,chunk2); chunk.effect_def := chunk2.effect_def; chunk.effect := chunk2.effect; put_chunk(pattern,page,track_chan_start+idx-1,chunk); end else begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); chunk.effect_def := FX(tstr[1]); temp := Str2num(Copy(tstr,2,Length(tstr)),16); If correct_range(chunk.effect_def,temp) or (tstr = '') then begin nope := TRUE; tstr := Copy(tstr,2,Length(tstr)); If (tstr <> '') then chunk.effect := Str2num(tstr,16) else chunk.effect := 0; put_chunk(pattern,page,track_chan_start+idx-1,chunk); end; end; end else begin get_chunk(pattern,page,chan,chunk); chunk.effect_def := FX(tstr[1]); temp := Str2num(Copy(tstr,2,Length(tstr)),16); If correct_range(chunk.effect_def,temp) or (tstr = '') then begin nope := TRUE; tstr := Copy(tstr,2,Length(tstr)); If (tstr <> '') then chunk.effect := Str2num(tstr,16) else chunk.effect := 0; put_chunk(pattern,page,chan,chunk) end; end; end; If nope and linefeed and (is_environment.keystroke = kENTER) then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; If nope and (is_environment.keystroke = kTAB) and (hpos+1 <= last_hpos) then Inc(hpos); until (is_environment.keystroke = kESC) or nope; is_setting.terminate_keys[3] := 0; nope := FALSE; end; If NOT (command_typing <> 0) and nope and (count_pos(hpos) = 3) and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<']) then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['0'..'9','a'..'z','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<']; is_environment.locate_pos := 2; tstr := CHAR(LO(fkey)); is_setting.terminate_keys[3] := kTAB; Repeat tstr := InputStr(tstr,08+pos3[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2),3,3, pattern_input_bckg+pattern_input, pattern_input_warn+pattern_input); is_setting.append_enabled := TRUE; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then If (tstr = '') then nope := TRUE else begin If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then If (idx > 1) then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); get_chunk(pattern,page,track_chan_start,chunk2); chunk.effect_def2 := chunk2.effect_def2; chunk.effect2 := chunk2.effect2; put_chunk(pattern,page,track_chan_start+idx-1,chunk); end else begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); chunk.effect_def2 := FX(tstr[1]); temp := Str2num(Copy(tstr,2,Length(tstr)),16); If correct_range(chunk.effect_def2,temp) or (tstr = '') then begin nope := TRUE; tstr := Copy(tstr,2,Length(tstr)); If (tstr <> '') then chunk.effect2 := Str2num(tstr,16) else chunk.effect2 := 0; put_chunk(pattern,page,track_chan_start+idx-1,chunk); end; end; end else begin get_chunk(pattern,page,chan,chunk); chunk.effect_def2 := FX(tstr[1]); temp := Str2num(Copy(tstr,2,Length(tstr)),16); If correct_range(chunk.effect_def2,temp) or (tstr = '') then begin nope := TRUE; tstr := Copy(tstr,2,Length(tstr)); If (tstr <> '') then chunk.effect2 := Str2num(tstr,16) else chunk.effect2 := 0; put_chunk(pattern,page,chan,chunk); end; end; end; If nope and linefeed and (is_environment.keystroke = kENTER) then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; If nope and (is_environment.keystroke = kTAB) and (hpos+1 <= last_hpos) then Inc(hpos); until (is_environment.keystroke = kESC) or nope; is_setting.terminate_keys[3] := 0; nope := FALSE; end; If NOT marking and nope then If (command_typing <> 0) and ((count_pos(hpos) > 0) and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<'])) then begin Case count_pos(hpos) of 1: If NOT (UpCase(CHAR(LO(fkey))) in ['1'..'9']) then nope := FALSE else begin nope := TRUE; get_chunk(pattern,page,chan,chunk); If (chunk.note in [1..12*8+1]) then chunk.note := ((chunk.note-1) MOD 12)+1+ 12*(Str2num(CHAR(LO(fkey)),10)-1) else If (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then chunk.note := ((chunk.note-1) MOD 12)+1+ 12*(Str2num(CHAR(LO(fkey)),10)-1)+fixed_note_flag; If (chunk.note in [1..12*8+1,fixed_note_flag+1..fixed_note_flag+12*8+1]) then put_chunk(pattern,page,chan,chunk) else nope := FALSE; end; 2, 3: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else begin nope := TRUE; If track_notes then begin For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); If (idx > 1) then begin get_chunk(pattern,page,track_chan_start,chunk2); chunk.instr_def := chunk2.instr_def; end; Case count_pos(hpos) of 2: chunk.instr_def := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.instr_def AND $0f; 3: chunk.instr_def := Str2num(CHAR(LO(fkey)),16)+ chunk.instr_def AND $f0; end; If (chunk.instr_def <= 255) and NOT shift_pressed then begin put_chunk(pattern,page,track_chan_start+idx-1,chunk); If (chunk.instr_def <> 0) and update_ins then begin current_inst := chunk.instr_def; instrum_page := current_inst; reset_marked_instruments; end; end else nope := FALSE; end; end else begin get_chunk(pattern,page,chan,chunk); Case count_pos(hpos) of 2: chunk.instr_def := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.instr_def AND $0f; 3: chunk.instr_def := Str2num(CHAR(LO(fkey)),16)+ chunk.instr_def AND $f0; end; If (chunk.instr_def <= 255) and NOT shift_pressed then begin put_chunk(pattern,page,chan,chunk); If (chunk.instr_def <> 0) and update_ins then begin current_inst := chunk.instr_def; instrum_page := current_inst; reset_marked_instruments; end; end else nope := FALSE; end; end; 4,5, 6: begin nope := TRUE; If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); If (idx > 1) then begin get_chunk(pattern,page,track_chan_start,chunk2); chunk.effect_def := chunk2.effect_def; chunk.effect := chunk2.effect; end; Case count_pos(hpos) of 4: begin chunk.effect_def := FX(CHAR(LO(fkey))); If (chunk.effect_def in [ef_SetSpeed,ef_SetTempo]) and (chunk.effect = 0) then Case chunk.effect_def of ef_SetSpeed: chunk.effect := songdata.speed; ef_SetTempo: chunk.effect := songdata.tempo; end; end; 5: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.effect AND $0f; 6: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect := Str2num(CHAR(LO(fkey)),16)+ chunk.effect AND $f0; end; If correct_range(chunk.effect_def,chunk.effect) and NOT (shift_pressed and NOT (FX(CHAR(LO(fkey))) in [ef_Extended2,ef_Extended3,ef_SetGlobalVolume, ef_ExtraFineArpeggio,ef_ExtraFineVibrato,ef_ExtraFineTremolo, ef_ForceInsVolume,ef_SwapArpeggio,ef_SwapVibrato, ef_SetCustomSpeedTab,ef_GlobalFSlideUp,ef_GlobalFSlideDown])) then put_chunk(pattern,page,track_chan_start+idx-1,chunk) else nope := FALSE; end; end else begin get_chunk(pattern,page,chan,chunk); Case count_pos(hpos) of 4: begin chunk.effect_def := FX(CHAR(LO(fkey))); If (chunk.effect_def in [ef_SetSpeed,ef_SetTempo]) and (chunk.effect = 0) then Case chunk.effect_def of ef_SetSpeed: chunk.effect := songdata.speed; ef_SetTempo: chunk.effect := songdata.tempo; end; end; 5: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.effect AND $0f; 6: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect := Str2num(CHAR(LO(fkey)),16)+ chunk.effect AND $f0; end; If correct_range(chunk.effect_def,chunk.effect) and NOT (shift_pressed and NOT (FX(CHAR(LO(fkey))) in [ef_Extended2,ef_Extended3,ef_SetGlobalVolume, ef_ExtraFineArpeggio,ef_ExtraFineVibrato,ef_ExtraFineTremolo, ef_ForceInsVolume,ef_SwapArpeggio,ef_SwapVibrato, ef_SetCustomSpeedTab,ef_GlobalFSlideUp,ef_GlobalFSlideDown])) then put_chunk(pattern,page,chan,chunk) else nope := FALSE; end; end; 7,8, 9: begin nope := TRUE; If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); If (idx > 1) then begin get_chunk(pattern,page,track_chan_start,chunk2); chunk.effect_def2 := chunk2.effect_def2; chunk.effect2 := chunk2.effect2; end; Case count_pos(hpos) of 7: begin chunk.effect_def2 := FX(CHAR(LO(fkey))); If (chunk.effect_def2 in [ef_SetSpeed,ef_SetTempo]) and (chunk.effect2 = 0) then Case chunk.effect_def2 of ef_SetSpeed: chunk.effect2 := songdata.speed; ef_SetTempo: chunk.effect2 := songdata.tempo; end; end; 8: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect2 := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.effect2 AND $0f; 9: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect2 := Str2num(CHAR(LO(fkey)),16)+ chunk.effect2 AND $f0; end; If correct_range(chunk.effect_def2,chunk.effect2) and NOT (shift_pressed and NOT (FX(CHAR(LO(fkey))) in [ef_Extended2,ef_Extended3,ef_SetGlobalVolume, ef_ExtraFineArpeggio,ef_ExtraFineVibrato,ef_ExtraFineTremolo, ef_ForceInsVolume,ef_SwapArpeggio,ef_SwapVibrato, ef_SetCustomSpeedTab,ef_GlobalFSlideUp,ef_GlobalFSlideDown])) then put_chunk(pattern,page,track_chan_start+idx-1,chunk) else nope := FALSE; end; end else begin get_chunk(pattern,page,chan,chunk); Case count_pos(hpos) of 7: begin chunk.effect_def2 := FX(CHAR(LO(fkey))); If (chunk.effect_def2 in [ef_SetSpeed,ef_SetTempo]) and (chunk.effect2 = 0) then Case chunk.effect_def2 of ef_SetSpeed: chunk.effect2 := songdata.speed; ef_SetTempo: chunk.effect2 := songdata.tempo; end; end; 8: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect2 := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.effect2 AND $0f; 9: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect2 := Str2num(CHAR(LO(fkey)),16)+ chunk.effect2 AND $f0; end; If correct_range(chunk.effect_def2,chunk.effect2) and NOT (shift_pressed and NOT (FX(CHAR(LO(fkey))) in [ef_Extended2,ef_Extended3,ef_SetGlobalVolume, ef_ExtraFineArpeggio,ef_ExtraFineVibrato,ef_ExtraFineTremolo, ef_ForceInsVolume,ef_SwapArpeggio,ef_SwapVibrato, ef_SetCustomSpeedTab,ef_GlobalFSlideUp,ef_GlobalFSlideDown])) then put_chunk(pattern,page,chan,chunk) else nope := FALSE; end; end; end; If (command_typing = 2) and (count_pos(hpos) in [2,5,8]) then Inc(hpos) else If nope and linefeed then begin If (command_typing = 2) and (count_pos(hpos) in [3,6,9]) then Dec(hpos); If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; end; end; fkey_X := WORD_NULL; _end: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} If scankey(SC_F11) and NOT ctrl_pressed and NOT alt_pressed and NOT shift_pressed then begin If (command_typing <> 0) then Case command_typing of 1: If cycle_pattern then begin command_typing := 2; cycle_pattern := FALSE; end else cycle_pattern := TRUE; 2: begin command_typing := 1; cycle_pattern := FALSE; end; end; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; If scankey(SC_F12) and NOT ctrl_pressed and NOT alt_pressed then begin If NOT shift_pressed then linefeed := NOT linefeed else jump_mark_mode := NOT jump_mark_mode; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; until (nope and ((fkey = kENTER) or (fkey = kESC) or (fkey = kF10))) or _force_program_quit; If track_notes then begin cancel_note_recorder; stop_playing; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(page); end; adlibtracker2-2.4.23/typcons2.inc0000644000000000000000000005162113176573533015307 0ustar rootrootconst frame_solid_type1 = ' '; frame_solid_type2 = 'ÛßÛÛÛÛÜÛ'; frame_single = 'ÚÄ¿³³ÀÄÙ'; frame_double = 'ÉÍ»ººÈͼ'; frame_double_side = 'ÖÄ·ººÓĽ'; frame_double_top = 'Õ͸³³Ô;'; const prog_exception_title = 'ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ'#13#10+ 'Û ABNORMAL PROGRAM TERMiNATiON Û'#13#10+ 'ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß'#13#10; const patt_win_tracks: array[0..2,1..5] of String[176] = ( ('ÉÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ PATTERN EDiTOR ( ) ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍ»', 'ºLiNEº 1 ³ 2 ³ 3 ³ 4 ³ 5 ºLiNEº', 'ÌÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍ͹', 'º º ³ ³ ³ ³ º º', 'ÈÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍͼ'), ('ÉÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ PATTERN EDiTOR ( ) ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍ»', 'ºLiNEº 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ºLiNEº', 'ÌÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍ͹', 'º º ³ ³ ³ ³ ³ ³ º º', 'ÈÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍͼ'), ('ÉÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ PATTERN EDiTOR ( ) ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍ»', 'ºLiNEº 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ³ 8 ³ 9 ³ 10 ³ 11 ºLiNEº', 'ÌÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍ͹', 'º º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º º', 'ÈÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍͼ')); patt_win: array[1..5] of String[176] = ('','','','',''); patt_tab_str: array[0..4] of String[18] = ( 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~~Í~~ÍÍÍÍÍÍÍÍÍÍÍ', 'ÍÍÍÍ~~ÍÍÍÍÍÍÍÍ', 'ÍÍÍÍÍÍÍ~~ÍÍÍÍ', 'ÍÍÍÍÍÍÍÍÍÍÍ~~'); ins_pan_str1: array[0..2] of String[23] = ( '~ú~úúúúú ~ ~ úúúúú~ú~', '~ ~ úúú~ú~úúúúúúú~ú~', '~ú~úúúúúúú~ú~úúú ~ ~'); ins_pan_str2: array[0..2] of String[7] = ( 'úú úú', ' úúúú', 'úúúú '); voice_pan_str: array[0..3] of String[13] = ( '~ú~ú ~ ~ ú~ú~', '~ ~ ~ú~úú~ú~', '~ú~úú~ú~ ~ ~', 'úúúúúúú'); note_keyoff_str: array[0..2] of String[3] = ( 'þþþ', 'ÍÍÍ', '^^ú'); perc_voice_str: array[0..5] of String[7] = ( 'MELODiC', 'PERC:BD', 'PERC:SD', 'PERC:TT', 'PERC:TC', 'PERC:HH'); a2b_header_str: array[1..3] of String[74] = ( ' iNSTRUMENT PANNiNG iNSTRUMENT ', ' NAME DESCRiPTiON ª c « F.TUNE VOiCE ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); a2b_header_hires_str: array[1..3] of String[104] = ( ' iNSTRUMENT PANNiNG iNSTRUMENT ', ' NAME DESCRiPTiON Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 ª c « F.TUNE VOiCE ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); av_browser_str: array[1..6] of String[75] = ( 'ÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ', ' º ~ARPEGGiO MACRO TABLE~ º ~ViBRATO MACRO TABLE~', ' ÇÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄ×ÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄ', ' NO.ºLEN. ³SPEED³L.BEG³L.LEN³K.OFF ºLEN. ³SPEED³DELAY³L.BEG³L.LEN³K.OFF ', 'ÍÍÍÍÎÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍÎÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍ', 'ÍÍÍÍÊÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÍÊÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÍ'); a2w_header_str: array[1..3] of String[72] = ( ' iNSTRUMENT iNSTRUMENT ', ' NAME DESCRiPTiON VOiCE MACROS ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); a2w_header_hires1_str: array[1..3] of String[102] = ( ' iNSTRUMENT iNSTRUMENT ', ' NAME DESCRiPTiON Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 VOiCE MACROS ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); a2w_header_hires2_str: array[1..3] of String[121] = ( ' iNSTRUMENT PANNiNG iNSTRUMENT ', ' NAME DESCRiPTiON Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 ª c « F.TUNE VOiCE MACROS ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); bnk_header_str: array[1..3] of String[72] = ( ' iNSTRUMENT MELODiC/ ', ' NAME Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 PERCUSSiON (VOiCE) ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); fib_header_str: array[1..3] of String[72] = ( ' DOS iNSTRUMENT ', ' NAME NAME Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); ibk_header_str: array[1..3] of String[44] = ( ' iNSTRUMENT ', ' NAME Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); debug_win_str1: array[1..3] of String[130] = ( ' TRACK ~³~ iNSTRUMENT ~³~NOTE~³ ~FX Nù1~ ³ ~FX Nù2~ ³~FREQ~³ ~VOL', 'ÄÄÂÄÄÂÄÄÄÂÄÄÂÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÂÄÄ', 'ÄÄÁÄÄÁÄÄÄÁÄÄÁÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÁÄÄ'); debug_win_str2: array[1..3] of String[130] = ( 'TRACK~³~iNS~³~NOTE~³ ~FX Nù1~ ³ ~FX Nù2~ ³~FREQ~³~CN/FB/ADSR/WF/KSL/MUL/TRM/ViB/KSR/EG~³ ~VOL', 'ÄÄÂÄÄÅÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÂÄÄ', 'ÄÄÁÄÄÁÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÁÄÄ'); debug_win_str3: array[1..3] of String[130] = ( 'TRACK~³~iNS~³~NOTE~³ ~FX Nù1~ ³ ~FX Nù2~ ³~MACRO FM-REG~ ³~MACRO ARPG~³~MACRO ViBR ~³~FREQ~³ ~VOL', 'ÄÄÂÄÄÅÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÂÄÄ', 'ÄÄÁÄÄÁÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÁÄÄ'); const inst_itm1: array[1..18] of Record str: String[24]; colr: Byte; end = ( (str: '~ENV.TYPE/MULT~ ÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~KSL/VOLUME~ ÄÄÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~ATTACK/DECAY~ ÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~SUSTAiN/RELEASE~ ÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~WAVEFORM~ ÄÄÄÄÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~CONNECTiON/FB~  ÄÄ'; colr: 1), (str: '~PANNiNG~  ÄÄ'; colr: 1), (str: '~F-TUNE~  ÄÄ'; colr: 1)); const inst_itm2: array[1..18] of Record str: String[25]; colr: Byte; end = ( (str: '~ENV.TYPE/MULT~ ÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~KSL/VOLUME~ ÄÄÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~ATTACK/DECAY~ ÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~SUSTAiN/RELEASE~ ÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~WAVEFORM~ ÄÄÄÄÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~CONNECTiON/FB~  ÄÄ'; colr: 1), (str: '~PANNiNG~  ÄÄ'; colr: 1), (str: '~F-TUNE~  ÄÄ'; colr: 1)); const inst_text: array[1..23] of String[72] = ( '~ATTACK RATE~ ±±±±±±±±±±±±±±± ~WAVEFORM TYPE~', '~DECAY RATE~ ±±±±±±±±±±±±±±± ( ) Sine', ' ( ) Half-Sine', '~SUSTAiN LEVEL~ ±±±±±±±±±±±±±±± ( ) Abs-Sine', '~RELEASE RATE~ ±±±±±±±±±±±±±±± ( ) Pulse-Sine', ' ( ) Sine (EPO)', '~OUTPUT LEVEL~ ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ( ) Abs-Sine (EPO)', ' ( ) Square', '', '', '', '', '', '', '', '', '', '', '~ENVELOPE TYPE FREQUENCY DATA MULTiPLiER~', '[ ] Tremolo (AM)', '[ ] Vibrato ( )'#159'0 ( )'#159'1 ( )'#159'2 ( )'#159'3 ( )'#159'4 ( )'#159'5', '[ ] Key scale rate (KSR) ( )'#159'6 ( )'#159'7 ( )'#159'8 ( )'#159'9 ( )'#159'10 ( )'#159'10', '[ ] Sustain ( )'#159'12 ( )'#159'12 ( )'#159'15 ( )'#159'15'); const inst_text_ext_2op: array[1..9] of String[72] = ( '~KEY SCALiNG LEVEL~ `GLOBAL iNSTRUMENT SETTiNGS` ( ) Derived square', '( ) Default `šššššššššššššššššššššššššš`', '( ) 1.5 dB/octave `CONNECTiON` `FEEDBACK`', '( ) 3.0 dB/octave ( ) FM ±±±±±±±±±±±±±±±±±', '( ) 6.0 dB/octave ( ) AM MiN MAX', ' ^( ) FM/FM^', '~PANNiNG~ ^( ) FM/AM^ `F-TUNE`', 'ª c « ^( ) AM/FM^ ±±±±±±±±±±±±±±±±±', 'úúúúúúúúúúúúúúúúú ^( ) AM/AM^ - ù +'); const inst_text_ext_perc: array[1..9] of String[72] = ( '~KEY SCALiNG LEVEL~ ^GLOBAL iNSTRUMENT SETTiNGS^ ( ) Derived square', '( ) Default ^šššššššššššššššššššššššššš^', '( ) 1.5 dB/octave ^CONNECTiON FEEDBACK 0^', '( ) 3.0 dB/octave ^( ) FM ±±±±±±±±±±±±±±±±±^', '( ) 6.0 dB/octave ^( ) AM MiN MAX^', ' ^( ) FM/FM^', '~PANNiNG~ ^( ) FM/AM^ `F-TUNE`', 'ª c « ^( ) AM/FM^ ±±±±±±±±±±±±±±±±±', 'úúúúúúúúúúúúúúúúú ^( ) AM/AM^ - ù +'); const inst_text_ext_4op: array[1..9] of String[72] = ( '~KEY SCALiNG LEVEL~ `GLOBAL iNSTRUMENT SETTiNGS` ( ) Derived square', '( ) Default `šššššššššššššššššššššššššš`', '( ) 1.5 dB/octave `CONNECTiON` `FEEDBACK`', '( ) 3.0 dB/octave ^( ) FM^ ±±±±±±±±±±±±±±±±±', '( ) 6.0 dB/octave ^( ) AM^ MiN MAX', ' ( ) FM/FM', '~PANNiNG~ ( ) FM/AM `F-TUNE`', 'ª c « ( ) AM/FM ±±±±±±±±±±±±±±±±±', 'úúúúúúúúúúúúúúúúú ( ) AM/AM - ù +'); const inst_con_scheme: array[0..6,1..6] of String[17] = ( (' ', ' ', ' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁÛ2Û'#26' ', ' ', ' '), (' ', ' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁ¿ ', ' ³ ', ' Û2ÛÄÁ'#26' ', ' '), (' ', ' ', 'ÚÄÄÄ¿ ', 'ÀÛ1ÛÁÛ2ÛÄÛ3ÛÄÛ4Û'#26, ' ', ' '), (' ', ' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁÄÄÄÄÄÄÄÄ¿ ', ' ³ ', ' Û2ÛÄÛ3ÛÄÛ4ÛÄÁ'#26' ', ' '), (' ', ' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁÛ2ÛÄ¿ ', ' Ã'#26' ', ' Û3ÛÄÛ4ÛÄÙ ', ' '), (' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁÄÄÄÄ¿ ', ' ³ ', ' Û2ÛÄÛ3ÛÄÅ'#26' ', ' ³ ', ' Û4ÛÄÄÄÄÄÙ '), (' ', ' ', ' ', ' ', ' ', ' ')); const copy_menu_str1: array[1..15] of String[30] = ( ' COPY ORDER DEF.', ' COPY ORDER TABLE', ' COPY ~i~NSTRUMENT', ' COPY iNSTRUMENT ~B~ANK', ' COPY NOTE', ' COPY iNSTRUMENT DEF.', ' COPY 1ST EFFECT', ' COPY 2ND EFFECT', ' COPY LiNE', ' COPY TRACK', ' COPY PATTERN', ' COPY MARKED BLOCK', ' COPY MACRO-TABLE LiNE', ' COPY MACRO-TABLE COLUMN', ' COPY MACRO-TABLE'); copy_menu_str2: array[1..15] of String[30] = ( ' COPY ORDER DEF.', ' COPY ORDER TABLE', ' COPY iNSTRUMENT', ' COPY iNSTRUMENT BANK', ' COPY ~N~OTE', ' COPY iN~S~TRUMENT DEF.', ' COPY ~1~ST EFFECT', ' COPY ~2~ND EFFECT', ' COPY ~L~iNE', ' COPY ~T~RACK', ' COPY ~P~ATTERN', '', ' COPY MACRO-TABLE LiNE', ' COPY MACRO-TABLE COLUMN', ' COPY MACRO-TABLE'); copy_menu_str3: array[1..15] of String[30] = ( ' COPY ~O~RDER DEF.', ' COPY O~R~DER TABLE', ' COPY iNSTRUMENT', ' COPY iNSTRUMENT BANK', ' COPY NOTE', ' COPY iNSTRUMENT DEF.', ' COPY 1ST EFFECT', ' COPY 2ND EFFECT', ' COPY LiNE', ' COPY TRACK', ' COPY PATTERN', ' COPY MARKED BLOCK', ' COPY MACRO-TABLE LiNE', ' COPY MACRO-TABLE COLUMN', ' COPY MACRO-TABLE'); copy_menu_str4: array[1..15] of String[30] = ( ' COPY ORDER DEF.', ' COPY ORDER TABLE', ' COPY iNSTRUMENT', ' COPY iNSTRUMENT BANK', ' COPY NOTE', ' COPY iNSTRUMENT DEF.', ' COPY 1ST EFFECT', ' COPY 2ND EFFECT', ' COPY LiNE', ' COPY TRACK', ' COPY PATTERN', ' COPY MARKED BLOCK', ' COPY M~A~CRO-TABLE LiNE', ' COPY MA~C~RO-TABLE COLUMN', ' COPY ~M~ACRO-TABLE'); copy_marked_str: array[1..2] of String[30] = ( ' COPY MARKED BLOCK', ' COPY MARKED BLOC~K~'); copy_macro_str: array[1..4] of String[30] = ( ' COPY MACRO-TABLE LiNE', ' COPY M~A~CRO-TABLE LiNE', ' COPY MACRO-TABLE COLUMN', ' COPY MA~C~RO-TABLE COLUMN'); const transp_menu_str1: array[1..17] of String[50] = ( ' [~1~] 1 UP ¿', ' [~2~] 12 UP ö CURRENT', ' [~3~] 1 DOWN ø iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', '', ' [~5~] 1 UP ¿ ÀÄÄÄÄÄÄÄÄÄÙ', ' [~6~] 12 UP ö ALL', ' [~7~] 1 DOWN ø iNSTRUMENTS', ' [~8~] 12 DOWN Ù', '', ' [~A~] 1 UP ¿', ' [~B~] 12 UP ö CURRENT', ' [~C~] 1 DOWN ø iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', '', ' [~E~] 1 UP ¿ ÀÄÄÄÄÄÄÄÄÄÙ', ' [~F~] 12 UP ö ALL', ' [~G~] 1 DOWN ø iNSTRUMENTS', ' [~H~] 12 DOWN Ù'); transp_menu_str2: array[1..8] of String[50] = ( ' [~A~] 1 UP ¿', ' [~B~] 12 UP ö CURRENT', ' [~C~] 1 DOWN ø iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', '', ' [~E~] 1 UP ¿ ÀÄÄÄÄÄÄÄÄÄÙ', ' [~F~] 12 UP ö ALL', ' [~G~] 1 DOWN ø iNSTRUMENTS', ' [~H~] 12 DOWN Ù'); transp_menu_str3: array[1..8] of String[50] = ( ' [A] 1 UP ¿', ' [B] 12 UP ö CURRENT', ' [C] 1 DOWN ø iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', ' [D] 12 DOWN Ù ³ BLOCK ³', ' [E] 1 UP ¿ ÀÄÄÄÄÄÄÄÄÄÙ', ' [F] 12 UP ö ALL', ' [G] 1 DOWN ø iNSTRUMENTS', ' [H] 12 DOWN Ù'); transp_menu_str4: array[1..4] of String[50] = ( ' [~4~] 12 DOWN Ù ³ PATTERN ³', ' [~D~] 12 DOWN Ù ³ SONG ³', ' [~4~] 12 DOWN Ù ³ TRACK ³', ' [~D~] 12 DOWN Ù ³ BLOCK ³'); transp_mnu_str5: array[1..19] of String[32] = ( '~CURRENT~', '~iNSTRUMENT ÉÍÍÍÍÍÍÍÍÍ»~', 'ALL', 'iNSTRUMENTS', 'CURRENT', 'iNSTRUMENT ~ÉÍÍÍÍÍÍÍÍÍ»~', '~ALL~', '~iNSTRUMENTS~', 'iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', '~º PATTERN º~', '~º TRACK º~', '³ PATTERN ³', '³ TRACK ³', '~º SONG º~', '~º BLOCK º~', '³ SONG ³', '³ BLOCK ³', '~ÈÍÍÍÍÍÍÍÍͼ~', 'ÀÄÄÄÄÄÄÄÄÄÙ'); const macro_table_hint_str: array[1..20+35] of String[77] = ( 'Length of FM-register definition macro-table {1-FF} (0 means no macros)', 'Loop cycle starting position {1-FF} (0 means no loop)', 'Length of loop cycle {1-FF} (0 means no loop)', 'Key-Off jump position {1-FF} (0 means no jump)', 'Arpeggio table number {1-FF} (0 means no arpeggio)', 'Vibrato table number {1-FF} (0 means no vibrato)', '', 'Length of arpeggio macro-table {1-FF} (0 means no macros)', 'Speed of arpeggio in macro-table {1-FF} (0 means no arpeggio)', 'Loop cycle starting position {1-FF} (0 means no loop)', 'Length of loop cycle {1-FF} (0 means no loop)', 'Key-Off jump position {1-FF} (0 means no jump)', 'Number of half-tones to add [1-96] or fixed-note [C,C-,C#,C1,C-1,C#1,...]', 'Length of vibrato macro-table {1-FF} (0 means no macros)', 'Speed of vibrato in macro-table {1-FF} (0 means no vibrato)', 'Delay before starting vibrato in macro-table {1-FF} (0 means no delay)', 'Loop cycle starting position {1-FF} (0 means no loop)', 'Length of loop cycle {1-FF} (0 means no loop)', 'Key-Off jump position {1-FF} (0 means no jump)', 'Frequency to add {1..7F} or subtract {-7F..-1}', 'Attack rate [modulator] {0-F}', 'Decay rate [modulator] {0-F}', 'Sustain level [modulator] {0-F}', 'Release rate [modulator] {0-F}', 'Waveform type [modulator] {0-7}', 'Output level [modulator] {0-3F}', 'Output level [modulator] {0-3F}', 'Key scaling level [modulator] {0-3}', 'Multiplier [modulator] {0-F}', 'Amplitude modulation (tremolo) [modulator] {on/off}', 'Vibrato [modulator] {on/off}', 'Key scale rate [modulator] {on/off}', 'Sustain [modulator] {on/off}', 'Attack rate [carrier] {0-F}', 'Decay rate [carrier] {0-F}', 'Sustain level [carrier] {0-F}', 'Release rate [carrier] {0-F}', 'Waveform type [carrier] {0-7}', 'Output level [carrier] {0-3F}', 'Output level [carrier] {0-3F}', 'Key scaling level [carrier] {0-3}', 'Multiplier [carrier] {0-F}', 'Amplitude modulation (tremolo) [carrier] {on/off}', 'Vibrato [carrier] {on/off}', 'Key scale rate [carrier] {on/off}', 'Sustain [carrier] {on/off}', 'Connection type {0-1} (0=FM,1=AM)', 'Feedback {0-7}', 'Frequency slide {-FFF..+FFF}', 'Frequency slide {-FFF..+FFF}', 'Frequency slide {-FFF..+FFF}', 'Frequency slide {-FFF..+FFF}', 'Panning {Left/Center/Right}', 'Duration {1-FF} (0 means skip)', 'Duration {1-FF} (0 means skip)'); inst_mult_hint: array[0..15] of String[35] = ( '1 octave below', 'at the voice''s specified frequency', '1 octave above', '1 octave and a 5th above', '2 octaves above', '2 octaves and a Major 3rd above', '2 octaves and a 5th above', '2 octaves and a Minor 7th above', '3 octaves above', '3 octaves and a Major 2nd above', '3 octaves and a Major 3rd above', '3 octaves and a Major 3rd above', '3 octaves and a 5th above', '3 octaves and a 5th above', '3 octaves and a Major 7th above', '3 octaves and a Major 7th above'); adlibtracker2-2.4.23/opl3emu.pas0000644000000000000000000010540313176573533015122 0ustar rootroot// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this file; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // // OPL3 EMULATOR // Based on NukedOPL3 1.6 by Nuke.YKT (Alexey Khokholov) // Special thanks to insane/Altair for initial C to Pascal conversion // unit OPL3EMU; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface procedure OPL3EMU_init; procedure OPL3EMU_WriteReg(reg: Word; data: Byte); procedure OPL3EMU_PollProc(p_data: pDword; var ch_table); implementation const LOG_SIN_VAL: array[0..255] of Word = ( $859,$6c3,$607,$58b,$52e,$4e4,$4a6,$471,$443,$41a,$3f5,$3d3,$3b5,$398,$37e,$365, $34e,$339,$324,$311,$2ff,$2ed,$2dc,$2cd,$2bd,$2af,$2a0,$293,$286,$279,$26d,$261, $256,$24b,$240,$236,$22c,$222,$218,$20f,$206,$1fd,$1f5,$1ec,$1e4,$1dc,$1d4,$1cd, $1c5,$1be,$1b7,$1b0,$1a9,$1a2,$19b,$195,$18f,$188,$182,$17c,$177,$171,$16b,$166, $160,$15b,$155,$150,$14b,$146,$141,$13c,$137,$133,$12e,$129,$125,$121,$11c,$118, $114,$10f,$10b,$107,$103,$0ff,$0fb,$0f8,$0f4,$0f0,$0ec,$0e9,$0e5,$0e2,$0de,$0db, $0d7,$0d4,$0d1,$0cd,$0ca,$0c7,$0c4,$0c1,$0be,$0bb,$0b8,$0b5,$0b2,$0af,$0ac,$0a9, $0a7,$0a4,$0a1,$09f,$09c,$099,$097,$094,$092,$08f,$08d,$08a,$088,$086,$083,$081, $07f,$07d,$07a,$078,$076,$074,$072,$070,$06e,$06c,$06a,$068,$066,$064,$062,$060, $05e,$05c,$05b,$059,$057,$055,$053,$052,$050,$04e,$04d,$04b,$04a,$048,$046,$045, $043,$042,$040,$03f,$03e,$03c,$03b,$039,$038,$037,$035,$034,$033,$031,$030,$02f, $02e,$02d,$02b,$02a,$029,$028,$027,$026,$025,$024,$023,$022,$021,$020,$01f,$01e, $01d,$01c,$01b,$01a,$019,$018,$017,$017,$016,$015,$014,$014,$013,$012,$011,$011, $010,$00f,$00f,$00e,$00d,$00d,$00c,$00c,$00b,$00a,$00a,$009,$009,$008,$008,$007, $007,$007,$006,$006,$005,$005,$005,$004,$004,$004,$003,$003,$003,$002,$002,$002, $002,$001,$001,$001,$001,$001,$001,$001,$000,$000,$000,$000,$000,$000,$000,$000); EXP_VAL: array[0..255] of Word = ( $000,$003,$006,$008,$00b,$00e,$011,$014,$016,$019,$01c,$01f,$022,$025,$028,$02a, $02d,$030,$033,$036,$039,$03c,$03f,$042,$045,$048,$04b,$04e,$051,$054,$057,$05a, $05d,$060,$063,$066,$069,$06c,$06f,$072,$075,$078,$07b,$07e,$082,$085,$088,$08b, $08e,$091,$094,$098,$09b,$09e,$0a1,$0a4,$0a8,$0ab,$0ae,$0b1,$0b5,$0b8,$0bb,$0be, $0c2,$0c5,$0c8,$0cc,$0cf,$0d2,$0d6,$0d9,$0dc,$0e0,$0e3,$0e7,$0ea,$0ed,$0f1,$0f4, $0f8,$0fb,$0ff,$102,$106,$109,$10c,$110,$114,$117,$11b,$11e,$122,$125,$129,$12c, $130,$134,$137,$13b,$13e,$142,$146,$149,$14d,$151,$154,$158,$15c,$160,$163,$167, $16b,$16f,$172,$176,$17a,$17e,$181,$185,$189,$18d,$191,$195,$199,$19c,$1a0,$1a4, $1a8,$1ac,$1b0,$1b4,$1b8,$1bc,$1c0,$1c4,$1c8,$1cc,$1d0,$1d4,$1d8,$1dc,$1e0,$1e4, $1e8,$1ec,$1f0,$1f5,$1f9,$1fd,$201,$205,$209,$20e,$212,$216,$21a,$21e,$223,$227, $22b,$230,$234,$238,$23c,$241,$245,$249,$24e,$252,$257,$25b,$25f,$264,$268,$26d, $271,$276,$27a,$27f,$283,$288,$28c,$291,$295,$29a,$29e,$2a3,$2a8,$2ac,$2b1,$2b5, $2ba,$2bf,$2c4,$2c8,$2cd,$2d2,$2d6,$2db,$2e0,$2e5,$2e9,$2ee,$2f3,$2f8,$2fd,$302, $306,$30b,$310,$315,$31a,$31f,$324,$329,$32e,$333,$338,$33d,$342,$347,$34c,$351, $356,$35b,$360,$365,$36a,$370,$375,$37a,$37f,$384,$38a,$38f,$394,$399,$39f,$3a4, $3a9,$3ae,$3b4,$3b9,$3bf,$3c4,$3c9,$3cf,$3d4,$3da,$3df,$3e4,$3ea,$3ef,$3f5,$3fa); MULT_VAL: array[0..15] of Byte = (1,2,4,6,8,10,12,14,16,18,20,20,24,24,30,30); KSL_VAL: array[0..15] of Byte = (0,32,40,45,48,51,53,55,56,58,59,60,61,62,63,64); KSL_SHIFT: array[0..3] of Byte = (8,1,2,0); SL_VAL: array[0..15] of Byte = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,31); VIB_SHIFT: array[0..7] of Byte = (3,1,0,1,3,1,0,1); VIB_S_SHIFT: array[0..7] of Shortint = (1,1,1,1,-1,-1,-1,-1); EG_IDX: array[0..15] of Byte =(0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2); EG_SHIFT: array[0..15] of Shortint = (0,11,10,9,8,7,6,5,4,3,2,1,0,0,-1,-2); EG_VAL: array[0..2,0..3,0..7] of Byte = (((0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0)), ((0,1,0,1,0,1,0,1),(0,1,0,1,1,1,0,1),(0,1,1,1,0,1,1,1),(0,1,1,1,1,1,1,1)), ((1,1,1,1,1,1,1,1),(2,2,1,1,1,1,1,1),(2,2,1,1,2,2,1,1),(2,2,2,2,2,2,1,1))); CH_5BIT_MASK: array[0..31] of Byte = (1,2,3,4,5,6,0,0,7,8,9,10,11,12,0,0,13,14,15,16,17,18,0,0,0,0,0,0,0,0,0,0); CH_SLOT_IDX: array[0..17] of Byte = (0,1,2,6,7,8,12,13,14,18,19,20,24,25,26,30,31,32); CH_4OP_MASK: array[0..17] of Byte = (4,5,6,1,2,3,0,0,0,13,14,15,10,11,12,0,0,0); CH_4OP_IDX: array[0..5] of Byte = (0,1,2,9,10,11); CH_MAPPING: array[0..17] of Byte = ( 3,0, // 2OP | 4OP #1 4,1, // 2OP | 4OP #2 5,2, // 2OP | 4OP #3 6, // 2OP | RHYTHM: BD 7, // 2OP | RHYTHM: HH + SD 8, // 2OP | RHYTHM: TT + TC 12,9, // 2OP | 4OP #4 13,10, // 2OP | 4OP #5 14,11, // 2OP | 4OP #6 15, // 2OP 16, // 2OP 17); // 2OP NOISE_HASH_VAL = $306600; NOISE_XOR = $800302; WORD_NULL = WORD(NOT 0); type OPL3_CHAN_TYPE = (CH_2OP,CH_4OP_1,CH_4OP_2,CH_RHYTHM); EG_GEN_STATE = (EG_OFF,EG_ATTACK,EG_DECAY,EG_SUSTAIN,EG_RELEASE); CHAN_PTR_TABLE = array[0..17] of pDword; P_OPL3_CHIP = ^OPL3_CHIP; P_OPL3_SLOT = ^OPL3_SLOT; P_OPL3_CHAN = ^OPL3_CHAN; OPL3_SLOT = Record p_chan: P_OPL3_CHAN; p_chip: P_OPL3_CHIP; p_mod: pSmallint; p_trem: pByte; fb_out, prev_out, output: Smallint; pg_phase: Dword; eg_state: EG_GEN_STATE; eg_rout, eg_out: Smallint; eg_inc, eg_rate, eg_ksl: Byte; reg_vib, reg_type, reg_ksr, reg_mult, reg_ksl, reg_tl, reg_ar, reg_dr, reg_sl, reg_rr, reg_wf, key: Byte; end; OPL3_CHAN = Record p_slot: array[0..1] of P_OPL3_SLOT; p_chan: P_OPL3_CHAN; p_chip: P_OPL3_CHIP; p_out: array[0..3] of ^Smallint; ch_type: OPL3_CHAN_TYPE; fnum: Word; block, fb, con, alg, ksr: Byte; out_l, out_r: Word; end; OPL3_CHIP = Record chan: array[0..17] of OPL3_CHAN; slot: array[0..35] of OPL3_SLOT; timer: Word; nts_bit, dva_bit, dvb_bit: 0..1; rhy_flag: Byte; trem_dir: 0..1; trem_pos, trem_val, vib_pos: Byte; noise: Dword; output: array[0..1] of Longint; out_l: array[0..17] of Smallint; out_r: array[0..17] of Smallint; out_null: Smallint; end; var opl3: OPL3_CHIP; function limit_value(value,lo_bound,hi_bound: Longint): Longint; begin If (value > hi_bound) then value := hi_bound else If (value < lo_bound) then value := lo_bound; limit_value := value; end; function envelope_calc_sin(wf: Byte; phase: Word; eg_out: Smallint): Smallint; var output, level, invert: Word; begin phase := phase AND $3ff; output := 0; invert := 0; Case wf of // Sine 0: begin If (phase AND $200 <> 0) then invert := NOT invert; If (phase AND $100 <> 0) then output := LOG_SIN_VAL[(phase AND $0ff) XOR $0ff] else output := LOG_SIN_VAL[phase and $0ff]; end; // Half-Sine 1: begin If (phase AND $200 <> 0) then output := $1000 else If (phase AND $100 <> 0) then output := LOG_SIN_VAL[(phase AND $0ff) xor $0ff] else output := LOG_SIN_VAL[phase AND $0ff]; end; // Abs-Sine 2: begin If (phase AND $100 <> 0) then output := LOG_SIN_VAL[(phase AND $0ff) XOR $0ff] else output := LOG_SIN_VAL[phase AND $0ff]; end; // Pulse-Sine 3: begin If (phase AND $100 <> 0) then output := $1000 else output := LOG_SIN_VAL[phase AND $0ff]; end; // Sine (EPO) 4: begin If (phase AND $300 = $100) then invert := NOT invert; If (phase AND $200 <> 0) then output := $1000 else If (phase AND $80 <> 0) then output := LOG_SIN_VAL[((phase XOR $0ff) SHL 1) AND $0ff] else output := LOG_SIN_VAL[(phase SHL 1) AND $0ff]; end; // Abs-Sine (EPO) 5: begin If (phase AND $200 <> 0) then output := $1000 else If (phase AND $80 <> 0) then output := LOG_SIN_VAL[((phase XOR $0ff) SHL 1) AND $0ff] else output := LOG_SIN_VAL[(phase SHL 1) AND $0ff]; end; // Square 6: begin If (phase AND $200 <> 0) then invert := WORD_NULL; output := 0; end; // Derived Square 7: begin If (phase AND $200 <> 0) then begin invert := NOT invert; phase := (phase AND $1ff) XOR $1ff; end; output := phase SHL 3; end; end; level := limit_value(output + (eg_out SHL 3),0,$1fff); envelope_calc_sin := SMALLINT(((EXP_VAL[(level AND $0ff) XOR $0ff] OR $400) SHL 1) SHR (level SHR 8)) XOR invert; end; function envelope_calc_rate(p_slot: P_OPL3_SLOT; reg_rate: Byte): Byte; var rate: Byte; begin If (reg_rate = 0) then begin envelope_calc_rate := 0; EXIT; end; rate := (reg_rate SHL 2); If (p_slot^.reg_ksr <> 0) then Inc(rate,p_slot^.p_chan^.ksr) else Inc(rate,(p_slot^.p_chan^.ksr SHR 2)); envelope_calc_rate := limit_value(rate,0,60); end; procedure envelope_update_ksl(p_slot: P_OPL3_SLOT); var ksl: Smallint; begin ksl := (KSL_VAL[p_slot^.p_chan^.fnum SHR 6] SHL 2) - (8 - p_slot^.p_chan^.block) SHL 5; p_slot^.eg_ksl := limit_value(ksl,0,255); end; procedure envelope_update_rate(p_slot: P_OPL3_SLOT); begin Case p_slot^.eg_state of EG_OFF: p_slot^.eg_rate := 0; EG_ATTACK: p_slot^.eg_rate := envelope_calc_rate(p_slot,p_slot^.reg_ar); EG_DECAY: p_slot^.eg_rate := envelope_calc_rate(p_slot,p_slot^.reg_dr); EG_SUSTAIN, EG_RELEASE: p_slot^.eg_rate := envelope_calc_rate(p_slot,p_slot^.reg_rr); end; end; procedure envelope_calc(p_slot: P_OPL3_SLOT); var rate_hi, rate_lo: Byte; begin rate_hi := p_slot^.eg_rate SHR 2; rate_lo := p_slot^.eg_rate AND 3; // calculate increment step for output If (EG_SHIFT[rate_hi] > 0) then begin If ((p_slot^.p_chip^.timer AND ((1 SHL EG_SHIFT[rate_hi]) - 1)) = 0) then p_slot^.eg_inc := EG_VAL[EG_IDX[rate_hi],rate_lo, ((p_slot^.p_chip^.timer) SHR EG_SHIFT[rate_hi]) AND 7] else p_slot^.eg_inc := 0; end else p_slot^.eg_inc := EG_VAL[EG_IDX[rate_hi],rate_lo, p_slot^.p_chip^.timer AND 7] SHL Abs(EG_SHIFT[rate_hi]); p_slot^.eg_out := p_slot^.eg_rout + p_slot^.reg_tl SHL 2 + p_slot^.eg_ksl SHR KSL_SHIFT[p_slot^.reg_ksl] + p_slot^.p_trem^; // apply LFO tremolo Case p_slot^.eg_state of EG_OFF: p_slot^.eg_rout := $1ff; EG_ATTACK: If (p_slot^.eg_rout <> 0) then begin Inc(p_slot^.eg_rout,((NOT p_slot^.eg_rout) * p_slot^.eg_inc) SHR 3); limit_value(p_slot^.eg_rout,0,$1ff); end else begin // continue with decay if max. level is reached p_slot^.eg_state := EG_DECAY; envelope_update_rate(p_slot); end; EG_DECAY: If (p_slot^.eg_rout < SMALLINT(p_slot^.reg_sl) SHL 4) then Inc(p_slot^.eg_rout,p_slot^.eg_inc) else begin // sustain level was reached p_slot^.eg_state := EG_SUSTAIN; envelope_update_rate(p_slot); end; EG_SUSTAIN, EG_RELEASE: If (p_slot^.eg_state = EG_SUSTAIN) and (p_slot^.reg_type <> 0) then // sustain phase else If (p_slot^.eg_rout < $1ff) then Inc(p_slot^.eg_rout,p_slot^.eg_inc) else begin // switch off generator if min. level is reached p_slot^.eg_state := EG_OFF; p_slot^.eg_rout := $1ff; envelope_update_rate(p_slot); end; end; end; procedure eg_key_on_off(p_slot: P_OPL3_SLOT; key_on: Boolean); begin If key_on then begin If (p_slot^.key = 0) then begin p_slot^.eg_state := EG_ATTACK; envelope_update_rate(p_slot); If (p_slot^.eg_rate SHR 2 = $0f) then begin p_slot^.eg_state := EG_DECAY; envelope_update_rate(p_slot); p_slot^.eg_rout := 0; end; p_slot^.pg_phase := 0; end; If (p_slot^.p_chan^.ch_type <> CH_RHYTHM) then p_slot^.key := p_slot^.key OR 1 else p_slot^.key := p_slot^.key OR 2; If (p_slot^.reg_ar = 0) then begin // faked decay prevents restart of envelope if AR=0 p_slot^.eg_state := EG_DECAY; Inc(p_slot^.eg_rout); end; end else // key off If (p_slot^.key <> 0) then begin If (p_slot^.p_chan^.ch_type <> CH_RHYTHM) then p_slot^.key := p_slot^.key AND $0fe else p_slot^.key := p_slot^.key AND $0fd; If (p_slot^.key = 0) then begin p_slot^.eg_state := EG_RELEASE; envelope_update_rate(p_slot); end; end; end; procedure pg_generate(p_slot: P_OPL3_SLOT); var fnum: Word; fnum_hi: Byte; begin fnum := p_slot^.p_chan^.fnum; If (p_slot^.reg_vib <> 0) then begin // apply LFO vibrato fnum_hi := fnum SHR (7 + VIB_SHIFT[(p_slot^.p_chip^.timer SHR 10) AND 7] + (1 - p_slot^.p_chip^.dvb_bit)); Inc(fnum,fnum_hi * VIB_S_SHIFT[(p_slot^.p_chip^.timer SHR 10) AND 7]); end; Inc(p_slot^.pg_phase,(((fnum SHL p_slot^.p_chan^.block) SHR 1) * MULT_VAL[p_slot^.reg_mult]) SHR 1); end; procedure update_lfo_eg_ksr_mult(p_slot: P_OPL3_SLOT; data: Byte); begin // assign LFO tremolo If ((data SHR 7) AND 1 <> 0) then p_slot^.p_trem := @p_slot^.p_chip^.trem_val else p_slot^.p_trem := @p_slot^.p_chip^.out_null; p_slot^.reg_vib := (data SHR 6) AND 1; p_slot^.reg_type := (data SHR 5) AND 1; p_slot^.reg_ksr := (data SHR 4) AND 1; p_slot^.reg_mult := data AND $0f; envelope_update_rate(p_slot); end; procedure update_ksl_tl(p_slot: P_OPL3_SLOT; data: Byte); begin p_slot^.reg_ksl := (data SHR 6) AND 3; p_slot^.reg_tl := data AND $3f; envelope_update_ksl(p_slot); end; procedure update_ar_dr(p_slot: P_OPL3_SLOT; data: Byte); begin p_slot^.reg_ar := (data SHR 4) AND $0f; p_slot^.reg_dr := data AND $0f; envelope_update_rate(p_slot); end; procedure update_sl_rr(p_slot: P_OPL3_SLOT; data: Byte); begin p_slot^.reg_sl := SL_VAL[(data SHR 4) AND $0f]; p_slot^.reg_rr := data AND $0f; envelope_update_rate(p_slot); end; procedure slot_generate(p_slot: P_OPL3_SLOT; phase: Word); begin If (phase = WORD_NULL) then phase := WORD(p_slot^.pg_phase SHR 9) + p_slot^.p_mod^; p_slot^.output := envelope_calc_sin(p_slot^.reg_wf,phase,p_slot^.eg_out); end; procedure slot_calc_fb(p_slot: P_OPL3_SLOT); begin If (p_slot^.p_chan^.fb <> 0) then p_slot^.fb_out := (p_slot^.prev_out + p_slot^.output) SHR (9 - p_slot^.p_chan^.fb) else p_slot^.fb_out := 0; p_slot^.prev_out := p_slot^.output; end; procedure chan_set_alg(p_chan: P_OPL3_CHAN); begin Case p_chan^.ch_type of CH_2OP: Case (p_chan^.alg AND 1) of 0: begin // FM p_chan^.p_slot[0]^.p_mod := @p_chan^.p_slot[0]^.fb_out; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; p_chan^.p_out[0] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[1] := @p_chan^.p_chip^.out_null; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; 1: begin // AM p_chan^.p_slot[0]^.p_mod := @p_chan^.p_slot[0]^.fb_out; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_out[0] := @p_chan^.p_slot[0]^.output; p_chan^.p_out[1] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; end; CH_4OP_2: begin p_chan^.p_chan^.p_out[0] := @p_chan^.p_chip^.out_null; p_chan^.p_chan^.p_out[1] := @p_chan^.p_chip^.out_null; p_chan^.p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; Case (p_chan^.alg AND 3) of 0: begin // FM-FM p_chan^.p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.fb_out; p_chan^.p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.output; p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[1]^.output; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; p_chan^.p_out[0] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[1] := @p_chan^.p_chip^.out_null; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; 1: begin // FM-AM p_chan^.p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.fb_out; p_chan^.p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.output; p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; p_chan^.p_out[0] := @p_chan^.p_chan^.p_slot[1]^.output; p_chan^.p_out[1] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; 2: begin // AM-AM p_chan^.p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.fb_out; p_chan^.p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[1]^.output; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; p_chan^.p_out[0] := @p_chan^.p_chan^.p_slot[0]^.output; p_chan^.p_out[1] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; 3: begin // AM-FM p_chan^.p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.fb_out; p_chan^.p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[1]^.output; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_out[0] := @p_chan^.p_chan^.p_slot[0]^.output; p_chan^.p_out[1] := @p_chan^.p_slot[0]^.output; p_chan^.p_out[2] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; end; end; CH_RHYTHM: Case (p_chan^.alg AND 1) of 0: begin // FM p_chan^.p_slot[0]^.p_mod := @p_chan^.p_slot[0]^.fb_out; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; end; 1: begin // AM p_chan^.p_slot[0]^.p_mod := @p_chan^.p_slot[0]^.fb_out; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; end; end; end; end; procedure chan_update_rhythm(p_chip: P_OPL3_CHIP; data: Byte); begin p_chip^.rhy_flag := data AND $3f; If (p_chip^.rhy_flag AND $20 <> 0) then begin // BD p_chip^.chan[6].ch_type := CH_RHYTHM; p_chip^.chan[6].p_out[0] := @p_chip^.chan[6].p_slot[1]^.output; p_chip^.chan[6].p_out[1] := @p_chip^.chan[6].p_slot[1]^.output; p_chip^.chan[6].p_out[2] := @p_chip^.out_null; p_chip^.chan[6].p_out[3] := @p_chip^.out_null; chan_set_alg(@p_chip^.chan[6]); eg_key_on_off(p_chip^.chan[6].p_slot[0],p_chip^.rhy_flag AND $10 <> 0); eg_key_on_off(p_chip^.chan[6].p_slot[1],p_chip^.rhy_flag AND $10 <> 0); // HH + SD p_chip^.chan[7].ch_type := CH_RHYTHM; p_chip^.chan[7].p_out[0] := @p_chip^.chan[7].p_slot[0]^.output; p_chip^.chan[7].p_out[1] := @p_chip^.chan[7].p_slot[0]^.output; p_chip^.chan[7].p_out[2] := @p_chip^.chan[7].p_slot[1]^.output; p_chip^.chan[7].p_out[3] := @p_chip^.chan[7].p_slot[1]^.output; eg_key_on_off(p_chip^.chan[7].p_slot[0],p_chip^.rhy_flag AND 1 <> 0); eg_key_on_off(p_chip^.chan[7].p_slot[1],p_chip^.rhy_flag AND 8 <> 0); // TT + TC p_chip^.chan[8].ch_type := CH_RHYTHM; p_chip^.chan[8].p_out[0] := @p_chip^.chan[8].p_slot[0]^.output; p_chip^.chan[8].p_out[1] := @p_chip^.chan[8].p_slot[0]^.output; p_chip^.chan[8].p_out[2] := @p_chip^.chan[8].p_slot[1]^.output; p_chip^.chan[8].p_out[3] := @p_chip^.chan[8].p_slot[1]^.output; eg_key_on_off(p_chip^.chan[8].p_slot[0],p_chip^.rhy_flag AND 4 <> 0); eg_key_on_off(p_chip^.chan[8].p_slot[1],p_chip^.rhy_flag AND 2 <> 0); end else begin // reset chan. 6/7/8 to 2OP p_chip^.chan[6].ch_type := CH_2OP; chan_set_alg(@p_chip^.chan[6]); p_chip^.chan[7].ch_type := CH_2OP; chan_set_alg(@p_chip^.chan[7]); p_chip^.chan[8].ch_type := CH_2OP; chan_set_alg(@p_chip^.chan[8]); end; end; procedure update_fnum_block_ksr(p_chan: P_OPL3_CHAN; data: Byte; msb_flag: Boolean); begin If (p_chan^.ch_type = CH_4OP_2) then EXIT; If msb_flag then begin // update upper bits p_chan^.fnum := (p_chan^.fnum AND $300) OR data; p_chan^.ksr := (p_chan^.block SHL 1) OR ((p_chan^.fnum SHR (9 - p_chan^.p_chip^.nts_bit)) AND 1); end else begin // update lower bits p_chan^.fnum := (p_chan^.fnum AND $0ff) OR ((data AND 3) SHL 8); p_chan^.block := (data shr 2) AND 7; p_chan^.ksr := (p_chan^.block SHL 1) OR ((p_chan^.fnum SHR (9 - p_chan^.p_chip^.nts_bit)) AND 1); end; envelope_update_ksl(p_chan^.p_slot[0]); envelope_update_ksl(p_chan^.p_slot[1]); envelope_update_rate(p_chan^.p_slot[0]); envelope_update_rate(p_chan^.p_slot[1]); If (p_chan^.ch_type = CH_4OP_1) then begin p_chan^.p_chan^.fnum := p_chan^.fnum; p_chan^.p_chan^.ksr := p_chan^.ksr; If msb_flag then p_chan^.p_chan^.block := p_chan^.block; envelope_update_ksl(p_chan^.p_chan^.p_slot[0]); envelope_update_ksl(p_chan^.p_chan^.p_slot[1]); envelope_update_rate(p_chan^.p_chan^.p_slot[0]); envelope_update_rate(p_chan^.p_chan^.p_slot[1]); end; end; procedure update_fb_con(p_chan: P_OPL3_CHAN; data: Byte); begin p_chan^.fb := (data AND $0e) SHR 1; p_chan^.con := data AND 1; p_chan^.alg := p_chan^.con; Case p_chan^.ch_type of CH_2OP, CH_RHYTHM: chan_set_alg(p_chan); CH_4OP_1: begin p_chan^.p_chan^.alg := 4 OR (p_chan^.con SHL 1) OR (p_chan^.p_chan^.con); chan_set_alg(p_chan^.p_chan); end; CH_4OP_2: begin p_chan^.alg := 4 OR (p_chan^.p_chan^.con SHL 1) OR (p_chan^.con); chan_set_alg(p_chan); end; end; // trigger output to left If ((data SHR 4) AND 1 <> 0) then p_chan^.out_l := WORD_NULL else p_chan^.out_l := 0; // trigger output to right If ((data SHR 5) AND 1 <> 0) then p_chan^.out_r := WORD_NULL else p_chan^.out_r := 0; end; procedure generate_rhythm_slots(p_chip: P_OPL3_CHIP); var p_slot: P_OPL3_SLOT; phase,phase_lo,phase_hi,phase_bit: Word; procedure calc_phase_slot7_slot8; begin phase_lo := (p_chip^.chan[7].p_slot[0]^.pg_phase SHR 9) AND $3ff; phase_hi := (p_chip^.chan[8].p_slot[1]^.pg_phase SHR 9) AND $3ff; If ((phase_lo AND 8) OR (((phase_lo SHR 5) XOR phase_lo) AND 4) OR (((phase_hi SHR 2) XOR phase_hi) AND 8) <> 0) then phase_bit := 1 else phase_bit := 0; end; begin // BD p_slot := p_chip^.chan[6].p_slot[0]; slot_generate(p_slot,WORD(p_slot^.pg_phase SHR 9) + (p_slot^.p_mod^)); p_slot := p_chip^.chan[6].p_slot[1]; slot_generate(p_slot,WORD(p_slot^.pg_phase SHR 9) + (p_slot^.p_mod^)); // HH p_slot := p_chip^.chan[7].p_slot[0]; calc_phase_slot7_slot8; phase := (phase_bit SHL 9) OR WORD($34 SHL ((phase_bit XOR (p_chip^.noise AND 1) SHL 1))); slot_generate(p_slot,phase); // TT p_slot := p_chip^.chan[8].p_slot[0]; slot_generate(p_slot,WORD(p_slot^.pg_phase SHR 9)); // SD p_slot := p_chip^.chan[7].p_slot[1]; calc_phase_slot7_slot8; phase := ($100 SHL ((phase_lo SHR 8) AND 1)) XOR WORD((p_chip^.noise AND 1) SHL 8); slot_generate(p_slot,phase); // TC p_slot := p_chip^.chan[8].p_slot[1]; phase := $100 OR (phase_bit SHL 9); slot_generate(p_slot,phase); end; procedure update_key(p_chan: P_OPL3_CHAN; key_on: Boolean); begin Case p_chan^.ch_type of CH_2OP, CH_4OP_1, CH_RHYTHM: begin eg_key_on_off(p_chan^.p_slot[0],key_on); eg_key_on_off(p_chan^.p_slot[1],key_on); If (p_chan^.ch_type = CH_4OP_1) then begin eg_key_on_off(p_chan^.p_chan^.p_slot[0],key_on); eg_key_on_off(p_chan^.p_chan^.p_slot[1],key_on); end; end; end; end; procedure chan_update_4op(p_chip: P_OPL3_CHIP; data: Byte); var bit_num: Byte; begin For bit_num := 0 to 5 do If ((data SHR bit_num) AND 1 <> 0) then begin // set chan. to 4OP p_chip^.chan[CH_4OP_IDX[bit_num]].ch_type := CH_4OP_1; p_chip^.chan[CH_4OP_IDX[bit_num]+3].ch_type := CH_4OP_2; end else begin // reset chan. to 2OP p_chip^.chan[CH_4OP_IDX[bit_num]].ch_type := CH_2OP; p_chip^.chan[CH_4OP_IDX[bit_num]+3].ch_type := CH_2OP; end; end; function chip_generate(p_chip: P_OPL3_CHIP): Dword; var slot_num: Byte; accm: Smallint; lr_mix: array[0..1] of Smallint; begin // generate slot data For slot_num := 0 to 35 do begin slot_calc_fb(@p_chip^.slot[slot_num]); pg_generate(@p_chip^.slot[slot_num]); envelope_calc(@p_chip^.slot[slot_num]); slot_generate(@p_chip^.slot[slot_num],WORD_NULL); end; // rhythm mode If (p_chip^.rhy_flag AND $20 <> 0) then generate_rhythm_slots(p_chip); // update channel mixer lr_mix[1] := limit_value(p_chip^.output[1],-$7fff,$7fff); lr_mix[0] := limit_value(p_chip^.output[0],-$7fff,$7fff); p_chip^.output[0] := 0; p_chip^.output[1] := 0; // left output For slot_num := 0 to 17 do begin accm := p_chip^.chan[slot_num].p_out[0]^ + p_chip^.chan[slot_num].p_out[1]^ + p_chip^.chan[slot_num].p_out[2]^ + p_chip^.chan[slot_num].p_out[3]^; Inc(p_chip^.output[0],SMALLINT(accm AND p_chip^.chan[slot_num].out_l)); p_chip^.out_l[slot_num] := SMALLINT(accm AND p_chip^.chan[slot_num].out_l); end; // right output For slot_num := 0 to 17 do begin accm := p_chip^.chan[slot_num].p_out[0]^ + p_chip^.chan[slot_num].p_out[1]^ + p_chip^.chan[slot_num].p_out[2]^ + p_chip^.chan[slot_num].p_out[3]^; Inc(p_chip^.output[1],SMALLINT(accm AND p_chip^.chan[slot_num].out_r)); p_chip^.out_r[slot_num] := SMALLINT(accm AND p_chip^.chan[slot_num].out_r); end; // update LFO tremolo If (p_chip^.timer AND $3f = $3f) then begin If (p_chip^.trem_dir = 0) then begin If (p_chip^.trem_pos < 105) then Inc(p_chip^.trem_pos) else begin Dec(p_chip^.trem_pos); p_chip^.trem_dir := 1; end end else begin If (p_chip^.trem_pos > 0) then Dec(p_chip^.trem_pos) else begin Inc(p_chip^.trem_pos); p_chip^.trem_dir := 0; end; end; p_chip^.trem_val := (p_chip^.trem_pos SHR 2) SHR ((1 - p_chip^.dva_bit) SHL 1); end; // update noise generator If (p_chip^.noise AND 1 <> 0) then p_chip^.noise := p_chip^.noise XOR NOISE_XOR; p_chip^.noise := p_chip^.noise SHR 1; Inc(p_chip^.timer); chip_generate := (WORD(lr_mix[1]) SHL 16) OR WORD(lr_mix[0]); end; procedure OPL3EMU_init; var slot_num, chan_num: Byte; begin // initialize slot data For slot_num := 0 to 35 do begin opl3.slot[slot_num].p_chip := @opl3; opl3.slot[slot_num].p_mod := @opl3.out_null; opl3.slot[slot_num].eg_rout := $1ff; opl3.slot[slot_num].eg_out := $1ff; opl3.slot[slot_num].eg_state := EG_OFF; opl3.slot[slot_num].p_trem := @opl3.out_null; end; // initialize chan. data For chan_num := 0 to 17 do begin opl3.out_l[chan_num] := 0; opl3.out_r[chan_num] := 0; opl3.chan[chan_num].out_l := WORD_NULL; opl3.chan[chan_num].out_r := WORD_NULL; opl3.chan[chan_num].p_chip := @opl3; opl3.chan[chan_num].ch_type := CH_2OP; opl3.chan[chan_num].p_out[0] := @opl3.out_null; opl3.chan[chan_num].p_out[1] := @opl3.out_null; opl3.chan[chan_num].p_out[2] := @opl3.out_null; opl3.chan[chan_num].p_out[3] := @opl3.out_null; opl3.chan[chan_num].p_slot[0] := @opl3.slot[CH_SLOT_IDX[chan_num]]; opl3.chan[chan_num].p_slot[1] := @opl3.slot[CH_SLOT_IDX[chan_num]+3]; opl3.slot[CH_SLOT_IDX[chan_num]].p_chan := @opl3.chan[chan_num]; opl3.slot[CH_SLOT_IDX[chan_num]+3].p_chan := @opl3.chan[chan_num]; If (CH_4OP_MASK[chan_num] <> 0) then opl3.chan[chan_num].p_chan := @opl3.chan[PRED(CH_4OP_MASK[chan_num])]; chan_set_alg(@opl3.chan[chan_num]); end; // initialize chip data opl3.noise := NOISE_HASH_VAL; opl3.timer := 0; opl3.nts_bit := 0; opl3.dva_bit := 0; opl3.dvb_bit := 0; opl3.rhy_flag := 0; opl3.vib_pos := 0; opl3.trem_dir := 0; opl3.trem_pos := 0; opl3.trem_val := 0; opl3.output[0] := 0; opl3.output[1] := 0; end; procedure OPL3EMU_WriteReg(reg: Word; data: Byte); var reg_hi, reg_lo: Byte; begin reg := reg AND $1ff; reg_hi := (reg SHR 8) AND 1; reg_lo := reg AND $0ff; Case reg_lo of // misc. registers $01..$08: If (reg_hi <> 0) then begin If (reg_lo AND $0f = 4) then // 4OP con. sel. chan_update_4op(@opl3,data); end else If (reg_lo AND $0f = 8) then // bit 'NTS' // 0 -> LSB for key is bit 10 of Fnum // 1 -> LSB for key is bit 9 of Fnum opl3.nts_bit := (data SHR 6) AND 1; // AM/VIB/EGT/KSR/MULT $20..$35: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then update_lfo_eg_ksr_mult(@opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])], data); // KSL/TL $40..$55: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then update_ksl_tl(@opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])], data); // AR/DR $60..$75: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then update_ar_dr(@opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])], data); // SL/RR $80..$95: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then update_sl_rr(@opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])], data); // Fnum/block/KSR $0a0..$a8: update_fnum_block_ksr(@opl3.chan[9 * reg_hi + (reg_lo AND $0f)], data,TRUE); // MSB part // Fnum/block/KSR $0b0..$0b8: begin // Fnum/block/KSR update_fnum_block_ksr(@opl3.chan[9 * reg_hi + (reg_lo AND $0f)], data,FALSE); // LSB part // key on/off update_key(@opl3.chan[9 * reg_hi + (reg_lo AND $0f)],data AND $20 <> 0); end; // LFO/rhythm $0bd: If (reg_hi = 0) then begin // bit 'DAM' (LFO tremolo) opl3.dva_bit := data SHR 7; // bit 'DVB' (LFO vibrato) opl3.dvb_bit := (data SHR 6) AND 1; // rhythm mode flag chan_update_rhythm(@opl3,data); end; // slot/feedback/con. $0c0..$0c8: update_fb_con(@opl3.chan[9 * reg_hi + (reg_lo AND $0f)], data); // waveform sel. $0e0..$0f5: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])].reg_wf := data AND 7; end; end; procedure OPL3EMU_PollProc(p_data: pDword; var ch_table); var chan_num: Byte; temp: Dword; begin // assign main output p_data^ := chip_generate(@opl3); // assign per-channel output For chan_num := 0 to 17 do CHAN_PTR_TABLE(ch_table)[chan_num]^:= (WORD(opl3.out_r[CH_MAPPING[chan_num]]) SHL 16) OR WORD(opl3.out_l[CH_MAPPING[chan_num]]); // sort rhythm channels as last If (opl3.rhy_flag AND $20 <> 0) then begin temp := CHAN_PTR_TABLE(ch_table)[15]^; CHAN_PTR_TABLE(ch_table)[15]^ := CHAN_PTR_TABLE(ch_table)[6]^; CHAN_PTR_TABLE(ch_table)[6]^ := temp; temp := CHAN_PTR_TABLE(ch_table)[16]^; CHAN_PTR_TABLE(ch_table)[16]^ := CHAN_PTR_TABLE(ch_table)[7]^; CHAN_PTR_TABLE(ch_table)[7]^ := temp; temp := CHAN_PTR_TABLE(ch_table)[17]^; CHAN_PTR_TABLE(ch_table)[17]^ := CHAN_PTR_TABLE(ch_table)[8]^; CHAN_PTR_TABLE(ch_table)[8]^ := temp; end; end; end. adlibtracker2-2.4.23/adtrack2.rc0000644000000000000000000000003713176573533015047 0ustar rootrootAdT2_icon ICON "progicon.ico" adlibtracker2-2.4.23/adt2ext2.pas0000644000000000000000000013713713176573533015204 0ustar rootrootunit AdT2ext2; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const quick_mark_type: Byte = 0; discard_block: Boolean = FALSE; old_chan_pos: Byte = 1; old_hpos: Byte = 1; old_page: Byte = 0; old_block_chan_pos: Byte = 1; old_block_patt_hpos: Byte = 1; old_block_patt_page: Byte = 0; procedure process_global_keys; procedure PROGRAM_SCREEN_init; function INSTRUMENT_CONTROL_alt(instr: Byte; title: String): Byte; procedure INSTRUMENT_test(instr,instr2,chan: Byte; fkey: Word; process_macros: Boolean); procedure INSTRUMENT_CONTROL_page_refresh(page: Byte); procedure INSTRUMENT_CONTROL_edit; procedure PATTERN_ORDER_page_refresh(page: Byte); procedure PATTERN_ORDER_edit(var page,hpos,vpos: Byte); procedure PATTERN_tabs_refresh; procedure PATTERN_page_refresh(page: Byte); procedure STATUS_LINE_refresh; procedure PATTERN_position_preview(pattern,line,channel,mode: Byte); function PATTERN_trace: Word; procedure PATTERN_edit(var pattern,page,hpos: Byte); procedure process_config_file; function _1st_marked: Byte; function _2nd_marked: Byte; function marked_instruments: Byte; procedure reset_marked_instruments; function get_4op_to_test: Word; function check_4op_to_test: Word; function check_4op_instrument(ins: Byte): Word; function check_4op_flag(ins: Byte): Boolean; procedure reset_4op_flag(ins: Byte); procedure set_4op_flag(ins: Byte); procedure update_4op_flag_marks; implementation uses {$IFNDEF UNIX} CRT, {$ENDIF} {$IFDEF GO32V2} GO32, {$ELSE} SDL_Timer, {$ENDIF} AdT2opl3,AdT2unit,AdT2sys,AdT2extn,AdT2ext4,AdT2ext5,AdT2text,AdT2pack,AdT2keyb, TxtScrIO,StringIO,DialogIO,ParserIO; var old_pattern_patt,old_pattern_page, old_pattern_hpos, old_block_xstart,old_block_ystart: Byte; old_marking: Boolean; {$i instedit.inc} {$i ipattord.inc} {$i ipattern.inc} procedure FADE_OUT_RECORDING; {$IFNDEF GO32V2} const frame_start: Longint = 0; frame_end: Longint = 0; actual_frame_end: Longint = 0; var xstart,ystart: Byte; temp,temp2: Byte; label _jmp1,_end; begin If (play_status = isStopped) or (sdl_opl3_emulator = 0) then begin sdl_opl3_emulator := 0; opl3_channel_recording_mode := FALSE; EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' WAV RECORDER ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; show_progress(40); ShowStr(screen_ptr,xstart+2,ystart+1, 'FADiNG OUT WAV RECORDiNG...', dialog_background+dialog_text); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_num_steps := 1; progress_step := 1; progress_value:= 63; progress_old_value := BYTE_NULL; For temp := 63 downto 0 do begin If scankey(1) then GOTO _jmp1; fade_out_volume := temp; set_global_volume; show_progress(temp); For temp2 := 1 to 10 do begin If scankey(1) then GOTO _jmp1; keyboard_reset_buffer; actual_frame_end := SDL_GetTicks; frame_end := frame_start+fade_delay_tab[temp]; If (actual_frame_end+fade_delay_tab[temp] > frame_end) then begin frame_end := actual_frame_end; _draw_screen_without_delay := TRUE; draw_screen; end; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; end; _draw_screen_without_delay := TRUE; draw_screen; end; _jmp1: show_progress(0); ShowStr(screen_ptr,xstart+2,ystart+1, 'FADiNG iN SONG PLAYBACK... ', dialog_background+dialog_text); flush_WAV_data; sdl_opl3_emulator := 0; opl3_channel_recording_mode := FALSE; For temp := 0 to 63 do begin If scankey(1) then GOTO _end; fade_out_volume := temp; set_global_volume; show_progress(temp); If scankey(1) then GOTO _end; _draw_screen_without_delay := TRUE; draw_screen; keyboard_reset_buffer; actual_frame_end := SDL_GetTicks; frame_end := frame_start+5; If (actual_frame_end > frame_end) then frame_end := actual_frame_end; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; end; _end: flush_WAV_data; sdl_opl3_emulator := 0; opl3_channel_recording_mode := FALSE; fade_out_volume := 63; set_global_volume; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; {$ELSE} begin {$ENDIF} end; procedure FADE_IN_RECORDING; {$IFNDEF GO32V2} const frame_start: Longint = 0; frame_end: Longint = 0; actual_frame_end: Longint = 0; var xstart,ystart: Byte; temp,temp2: Byte; smooth_fadeOut: Boolean; label _end; begin If (sdl_opl3_emulator = 1) or (calc_following_order(0) = -1) then EXIT; If (play_status = isStopped) then smooth_fadeOut := FALSE else smooth_fadeOut := TRUE; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' WAV RECORDER ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; progress_xstart := xstart+2; progress_ystart := ystart+2; progress_num_steps := 1; progress_step := 1; progress_value:= 63; progress_old_value := BYTE_NULL; If smooth_fadeOut then begin show_progress(40); ShowStr(screen_ptr,xstart+2,ystart+1, 'FADiNG OUT SONG PLAYBACK...', dialog_background+dialog_text); For temp := 63 downto 0 do begin If scankey(1) then GOTO _end; fade_out_volume := temp; set_global_volume; show_progress(temp); _draw_screen_without_delay := TRUE; draw_screen; keyboard_reset_buffer; actual_frame_end := SDL_GetTicks; frame_end := frame_start+5; If (actual_frame_end > frame_end) then frame_end := actual_frame_end; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; If scankey(1) then GOTO _end; end; end else SDL_Delay(100); show_progress(0); ShowStr(screen_ptr,xstart+2,ystart+1, 'FADiNG iN WAV RECORDiNG... ', dialog_background+dialog_text); Case play_status of isStopped: begin If trace_by_default then tracing := TRUE; start_playing; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; end; end; fade_out_playback(FALSE); sdl_opl3_emulator := 1; For temp := 0 to 63 do begin If scankey(1) then GOTO _end; fade_out_volume := temp; set_global_volume; show_progress(temp); _draw_screen_without_delay := TRUE; draw_screen; For temp2 := 1 to 10 do begin If scankey(1) then GOTO _end; keyboard_reset_buffer; actual_frame_end := SDL_GetTicks; frame_end := frame_start+fade_delay_tab[temp]; If (actual_frame_end+fade_delay_tab[temp] > frame_end) then begin frame_end := actual_frame_end; _draw_screen_without_delay := TRUE; draw_screen; end; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; end; _draw_screen_without_delay := TRUE; draw_screen; end; _end: sdl_opl3_emulator := 1; fade_out_volume := 63; set_global_volume; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; {$ELSE} begin {$ENDIF} end; procedure process_global_keys; var temp,temp2: Byte; start_row,end_row: Byte; chunk: tCHUNK; begin If NOT ins_trailing_flag and ctrl_pressed then If scankey(SC_1) then current_octave := 1 else If scankey(SC_2) then current_octave := 2 else If scankey(SC_3) then current_octave := 3 else If scankey(SC_4) then current_octave := 4 else If scankey(SC_5) then current_octave := 5 else If scankey(SC_6) then current_octave := 6 else If scankey(SC_7) then current_octave := 7 else If scankey(SC_8) then current_octave := 8; If alt_pressed and NOT ctrl_pressed then If scankey(SC_PLUS) or (shift_pressed and scankey(SC_UP)) then begin If (overall_volume < 63) then begin Inc(overall_volume); set_global_volume; end; end else If scankey(SC_MINUS2) or (shift_pressed and scankey(SC_DOWN)) then begin If (overall_volume > 0) then begin Dec(overall_volume); set_global_volume; end; end; {$IFNDEF GO32V2} If scankey(SC_F11) and ((alt_pressed and NOT ctrl_pressed) or (ctrl_pressed and NOT alt_pressed)) then begin If ctrl_pressed and NOT opl3_flushmode and ((sdl_opl3_emulator = 0) or (play_status = isStopped)) then begin opl3_channel_recording_mode := TRUE; track_notes := FALSE; If shift_pressed then sdl_opl3_emulator := 0; end; If NOT shift_pressed then sdl_opl3_emulator := 1 else FADE_IN_RECORDING; keyboard_reset_buffer; end; If scankey(SC_F12) and ((alt_pressed and NOT ctrl_pressed) or (ctrl_pressed and NOT alt_pressed)) then begin If NOT shift_pressed then begin flush_WAV_data; sdl_opl3_emulator := 0; opl3_channel_recording_mode := FALSE; end else FADE_OUT_RECORDING; keyboard_reset_buffer; end; {$ENDIF} If track_notes and scankey(SC_BACKSPACE) then begin If NOT ctrl_pressed then begin start_row := pattern_page; end_row := pattern_page; end else begin start_row := 0; end_row := songdata.patt_len; end; For temp2 := start_row to end_row do For temp := 1 to nm_track_chan do If channel_flag[track_chan_start+temp-1] then begin chunk := pattdata^[pattern_patt DIV 8][pattern_patt MOD 8] [track_chan_start+temp-1][temp2]; chunk.note := 0; chunk.instr_def := 0; pattdata^[pattern_patt DIV 8][pattern_patt MOD 8] [track_chan_start+temp-1][temp2] := chunk; end; end; end; procedure PROGRAM_SCREEN_init; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:PROGRAM_SCREEN_init'; {$ENDIF} fr_setting.shadow_enabled := FALSE; Frame(screen_ptr,01,MAX_PATTERN_ROWS+12,MAX_COLUMNS,MAX_PATTERN_ROWS+22, main_background+main_border,'', main_background+main_title, frame_double); Frame(screen_ptr,01,01,MAX_COLUMNS,MAX_PATTERN_ROWS+12, main_background+main_border,'- '+_ADT2_TITLE_STRING_+' -', main_background+main_border, frame_single); Frame(screen_ptr,02,02,24,07, status_background+status_border,' STATUS ', status_background+status_border, frame_double); Frame(screen_ptr,25,02,25+MAX_ORDER_COLS*7-1+PATTORD_xshift*2,07, order_background+order_border,' PATTERN ORDER ( ) ', order_background+order_border, frame_double); fr_setting.shadow_enabled := TRUE; area_x1 := 0; area_y1 := 0; area_x2 := 0; area_y2 := 0; ShowVStr(screen_ptr,02,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,03,MAX_PATTERN_ROWS+13,'MAX MiN', analyzer_bckg+analyzer); For temp := 05 to MAX_COLUMNS-6 do ShowVStr(screen_ptr,temp,MAX_PATTERN_ROWS+13, #242#224#224#224#224#224#224#224#243, analyzer_bckg+analyzer); ShowVStr(screen_ptr,04,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-5,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-3,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-2,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-1,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+13,'dB', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+14,#224'47', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+15,#224, analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+16,#224'23', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+17,#224, analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+18,#224'12', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+19,#224'4', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+20,#224'2', analyzer_bckg+analyzer); ShowCStr(screen_ptr,03,03,'~ORDER/PATTERN ~ /', status_background+status_dynamic_txt, status_background+status_static_txt); ShowCStr(screen_ptr,03,04,'~ROW ~', status_background+status_dynamic_txt, status_background+status_static_txt); ShowCStr(screen_ptr,03,05,'~SPEED/TEMPO ~ /', status_background+status_dynamic_txt, status_background+status_static_txt); ShowStr(screen_ptr,02,08,patt_win[1], pattern_bckg+pattern_border); ShowStr(screen_ptr,02,09,patt_win[2], pattern_bckg+pattern_border); ShowStr(screen_ptr,02,10,patt_win[3], pattern_bckg+pattern_border); For temp := 11 to 11+MAX_PATTERN_ROWS-1 do ShowStr(screen_ptr,02,temp,patt_win[4], pattern_bckg+pattern_border); ShowStr(screen_ptr,02,11+MAX_PATTERN_ROWS,patt_win[5], pattern_bckg+pattern_border); end; procedure process_config_file; var data: String; function check_number(str: String; base: Byte; limit1,limit2: Longint; default: Longint): Longint; var idx,temp: Byte; temp2: Longint; result: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:check_number'; {$ENDIF} result := default; temp2 := 1000000000; For idx := 10 downto 1 do begin If (limit2 >= temp2) then begin temp := idx; BREAK; end; temp2 := temp2 DIV 10; end; If SameName(str+'='+ExpStrL('',temp,'?'),data) and (Length(data) < Length(str)+temp+2) then begin result := Str2num(Copy(data,Length(str)+2,temp),base); If (result >= limit1) and (result <= limit2) then else result := default; end; check_number := result; end; function validate_number(var num: Longint; str: String; base: Byte; limit1,limit2: Longint): Boolean; var idx,temp: Byte; temp2: Longint; result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:validate_number'; {$ENDIF} result := FALSE; temp2 := 1000000000; For idx := 10 downto 1 do begin If (limit2 >= temp2) then begin temp := idx; BREAK; end; temp2 := temp2 DIV 10; end; If SameName(str+'='+ExpStrL('',temp,'?'),data) and (Length(data) < Length(str)+temp+2) then begin num := Str2num(Copy(data,Length(str)+2,temp),base); If (num >= limit1) and (num <= limit2) then result := TRUE; end else result := TRUE; validate_number := result; end; type tRANGE = Set of 1..255; function check_range(str: String; base: Byte; range: tRANGE; default: Byte): Byte; var result: Word; begin result := default; If SameName(str+'='+ExpStrL('',3,'?'),data) and (Length(data) < Length(str)+5) then If (Str2num(Copy(data,Length(str)+2,3),base) in range) then result := Str2num(Copy(data,Length(str)+2,3),base); check_range := result; end; function check_boolean(str: String; default: Boolean): Boolean; var result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:process_config_file:check_boolean'; {$ENDIF} result := default; If SameName(str+'=???',data) and (Length(data) < Length(str)+5) then begin If (Copy(data,Length(str)+2,3) = 'on') then result := TRUE; If (Copy(data,Length(str)+2,3) = 'off') then result := FALSE; end; check_boolean := result; end; procedure check_rgb(str: String; var default: tRGB); var result: tRGB; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:process_config_file:check_rgb'; {$ENDIF} If SameName(str+'=??,??,??',data) and (Length(data) < Length(str)+10) then begin result.r := Str2num(Copy(data,Length(str)+2,2),10); result.g := Str2num(Copy(data,Length(str)+5,2),10); result.b := Str2num(Copy(data,Length(str)+8,2),10); If (result.r <= 63) and (result.g <= 63) and (result.b <= 63) then begin default := result; {$IFNDEF GO32V2} default.r := default.r SHL 2; default.g := default.g SHL 2; default.b := default.b SHL 2; {$ENDIF} end; end; end; procedure check_option_data; var temp: Byte; {$IFNDEF GO32V2} temp_str: String; {$ENDIF} begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:check_option_data'; opl3port := check_number('adlib_port',16,1,$0ffff,opl3port); typematic_rate := check_number('typematic_rate',10,0,31,typematic_rate); typematic_delay:= check_number('typematic_delay',10,0,3,typematic_delay); mouse_hspeed := check_number('mouse_hspeed',10,0,65535,mouse_hspeed); mouse_vspeed := check_number('mouse_vspeed',10,0,65535,mouse_vspeed); mouse_threshold := check_number('mouse_threshold',10,0,65535,mouse_threshold); screen_mode := check_number('screen_mode',10,0,5,screen_mode); comp_text_mode := check_number('comp_text_mode',10,0,4,comp_text_mode); opl_latency := check_number('opl_latency',10,0,1,opl_latency); fps_down_factor := check_number('fps_down_factor',10,0,10,fps_down_factor); mouse_disabled := check_boolean('mouse_disabled',mouse_disabled); // validate custom SVGA text-mode configuration custom_svga_mode := check_boolean('custom_svga_mode',custom_svga_mode); _custom_svga_cfg[1].flag := validate_number(_custom_svga_cfg[1].value,'svga_txt_columns',10,80,180); _custom_svga_cfg[2].flag := validate_number(_custom_svga_cfg[2].value,'svga_txt_rows',10,25,60); _custom_svga_cfg[3].flag := validate_number(_custom_svga_cfg[3].value,'crtc_misc_out',16,0,255); _custom_svga_cfg[4].flag := validate_number(_custom_svga_cfg[4].value,'crtc_h_total',16,0,255); _custom_svga_cfg[5].flag := validate_number(_custom_svga_cfg[5].value,'crtc_h_disp_en_end',16,0,255); _custom_svga_cfg[6].flag := validate_number(_custom_svga_cfg[6].value,'crtc_h_blank_start',16,0,255); _custom_svga_cfg[7].flag := validate_number(_custom_svga_cfg[7].value,'crtc_h_blank_end',16,0,255); _custom_svga_cfg[8].flag := validate_number(_custom_svga_cfg[8].value,'crtc_h_ret_start',16,0,255); _custom_svga_cfg[9].flag := validate_number(_custom_svga_cfg[9].value,'crtc_h_ret_end',16,0,255); _custom_svga_cfg[10].flag := validate_number(_custom_svga_cfg[10].value,'crtc_v_total',16,0,255); _custom_svga_cfg[11].flag := validate_number(_custom_svga_cfg[11].value,'crtc_overflow_reg',16,0,255); _custom_svga_cfg[12].flag := validate_number(_custom_svga_cfg[12].value,'crtc_preset_r_scan',16,0,255); _custom_svga_cfg[13].flag := validate_number(_custom_svga_cfg[13].value,'crtc_max_scan_h',16,0,255); _custom_svga_cfg[14].flag := validate_number(_custom_svga_cfg[14].value,'crtc_v_ret_start',16,0,255); _custom_svga_cfg[15].flag := validate_number(_custom_svga_cfg[15].value,'crtc_v_ret_end',16,0,255); _custom_svga_cfg[16].flag := validate_number(_custom_svga_cfg[16].value,'crtc_v_disp_en_end',16,0,255); _custom_svga_cfg[17].flag := validate_number(_custom_svga_cfg[17].value,'crtc_offs_width',16,0,255); _custom_svga_cfg[18].flag := validate_number(_custom_svga_cfg[18].value,'crtc_underline_loc',16,0,255); _custom_svga_cfg[19].flag := validate_number(_custom_svga_cfg[19].value,'crtc_v_blank_start',16,0,255); _custom_svga_cfg[20].flag := validate_number(_custom_svga_cfg[20].value,'crtc_v_blank_end',16,0,255); _custom_svga_cfg[21].flag := validate_number(_custom_svga_cfg[21].value,'crtc_mode_ctrl',16,0,255); _custom_svga_cfg[22].flag := validate_number(_custom_svga_cfg[22].value,'crtc_clock_m_reg',16,0,255); _custom_svga_cfg[23].flag := validate_number(_custom_svga_cfg[23].value,'crtc_char_gen_sel',16,0,255); _custom_svga_cfg[24].flag := validate_number(_custom_svga_cfg[24].value,'crtc_memory_m_reg',16,0,255); _custom_svga_cfg[25].flag := validate_number(_custom_svga_cfg[25].value,'crtc_mode_reg',16,0,255); _custom_svga_cfg[26].flag := validate_number(_custom_svga_cfg[26].value,'crtc_misc_reg',16,0,255); _custom_svga_cfg[27].flag := validate_number(_custom_svga_cfg[27].value,'crtc_mode_control',16,0,255); _custom_svga_cfg[28].flag := validate_number(_custom_svga_cfg[28].value,'crtc_screen_b_clr',16,0,255); _custom_svga_cfg[29].flag := validate_number(_custom_svga_cfg[29].value,'crtc_colr_plane_en',16,0,255); _custom_svga_cfg[30].flag := validate_number(_custom_svga_cfg[30].value,'crtc_h_panning',16,0,255); _custom_svga_cfg[31].flag := validate_number(_custom_svga_cfg[31].value,'crtc_color_select',16,0,255); {$ELSE} sdl_screen_mode := check_number('sdl_screen_mode',10,0,2,sdl_screen_mode); sdl_frame_rate := check_number('sdl_frame_rate',10,50,200,sdl_frame_rate); sdl_timer_slowdown := check_number('sdl_timer_slowdown',10,0,50,sdl_timer_slowdown); sdl_typematic_rate := check_number('sdl_typematic_rate',10,1,100,sdl_typematic_rate); sdl_typematic_delay := check_number('sdl_typematic_delay',10,0,2000,sdl_typematic_delay); If (Copy(data,1,18) = 'sdl_wav_directory=') and (Length(data) > 18) then begin temp_str := Copy(data,19,Length(data)-18); If (temp_str[1] = PATHSEP) then Delete(temp_str,1,1); If (temp_str <> '') then begin If (Length(temp_str) > 4) then If NOT (Lower(Copy(temp_str,Length(temp_str)-3,4)) = '.wav') then temp_str := temp_str+PATHSEP else opl3_flushmode := TRUE else If (temp_str[Length(temp_str)] <> PATHSEP) then temp_str := temp_str+PATHSEP; end; sdl_wav_directory := temp_str; If NOT (Pos(':',sdl_wav_directory) <> 0) then sdl_wav_directory := PathOnly(ParamStr(0))+PATHSEP+sdl_wav_directory; end; {$ENDIF} init_tempo := check_number('init_tempo',10,1,255,Round(init_tempo)); init_speed := check_number('init_speed',16,1,255,init_speed); init_macro_speedup := check_number('init_macro_speedup',10,1,calc_max_speedup(init_tempo),init_macro_speedup); midiboard := check_boolean('midiboard',midiboard); default_octave := check_number('octave',10,1,8,default_octave); patt_len := check_number('patt_len',10,1,255,patt_len); nm_tracks := check_number('nm_tracks',10,1,20,nm_tracks); mod_description := check_boolean('mod_description',mod_description); highlight_controls := check_boolean('highlight_controls',highlight_controls); use_H_for_B := check_boolean('use_h_for_b',use_H_for_B); linefeed := check_boolean('linefeed',linefeed); update_ins := check_boolean('update_ins',update_ins); adjust_tracks := check_boolean('adjust_tracks',adjust_tracks); cycle_pattern := check_boolean('cycle_pattern',cycle_pattern); keep_track_pos := check_boolean('keep_track_pos',keep_track_pos); remember_ins_pos := check_boolean('remember_ins_pos',remember_ins_pos); backspace_dir := check_number('backspace_dir',10,1,2,backspace_dir); scroll_bars := check_boolean('scroll_bars',scroll_bars); fforward_factor := check_number('fforward_factor',10,1,5,fforward_factor); rewind_factor := check_number('rewind_factor',10,1,5,rewind_factor); ssaver_time := check_number('ssaver_time',10,0,1440,ssaver_time DIV 60)*60; timer_fix := check_boolean('18hz_fix',timer_fix); decay_bar_rise := check_number('decay_bar_rise',10,1,10,Round(decay_bar_rise)); If (check_number('decay_bar_fall',10,1,10,0) <> 0) then decay_bar_fall := check_number('decay_bar_fall',10,1,10,0)/10; force_ins := check_number('force_ins',10,0,2,force_ins); keep_position := check_boolean('keep_position',keep_position); alt_ins_name := check_boolean('alt_ins_name',alt_ins_name); trace_by_default := check_boolean('trace_by_default',trace_by_default); nosync_by_default := check_boolean('nosync_by_default',nosync_by_default); pattern_layout := check_number('pattern_layout',10,0,2,pattern_layout); command_typing := check_number('command_typing',10,0,2,command_typing); mark_lines := check_boolean('mark_lines',mark_lines); fix_c_note_bug := check_boolean('fix_c_note_bug',fix_c_note_bug); accurate_conv := check_boolean('accurate_conv',accurate_conv); pattern_bckg := check_number('pattern_bckg',10,0,15,pattern_bckg SHR 4) SHL 4; pattern_border := check_number('pattern_border',10,0,15,pattern_border); pattern_pos_indic := check_number('pattern_pos_indic',10,0,15,pattern_pos_indic); pattern_pan_indic := check_number('pattern_pan_indic',10,0,15,pattern_pan_indic); pattern_gpan_indic := check_number('pattern_gpan_indic',10,0,15,pattern_gpan_indic); pattern_lock_indic := check_number('pattern_lock_indic',10,0,15,pattern_lock_indic); pattern_perc_indic := check_number('pattern_perc_indic',10,0,15,pattern_perc_indic); pattern_4op_indic := check_number('pattern_4op_indic',10,0,15,pattern_4op_indic); pattern_chan_indic := check_number('pattern_chan_indic',10,0,15,pattern_chan_indic); pattern_row_bckg := check_number('pattern_row_bckg',10,0,15,pattern_row_bckg SHR 4) SHL 4; pattern_row_bckg_p := check_number('pattern_row_bckg_p',10,0,15,pattern_row_bckg_p SHR 4) SHL 4; pattern_row_bckg_m := check_number('pattern_row_bckg_m',10,0,15,pattern_row_bckg_m SHR 4) SHL 4; pattern_block_bckg := check_number('pattern_block_bckg',10,0,15,pattern_block_bckg SHR 4) SHL 4; pattern_line := check_number('pattern_line#',10,0,15,pattern_line); pattern_line_p := check_number('pattern_line#_p',10,0,15,pattern_line_p); pattern_line_m := check_number('pattern_line#_m',10,0,15,pattern_line_m); pattern_hi_line := check_number('pattern_hi_line#',10,0,15,pattern_hi_line); pattern_hi_line_m := check_number('pattern_hi_line#_m',10,0,15,pattern_hi_line_m); pattern_note := check_number('pattern_note',10,0,15,pattern_note); pattern_hi_note := check_number('pattern_hi_note',10,0,15,pattern_hi_note); pattern_note0 := check_number('pattern_note0',10,0,15,pattern_note0); pattern_hi_note0 := check_number('pattern_hi_note0',10,0,15,pattern_hi_note0); pattern_note_hid := check_number('pattern_note_hid',10,0,15,pattern_note_hid); pattern_hi_note_h := check_number('pattern_hi_note_h',10,0,15,pattern_hi_note_h); pattern_inst := check_number('pattern_ins#',10,0,15,pattern_inst); pattern_hi_inst := check_number('pattern_hi_ins#',10,0,15,pattern_hi_inst); pattern_inst0 := check_number('pattern_ins#0',10,0,15,pattern_inst0); pattern_hi_inst0 := check_number('pattern_hi_ins#0',10,0,15,pattern_hi_inst0); pattern_cmnd := check_number('pattern_cmnd',10,0,15,pattern_cmnd); pattern_hi_cmnd := check_number('pattern_hi_cmnd',10,0,15,pattern_hi_cmnd); pattern_cmnd0 := check_number('pattern_cmnd0',10,0,15,pattern_cmnd0); pattern_hi_cmnd0 := check_number('pattern_hi_cmnd0',10,0,15,pattern_hi_cmnd0); pattern_note_m := check_number('pattern_note_m',10,0,15,pattern_note_m); pattern_note0_m := check_number('pattern_note0_m',10,0,15,pattern_note0_m); pattern_note_hid_m := check_number('pattern_note_hid_m',10,0,15,pattern_note_hid_m); pattern_inst_m := check_number('pattern_ins#_m',10,0,15,pattern_inst_m); pattern_inst0_m := check_number('pattern_ins#0_m',10,0,15,pattern_inst0_m); pattern_cmnd_m := check_number('pattern_cmnd_m',10,0,15,pattern_cmnd_m); pattern_cmnd0_m := check_number('pattern_cmnd0_m',10,0,15,pattern_cmnd0_m); pattern_note_b := check_number('pattern_note_b',10,0,15,pattern_note_b); pattern_note0_b := check_number('pattern_note0_b',10,0,15,pattern_note0_b); pattern_note_hid_b := check_number('pattern_note_hid_b',10,0,15,pattern_note_hid_b); pattern_inst_b := check_number('pattern_ins#_b',10,0,15,pattern_inst_b); pattern_inst0_b := check_number('pattern_ins#0_b',10,0,15,pattern_inst0_b); pattern_cmnd_b := check_number('pattern_cmnd_b',10,0,15,pattern_cmnd_b); pattern_cmnd0_b := check_number('pattern_cmnd0_b',10,0,15,pattern_cmnd0_b); pattern_cmnd_ctrl := check_number('pattern_cmnd_ctrl',10,0,15,pattern_cmnd_ctrl); pattern_fix_note := check_number('pattern_fix_note',10,0,15,pattern_fix_note); pattern_hi_fx_note := check_number('pattern_hi_fx_note',10,0,15,pattern_hi_fx_note); pattern_fix_note_m := check_number('pattern_fix_note_m',10,0,15,pattern_fix_note_m); pattern_fix_note_b := check_number('pattern_fix_note_b',10,0,15,pattern_fix_note_b); pattern_input_bckg := check_number('pattern_input_bckg',10,0,15,pattern_input_bckg SHR 4) SHL 4; pattern_input := check_number('pattern_input',10,0,15,pattern_input); pattern_input_warn := check_number('pattern_input_warn',10,0,15,pattern_input_warn SHR 4) SHL 4; analyzer_bckg := check_number('analyzer_bckg',10,0,15,analyzer_bckg SHR 4) SHL 4; analyzer := check_number('analyzer',10,0,15,analyzer); analyzer_ovrllvol := check_number('analyzer_overallvol',10,0,15,analyzer_ovrllvol); analyzer_volumelvl := check_number('analyzer_volumelvl',10,0,15,analyzer_volumelvl); analyzer_carrier := check_number('analyzer_carrier',10,0,15,analyzer_carrier); analyzer_modulator := check_number('analyzer_modulator',10,0,15,analyzer_modulator); debug_info_bckg := check_number('debug_info_bckg',10,0,15,debug_info_bckg SHR 4) SHL 4; debug_info_bckg2 := check_number('debug_info_bckg2',10,0,15,debug_info_bckg2 SHR 4) SHL 4; debug_info_border := check_number('debug_info_border',10,0,15,debug_info_border); debug_info_title := check_number('debug_info_title',10,0,15,debug_info_title); debug_info_border2 := check_number('debug_info_border2',10,0,15,debug_info_border2); debug_info_topic := check_number('debug_info_topic',10,0,15,debug_info_topic); debug_info_txt := check_number('debug_info_txt',10,0,15,debug_info_txt); debug_info_hi_txt := check_number('debug_info_hi_txt',10,0,15,debug_info_hi_txt); debug_info_txt_hid := check_number('debug_info_txt_hid',10,0,15,debug_info_txt_hid); debug_info_mod := check_number('debug_info_mod',10,0,15,debug_info_mod); debug_info_hi_mod := check_number('debug_info_hi_mod',10,0,15,debug_info_hi_mod); debug_info_car := check_number('debug_info_car',10,0,15,debug_info_car); debug_info_hi_car := check_number('debug_info_hi_car',10,0,15,debug_info_hi_car); debug_info_4op := check_number('debug_info_4op',10,0,15,debug_info_4op); debug_info_perc := check_number('debug_info_perc',10,0,15,debug_info_perc); help_background := check_number('help_background',10,0,15,help_background SHR 4) SHL 4; help_title := check_number('help_title',10,0,15,help_title); help_border := check_number('help_border',10,0,15,help_border); help_topic := check_number('help_topic',10,0,15,help_topic); help_text := check_number('help_text',10,0,15,help_text); help_hi_text := check_number('help_hi_text',10,0,15,help_hi_text); help_indicators := check_number('help_indicators',10,0,15,help_indicators); help_keys := check_number('help_keys',10,0,15,help_keys); dialog_background := check_number('dialog_background',10,0,15,dialog_background SHR 4) SHL 4; dialog_title := check_number('dialog_title',10,0,15,dialog_title); dialog_border := check_number('dialog_border',10,0,15,dialog_border); dialog_text := check_number('dialog_text',10,0,15,dialog_text); dialog_hi_text := check_number('dialog_hi_text',10,0,15,dialog_hi_text); dialog_hid := check_number('dialog_hid',10,0,15,dialog_hid); dialog_item := check_number('dialog_item',10,0,15,dialog_item); dialog_sel_itm_bck := check_number('dialog_sel_itm_bckg',10,0,15,dialog_sel_itm_bck SHR 4) SHL 4; dialog_sel_itm := check_number('dialog_sel_itm',10,0,15,dialog_sel_itm); dialog_short := check_number('dialog_short',10,0,15,dialog_short); dialog_sel_short := check_number('dialog_sel_short',10,0,15,dialog_sel_short); dialog_item_dis := check_number('dialog_item_dis',10,0,15,dialog_item_dis); dialog_context := check_number('dialog_context',10,0,15,dialog_context); dialog_context_dis := check_number('dialog_context_dis',10,0,15,dialog_context_dis); dialog_contxt_dis2 := check_number('dialog_context_dis2',10,0,15,dialog_contxt_dis2); dialog_input_bckg := check_number('dialog_input_bckg',10,0,15,dialog_input_bckg SHR 4) SHL 4; dialog_input := check_number('dialog_input',10,0,15,dialog_input); dialog_def_bckg := check_number('dialog_def_bckg',10,0,15,dialog_def_bckg SHR 4) SHL 4; dialog_def := check_number('dialog_def',10,0,15,dialog_def); dialog_prog_bar1 := check_number('dialog_prog_bar1',10,0,15,dialog_prog_bar1); dialog_prog_bar2 := check_number('dialog_prog_bar2',10,0,15,dialog_prog_bar2); dialog_topic := check_number('dialog_topic',10,0,15,dialog_topic); dialog_hi_topic := check_number('dialog_hi_topic',10,0,15,dialog_hi_topic); dialog_mod_text := check_number('dialog_mod_text',10,0,15,dialog_mod_text); dialog_car_text := check_number('dialog_car_text',10,0,15,dialog_car_text); macro_background := check_number('macro_background',10,0,15,macro_background SHR 4) SHL 4; macro_title := check_number('macro_title',10,0,15,macro_title); macro_border := check_number('macro_border',10,0,15,macro_border); macro_topic := check_number('macro_topic',10,0,15,macro_topic); macro_topic2 := check_number('macro_topic2',10,0,15,macro_topic2); macro_hi_topic := check_number('macro_hi_topic',10,0,15,macro_hi_topic); macro_text := check_number('macro_text',10,0,15,macro_text); macro_hi_text := check_number('macro_hi_text',10,0,15,macro_hi_text); macro_text_dis := check_number('macro_text_dis',10,0,15,macro_text_dis); macro_text_loop := check_number('macro_text_loop',10,0,15,macro_text_loop); macro_text_keyoff := check_number('macro_text_keyoff',10,0,15,macro_text_keyoff); macro_current_bckg := check_number('macro_current_bckg',10,0,15,macro_current_bckg SHR 4) SHL 4; macro_current := check_number('macro_current',10,0,15,macro_current); macro_current_dis := check_number('macro_current_dis',10,0,15,macro_current_dis); macro_current_loop := check_number('macro_current_loop',10,0,15,macro_current_loop); macro_current_koff := check_number('macro_current_koff',10,0,15,macro_current_koff); macro_input_bckg := check_number('macro_input_bckg',10,0,15,macro_input_bckg SHR 4) SHL 4; macro_input := check_number('macro_input',10,0,15,macro_input); macro_def_bckg := check_number('macro_def_bckg',10,0,15,macro_def_bckg SHR 4) SHL 4; macro_def := check_number('macro_def',10,0,15,macro_def); macro_scrbar_bckg := check_number('macro_scrbar_bckg',10,0,15,macro_scrbar_bckg SHR 4) SHL 4; macro_scrbar_text := check_number('macro_scrbar_text',10,0,15,macro_scrbar_text); macro_scrbar_mark := check_number('macro_scrbar_mark',10,0,15,macro_scrbar_mark); macro_hint := check_number('macro_hint',10,0,15,macro_hint); macro_item := check_number('macro_item',10,0,15,macro_item); macro_sel_itm_bck := check_number('macro_sel_itm_bckg',10,0,15,macro_sel_itm_bck SHR 4) SHL 4; macro_sel_itm := check_number('macro_sel_itm',10,0,15,macro_sel_itm); macro_short := check_number('macro_short',10,0,15,macro_short); macro_sel_short := check_number('macro_sel_short',10,0,15,macro_sel_short); macro_item_dis := check_number('macro_item_dis',10,0,15,macro_item_dis); macro_context := check_number('macro_context',10,0,15,macro_context); macro_context_dis := check_number('macro_context_dis',10,0,15,macro_context_dis); scrollbar_bckg := check_number('scrollbar_bckg',10,0,15,scrollbar_bckg SHR 4) SHL 4; scrollbar_text := check_number('scrollbar',10,0,15,scrollbar_text); scrollbar_mark := check_number('scrollbar_mark',10,0,15,scrollbar_mark); scrollbar_2nd_mark := check_number('scrollbar_2nd_mark',10,0,15,scrollbar_2nd_mark); main_background := check_number('main_background',10,0,15,main_background SHR 4) SHL 4; main_title := check_number('main_title',10,0,15,main_title); main_border := check_number('main_border',10,0,15,main_border); main_stat_line := check_number('main_stat_line',10,0,15,main_stat_line); main_hi_stat_line := check_number('main_hi_stat_line',10,0,15,main_hi_stat_line); main_dis_stat_line := check_number('main_dis_stat_line',10,0,15,main_dis_stat_line); main_behavior := check_number('main_behavior',10,0,15,main_behavior); main_behavior_dis := check_number('main_behavior_dis',10,0,15,main_behavior_dis); status_background := check_number('status_background',10,0,15,status_background SHR 4) SHL 4; status_border := check_number('status_border',10,0,15,status_border); status_static_txt := check_number('status_static_txt',10,0,15,status_static_txt); status_dynamic_txt := check_number('status_dynamic_txt',10,0,15,status_dynamic_txt); status_play_state := check_number('status_play_state',10,0,15,status_play_state); status_text_dis := check_number('status_text_dis',10,0,15,status_text_dis); order_background := check_number('order_background',10,0,15,order_background SHR 4) SHL 4; order_hi_bckg := check_number('order_hi_bckg',10,0,15,order_hi_bckg SHR 4) SHL 4; order_border := check_number('order_border',10,0,15,order_border); order_entry := check_number('order_entry',10,0,15,order_entry); order_hi_entry := check_number('order_hi_entry',10,0,15,order_hi_entry); order_pattn_jump := check_number('order_patt#_jump',10,0,15,order_pattn_jump); order_pattn := check_number('order_patt#',10,0,15,order_pattn); order_hi_pattn := check_number('order_hi_patt#',10,0,15,order_hi_pattn); order_played_b := check_number('order_played_b',10,0,15,order_played_b SHR 4) SHL 4; order_played := check_number('order_played',10,0,15,order_played); order_input_bckg := check_number('order_input_bckg',10,0,15,order_input_bckg SHR 4) SHL 4; order_input := check_number('order_input',10,0,15,order_input); order_input_warn := check_number('order_input_warn',10,0,15,order_input_warn SHR 4) SHL 4; instrument_bckg := check_number('instrument_bckg',10,0,15,instrument_bckg SHR 4) SHL 4; instrument_title := check_number('instrument_title',10,0,15,instrument_title); instrument_border := check_number('instrument_border',10,0,15,instrument_border); instrument_text := check_number('instrument_text',10,0,15,instrument_text); instrument_hi_text := check_number('instrument_hi_text',10,0,15,instrument_hi_text); instrument_glob := check_number('instrument_glob',10,0,15,instrument_glob); instrument_hi_glob := check_number('instrument_hi_glob',10,0,15,instrument_hi_glob); instrument_hid := check_number('instrument_hid',10,0,15,instrument_hid); instrument_mod := check_number('instrument_mod',10,0,15,instrument_mod); instrument_car := check_number('instrument_car',10,0,15,instrument_car); instrument_hi_mod := check_number('instrument_hi_mod',10,0,15,instrument_hi_mod); instrument_hi_car := check_number('instrument_hi_car',10,0,15,instrument_hi_car); instrument_context := check_number('instrument_context',10,0,15,instrument_context); instrument_con_dis := check_number('instrument_con_dis',10,0,15,instrument_con_dis); instrument_adsr := check_number('instrument_adsr',10,0,15,instrument_adsr SHR 4) SHL 4; instrument_ai_off := check_number('instrument_ai_off',10,0,15,instrument_ai_off); instrument_ai_on := check_number('instrument_ai_on',10,0,15,instrument_ai_on); instrument_ai_trig := check_number('instrument_ai_trig',10,0,15,instrument_ai_trig); If (Copy(data,1,14) = 'home_dir_path=') and (Length(data) > 14) then begin home_dir_path := Copy(data,15,Length(data)-14); If (home_dir_path <> '') and (home_dir_path[Length(home_dir_path)] <> PATHSEP) then home_dir_path := home_dir_path+PATHSEP; end; If (Copy(data,1,17) = 'a2m_default_path=') and (Length(data) > 17) then begin a2m_default_path := Copy(data,18,Length(data)-17); If (a2m_default_path <> '') and (a2m_default_path[Length(a2m_default_path)] <> PATHSEP) then a2m_default_path := a2m_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2t_default_path=') and (Length(data) > 17) then begin a2t_default_path := Copy(data,18,Length(data)-17); If (a2t_default_path <> '') and (a2t_default_path[Length(a2t_default_path)] <> PATHSEP) then a2t_default_path := a2t_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2i_default_path=') and (Length(data) > 17) then begin a2i_default_path := Copy(data,18,Length(data)-17); If (a2i_default_path <> '') and (a2i_default_path[Length(a2i_default_path)] <> PATHSEP) then a2i_default_path := a2i_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2f_default_path=') and (Length(data) > 17) then begin a2f_default_path := Copy(data,18,Length(data)-17); If (a2f_default_path <> '') and (a2f_default_path[Length(a2f_default_path)] <> PATHSEP) then a2f_default_path := a2f_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2p_default_path=') and (Length(data) > 17) then begin a2p_default_path := Copy(data,18,Length(data)-17); If (a2p_default_path <> '') and (a2p_default_path[Length(a2p_default_path)] <> PATHSEP) then a2p_default_path := a2p_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2b_default_path=') and (Length(data) > 17) then begin a2b_default_path := Copy(data,18,Length(data)-17); If (a2b_default_path <> '') and (a2b_default_path[Length(a2b_default_path)] <> PATHSEP) then a2b_default_path := a2b_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2w_default_path=') and (Length(data) > 17) then begin a2w_default_path := Copy(data,18,Length(data)-17); If (a2w_default_path <> '') and (a2w_default_path[Length(a2w_default_path)] <> PATHSEP) then a2w_default_path := a2w_default_path+PATHSEP; end; For temp := 0 to 15 do check_rgb('color'+ExpStrL(Num2str(temp,10),2,'0'),rgb_color[temp]); end; var txtf: Text; idx: Byte; config_found_flag: Boolean; begin { process_config_file } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:process_config_file'; {$ENDIF} config_found_flag := FALSE; Write('Reading configuration file ... '); {$i-} Assign(txtf,'adtrack2.ini'); Reset (txtf); {$i+} If (IOresult <> 0) then begin {$i-} Assign(txtf,PathOnly(ParamStr(0))+'adtrack2.ini'); Reset (txtf); {$i+} If (IOresult <> 0) then WriteLn('not found!') else begin config_found_flag := TRUE; WriteLn('ok'); end; end else begin config_found_flag := TRUE; WriteLn('ok'); end; If config_found_flag then begin While NOT EOF(txtf) do begin {$i-} ReadLn(txtf,data); {$i+} If (IOresult <> 0) then begin {$i-} Close(txtf); {$i+} If (IOresult <> 0) then ; BREAK; end; If (Pos(';',data) <> 0) then Delete(data,Pos(';',data),Length(data)-Pos(';',data)+1); data := CutStr(Lower(data)); check_option_data; end; {$i-} Close(txtf); {$i+} If (IOresult <> 0) then ; end; If (ParamCount <> 0) then For idx := 1 to ParamCount do begin data := CutStr(Lower(ParamStr(idx))); If (Copy(data,1,5) = '/cfg:') then begin Delete(data,1,5); check_option_data; end; end; end; end. adlibtracker2-2.4.23/readme-sdl.txt0000644000000000000000000000066613176573533015614 0ustar rootroot Please distribute this file with the SDL runtime environment: The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library designed to make it easy to write multi-media software, such as games and emulators. The Simple DirectMedia Layer library source code is available from: http://www.libsdl.org/ This library is distributed under the terms of the GNU LGPL license: http://www.gnu.org/copyleft/lesser.html adlibtracker2-2.4.23/makefile.bat0000644000000000000000000000164213176573533015276 0ustar rootroot@echo off if exist adtrack2.res goto :res_ok windres -i adtrack2.rc -o adtrack2.res :res_ok if not exist adtrack2.exe goto :exe_ok del /F /Q adtrack2.exe >nul if exist adtrack2.exe goto :error :exe_ok echo. echo ************************************ echo ** ** echo ** Compiling ADTRACK2 ** echo ** ** echo ************************************ echo. fpc.exe -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Twin32 -WC -Fusdl adtrack2.pas -oadtrack2.exe set ERR_RESULT="OK" goto :end :error echo. echo ************************************ echo ** ** echo ** COMPILATION WAS ABORTED ** echo ** ** echo ** Some files are still in use ** echo ** by other process! ** echo ** ** echo ************************************ :end adlibtracker2-2.4.23/txtscrio.pas0000644000000000000000000024234613176573533015425 0ustar rootrootunit TxtScrIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const SCREEN_RES_x: Word = 720; SCREEN_RES_y: Word = 480; MAX_COLUMNS: Byte = 90; MAX_ROWS: Byte = 40; MAX_TRACKS: Byte = 5; MAX_ORDER_COLS: Byte = 9; MAX_PATTERN_ROWS: Byte = 18; INSCTRL_xshift: Byte = 0; INSCTRL_yshift: Shortint = 0; INSEDIT_yshift: Byte = 0; PATTORD_xshift: Byte = 0; GOTOXY_xshift: Byte = 0; const MAX_SCREEN_MEM_SIZE = 180*60*2; SCREEN_MEM_SIZE: Longint = MAX_SCREEN_MEM_SIZE; type tSCREEN_MEM = array[0..PRED(MAX_SCREEN_MEM_SIZE)] of Byte; tSCREEN_MEM_PTR = ^tSCREEN_MEM; var temp_screen: tSCREEN_MEM; temp_screen2: tSCREEN_MEM; screen_backup: tSCREEN_MEM; scr_backup: tSCREEN_MEM; scr_backup2: tSCREEN_MEM; screen_mirror: tSCREEN_MEM; screen_emulator: tSCREEN_MEM; centered_frame_vdest: tSCREEN_MEM_PTR; text_screen_shadow: tSCREEN_MEM; const screen_ptr: Pointer = Addr(text_screen_shadow); ptr_temp_screen: Pointer = Addr(temp_screen); ptr_temp_screen2: Pointer = Addr(temp_screen2); ptr_screen_backup: Pointer = Addr(screen_backup); ptr_scr_backup: Pointer = Addr(scr_backup); ptr_scr_backup2: Pointer = Addr(scr_backup2); ptr_screen_mirror: Pointer = Addr(screen_mirror); ptr_screen_emulator: Pointer = Addr(screen_emulator); const move_to_screen_data: Pointer = NIL; move_to_screen_area: array[1..4] of Byte = (0,0,0,0); move_to_screen_routine: procedure = NIL; const program_screen_mode: Byte = 0; const MaxLn: Byte = 0; MaxCol: Byte = 0; hard_maxcol: Byte = 0; hard_maxln: Byte = 0; work_maxcol: Byte = 0; work_maxln: Byte = 0; scr_font_width: Byte = 0; scr_font_height: Byte = 0; const area_x1: Byte = 0; area_y1: Byte = 0; area_x2: Byte = 0; area_y2: Byte = 0; scroll_pos0: Byte = BYTE(NOT 0); scroll_pos1: Byte = BYTE(NOT 0); scroll_pos2: Byte = BYTE(NOT 0); scroll_pos3: Byte = BYTE(NOT 0); scroll_pos4: Byte = BYTE(NOT 0); var cursor_backup: Longint; const Black = $00; DGray = $08; Blue = $01; LBlue = $09; Green = $02; LGreen = $0a; Cyan = $03; LCyan = $0b; Red = $04; LRed = $0c; Magenta = $05; LMagenta = $0d; Brown = $06; Yellow = $0e; LGray = $07; White = $0f; Blink = $80; procedure ShowStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; attr: Byte); procedure ShowVStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; attr: Byte); procedure ShowCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); procedure ShowCStr2(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); procedure ShowVCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); procedure ShowVCStr2(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); procedure ShowC3Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); procedure ShowVC3Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); procedure ShowC4Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); procedure show_str(xpos,ypos: Byte; str: String; color: Byte); procedure show_cstr(xpos,ypos: Byte; str: String; attr1,attr2: Byte); procedure show_cstr_alt(xpos,ypos: Byte; str: String; attr1,attr2: Byte); procedure show_vstr(xpos,ypos: Byte; str: String; color: Byte); procedure show_vcstr(xpos,ypos: Byte; str: String; attr1,attr2: Byte); function CStrLen(str: String): Byte; function CStr2Len(str: String): Byte; function C3StrLen(str: String): Byte; procedure ScreenMemCopy(source,dest: tSCREEN_MEM_PTR); procedure move2screen; procedure move2screen_alt; procedure TxtScrIO_Init; function is_default_screen_mode: Boolean; {$IFDEF GO32V2} function is_VESA_emulated_mode: Boolean; function get_VESA_emulated_mode_idx: Byte; {$ENDIF} function is_scrollable_screen_mode: Boolean; type tFRAME_SETTING = Record shadow_enabled, wide_range_type, zooming_enabled, update_area: Boolean; end; const fr_setting: tFRAME_SETTING = (shadow_enabled: TRUE; wide_range_type: FALSE; zooming_enabled: FALSE; update_area: TRUE); procedure Frame(dest: tSCREEN_MEM_PTR; x1,y1,x2,y2,atr1: Byte; title: String; atr2: Byte; border: String); function WhereX: Byte; function WhereY: Byte; procedure GotoXY(x,y: Byte); function GetCursor: Longint; procedure SetCursor(cursor: Longint); procedure ThinCursor; procedure WideCursor; procedure HideCursor; function GetCursorShape: Word; procedure SetCursorShape(shape: Word); const v_seg: Word = $0b800; v_ofs: Word = 0; v_mode: Byte = $03; {$IFDEF GO32V2} var DispPg: Byte; type tCUSTOM_VIDEO_MODE = 0..52; function iVGA: Boolean; procedure initialize; procedure ResetMode; procedure SetCustomVideoMode(vmode: tCUSTOM_VIDEO_MODE); procedure GetRGBitem(color: Byte; var red,green,blue: Byte); procedure SetRGBitem(color: Byte; red,green,blue: Byte); procedure WaitRetrace; procedure GetPalette(var pal; first,last: Word); procedure SetPalette(var pal; first,last: Word); type tFADE = (first,fadeOut,fadeIn); tDELAY = (fast,delayed); type tFADE_BUF = Record action: tFADE; pal0: array[0..255] of Record r,g,b: Byte end; pal1: array[0..255] of Record r,g,b: Byte end; end; const fade_speed: Byte = 63; procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY); procedure RefreshEnable; procedure RefreshDisable; procedure Split2Static; procedure SplitScr(line: Word); procedure SetSize(columns,lines: Word); procedure SetTextDisp(x,y: Word); procedure set_vga_txtmode_80x25; procedure set_svga_txtmode_100x38; procedure set_svga_txtmode_128x48; procedure set_custom_svga_txtmode; type VGA_REGISTER = Record port: Word; idx: Byte; val: Byte; end; type VGA_REG_DATA = array[1..29] of VGA_REGISTER; const svga_txtmode_cols: Byte = 100; svga_txtmode_rows: Byte = 37; svga_txtmode_regs: VGA_REG_DATA = ( (port: $3c2; idx: $00; val: $06b), // Miscellaneous output (port: $3d4; idx: $00; val: $070), // Horizontal total (port: $3d4; idx: $01; val: $063), // Horizontal display enable end (port: $3d4; idx: $02; val: $064), // Horizontal blank start (port: $3d4; idx: $03; val: $082), // Horizontal blank end (port: $3d4; idx: $04; val: $065), // Horizontal retrace start (port: $3d4; idx: $05; val: $082), // Horizontal retrace end (port: $3d4; idx: $06; val: $070), // Vertical total (port: $3d4; idx: $07; val: $0f0), // Overflow register (port: $3d4; idx: $08; val: $000), // Preset row scan (port: $3d4; idx: $09; val: $04f), // Maximum scan line/char height (port: $3d4; idx: $10; val: $05b), // Vertical retrace start (port: $3d4; idx: $11; val: $08c), // Vertical retrace end (port: $3d4; idx: $12; val: $04f), // Vertical display enable end (port: $3d4; idx: $13; val: $03c), // Offset/logical width (port: $3d4; idx: $14; val: $000), // Underline location (port: $3d4; idx: $15; val: $058), // Vertical blank start (port: $3d4; idx: $16; val: $070), // Vertical blank end (port: $3d4; idx: $17; val: $0a3), // Mode control (port: $3c4; idx: $01; val: $001), // Clock mode register (port: $3c4; idx: $03; val: $000), // Character generator select (port: $3c4; idx: $04; val: $000), // Memory mode register (port: $3ce; idx: $05; val: $010), // Mode register (port: $3ce; idx: $06; val: $00e), // Miscellaneous register (port: $3c0; idx: $10; val: $002), // Mode control (port: $3c0; idx: $11; val: $000), // Screen border color (port: $3c0; idx: $12; val: $00f), // Color plane enable (port: $3c0; idx: $13; val: $000), // Horizontal panning (port: $3c0; idx: $14; val: $000)); // Color select {$ENDIF} implementation uses {$IFDEF GO32V2} CRT,GO32, {$ENDIF} AdT2unit,AdT2sys,AdT2ext2, DialogIO,ParserIO; procedure show_str(xpos,ypos: Byte; str: String; color: Byte); var x11,x12,x21,x22,y11,y21: Byte; index: Byte; begin asm xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos add bl,index sub bl,2 mov ah,ypos dec ah mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos add al,index dec al mov ah,ypos cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx movsb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 lodsb jmp @@6 @@5: add edi,ebx lodsb mov ah,color stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; procedure show_cstr(xpos,ypos: Byte; str: String; attr1,attr2: Byte); var x11,x12,x21,x22,y11,y21: Byte; index,color1,color2: Byte; begin asm mov al,attr1 mov color1,al mov al,attr2 mov color2,al xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos add bl,index sub bl,2 mov ah,ypos dec ah mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos add al,index dec al mov ah,ypos cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx @@3a: lodsb cmp al,'~' jnz @@3b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@3a cmp al,'~' jz @@7 @@3b: stosb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 @@4a: lodsb cmp al,'~' jnz @@6 push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@4a jmp @@7 @@5: add edi,ebx @@5a: lodsb cmp al,'~' jnz @@5b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@5a jmp @@7 @@5b: mov ah,color1 stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; procedure show_cstr_alt(xpos,ypos: Byte; str: String; attr1,attr2: Byte); var x11,x12,x21,x22,y11,y21: Byte; index,color1,color2: Byte; begin asm mov al,attr1 mov color1,al mov al,attr2 mov color2,al xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos add bl,index sub bl,2 mov ah,ypos dec ah mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos add al,index dec al mov ah,ypos cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx @@3a: lodsb cmp al,10 jnz @@3b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@3a cmp al,10 jz @@7 @@3b: stosb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 @@4a: lodsb cmp al,10 jnz @@6 push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@4a jmp @@7 @@5: add edi,ebx @@5a: lodsb cmp al,10 jnz @@5b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@5a jmp @@7 @@5b: mov ah,color1 stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; procedure show_vstr(xpos,ypos: Byte; str: String; color: Byte); var x11,x12,x21,x22,y11,y21: Byte; index: Byte; begin asm xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos dec bl mov ah,ypos add ah,index sub ah,2 mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos mov ah,ypos add ah,index dec ah cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx movsb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 lodsb jmp @@6 @@5: add edi,ebx lodsb mov ah,color stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; procedure show_vcstr(xpos,ypos: Byte; str: String; attr1,attr2: Byte); var x11,x12,x21,x22,y11,y21: Byte; index,color1,color2: Byte; begin asm mov al,attr1 mov color1,al mov al,attr2 mov color2,al xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos dec bl mov ah,ypos add ah,index sub ah,2 mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos mov ah,ypos add ah,index dec ah cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx @@3a: lodsb cmp al,'~' jnz @@3b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@3a cmp al,'~' jz @@7 @@3b: stosb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 @@4a: lodsb cmp al,'~' jnz @@6 push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@4a jmp @@7 @@5: add edi,ebx @@5a: lodsb cmp al,'~' jnz @@5b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@5a jmp @@7 @@5b: mov ah,color1 stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; var absolute_pos: Word; procedure DupChar; assembler; asm pushad { IN/ al -column } xor ebx,ebx { ah -line } xchg ax,bx { dl -character } xor eax,eax { dh -attribute } xchg ax,bx { ecx -count } mov bl,al { edi -ptr. to write } mov al,MaxCol mul ah add ax,bx mov bl,MaxCol sub ax,bx dec ax shl ax,1 jecxz @@1 add edi,eax xchg ax,dx rep stosw xchg ax,dx @@1: mov absolute_pos,ax popad end; procedure ShowStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; attr: Byte); begin asm mov edi,dword ptr [dest] lea esi,[str] mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos lodsb mov cl,al jecxz @@2 add edi,edx mov ah,attr @@1: lodsb stosw loop @@1 @@2: end; end; procedure ShowVStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; attr: Byte); begin asm mov al,MaxCol dec al xor ah,ah xor ebx,ebx mov bl,2 mul bl mov bx,ax mov edi,dword ptr [dest] lea esi,[str] mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos lodsb mov cl,al jecxz @@2 add edi,edx mov ah,attr @@1: lodsb stosw add edi,ebx loop @@1 @@2: end; end; procedure ShowCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); begin asm lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@3 push ecx mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos pop ecx add edi,edx mov ah,atr1 mov bh,atr2 @@1: lodsb cmp al,'~' jz @@2 stosw loop @@1 jmp @@3 @@2: xchg ah,bh loop @@1 @@3: end; end; procedure ShowCStr2(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); begin asm lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@3 push ecx mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos pop ecx add edi,edx mov ah,atr1 mov bh,atr2 @@1: lodsb cmp al,'"' jz @@2 stosw loop @@1 jmp @@3 @@2: xchg ah,bh loop @@1 @@3: end; end; procedure ShowVCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); begin asm mov al,MaxCol dec al xor ah,ah mov bl,2 mul bl mov bx,ax lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@3 push ecx mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos pop ecx add edi,edx mov dx,bx mov ah,atr1 mov bh,atr2 @@1: lodsb cmp al,'~' jz @@2 stosw add edi,edx loop @@1 jmp @@3 @@2: xchg ah,bh loop @@1 @@3: end; end; procedure ShowVCStr2(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); begin asm mov al,MaxCol dec al xor ah,ah mov bl,2 mul bl mov bx,ax lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@3 push ecx mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos pop ecx add edi,edx mov dx,bx mov ah,atr1 mov bh,atr2 @@1: lodsb cmp al,'`' jz @@2 stosw add edi,edx loop @@1 jmp @@3 @@2: xchg ah,bh loop @@1 @@3: end; end; procedure ShowC3Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); begin asm lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@4 push ecx mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos pop ecx add edi,edx mov ah,atr1 mov bl,atr2 mov bh,atr3 @@1: lodsb cmp al,'~' jz @@2 cmp al,'`' jz @@3 stosw loop @@1 jmp @@4 @@2: xchg ah,bl loop @@1 jmp @@4 @@3: xchg ah,bh loop @@1 @@4: end; end; procedure ShowC4Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); begin asm lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@5 push ecx mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos pop ecx add edi,edx mov ah,atr1 mov bl,atr2 mov bh,atr3 mov dl,atr4 @@1: lodsb cmp al,'~' jz @@2 cmp al,'`' jz @@3 cmp al,'^' jz @@4 stosw loop @@1 jmp @@5 @@2: xchg ah,bl loop @@1 jmp @@5 @@3: xchg ah,bh loop @@1 jmp @@5 @@4: xchg ah,dl loop @@1 @@5: end; end; procedure ShowVC3Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); begin asm mov al,MaxCol dec al xor ah,ah mov bl,2 mul bl mov bx,ax lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@4 push ecx mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos pop ecx add edi,edx mov dx,bx mov ah,atr1 mov bl,atr2 mov bh,atr3 @@1: lodsb cmp al,'~' jz @@2 cmp al,'`' jz @@3 stosw add edi,edx loop @@1 jmp @@4 @@2: xchg ah,bl loop @@1 jmp @@4 @@3: xchg ah,bh loop @@1 @@4: end; end; function CStrLen(str: String): Byte; var result: Byte; begin asm lea esi,[str] lodsb xor ebx,ebx xor ecx,ecx mov cl,al jecxz @@3 @@1: lodsb cmp al,'~' jz @@2 inc ebx loop @@1 jmp @@3 @@2: loop @@1 @@3: mov eax,ebx mov result,al end; CStrLen := result; end; function CStr2Len(str: String): Byte; var result: Byte; begin asm lea esi,[str] lodsb xor ebx,ebx xor ecx,ecx mov cl,al jecxz @@3 @@1: lodsb cmp al,'`' jz @@2 inc ebx loop @@1 jmp @@3 @@2: loop @@1 @@3: mov eax,ebx mov result,al end; CStr2Len := result; end; function C3StrLen(str: String): Byte; var result: Byte; begin asm lea esi,[str] lodsb xor ebx,ebx xor ecx,ecx mov cl,al jecxz @@4 @@1: lodsb cmp al,'~' jz @@2 cmp al,'`' jz @@3 inc ebx loop @@1 jmp @@4 @@2: loop @@1 jmp @@4 @@3: loop @@1 @@4: mov eax,ebx mov result,al end; C3StrLen := result; end; procedure ScreenMemCopy(source,dest: tSCREEN_MEM_PTR); begin cursor_backup := GetCursor; asm xor edx,edx mov eax,SCREEN_MEM_SIZE cmp eax,16 jb @@1 mov ecx,4 div ecx mov ecx,eax jecxz @@1 mov esi,dword ptr [source] mov edi,dword ptr [dest] cld rep movsd mov ecx,edx jecxz @@2 rep movsb jmp @@2 @@1: mov ecx,SCREEN_MEM_SIZE mov esi,dword ptr [source] mov edi,dword ptr [dest] cld rep movsb @@2: end; end; procedure Frame(dest: tSCREEN_MEM_PTR; x1,y1,x2,y2,atr1: Byte; title: String; atr2: Byte; border: String); var xexp1,xexp2,xexp3,yexp1,yexp2: Byte; offs: Longint; begin asm cmp fr_setting.update_area,1 jnz @@0 mov al,x1 mov area_x1,al mov al,y1 mov area_y1,al mov al,x2 mov area_x2,al mov al,y2 mov area_y2,al @@0: mov bl,fr_setting.wide_range_type mov bh,fr_setting.shadow_enabled lea esi,[border] mov edi,[dest] mov offs,edi cmp bl,0 je @@1 mov xexp1,4 mov xexp2,-1 mov xexp3,7 mov yexp1,1 mov yexp2,2 jmp @@2 @@1: mov xexp1,1 mov xexp2,2 mov xexp3,1 mov yexp1,0 mov yexp2,1 jmp @@4 @@2: mov al,x1 sub al,3 mov ah,y1 dec ah mov dl,' ' mov dh,atr1 xor ecx,ecx mov cl,x2 sub cl,x1 add cl,7 call DupChar mov ah,y2 inc ah call DupChar mov bl,y1 @@3: mov al,x1 sub al,3 mov ah,bl mov dl,' ' mov ecx,3 call DupChar mov al,x2 inc al mov dl,' ' mov ecx,3 call DupChar inc bl cmp bl,y2 jng @@3 @@4: mov al,x1 mov ah,y1 mov dl,[esi+1] mov dh,atr1 mov ecx,1 push edi call DupChar inc al mov dl,[esi+2] mov dh,atr1 mov cl,x2 sub cl,x1 dec cl call DupChar mov al,x2 mov dl,[esi+3] mov dh,atr1 mov ecx,1 call DupChar mov bl,y1 @@5: inc bl mov al,x1 mov ah,bl mov dl,[esi+4] mov dh,atr1 mov ecx,1 call DupChar inc al mov dl,' ' mov dh,atr1 mov cl,x2 sub cl,x1 dec cl call DupChar mov al,x2 mov dl,[esi+5] mov dh,atr1 mov ecx,1 call DupChar cmp bl,y2 jnge @@5 mov al,x1 mov ah,y2 mov dl,[esi+6] mov dh,atr1 mov ecx,1 call DupChar inc al mov dl,[esi+7] mov cl,x2 sub cl,x1 dec cl call DupChar mov al,x2 mov dl,[esi+8] mov dh,atr1 mov ecx,1 call DupChar lea esi,[title] mov cl,[esi] jecxz @@7 xor eax,eax mov al,x2 sub al,x1 sub al,cl mov bl,2 div bl add al,x1 add al,ah mov ah,y1 xor ecx,ecx call DupChar push eax xor eax,eax mov ax,absolute_pos mov edi,offs add edi,eax pop eax lodsb mov cl,al mov ah,atr2 @@6: lodsb stosw loop @@6 @@7: cmp bh,0 je @@11 mov bl,y1 sub bl,yexp1 @@8: inc bl mov al,x2 add al,xexp1 mov ah,bl xor ecx,ecx call DupChar push eax xor eax,eax mov ax,absolute_pos mov edi,offs add edi,eax pop eax inc edi mov al,07 stosb inc edi stosb cmp MaxCol,180 jna @@9 inc edi stosb @@9: cmp bl,y2 jng @@8 mov al,x1 add al,xexp2 mov ah,y2 add ah,yexp2 xor ecx,ecx call DupChar push eax xor eax,eax mov ax,absolute_pos mov edi,offs add edi,eax pop eax inc edi mov al,07 mov cl,x2 sub cl,x1 add cl,xexp3 cmp MaxLn,60 jb @@10 dec cl @@10: stosb inc edi loop @@10 @@11: end; end; {$IFDEF GO32V2} function WhereX: Byte; var result: Byte; begin asm mov bh,DispPg mov ah,03h int 10h inc dl mov result,dl end; WhereX := result; end; function WhereY: Byte; var result: Byte; begin asm mov bh,DispPg mov ah,03h int 10h inc dh mov result,dh end; WhereY := result; end; procedure GotoXY(x,y: Byte); begin asm lea edi,[virtual_cur_pos] mov ah,y mov al,x stosw mov dh,y mov dl,x add dl,GOTOXY_xshift dec dh dec dl mov bh,DispPg mov ah,02h int 10h end; end; function GetCursor: Longint; var result: Longint; begin asm xor edx,edx mov bh,DispPg mov ah,03h int 10h shl edx,16 xor eax,eax push edx call GetCursorShape pop edx add edx,eax mov result,edx end; GetCursor := result; end; procedure SetCursor(cursor: Longint); begin asm lea edi,[virtual_cur_pos] mov ax,word ptr [cursor+2] stosw xor eax,eax mov ax,word ptr [cursor] push eax call SetCursorShape mov dx,word ptr [cursor+2] mov bh,DispPg mov ah,02h int 10h end; end; procedure ThinCursor; begin SetCursorShape($0d0e); end; procedure WideCursor; begin SetCursorShape($010e); end; procedure HideCursor; begin SetCursorShape($1010); end; function GetCursorShape: Word; var result: Word; begin asm mov dx,03d4h mov al,0ah out dx,al inc dx in al,dx and al,1fh mov ah,al dec dx mov al,0bh out dx,al inc dx in al,dx and al,1fh mov result,ax end; GetCursorShape := result; end; procedure SetCursorShape(shape: Word); begin asm mov ax,shape mov word ptr [virtual_cur_shape],ax mov dx,03d4h mov al,0ah out dx,al inc dx in al,dx mov ah,byte ptr [shape+1] and al,0e0h or al,ah out dx,al dec dx mov al,0bh out dx,al inc dx in al,dx mov ah,byte ptr [shape] and al,0e0h or al,ah out dx,al end; end; {$ELSE} function WhereX: Byte; begin WhereX := virtual_cur_pos AND $0ff; end; function WhereY: Byte; begin WhereY := virtual_cur_pos SHR 8; end; procedure GotoXY(x,y: Byte); begin virtual_cur_pos := x OR (y SHL 8); end; function GetCursor: Longint; begin GetCursor := 0; end; procedure SetCursor(cursor: Longint); begin virtual_cur_pos := cursor SHR 16; SetCursorShape(cursor AND WORD_NULL); end; procedure ThinCursor; begin SetCursorShape($0d0e); end; procedure WideCursor; begin SetCursorShape($010e); end; procedure HideCursor; begin SetCursorShape($1010); end; function GetCursorShape: Word; begin GetCursorShape := virtual_cur_shape; end; procedure SetCursorShape(shape: Word); begin virtual_cur_shape := shape; end; {$ENDIF} {$IFDEF GO32V2} procedure initialize; begin asm mov ah,0fh int 10h and al,7fh mov v_mode,al mov DispPg,bh end; MaxCol := MEM[SEG0040:$4a]; MaxLn := SUCC(MEM[SEG0040:$84]); work_MaxLn := MaxLn; work_MaxCol := MaxCol; FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; function iVGA: Boolean; var result: Boolean; begin asm mov ax,1a00h int 10h cmp al,1ah jnz @@1 cmp bl,7 jb @@1 cmp bl,0ffh jnz @@2 @@1: mov result,FALSE jmp @@3 @@2: mov result,TRUE @@3: end; iVGA := result; end; procedure ResetMode; begin asm xor ah,ah mov al,v_mode mov bh,DispPg int 10h end; v_seg := $0b800; v_ofs := 0; MaxCol := MEM[SEG0040:$4a]; MaxLn := SUCC(MEM[SEG0040:$84]); FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; procedure GetRGBitem(color: Byte; var red,green,blue: Byte); begin outportb($3c7,color); red := inportb($3c9); green := inportb($3c9); blue := inportb($3c9); end; procedure SetRGBitem(color: Byte; red,green,blue: Byte); begin outportb($3c8,color); outportb($3c9,red); outportb($3c9,green); outportb($3c9,blue); end; procedure WaitRetrace; begin asm mov dx,3dah @@1: in al,dx and al,08h jnz @@1 @@2: in al,dx and al,08h jz @@2 end; end; procedure GetPalette(var pal; first,last: Word); begin asm xor eax,eax xor ecx,ecx mov ax,first mov cx,last sub ecx,eax inc ecx mov dx,03c7h out dx,al add dx,2 mov edi,[pal] add edi,eax add edi,eax add edi,eax mov eax,ecx add ecx,eax add ecx,eax rep insb end; end; procedure SetPalette(var pal; first,last: Word); begin asm mov dx,03dah @@1: in al,dx test al,8 jz @@1 xor eax,eax xor ecx,ecx mov ax,first mov cx,last sub ecx,eax inc ecx mov dx,03c8h out dx,al inc dx mov esi,[pal] add esi,eax add esi,eax add esi,eax mov eax,ecx add ecx,eax add ecx,eax rep outsb end; end; procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY); var i,j: Byte; begin If (fade = fadeOut) and (data.action in [first,fadeIn]) then begin GetPalette(data.pal0,0,255); If delay = delayed then For i := fade_speed downto 0 do begin For j := 0 to 255 do begin data.pal1[j].r := data.pal0[j].r * i DIV fade_speed; data.pal1[j].g := data.pal0[j].g * i DIV fade_speed; data.pal1[j].b := data.pal0[j].b * i DIV fade_speed; end; SetPalette(data.pal1,0,255); CRT.Delay(1); end else begin FillChar(data.pal1,SizeOf(data.pal1),0); SetPalette(data.pal1,0,255); end; data.action := fadeOut; end; If (fade = fadeIn) and (data.action = fadeOut) then begin If delay = delayed then For i := 0 to fade_speed do begin For j := 0 to 255 do begin data.pal1[j].r := data.pal0[j].r * i DIV fade_speed; data.pal1[j].g := data.pal0[j].g * i DIV fade_speed; data.pal1[j].b := data.pal0[j].b * i DIV fade_speed; end; SetPalette(data.pal1,0,255); CRT.Delay(1); end else SetPalette(data.pal0,0,255); data.action := fadeIn; end; end; procedure RefreshEnable; begin asm mov ax,1200h mov bl,36h int 10h end; end; procedure RefreshDisable; begin asm mov ax,1201h mov bl,36h int 10h end; end; procedure Split2Static; begin inportb($3da); outportb($3c0,$10 OR $20); outportb($3c0,inportb($3c1) OR $20); end; procedure SplitScr(line: Word); var temp: Byte; begin outportb($3d4,$18); outportb($3d5,LO(line)); outportb($3d4,$07); temp := inportb($3d5); If (line < $100) then temp := temp AND $0ef else temp := temp OR $10; outportb($3d5,temp); outportb($3d4,$09); temp := inportb($3d5); If (line < $200) then temp := temp AND $0bf else temp := temp OR $40; outportb($3d5,temp); end; procedure SetSize(columns,lines: Word); begin outportb($3d4,$13); outportb($3d5,columns SHR 1); MEMW[Seg0040:$4a] := columns; MEMW[Seg0040:$84] := lines-1; MEMW[Seg0040:$4c] := columns*lines; end; procedure SetTextDisp(x,y: Word); var maxcol_val: Byte; begin While (inportb($3da) AND 1 = 1) do ; While (inportb($3da) AND 1 <> 1) do ; If NOT (program_screen_mode in [4,5]) then maxcol_val := MaxCol else maxcol_val := SCREEN_RES_X DIV scr_font_width; outportb($3d4,$0c); outportw($3d5,HI(WORD((y DIV scr_font_height)*maxcol_val+(x DIV scr_font_width)))); outportb($3d4,$0d); outportw($3d5,LO(WORD((y DIV scr_font_height)*maxcol_val+(x DIV scr_font_width)))); outportb($3d4,$08); outportb($3d5,(inportb($3d5) AND $0e0) OR (y AND $0f)); end; procedure SetCustomVideoMode(vmode: tCUSTOM_VIDEO_MODE); const vmode_data: array[0..52,0..63] of Byte = ( { 1..5 - BIOS variables, 6..9 - Sequencer, 10 - Miscellaneous Output, 11..35 - CRTC, 36..55 - Attribute, 56..64 - Graphics } { 0, Text 36x14, 9x14, complete } ( 36, 13, 14, 0, 4, 8, 3, 0, 2, 99, 40, 35, 36,138, 38,192,183, 31, 0,205, 11, 12, 0, 0, 0, 0,148,134,135, 18, 31,142,177,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 1, Text 40x14, 8x14, complete } ( 40, 13, 14, 0, 5, 9, 3, 0, 2, 99, 45, 39, 40,144, 43,160,183, 31, 0,205, 11, 12, 0, 0, 0, 0,148,134,135, 20, 31,142,177,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 2, Text 40x14, 9x14, complete } ( 40, 13, 14, 0, 5, 8, 3, 0, 2, 103, 45, 39, 40,144, 43,160,183, 31, 0,205, 11, 12, 0, 0, 0, 0,148,134,135, 20, 31,142,177,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 3, Text 46x14, 8x14, complete } ( 46, 13, 14, 0, 6, 9, 3, 0, 2, 103, 52, 45, 46,151, 50,150,183, 31, 0,205, 11, 12, 0, 0, 0, 0,148,134,135, 23, 31,142,177,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 4, Text 36x15, 9x16, complete } ( 36, 14, 16, 0, 5, 8, 3, 0, 2, 227, 40, 35, 36,138, 38,192, 11, 62, 0,207, 13, 14, 0, 0, 0, 0,234,172,223, 18, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 5, Text 40x15, 8x16, complete } ( 40, 14, 16, 0, 5, 9, 3, 0, 2, 227, 45, 39, 40,144, 43,160, 11, 62, 0,207, 13, 14, 0, 0, 0, 0,234,172,223, 20, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 6, Text 40x15, 9x16, complete } ( 40, 14, 16, 0, 5, 8, 3, 0, 2, 231, 45, 39, 40,144, 43,160, 11, 62, 0,207, 13, 14, 0, 0, 0, 0,234,172,223, 20, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 7, Text 46x15, 8x16, complete } ( 46, 14, 16, 0, 6, 9, 3, 0, 2, 231, 52, 45, 46,151, 50,150, 11, 62, 0,207, 13, 14, 0, 0, 0, 0,234,172,223, 23, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 8, Text 36x17, 9x14, complete } ( 36, 16, 14, 0, 5, 8, 3, 0, 2, 227, 40, 35, 36,138, 38,192, 7, 62, 0,205, 11, 12, 0, 0, 0, 0,230,168,219, 18, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 9, Text 40x17, 8x14, complete } ( 40, 16, 14, 0, 6, 9, 3, 0, 2, 227, 45, 39, 40,144, 43,160, 7, 62, 0,205, 11, 12, 0, 0, 0, 0,230,168,219, 20, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 10, Text 40x17, 9x14, complete } ( 40, 16, 14, 0, 6, 8, 3, 0, 2, 231, 45, 39, 40,144, 43,160, 7, 62, 0,205, 11, 12, 0, 0, 0, 0,230,168,219, 20, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 11, Text 46x17, 9x14, complete } ( 46, 16, 14, 0, 7, 9, 3, 0, 2, 231, 52, 45, 46,151, 50,150, 7, 62, 0,205, 11, 12, 0, 0, 0, 0,230,168,219, 23, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 12, Text 36x22, 9x16, complete } ( 36, 21, 16, 0, 7, 8, 3, 0, 2, 163, 40, 35, 36,138, 38,192,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 18, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 13, Text 40x22, 8x16, complete } ( 40, 21, 16, 0, 7, 9, 3, 0, 2, 163, 45, 39, 40,144, 43,160,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 20, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 14, Text 40x22, 9x16, complete } ( 40, 21, 16, 0, 7, 8, 3, 0, 2, 167, 45, 39, 40,144, 43,160,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 20, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 15, Text 46x22, 8x16, complete } ( 46, 21, 16, 0, 8, 9, 3, 0, 2, 167, 52, 45, 46,151, 50,150,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 23, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 16, Text 70x22, 9x16, complete } ( 70, 21, 16, 0,13, 0, 3, 0, 2, 163, 83, 69, 70,150, 75, 21,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 35, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 17, Text 80x22, 8x16, complete } ( 80, 21, 16, 0,14, 1, 3, 0, 2, 163, 95, 79, 80,130, 85,129,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 40, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 18, Text 80x22, 9x16, complete } ( 80, 21, 16, 0,14, 0, 3, 0, 2, 167, 95, 79, 80,130, 85,129,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 40, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 19, Text 90x22, 8x16, complete } ( 90, 21, 16, 0,16, 1, 3, 0, 2, 167, 107, 89, 90,142, 95,138,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 45, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 20, Text 36x25, 9x16, complete } ( 36, 24, 16, 0, 8, 8, 3, 0, 2, 99, 40, 35, 36,138, 38,192,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 18, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 21, Text 40x25, 8x16, complete } ( 40, 24, 16, 0, 8, 9, 3, 0, 2, 99, 45, 39, 40,144, 43,160,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 20, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 22, Text 40x25, 9x16, complete } ( 40, 24, 16, 0, 8, 8, 3, 0, 2, 103, 45, 39, 40,144, 43,160,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 20, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 23, Text 46x25, 8x16, complete } ( 46, 24, 16, 0,10, 9, 3, 0, 2, 103, 52, 45, 46,151, 50,150,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 23, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 24, Text 70x25, 9x16, complete } ( 70, 24, 16, 0,14, 0, 3, 0, 2, 99, 83, 69, 70,150, 75, 21,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 35, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 25, Text 80x25, 8x16, complete } ( 80, 24, 16, 0,16, 1, 3, 0, 2, 99, 95, 79, 80,130, 85,129,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 26, Text 80x25, 9x16, standard } ( 80, 24, 16, 0,16, 0, 3, 0, 2, 103, 95, 79, 80,130, 85,129,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 27, Text 90x25, 8x16, complete } ( 90, 24, 16, 0, 18 , 1, 3, 0, 2, 103, 107, 89, 90,142, 95,138,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 45, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 28, Text 46x29, 8x16, complete } ( 46, 28, 14, 0,11, 9, 3, 0, 2, 103, 52, 45, 46,151, 50,150,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 23, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 29, Text 70x29, 9x14, complete } ( 70, 28, 14, 0, 16 , 0, 3, 0, 2, 99, 83, 69, 70,150, 75, 21,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 35, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 30, Text 80x29, 8x14, complete } ( 80, 28, 14, 0, 19 , 1, 3, 0, 2, 99, 95, 79, 80,130, 85,129,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 40, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 31, Text 80x29, 9x14, complete } ( 80, 28, 14, 0, 19 , 0, 3, 0, 2, 103, 95, 79, 80,130, 85,129,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 40, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 32, Text 90x29, 8x14, complete } ( 90, 28, 14, 0, 21 , 1, 3, 0, 2, 103, 107, 89, 90,142, 95,138,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 45, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 33, Text 70x30, 9x16, complete } ( 70, 29, 16, 0, 17 , 0, 3, 0, 2, 227, 83, 69, 70,150, 75, 21, 11, 62, 0, 79, 13, 14, 0, 0, 0, 0,234,172,223, 35, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 34, Text 80x30, 8x16, complete } ( 80, 29, 16, 0, 19 , 1, 3, 0, 2, 227, 95, 79, 80,130, 85,129, 11, 62, 0, 79, 13, 14, 0, 0, 0, 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 35, Text 80x30, 9x16, complete } ( 80, 29, 16, 0, 19 , 0, 3, 0, 2, 231, 95, 79, 80,130, 85,129, 11, 62, 0, 79, 13, 14, 0, 0, 0, 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 36, Text 90x30, 8x16 ,complete } ( 90, 29, 16, 0, 22 , 1, 3, 0, 2, 231, 107, 89, 90,142, 95,138, 11, 62, 0, 79, 13, 14, 0, 0, 0, 0,234,172,223, 45, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 37, Text 70x34, 9x14, complete } ( 70, 33, 14, 0, 19 , 0, 3, 0, 2, 227, 83, 69, 70,150, 75, 21, 7, 62, 0, 77, 11, 12, 0, 0, 0, 0,230,168,219, 35, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 38, Text 80x34, 8x14, complete } ( 80, 33, 14, 0, 22 , 1, 3, 0, 2, 227, 95, 79, 80,130, 85,129, 7, 62, 0, 77, 11, 12, 0, 0, 0, 0,230,168,219, 40, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 39, Text 80x34, 9x14, complete } ( 80, 33, 14, 0, 22 , 0, 3, 0, 2, 231, 95, 79, 80,130, 85,129, 7, 62, 0, 77, 11, 12, 0, 0, 0, 0,230,168,219, 40, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 40, Text 90x34, 8x14, complete } ( 90, 33, 14, 0, 24 , 1, 3, 0, 2, 231, 107, 89, 90,142, 95,138, 7, 62, 0, 77, 11, 12, 0, 0, 0, 0,230,168,219, 45, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 41, Text 70x44, 9x8, complete } ( 70, 43, 8, 0,25, 0, 3, 0, 2, 163, 83, 69, 70,150, 75, 21,193, 31, 0, 71, 6, 7, 0, 0, 0, 0,133,135, 95, 35, 15,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 42, Text 80x44, 8x8, complete } ( 80, 43, 8, 0,28, 1, 3, 0, 2, 163, 95, 79, 80,130, 85,129,193, 31, 0, 71, 6, 7, 0, 0, 0, 0,133,135, 95, 40, 15,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 43, Text 80x44, 9x8, complete } ( 80, 43, 8, 0,28, 0, 3, 0, 2, 167, 95, 79, 80,130, 85,129,193, 31, 0, 71, 6, 7, 0, 0, 0, 0,133,135, 95, 40, 15,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 44, Text 90x44, 8x8, complete } ( 90, 43, 8, 0,31, 1, 3, 0, 2, 167, 107, 89, 90,142, 95,138,193, 31, 0, 71, 6, 7, 0, 0, 0, 0,133,135, 95, 45, 15,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 45, Text 70x50, 9x8, complete } ( 70, 49, 8, 0,28, 0, 3, 0, 2, 99, 83, 69, 70,150, 75, 21,191, 31, 0, 71, 6, 7, 0, 0, 0, 0,156,142,143, 35, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 46, Text 80x50, 8x8, complete } ( 80, 49, 8, 0,32, 1, 3, 0, 2, 99, 95, 79, 80,130, 85,129,191, 31, 0, 71, 6, 7, 0, 0, 0, 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 47, Text 80x50, 9x8, standard } ( 80, 49, 8, 0,32, 0, 3, 0, 2, 103, 95, 79, 80,130, 85,129,191, 31, 0, 71, 6, 7, 0, 0, 0, 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 48, Text 90x50, 8x8, complete } ( 90, 49, 8, 0, 36 , 1, 3, 0, 2, 103, 107, 89, 90,142, 95,138,191, 31, 0, 71, 6, 7, 0, 0, 0, 0,156,142,143, 45, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 49, Text 70x60, 9x8, complete } ( 70, 59, 8, 0, 33 , 0, 3, 0, 2, 227, 83, 69, 70,150, 75, 21, 11, 62, 0, 71, 6, 7, 0, 0, 0, 0,234,172,223, 35, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 50, Text 80x60, 8x8, complete } ( 80, 59, 8, 0, 38 , 1, 3, 0, 2, 227, 95, 79, 80,130, 85,129, 11, 62, 0, 71, 6, 7, 0, 0, 0, 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 51, Text 80x60, 9x8, complete } ( 80, 59, 8, 0, 38 , 0, 3, 0, 2, 231, 95, 79, 80,130, 85,129, 11, 62, 0, 71, 6, 7, 0, 0, 0, 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 52, Text 90x60, 8x8, complete } ( 90, 59, 8,128, 42 , 1, 3, 0, 2, 231, 107, 89, 90,142, 95,138, 11, 62, 0, 71, 6, 7, 0, 0, 0, 0,234,172,223, 45, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255) ); var _seg0040: Dword; temp: Byte; begin _seg0040 := Seg0040; asm movzx eax,vmode shl eax,6 lea esi,[vmode_data] add esi,eax mov dx,3cch in al,dx mov dl,0d4h test al,1 jnz @@1 mov dl,0b4h @@1: add dx,6 in al,dx xor al,al mov dx,3c0h out dx,al mov ax,100h mov dx,3c4h out dx,ax add esi,5 mov ecx,4 mov al,1 mov dx,3c4h @@2: mov ah,[esi] inc esi out dx,ax inc al loop @@2 mov al,[esi] inc esi mov dx,3c2h out dx,al mov dx,3c4h mov ax,300h out dx,ax mov dx,3cch in al,dx mov dl,0d4h test al,1 jnz @@3 mov dl,0b4h @@3: mov edi,_seg0040 shl edi,4 add edi,63h shl edi,4 mov [edi],dx mov al,11h out dx,al inc dx mov ah,al in al,dx dec dx xchg al,ah and ah,7fh out dx,ax mov ecx,25 xor al,al @@4: mov ah,[esi] inc esi out dx,ax inc al loop @@4 add dx,6 in al,dx xor ah,ah mov ecx,20 mov dx,3c0h @@5: mov al,ah out dx,al inc ah mov al,[esi] inc esi out dx,al loop @@5 xor al,al mov ecx,9 mov dx,3ceh @@6: mov ah,[esi] inc esi out dx,ax inc al loop @@6 mov dx,3c0h mov al,32 out dx,al end; MEM[SEG0040:$4a] := vmode_data[vmode,0]; MEM[SEG0040:$84] := vmode_data[vmode,1]; MEM[SEG0040:$85] := vmode_data[vmode,2]; MEM[SEG0040:$4c] := vmode_data[vmode,3]; MEM[SEG0040:$4d] := vmode_data[vmode,4]; For temp := 0 to 16 do MEM[SEG0040:$4e+temp] := 0; MEM[SEG0040:$60] := vmode_data[vmode,20]; MEM[SEG0040:$61] := vmode_data[vmode,21]; MEM[SEG0040:$62] := 0; Case vmode_data[vmode,2] of 8: asm mov ah,11h; mov al,2; xor bx,bx; int 10h end; 14: asm mov ah,11h; mov al,1; xor bx,bx; int 10h end; 16: asm mov ah,11h; mov al,4; xor bx,bx; int 10h end; end; initialize; dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; procedure set_vga_txtmode_80x25; begin asm mov ax,03h xor bh,bh int 10h end; v_seg := $0b800; v_ofs := 0; MaxCol := 80; MaxLn := 25; FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; procedure set_svga_txtmode_100x38; var crt_address: Word; begin // set VESA gfx mode 102h (800x600) asm mov ax,4f02h mov bx,102h int 10h end; // rerogram CRT controller crt_address := MEMW[SEG0040:$63]; asm cli mov dx,crt_address // clear write protection for CRT register 0-7 mov al,11h // vertical retrace end register bit 7 reset out dx,al inc dx in al,dx and al,7fh out dx,al dec dx mov al,9 out dx,al inc dx in al,dx and al,0e0h // clear bits 0-4 or al,0fh // set max scan line to 15 out dx,al dec dx mov ax,0e0ah out dx,ax mov ax,0f0bh out dx,ax mov al,17h // mode control register out dx,al inc dx in al,dx and al,not 40h // set byte mode out dx,al dec dx // restore write protection for CRT register 0-7 mov al,11h out dx,al inc dx in al,dx or al,80h out dx,al dec dx // write sequencer: make planes 2+3 write protected mov dx,3c4h mov al,2 mov ah,3 out dx,ax // set odd/even mode, reset chain 4, more than 64 kB mov dx,3c4h mov al,4 mov ah,2 out dx,ax // write graphics controller mov dx,3ceh mov ax,1005h // set write mode 0, read mode 0, odd/even addressing out dx,ax mov dx,3ceh mov al,6 out dx,al inc dx in al,dx and al,0f0h or al,0eh // set B800h as base, set text mode, set odd/even out dx,al // write attribute controller mov dx,3cch in al,dx mov dx,3dah test al,1 jnz @@1 mov dx,3bah @@1: in al,dx // reset attribute controller mov dx,3c0h mov al,10h // select mode register out dx,al mov al,0 // set text mode [bit 0=0] out dx,al mov al,20h // turn screen on again out dx,al sti end; MaxCol := 100; MaxLn := 38; MEM[SEG0040:$4a] := MaxCol; MEM[SEG0040:$84] := MaxLn-1; initialize; dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; procedure set_svga_txtmode_128x48; var crt_address: Word; begin // set VESA gfx mode 104h (1024x768) asm mov ax,4f02h mov bx,104h int 10h end; // rerogram CRT controller crt_address := MEMW[SEG0040:$63]; asm cli mov dx,crt_address // clear write protection for CRT register 0-7 mov al,11h // vertical retrace end register bit 7 reset out dx,al inc dx in al,dx and al,7fh out dx,al dec dx mov al,9 out dx,al inc dx in al,dx and al,0e0h // clear bits 0-4 or al,0fh // set max scan line to 15 out dx,al dec dx mov ax,0e0ah out dx,ax mov ax,0f0bh out dx,ax mov al,17h // mode control register out dx,al inc dx in al,dx and al,not 40h // set byte mode out dx,al dec dx // restore write protection for CRT register 0-7 mov al,11h out dx,al inc dx in al,dx or al,80h out dx,al dec dx // write sequencer: make planes 2+3 write protected mov dx,3c4h mov al,2 mov ah,3 out dx,ax // set odd/even mode, reset chain 4, more than 64 kB mov dx,3c4h mov al,4 mov ah,2 out dx,ax // write graphics controller mov dx,3ceh mov ax,1005h // set write mode 0, read mode 0, odd/even addressing out dx,ax mov dx,3ceh mov al,6 out dx,al inc dx in al,dx and al,0f0h or al,0eh // set B800h as base, set text mode, set odd/even out dx,al // write attribute controller mov dx,3cch in al,dx mov dx,3dah test al,1 jnz @@1 mov dx,3bah @@1: in al,dx // reset attribute controller mov dx,3c0h mov al,10h // select mode register out dx,al mov al,0 // set text mode [bit 0=0] out dx,al mov al,20h // turn screen on again out dx,al sti end; MaxCol := 128; MaxLn := 48; MEM[SEG0040:$4a] := MaxCol; MEM[SEG0040:$84] := MaxLn-1; initialize; dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; const ATTRCON_ADDR = $3c0; // Attribute Controller MISC_ADDR = $3c2; // Miscellaneous Register VGAENABLE_ADDR = $3c3; // VGA Enable Register SEQ_ADDR = $3c4; // Sequencer GRACON_ADDR = $3ce; // Graphics Controller CRTC_ADDR = $3d4; // CRT Controller STATUS_ADDR = $3da; // Status Register procedure LoadVgaRegisters(reg: VGA_REG_DATA); procedure out_reg(reg: VGA_REGISTER); begin Case (reg.port) of ATTRCON_ADDR: begin inportb(STATUS_ADDR); outportb(ATTRCON_ADDR,reg.idx OR $20); outportb(ATTRCON_ADDR,reg.val); end; MISC_ADDR, VGAENABLE_ADDR: outportb(reg.port,reg.val); else begin outportb(reg.port,reg.idx); outportb(reg.port+1,reg.val); end; end; end; var idx,temp: Byte; begin outportb($3d4,$11); temp := inportb($3d5) AND $7f; outportb($3d4,$11); outportb($3d5,temp); For idx := 1 to 29 do out_reg(reg[idx]); end; procedure set_custom_svga_txtmode; begin LoadVgaRegisters(svga_txtmode_regs); MaxCol := svga_txtmode_cols; MaxLn := svga_txtmode_rows; MEM[SEG0040:$4a] := MaxCol; MEM[SEG0040:$84] := MaxLn-1; initialize; dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; {$ENDIF} procedure move2screen; var screen_ptr_backup: Pointer; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'TXTSCRIO.PAS:move2screen'; {$ENDIF} HideCursor; screen_ptr_backup := screen_ptr; screen_ptr := move_to_screen_data; area_x1 := 0; area_y1 := 0; area_x2 := 0; area_y2 := 0; scroll_pos0 := BYTE_NULL; scroll_pos1 := BYTE_NULL; scroll_pos2 := BYTE_NULL; scroll_pos3 := BYTE_NULL; scroll_pos4 := BYTE_NULL; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); status_refresh; decay_bars_refresh; ScreenMemCopy(screen_ptr,screen_ptr_backup); screen_ptr := screen_ptr_backup; SetCursor(cursor_backup); end; procedure move2screen_alt; var pos1,pos2: Byte; begin If (move_to_screen_data <> NIL) then asm mov esi,dword ptr [screen_ptr] lea edi,[temp_screen2] mov ecx,SCREEN_MEM_SIZE rep movsb mov esi,[move_to_screen_data] mov edi,dword ptr [ptr_temp_screen2] xor ecx,ecx mov cl,byte ptr [move_to_screen_area+1] @@1: mov pos2,cl xor ecx,ecx mov cl,byte ptr [move_to_screen_area+0] @@2: mov pos1,cl mov al,pos1 mov ah,pos2 xor ecx,ecx call DupChar movzx ecx,absolute_pos mov ax,word ptr [esi+ecx] mov word ptr [edi+ecx],ax movzx ecx,pos1 inc ecx cmp cl,byte ptr [move_to_screen_area+2] jbe @@2 movzx ecx,pos2 inc ecx cmp cl,byte ptr [move_to_screen_area+3] jbe @@1 lea esi,[temp_screen2] mov edi,dword ptr [screen_ptr] mov ecx,SCREEN_MEM_SIZE rep movsb end; end; function is_default_screen_mode: Boolean; begin {$IFDEF GO32V2} is_default_screen_mode := (program_screen_mode = 0) or ((program_screen_mode = 3) and (comp_text_mode < 4)); {$ELSE} is_default_screen_mode := (program_screen_mode = 0); {$ENDIF} end; {$IFDEF GO32V2} function is_VESA_emulated_mode: Boolean; begin is_VESA_emulated_mode := (program_screen_mode = 3) and (comp_text_mode > 1); end; function get_VESA_emulated_mode_idx: Byte; begin get_VESA_emulated_mode_idx := min(comp_text_mode-2,0); end; {$ENDIF} function is_scrollable_screen_mode: Boolean; begin {$IFDEF GO32V2} is_scrollable_screen_mode := (program_screen_mode = 0) or ((program_screen_mode = 3) and (comp_text_mode < 2)) or (is_VESA_emulated_mode and (get_VESA_emulated_mode_idx in [0,1])); {$ELSE} is_scrollable_screen_mode := (program_screen_mode = 0); {$ENDIF} end; procedure TxtScrIO_Init; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'TXTSCRIO.PAS:TxtScrIO_Init'; program_screen_mode := screen_mode; {$ENDIF} mn_environment.v_dest := screen_ptr; centered_frame_vdest := screen_ptr; {$IFDEF GO32V2} If NOT is_VESA_emulated_mode then {$ENDIF} Case program_screen_mode of 0: begin SCREEN_RES_X := 720; SCREEN_RES_Y := 480; MAX_COLUMNS := 90; MAX_ROWS := 40; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 18; INSCTRL_xshift := 0; INSCTRL_yshift := 0; INSEDIT_yshift := 0; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 30; work_MaxCol := MAX_COLUMNS; work_MaxLn := 30; scr_font_width := 8; scr_font_height := 16; end; // full-screen view 1: begin SCREEN_RES_X := 960; SCREEN_RES_Y := 800; MAX_COLUMNS := 120; MAX_ROWS := 50; MAX_ORDER_COLS := 13; MAX_TRACKS := 7; MAX_PATTERN_ROWS := 28; INSCTRL_xshift := 15; INSCTRL_yshift := 6; INSEDIT_yshift := 12; PATTORD_xshift := 1; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 50; work_MaxCol := MAX_COLUMNS; work_MaxLn := 40; scr_font_width := 8; scr_font_height := 16; end; // wide full-screen view 2: begin SCREEN_RES_X := 1440; SCREEN_RES_Y := 960; MAX_COLUMNS := 180; MAX_ROWS := 60; MAX_ORDER_COLS := 22; MAX_TRACKS := 11; MAX_PATTERN_ROWS := 38; INSCTRL_xshift := 45; INSCTRL_yshift := 12; INSEDIT_yshift := 12; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 60; work_MaxCol := MAX_COLUMNS; work_MaxLn := 50; scr_font_width := 8; scr_font_height := 16; end; // 90x47 4: begin SCREEN_RES_X := 800; SCREEN_RES_Y := 600; MAX_COLUMNS := 90; MAX_ROWS := 38; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 16; INSCTRL_xshift := 0; INSCTRL_yshift := 4; INSEDIT_yshift := 12; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 38; work_MaxCol := MAX_COLUMNS; work_MaxLn := 38; scr_font_width := 8; scr_font_height := 16; GOTOXY_xshift := ((SCREEN_RES_X DIV scr_font_width)-MAX_COLUMNS) DIV 2; end; // 120x47 5: begin SCREEN_RES_X := 1024; SCREEN_RES_Y := 768; MAX_COLUMNS := 120; MAX_ROWS := 48; MAX_ORDER_COLS := 13; MAX_TRACKS := 7; MAX_PATTERN_ROWS := 26; INSCTRL_xshift := 15; INSCTRL_yshift := 7; INSEDIT_yshift := 12; PATTORD_xshift := 1; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 48; work_MaxCol := MAX_COLUMNS; work_MaxLn := 48; scr_font_width := 8; scr_font_height := 16; GOTOXY_xshift := ((SCREEN_RES_X DIV scr_font_width)-MAX_COLUMNS) DIV 2; end; {$IFDEF GO32V2} // compatibility text-mode 3: Case comp_text_mode of 0, 1: begin SCREEN_RES_X := 720; SCREEN_RES_Y := 480; MAX_COLUMNS := 90; MAX_ROWS := 40; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 18; INSCTRL_xshift := 0; INSCTRL_yshift := 0; PATTORD_xshift := 0; INSEDIT_yshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 30; work_MaxCol := MAX_COLUMNS; work_MaxLn := 30; scr_font_width := 9; scr_font_height := 16; end; end; end else // VESA-emulated text-mode Case get_VESA_emulated_mode_idx of // 90x30 (default mode) 0: begin SCREEN_RES_X := 800; SCREEN_RES_Y := 600; MAX_COLUMNS := 90; MAX_ROWS := 40; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 18; INSCTRL_xshift := 0; INSCTRL_yshift := 0; INSEDIT_yshift := 0; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 30; work_MaxCol := MAX_COLUMNS; work_MaxLn := 30; scr_font_width := 8; scr_font_height := 16; end; // 90x47 1: begin SCREEN_RES_X := 800; SCREEN_RES_Y := 600; MAX_COLUMNS := 90; MAX_ROWS := 46; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 24; INSCTRL_xshift := 0; INSCTRL_yshift := 4; INSEDIT_yshift := 0; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 36; work_MaxCol := MAX_COLUMNS; work_MaxLn := 36; scr_font_width := 8; scr_font_height := 16; end; // 120x47 2: begin SCREEN_RES_X := 1024; SCREEN_RES_Y := 768; MAX_COLUMNS := 120; MAX_ROWS := 46; MAX_ORDER_COLS := 13; MAX_TRACKS := 7; MAX_PATTERN_ROWS := 24; INSCTRL_xshift := 15; INSCTRL_yshift := 7; INSEDIT_yshift := 12; PATTORD_xshift := 1; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 47; work_MaxCol := MAX_COLUMNS; work_MaxLn := 36; scr_font_width := 8; scr_font_height := 16; end; end; {$ELSE} end; {$ENDIF} FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); SCREEN_MEM_SIZE := (SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2; move_to_screen_routine := move2screen; If (command_typing = 0) then _pattedit_lastpos := 4*MAX_TRACKS else _pattedit_lastpos := 10*MAX_TRACKS; Case MAX_COLUMNS of 120: temp := 1; 180: temp := 2; else temp := 0; end; patt_win[1] := patt_win_tracks[temp][1]; patt_win[2] := patt_win_tracks[temp][2]; patt_win[3] := patt_win_tracks[temp][3]; patt_win[4] := patt_win_tracks[temp][4]; patt_win[5] := patt_win_tracks[temp][5]; end; end.