HRESULT
SoundD3D::Rewind()
{
	if (!buffer) return E_FAIL;

	HRESULT hr = S_OK;

	if (IsPlaying())
	hr = Stop();

	if (flags & STREAMED) {
		RewindStream();
		StreamBlock();
	}

	else {
		hr = buffer->SetCurrentPosition(0);
	}

	if (SUCCEEDED(hr)) {
		status = READY;
		looped = 0;
	}

	return hr;
}
Пример #2
0
void handleInvokeForwardRequest(RemoteOpHeader *h, Node srv, Stream str)
{
  ConcreteType ct;
  Object o;
  unsigned int answer;

  anticipateGC(64*1024 + 2 * StreamLength(str));
  TRACE(rinvoke, 3, ("InvokeForwardRequest received"));
  TRACE(rinvoke, 6, ("Checking for CT for incoming activation"));
  ct = (ConcreteType) doObjectRequest(srv, &h->targetct, ctct);
  assert(! ISNIL(ct));

  TRACE(rinvoke, 4, ("InvokeForwarded for object with ID %s", OIDString(h->target)));
  o = OIDFetch(h->target);
  assert(!ISNIL(o));
  if (RESDNT(o->flags)) {
    int more;
    State *state;
    TRACE(rinvoke, 4, ("The object is here, accepting activation"));
    ReadInt(&answer, str);
    more = memcmp(ReadStream(str, 4), "ACT!", 4);
    assert(!more);
    /* Suck out an activation record - argh! */
    TRACE(rinvoke, 6, ("Incoming activation record!!"));
    state = extractActivation(o, ct, str, srv);
    if (!ISNIL(answer)) {
#define sp state->sp
      PUSH(u32, answer);
      PUSH(ConcreteType, BuiltinInstCT(BOOLEANI));
    }
#undef sp
  } else {
    Node newsrv = getLocFromObj(o);
    TRACE(rinvoke, 4, ("Forwarding request to %s", NodeString(newsrv)));
    if (forwardMsg(newsrv, h, str) < 0) {
      Stream newstr;
      RewindStream(str);
      newstr = StealStream(str);
      findAndSendTo(h->target, newstr);
    }
  }
  TRACE(rinvoke, 4, ("Invoke forward request done"));
  inhibit_gc--;
}
Пример #3
0
void handleInvokeRequest(RemoteOpHeader *h, Node srv, Stream str)
{
  Stream newstr;
  int argc = h->option2, retc = h->option1, fn = h->status, i;
  Object obj;
  ConcreteType ct = 0;
  RemoteOpHeader replyh;
  int *sp;
  State *state;

  anticipateGC(64 * 1024 + 2 * StreamLength(str));
  TRACE(rinvoke, 3, ("InvokeRequest received"));
  /* figure out who we're invoking on */
  obj = OIDFetch(h->target);

  if (!ISNIL(obj)) {
    ct = CODEPTR(obj->flags);
    TRACE(rinvoke, 4, ("Target is a %.*s, operation name is %.*s[%d]",
		       ct->d.name->d.items, ct->d.name->d.data, 
		       ct->d.opVector->d.data[fn]->d.name->d.items,
		       ct->d.opVector->d.data[fn]->d.name->d.data, argc));
  } else {
    TRACE(rinvoke, 1, ("Invoking %s op %d [%d] -> [%d]", OIDString(h->target),
		       fn, argc, retc));
  }

  if (ISNIL(obj)) {
    /*
     * Invoke came here, but we don't know anything about this object.
     * First find it, then send it the message.
     */
    TRACE(rinvoke, 1, ("Trying to find the object and send it the message"));
    ct = (ConcreteType)doObjectRequest(replyh.sslocation, &h->targetct, ctct);
    obj = createStub(ct, getNodeRecordFromSrv(replyh.sslocation), h->target);

    RewindStream(str);
    newstr = StealStream(str);
    findAndSendTo(h->target, newstr);
  } else if (!RESDNT(obj->flags)) {
    Node newsrv = getLocFromObj(obj);
    /* Invoke came here, but the object is elsewhere */
    /* First check to see if we think the object is where this invoke
       came from */
    if (SameNode(srv, newsrv) || SameNode(myid, newsrv) || SameNode(limbo, newsrv)) {
      TRACE(rinvoke, 1, ("Have stub, but points back.  Forwarding to limbo"));
      RewindStream(str);
      newstr = StealStream(str);
      findAndSendTo(h->target, newstr);
    } else {
      TRACE(rinvoke, 1, ("Forwarding invoke to %s", NodeString(newsrv)));
      if (forwardMsg(newsrv, h, str) < 0) {
	RewindStream(str);
	newstr = StealStream(str);
	findAndSendTo(h->target, newstr);
      }
    }
  } else if (fakeUnavailable && ((random() % 100) < fakeUnavailable)) {
    newstr = StealStream(str);
    sendUnavailableReply(newstr);
  } else {
    OID oid;
    state = newState(obj, ct);
    OIDRemoveAny((Object)state);
    ReadOID(&oid, str);
    OIDInsert(oid, (Object) state);
    for (sp = (int *)state->sb, i = 0 ; i < 2 * retc ; i++) *sp++ = JNIL;
    extractNVars(str, argc, sp, &state->ep, &state->et, srv);
    sp += argc * 2;
    TRACE(rinvoke, 4, ("Doing upcall on a %.*s",
		       CODEPTR(obj->flags)->d.name->d.items, 
		       CODEPTR(obj->flags)->d.name->d.data));
    state->sp = (u32)sp;
    pushBottomAR(state);

    /* set up the interpreter state */
    state->pc = (u32) ct->d.opVector->d.data[fn]->d.code->d.data;
    dependsOn(state, stateFetch(h->ss, h->sslocation), retc);
    makeReady(state);
  }
  inhibit_gc--;
}
Пример #4
0
void handleInvokeReply(RemoteOpHeader *h, Node srv, Stream str)
{
  State *state;

  anticipateGC(64 * 1024 + 2 * StreamLength(str));
  state = (State *)OIDFetch(h->ss);
  if (ISNIL(state) || !RESDNT(state->firstThing)) {
    /*
     * We probably gc'd this state because we couldn't find any references
     * to it.  Find it and send it this reply.
     */
    Stream newstr;
    RewindStream(str);
    newstr = StealStream(str);
    findAndSendTo(h->ss, newstr);
  } else {
    TRACE(rinvoke, 3, ("InvokeReply received"));

    assert(!ISNIL(state));
    assert(RESDNT(state->firstThing));
    assert(ISetMember(allProcesses, (int)state));

    TRACE(process, 5, ("Resetting nsoid in state %#x", state));
    state->nsoid = nooid;
    state->nstoid = nooid;
    if (h->status) {
      TRACE(rinvoke, 0, ("Obsolete remote invocation return code"));
      h->option1 = 2;
    }
    if (h->option1) {
      /*
       * We are supposed to propagate a failure.
       */
      TRACE(rinvoke, 1, ("Remote invocation raised %s",
			 h->option1 == 1 ? "failure" :
			 h->option1 == 2 ? "unavailable" :
			 "unknown"));
      if (!findHandler(state, h->option1 - 1, (Object)JNIL)) {
	if (!debugInteractively) {
	  state = processDone(state, h->option1);
	} else {
	  char buf[80];
	  sprintf(buf, "Remote invocation raised %s",
		  h->option1 == 1 ? "failure" :
		  h->option1 == 2 ? "unavailable" :
		  "unknown");
	  if (debug(state, buf)) {
	    /*
	     * debug returns 1 when we shouldn't run the state no more.
	     */
	    state = 0;
	  }
	}
      }
      if (state) makeReady(state);
    } else if (RESDNT(state->op->flags) &&
	       BROKEN(state->op->flags) && isBroken(state->op)) {
      if (returnToBrokenObject(state)) {
	/* nothing to do */
      } else {
	makeReady(state);
      }
    } else {
      extractNVars(str, -1, (int *)state->sp, &state->ep, &state->et, srv);
      makeReady(state);
    }
  }
  TRACE(rinvoke, 4, ("Invoke return handled"));
  inhibit_gc--;
}
void
SoundD3D::Update()
{
	if (!buffer || status != PLAYING) return; // nothing to do

	DWORD dstat;
	HRESULT hr = buffer->GetStatus(&dstat);
	if (FAILED(hr)) {
		SoundD3DError("Update: GetStatus failed", hr);
		return;
	}

	AutoThreadSync a(sync);

	if (sound_check) sound_check->Update(this);

	if (!Game::Paused() || flags & STREAMED) {
		// see if we are done:
		if (!(dstat & DSBSTATUS_PLAYING)) {
			status = DONE;
			buffer->Stop();
			return;
		}

		// if not done, see if we need to change location params:
		if (moved) {
			Localize();
		}
	}

	// if not done, see if we need to load more data
	// into the streaming buffer:
	if (flags & STREAMED) {
		buffer->GetCurrentPosition(&r, 0);
		
		DWORD data_left;
		if (w > r)
		data_left = w - r;
		else
		data_left = w + (read_size + min_safety) - r;

		// getting low, fill 'er up:
		if (eos_written || data_left <= min_safety) {
			StreamBlock();

			if (stream_left == 0) {
				// if this is the end of a looping stream,
				if (flags & LOOP) {
					RewindStream();
					looped++;
				}
				else {
					if (!eos_written) {
						eos_written = true;
						eos_latch   = 3;
					}

					else if (--eos_latch == 0) {
						status = DONE;
						buffer->Stop();
					}
				}
			}

			status = PLAYING;
		}
	}
}