char *GetBlock(struct marking *block, struct InstData *data) { LONG startx, stopx; struct line_node *startline, *stopline, *act; char *text = NULL; struct ExportMessage emsg; ENTER(); startx = block->startx; stopx = block->stopx; startline = block->startline; stopline = block->stopline; data->CPos_X = startx; data->actualline = startline; // clear the export message memset(&emsg, 0, sizeof(struct ExportMessage)); // fill it afterwards emsg.UserData = NULL; emsg.ExportWrap = 0; emsg.Last = FALSE; emsg.data = data; if(startline != stopline) { /* Create a firstline look-a-like */ emsg.Contents = (STRPTR)MyAllocPooled(data->mypool, startline->line.Length-startx); if(startline->line.Styles && *startline->line.Styles != EOS) { ULONG startstyle = GetStyle(startx, startline); if((emsg.Styles = (UWORD *)MyAllocPooled(data->mypool, *((ULONG *)startline->line.Styles-1)+16))) { UWORD *styles = emsg.Styles, *oldstyles = startline->line.Styles; if(startstyle & BOLD) { *styles++ = 1; *styles++ = BOLD; } if(startstyle & ITALIC) { *styles++ = 1; *styles++ = ITALIC; } if(startstyle & UNDERLINE) { *styles++ = 1; *styles++ = UNDERLINE; } while(*oldstyles <= startx) oldstyles += 2; while(*oldstyles != EOS) { *styles++ = *oldstyles++ - startx; *styles++ = *oldstyles++; } *styles = EOS; } } else emsg.Styles = NULL; emsg.Colors = NULL; if(emsg.Contents) { memcpy(emsg.Contents, startline->line.Contents + startx, startline->line.Length - startx); emsg.Length = startline->line.Length - startx; emsg.Flow = startline->line.Flow; emsg.Separator = startline->line.Separator; emsg.Highlight = startline->line.Color; emsg.UserData = (APTR)CallHookA(&ExportHookPlain, NULL, &emsg); MyFreePooled(data->mypool, emsg.Contents); } if(emsg.Styles) MyFreePooled(data->mypool, emsg.Styles); /* Start iterating... */ act = startline->next; while(act != stopline) { emsg.Contents = act->line.Contents; emsg.Length = act->line.Length; emsg.Styles = act->line.Styles; emsg.Colors = act->line.Colors; emsg.Flow = act->line.Flow; emsg.Separator = act->line.Separator; emsg.Highlight = act->line.Color; emsg.UserData = (APTR)CallHookA(&ExportHookPlain, (APTR)NULL, &emsg); act = act->next; } /* Create a Lastline look-a-like */ emsg.Contents = (STRPTR)MyAllocPooled(data->mypool, stopx); if(stopline->line.Styles && *stopline->line.Styles != EOS) { ULONG stopstyle = GetStyle(stopx, stopline); if((emsg.Styles = (UWORD *)MyAllocPooled(data->mypool, *((ULONG *)stopline->line.Styles-1)+16))) { UWORD *styles = emsg.Styles, *oldstyles = stopline->line.Styles; while(*oldstyles <= stopx) { *styles++ = *oldstyles++; *styles++ = *oldstyles++; } if(stopstyle & BOLD) { *styles++ = stopx+1; *styles++ = ~BOLD; } if(stopstyle & ITALIC) { *styles++ = stopx+1; *styles++ = ~ITALIC; } if(stopstyle & UNDERLINE) { *styles++ = stopx+1; *styles++ = ~UNDERLINE; } *styles = EOS; } } else emsg.Styles = NULL; emsg.Colors = NULL; if(emsg.Contents) { memcpy(emsg.Contents, stopline->line.Contents, stopx); emsg.Length = stopx; emsg.Flow = stopline->line.Flow; emsg.Separator = stopline->line.Separator; emsg.Highlight = stopline->line.Color; emsg.Last = TRUE; text = (STRPTR)CallHookA(&ExportHookPlain, NULL, &emsg); MyFreePooled(data->mypool, emsg.Contents); } if(emsg.Styles) MyFreePooled(data->mypool, emsg.Styles); } else { /* Create a single line */ emsg.Contents = (STRPTR)MyAllocPooled(data->mypool, stopx-startx); if(startline->line.Styles && *startline->line.Styles != EOS) { ULONG startstyle = GetStyle(startx, startline); ULONG stopstyle = GetStyle(stopx, stopline); if((emsg.Styles = (UWORD *)MyAllocPooled(data->mypool, *((ULONG *)startline->line.Styles-1)))) { UWORD *styles = emsg.Styles, *oldstyles = startline->line.Styles; if(startstyle & BOLD) { *styles++ = 1; *styles++ = BOLD; } if(startstyle & ITALIC) { *styles++ = 1; *styles++ = ITALIC; } if(startstyle & UNDERLINE) { *styles++ = 1; *styles++ = UNDERLINE; } while(*oldstyles <= startx) oldstyles += 2; while(*oldstyles <= stopx) { *styles++ = *oldstyles++ - startx; *styles++ = *oldstyles++; } if(stopstyle & BOLD) { *styles++ = stopx-startx+1; *styles++ = ~BOLD; } if(stopstyle & ITALIC) { *styles++ = stopx-startx+1; *styles++ = ~ITALIC; } if(stopstyle & UNDERLINE) { *styles++ = stopx-startx+1; *styles++ = ~UNDERLINE; } *styles = EOS; } } else emsg.Styles = NULL; emsg.Colors = NULL; if(emsg.Contents) { memcpy(emsg.Contents, startline->line.Contents+startx, stopx-startx); emsg.Length = stopx-startx; emsg.Flow = startline->line.Flow; emsg.Separator = startline->line.Separator; emsg.Highlight = startline->line.Color; emsg.Last = TRUE; text = (STRPTR)CallHookA(&ExportHookPlain, NULL, &emsg); MyFreePooled(data->mypool, emsg.Contents); } if(emsg.Styles) MyFreePooled(data->mypool, emsg.Styles); } RETURN(text); return(text); }
static void Slave( struct ExecBase* SysBase ) { struct AHIAudioCtrlDrv* AudioCtrl; struct DriverBase* AHIsubBase; struct AROSBase* AROSBase; BOOL running; ULONG signals; int bytes_in_buffer = 0; int offset_in_buffer = 0; AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData; AHIsubBase = (struct DriverBase*) dd->ahisubbase; AROSBase = (struct AROSBase*) AHIsubBase; dd->slavesignal = AllocSignal( -1 ); if( dd->slavesignal != -1 ) { // Everything set up. Tell Master we're alive and healthy. Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal ); running = TRUE; // The main playback loop follow while( running ) { signals = SetSignal(0L,0L); // KPrintF("++++ arosdriver_after signal checking\n"); if( signals & ( SIGBREAKF_CTRL_C | (1L << dd->slavesignal) ) ) { running = FALSE; } else { int skip_mix; int bytes_avail; // First Delay() until there is at least one fragment free while( TRUE ) { int frag_avail, frag_alloc, frag_size; OSS_GetOutputInfo( &frag_avail, &frag_alloc, &frag_size, &bytes_avail ); // KPrintF( "%ld fragments available, %ld alloced (%ld bytes each). %ld bytes total\n", frag_avail, frag_alloc, frag_size, bytes_avail ); if( frag_avail == 0 ) { // This is actually quite a bit too long delay :-( For // comparison, the SB Live/Audigy driver uses 1/1000 s // polling ... // KPrintF("Delay\n"); #if USE_TIMERTICK SmallDelay(SysBase); #else Delay( 1 ); #endif } else { break; } } skip_mix = 0;/*CallHookA( AudioCtrl->ahiac_PreTimerFunc, (Object*) AudioCtrl, 0 );*/ while( bytes_avail > 0 ) { // KPrintF( "%ld bytes in current buffer.\n", bytes_in_buffer ); if( bytes_in_buffer == 0 ) { int skip = 0; int offset = 0; int samples = 0; int bytes = 0; int i; WORD* src; WORD* dst; CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL ); samples = AudioCtrl->ahiac_BuffSamples; bytes = samples * 2; // one 16 bit sample is 2 bytes switch( AudioCtrl->ahiac_BuffType ) { case AHIST_M16S: skip = 1; offset = 0; break; case AHIST_M32S: skip = 2; offset = 1; break; case AHIST_S16S: skip = 1; offset = 0; samples *= 2; bytes *= 2; break; case AHIST_S32S: skip = 2; offset = 1; samples *= 2; bytes *= 2; break; } bytes_in_buffer = bytes; offset_in_buffer = 0; if( ! skip_mix ) { CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->mixbuffer ); } src = ((WORD*) dd->mixbuffer) + offset; dst = dd->mixbuffer; for( i = 0; i < samples; ++i ) { *dst++ = *src; src += skip; } // KPrintF( "Mixed %ld/%ld new bytes/samples\n", bytes, samples ); } while( bytes_in_buffer > 0 && bytes_avail > 0 ) { int written; int counter = 0; do { written = OSS_Write( dd->mixbuffer + offset_in_buffer, min( bytes_in_buffer, bytes_avail ) ); if (counter > 10) { if (written < 0) written = 0; break; } if (written < 0) KPrintF("OSS_Write returned %ld. counter %ld bytes_in_buffer %ld bytes_avail %ld\n", written, counter, bytes_in_buffer, bytes_avail); counter++; } while (written < 0); bytes_in_buffer -= written; offset_in_buffer += written; bytes_avail -= written; // KPrintF( "Wrote %ld bytes (%ld bytes in buffer, offset=%ld, %ld bytes available in OSS buffers\n", // written, bytes_in_buffer, offset_in_buffer, bytes_avail ); } } CallHookA( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 ); } } } FreeSignal( dd->slavesignal ); dd->slavesignal = -1; Forbid(); // Tell the Master we're dying Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal ); dd->slavetask = NULL; // Multitaking will resume when we are dead. }
BOOL ReadStruct ( /* SYNOPSIS */ struct Hook * hook, APTR * dataptr, void * stream, const IPTR * sd) /* FUNCTION Reads one big endian structure from a streamhook. INPUTS hook - Streamhook dataptr - Put the data here stream - Read from this stream sd - Description of the structure to be read. The first element is the size of the structure. RESULT The function returns TRUE on success. On success, the value read is written into dataptr. On failure, FALSE is returned and the contents of dataptr are not changed. NOTES This function reads big endian values from a streamhook even on little endian machines. EXAMPLE See below. BUGS SEE ALSO ReadByte(), ReadWord(), ReadLong(), ReadFloat(), ReadDouble(), ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(), WriteFloat(), WriteDouble(), WriteString(), WriteStruct() HISTORY ******************************************************************************/ { struct MinList _list; struct ReadLevel * curr; # define list ((struct List *)&_list) NEWLIST(list); if (!(curr = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) return FALSE; AddTail (list, (struct Node *)curr); curr->sd = sd; curr->pos = 0; curr->s = NULL; # define DESC curr->sd[curr->pos] # define IDESC curr->sd[curr->pos ++] for (;;) { if (!curr->pos) { if (!(curr->s = AllocMem (IDESC, MEMF_CLEAR)) ) goto error; } if (DESC == SDT_END) break; switch (IDESC) { case SDT_UBYTE: /* Read one 8bit byte */ if (!ReadByte (hook, (UBYTE *)(curr->s + IDESC), stream)) goto error; break; case SDT_UWORD: /* Read one 16bit word */ if (!ReadWord (hook, (UWORD *)(curr->s + IDESC), stream)) goto error; break; case SDT_ULONG: /* Read one 32bit long */ if (!ReadLong (hook, (ULONG *)(curr->s + IDESC), stream)) goto error; break; case SDT_FLOAT: /* Read one 32bit IEEE */ if (!ReadFloat (hook, (FLOAT *)(curr->s + IDESC), stream)) goto error; break; case SDT_DOUBLE: /* Read one 64bit IEEE */ if (!ReadDouble (hook, (DOUBLE *)(curr->s + IDESC), stream)) goto error; break; case SDT_STRING: { /* Read a string */ UBYTE valid_ptr; STRPTR * sptr; sptr = (STRPTR *)(curr->s + IDESC); if (!ReadByte (hook, &valid_ptr, stream)) goto error; if (valid_ptr) { if (!ReadString (hook, sptr, stream)) goto error; } else { *sptr = NULL; } break; } case SDT_STRUCT: { /* Read a structure */ struct ReadLevel * next; IPTR * desc; APTR aptr; aptr = (APTR)(curr->s + IDESC); desc = (IPTR *)IDESC; curr->pos -= 3; /* Go back to type */ if (!(next = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) goto error; AddTail (list, (struct Node *)next); next->sd = desc; next->pos = 1; next->s = aptr; curr = next; break; } case SDT_PTR: { /* Follow a pointer */ struct ReadLevel * next; UBYTE valid_ptr; IPTR * desc; APTR * aptr; aptr = ((APTR *)(curr->s + IDESC)); desc = (IPTR *)IDESC; if (!ReadByte (hook, &valid_ptr, stream)) goto error; if (valid_ptr) { curr->pos -= 3; if (!(next = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) ) goto error; AddTail (list, (struct Node *)next); next->sd = desc; next->pos = 0; curr = next; } else { *aptr = NULL; } break; } case SDT_IGNORE: { /* Ignore x bytes */ struct BEIOM_Ignore ig = {BEIO_IGNORE, IDESC}; if (CallHookA (hook, stream, &ig) == EOF) goto error; break; } case SDT_FILL_BYTE: { /* Fill x bytes */ IPTR offset; UBYTE value; IPTR count; offset = IDESC; value = IDESC; count = IDESC; memset (curr->s + offset, value, count); break; } case SDT_FILL_LONG: { /* Fill x longs */ ULONG * ulptr; ULONG value; IPTR count; ulptr = (ULONG *)(curr->s + IDESC); value = IDESC; count = IDESC; while (count --) *ulptr ++ = value; break; } case SDT_IFILL_BYTE: { /* Fill x bytes */ IPTR offset; UBYTE value; IPTR count; offset = IDESC; value = IDESC; count = IDESC; struct BEIOM_Ignore ig = {BEIO_IGNORE, count}; if (CallHookA (hook, stream, &ig) == EOF) goto error; memset (curr->s + offset, value, count); break; } case SDT_IFILL_LONG: { /* Fill x longs */ ULONG * ulptr; ULONG value; IPTR count; ulptr = (ULONG *)(curr->s + IDESC); value = IDESC; count = IDESC; struct BEIOM_Ignore ig = {BEIO_IGNORE, count << 2}; if (CallHookA (hook, stream, &ig) == EOF) goto error; while (count --) *ulptr ++ = value; break; } case SDT_SPECIAL: { /* Call user hook */ struct Hook * uhook; struct SDData data; data.sdd_Dest = ((APTR)(curr->s + IDESC)); data.sdd_Mode = SDV_SPECIALMODE_READ; data.sdd_Stream = stream; uhook = (struct Hook *)IDESC; if (!CallHookA (uhook, hook, &data)) goto error; break; } default: goto error; } /* switch */ /* End of the description list ? */ if (DESC == SDT_END) { struct ReadLevel * last; /* Remove the current level */ last = curr; Remove ((struct Node *)last); /* Get the last level */ if ((curr = (struct ReadLevel *)GetTail (list))) { switch (IDESC) { case SDT_STRUCT: curr->pos += 2; /* Skip 2 parameters */ break; case SDT_PTR: { APTR * aptr; aptr = ((APTR *)(curr->s + IDESC)); curr->pos ++; /* Skip description parameter */ /* Now put the result of the current level in the struct of the previous level. */ *aptr = last->s; break; } } FreeMem (last, sizeof (struct ReadLevel)); } else { curr = last; } } } /* while */ *dataptr = curr->s; FreeMem (curr, sizeof (struct ReadLevel)); return TRUE; error: curr = (struct ReadLevel *)GetHead (list); if (curr && curr->s) FreeStruct (curr->s, curr->sd); while ((curr = (struct ReadLevel *)RemTail (list))) FreeMem (curr, sizeof (struct ReadLevel)); return FALSE; } /* ReadStruct */