#include #include #include #include #include #include #include int play_sam( void *adr, void *end, long hertz, long hold, int dma ); typedef struct view { int handle, s1; int lbc, /* left-border-count fr Fenster. */ tlc, /* top-line-count fr Fenster. */ bc, /* border-count fr Fenster. */ lc, /* line-count fr Fenster. */ xfac, yfac, /* Scroll- und Rastereinheiten. */ x, y, w, h, /* Arbeitsbereich des Fensters. */ hslide, vslide, /* Puffer fr Sliderpositionen. */ (*key)( struct view *tv, int code, int ks ); void (*draw)( struct view *tv, int *clip ), (*free)( struct view *tv ), (*sclick)( struct view *tv, int mx, int my, int flag ); char path[128]; /* Datei-Pfad (Fenstertitel). */ struct view *next; /* Zeiger auf nchste Fensterstruktur. */ struct view *prev; /* Zeiger auf vorige Fensterstruktur. */ BASPAG *actpd; /* Zeiger auf Prozess-Descriptor. */ int dma, data; long dw, dh, hertz; char *start, *end, buf[]; /* Sample-Buffer. */ } VIEW; #include "1stview.h" #include "util.h" static int dmaflag = 0; static char samstring[] = "--- Hertz ---", hertzstring[] = " ", wstring[] = " Fenster ^E", ostring[] = " Original ^S", normstring[] = " Norm ^N ", dmastring[] = " DMA ^M "; #pragma warn -rpt static OBJECT popup[] = { 0, 1, 10, G_BOX, NONE, SHADOWED, 0xFF1100L, 0, 0, 19,7, 2, -1, -1, G_STRING, NONE, DISABLED, samstring, 0, 0, 19,1, 3, -1, -1, G_STRING, NONE, NORMAL, wstring, 0, 1, 19,1, 4, -1, -1, G_BUTTON, NONE, NORMAL, "- ^\004", 0, 2, 6, 1, 5, -1, -1, G_BUTTON, NONE, DISABLED, hertzstring, 6, 2, 7, 1, 6, -1, -1, G_BUTTON, NONE, NORMAL, "+ ^\003", 13,2, 6, 1, 7, -1, -1, G_STRING, NONE, NORMAL, ostring, 0, 3, 19,1, 8, -1, -1, G_STRING, NONE, DISABLED, "----- P L A Y -----", 0, 4, 19,1, 9, -1, -1, G_BUTTON, NONE, NORMAL, normstring, 0, 5, 10,1, 10, -1, -1, G_BUTTON, NONE, DISABLED, dmastring, 10,5, 9, 1, 0, -1, -1, G_STRING, LASTOB, NORMAL, " STOP ^T ", 0, 6, 19,1 }; #pragma warn +rpt static void check_dma( void ) { #ifdef __TOS__ void *oldstack; long *cookiejar; oldstack = (void *)Super( 0 ); cookiejar = *(long **)0x5A0; if (cookiejar) { while (*cookiejar) { if (*cookiejar == '_SND') { if (cookiejar[1] & 2L) popup[9].ob_state = NORMAL; break; } cookiejar += 2; } } Super( oldstack ); #endif } static void change_hz( VIEW *tv, int flag ) { #ifdef __TOS__ void *oldstack; oldstack = (void *)Super( 0 ); if (tv->dma) { flag += tv->data; if (flag < 0x80) flag = 0x80; if (flag > 0x83) flag = 0x83; *(int *)0xFFFF8920L = flag; } else { if ((flag = tv->data - flag) <= 0) flag = 1; if (flag > 255) flag = 255; *(char *)0xFFFFFA1FL = flag; } Super( oldstack ); tv->data = flag; #endif } static void new_item( VIEW *tv, int new ) { if (new == 2) { if (tv->dw == tv->w && tv->dh == tv->h) return; tv->dw = tv->w; tv->dh = tv->h; } else { if (tv->dw == tv->end - tv->start && tv->dh == 256) return; tv->dw = tv->end - tv->start; tv->dh = 256; } tv->bc = (int)((tv->dw + 31) >> 5); tv->lc = (int)((tv->dh + 7) >> 3); new_redraw(); } static int *pline( int *pxy ) { VDI( 6, (int)(pxy - ptsin) >> 1, 0, handle ); return ptsin; } static void draw_sample( VIEW *tv, int *clip ) { int *pxy; char *p, *q; long len; int dx, dy; vr_recfl( handle, clip ); vs_clip( handle, 1, clip ); pxy = ptsin; q = p = tv->start; len = tv->end - p; dy = tv->y - (tv->tlc << 3); if (tv->dw == len) { p += ((long)tv->lbc << 5) + clip[0] - tv->x; q = p; q += clip[2] - clip[0]; if (++q > tv->end) q = tv->end; dx = clip[0] - 1; if (--p < tv->start) { ++p; ++dx; } while (p < q) { *pxy++ = dx++; *pxy++ = dy + (int)(((127 - *p++) * tv->dh) >> 8); if (pxy == ptsin + 128) { pxy = pline( pxy ); *(long *)pxy = *(long *)(pxy + 126); pxy += 2; } } } else { dx = tv->x - (tv->lbc << 5); p += ((clip[0] - 1 - dx) * len) / tv->dw; q += ((clip[2] + 1 - dx) * len) / tv->dw; if (p < tv->start) p = tv->start; if (q > tv->end) q = tv->end; while (p < q) { *pxy++ = dx + (int)(((p - tv->start) * tv->dw) / len); *pxy++ = dy + (int)(((127 - *p++) * tv->dh) >> 8); if (pxy == ptsin + 128) { pxy = pline( pxy ); *(long *)pxy = *(long *)(pxy + 126); pxy += 2; } } } pline( pxy ); vs_clip( handle, 0, clip ); } static void free_sample( VIEW *tv ) { #ifdef __TOS__ play_sam( tv->start, tv->start, tv->hertz, 0, tv->dma ); #endif } static void do_play( VIEW *tv ) { tv->dma = dmaflag; #ifdef __TOS__ tv->data = play_sam( tv->start, tv->end, tv->hertz, 1, tv->dma ); #else tv->data = (int)(614400L / tv->hertz); #endif } #pragma warn -par static int key_sample( VIEW *tv, int code, int ks ) { switch (code) { case CNTRL_E: new_item( tv, 2 ); return 0; case CNTRL_S: new_item( tv, 6 ); return 0; case CNTRL_M: if (popup[9].ob_state == NORMAL) { free_sample( tv ); dmaflag = 1; do_play( tv ); } return 0; case CNTRL_N: free_sample( tv ); dmaflag = 0; do_play( tv ); return 0; case CNTRL_T: free_sample( tv ); return 0; case CNTRL_CL: change_hz( tv, -1 ); return 0; case CNTRL_CR: change_hz( tv, 1 ); return 0; } return 1; } #pragma warn +par static void sclick_sample( VIEW *tv, int mx, int my, int flag ) { long value, count; char *string; if (flag) return; value = tv->hertz; count = 6; string = samstring + 9; do *--string = '0' + value % 10; while (--count && (value /= 10) != 0); while (--count > 0) *--string = ' '; if (tv->dma == 0) value = 614400L / tv->data; else switch (tv->data) { case 0x80: value = 6258L; break; case 0x81: value = 12517L; break; case 0x82: value = 25033L; break; default: value = 50066L; } ltoa( value, hertzstring, 10 ); *wstring = tv->dw == tv->w && tv->dh == tv->h ? 8 : ' '; *ostring = tv->dw == tv->end - tv->start && tv->dh == 256 ? 8 : ' '; *normstring = tv->dma ? ' ' : 8; *dmastring = tv->dma ? 8 : ' '; switch (popup_menu( popup, 4, mx, my, objc_draw )) { case 2: new_item( tv, 2 ); break; case 3: change_hz( tv, -1 ); break; case 5: change_hz( tv, 1 ); break; case 6: new_item( tv, 6 ); break; case 8: free_sample( tv ); dmaflag = 0; do_play( tv ); break; case 9: free_sample( tv ); dmaflag = 1; do_play( tv ); break; case 10: free_sample( tv ); } } VIEW *load_sample( int fh, long len ) { VIEW *rv; char *stop, *start; if ((rv = Malloc( sizeof(VIEW) + len )) == 0) { Fclose( fh ); form_error( EINVMEM ); return 0; } rv->hertz = par.hertz; start = rv->buf; rv->end = stop = start + len; Fread( fh, len, start ); Fclose( fh ); if (popup->ob_next == 0) { --popup->ob_next; fix_tree( popup, 10 ); check_dma(); } #ifdef __TOS__ if (*(long *)start == 0xAABBCCDDL) /* SoundMerlin Format */ #else if (*(long *)start == 0xDDCCBBAAL) #endif { rv->hertz = 10U * ((unsigned *)start)[10]; stop = start += 50; } #ifdef __TOS__ else if (*(long *)start == 0x0000AB12L) /* SoundMachine Format */ #else else if (*(long *)start == 0x12AB0000L) #endif { rv->hertz = 13000; stop = start += 34; } #ifdef __TOS__ else if ((*(long *)start & 0xFFFFFF00L) == 'JON\0') /* ??? */ #else else if ((*(long *)start & 0x00FFFFFFL) == ((long)'N' << 16) + ((long)'O' << 8) + 'J') #endif { rv->hertz = 1000U * ((unsigned char *)start)[3]; start += 4; } while (stop > start) *--stop -= 128; rv->start = start; rv->xfac = 32; rv->yfac = 8; rv->w = 512; rv->h = 256; rv->dh = 256; rv->lc = 32; rv->dw = rv->end - start; rv->bc = (int)((rv->dw + 31) >> 5); rv->draw = draw_sample; rv->free = free_sample; rv->key = key_sample; rv->sclick = sclick_sample; do_play( rv ); return rv; }