void Player_SID::releaseResChannels(int resIndex) { // $5070 for (int i = 3; i >= 0; --i) { if (resIndex == channelMap[i]) { releaseChannel(i); } } }
void WebSocket::stop() { m_eventQueue->stop(); if (m_channel) { m_channel->close(WebSocketChannel::CloseEventCodeGoingAway, String()); releaseChannel(); } m_state = CLOSED; }
void WebSocket::didClose(unsigned long unhandledBufferedAmount, ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) { WTF_LOG(Network, "WebSocket %p didClose()", this); if (!m_channel) return; bool wasClean = m_state == CLOSING && !unhandledBufferedAmount && closingHandshakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEventCodeAbnormalClosure; m_state = CLOSED; m_bufferedAmount = unhandledBufferedAmount; m_eventQueue->dispatch(CloseEvent::create(wasClean, code, reason)); releaseChannel(); }
void Player_SID::resetPlayerState() { // $48f7 for (int i = 6; i >= 0; --i) releaseChannel(i); isMusicPlaying = false; unlockCodeLocation(); // does nothing statusBits1B = 0; statusBits1A = 0; freeChannelCount = 3; swapPrepared = false; filterSwapped = false; pulseWidthSwapped = false; //var5163 = 0; }
void Player_SID::readSongChunk(int channel) { // $4a6b while (true) { if (setupSongPtr(channel) == 1) { // do something with code resource releaseResourceUnk(1); return; } uint8* ptr1 = songPosPtr[channel]; //curChannelActive = true; uint8 l_cmdByte = ptr1[0]; if (l_cmdByte == 0) { //curChannelActive = false; songPosUpdateCounter[channel] = 0; var481A = -1; releaseChannel(channel); return; } //vec19[channel] = l_cmdByte; // attack (1) / release (0) phase if (isVoiceChannel) { if (GETBIT(l_cmdByte, 0)) waveCtrlReg[channel] |= 0x01; // start attack phase else waveCtrlReg[channel] &= 0xfe; // start release phase } // channel finished bit if (GETBIT(l_cmdByte, 1)) { var481A = -1; releaseChannel(channel); return; } int y = 0; // frequency if (GETBIT(l_cmdByte, 2)) { y += 2; freqReg[channel] = READ_LE_UINT16(&ptr1[y-1]); if (!GETBIT(l_cmdByte, 6)) { y += 2; freqDeltaCounter[channel] = READ_LE_UINT16(&ptr1[y-1]); y += 2; freqDelta[channel] = READ_LE_UINT16(&ptr1[y-1]); } else { resetFreqDelta(channel); } } else { resetFreqDelta(channel); } // attack / release if (isVoiceChannel && GETBIT(l_cmdByte, 3)) { // start release phase waveCtrlReg[channel] &= 0xfe; setSIDWaveCtrlReg(channel); ++y; attackReg[channel] = ptr1[y]; ++y; sustainReg[channel] = ptr1[y]; // set attack (1) or release (0) phase waveCtrlReg[channel] |= (l_cmdByte & 0x01); } if (GETBIT(l_cmdByte, 4)) { ++y; uint8 curByte = ptr1[y]; // pulse width if (isVoiceChannel && GETBIT(curByte, 0)) { int reg = SID_REG_OFFSET[channel+4]; y += 2; SID_Write(reg, ptr1[y-1]); SID_Write(reg+1, ptr1[y]); } if (GETBIT(curByte, 1)) { ++y; readSetSIDFilterAndProps(&y, ptr1); y += 2; SID_Write(21, ptr1[y-1]); SID_Write(22, ptr1[y]); } if (GETBIT(curByte, 2)) { resetFreqDelta(channel); y += 2; freqDeltaCounter[channel] = READ_LE_UINT16(&ptr1[y-1]); } } // set waveform (?) if (GETBIT(l_cmdByte, 5)) { ++y; waveCtrlReg[channel] = (waveCtrlReg[channel] & 0x0f) | ptr1[y]; } // song position if (GETBIT(l_cmdByte, 7)) { if (songPosUpdateCounter[channel] == 1) { y += 2; --songPosUpdateCounter[channel]; saveSongPos(y, channel); } else { // looping / skipping / ... ++y; songPosPtr[channel] -= ptr1[y]; songFileOrChanBufOffset[channel] -= ptr1[y]; ++y; if (songPosUpdateCounter[channel] == 0) { songPosUpdateCounter[channel] = ptr1[y]; } else { --songPosUpdateCounter[channel]; } } } else { saveSongPos(y, channel); return; } } }
void WebSocket::connect(const String& url, const Vector<String>& protocols, ExceptionState& exceptionState) { WTF_LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data()); m_url = KURL(KURL(), url); if (!m_url.isValid()) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL '" + url + "' is invalid."); return; } if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL's scheme must be either 'ws' or 'wss'. '" + m_url.protocol() + "' is not allowed."); return; } if (MixedContentChecker::isMixedContent(executionContext()->securityOrigin(), m_url)) { // FIXME: Throw an exception and close the connection. String message = "Connecting to a non-secure WebSocket server from a secure origin is deprecated."; executionContext()->addConsoleMessage(JSMessageSource, WarningMessageLevel, message); } if (m_url.hasFragmentIdentifier()) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL contains a fragment identifier ('" + m_url.fragmentIdentifier() + "'). Fragment identifiers are not allowed in WebSocket URLs."); return; } if (!portAllowed(m_url)) { m_state = CLOSED; exceptionState.throwSecurityError("The port " + String::number(m_url.port()) + " is not allowed."); return; } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. bool shouldBypassMainWorldContentSecurityPolicy = false; if (executionContext()->isDocument()) { Document* document = toDocument(executionContext()); shouldBypassMainWorldContentSecurityPolicy = document->frame()->script().shouldBypassMainWorldContentSecurityPolicy(); } if (!shouldBypassMainWorldContentSecurityPolicy && !executionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { m_state = CLOSED; // The URL is safe to expose to JavaScript, as this check happens synchronously before redirection. exceptionState.throwSecurityError("Refused to connect to '" + m_url.elidedString() + "' because it violates the document's Content Security Policy."); return; } m_channel = WebSocketChannel::create(executionContext(), this); // FIXME: There is a disagreement about restriction of subprotocols between WebSocket API and hybi-10 protocol // draft. The former simply says "only characters in the range U+0021 to U+007E are allowed," while the latter // imposes a stricter rule: "the elements MUST be non-empty strings with characters as defined in [RFC2616], // and MUST all be unique strings." // // Here, we throw SyntaxError if the given protocols do not meet the latter criteria. This behavior does not // comply with WebSocket API specification, but it seems to be the only reasonable way to handle this conflict. for (size_t i = 0; i < protocols.size(); ++i) { if (!isValidProtocolString(protocols[i])) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The subprotocol '" + encodeProtocolString(protocols[i]) + "' is invalid."); releaseChannel(); return; } } HashSet<String> visited; for (size_t i = 0; i < protocols.size(); ++i) { if (!visited.add(protocols[i]).isNewEntry) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The subprotocol '" + encodeProtocolString(protocols[i]) + "' is duplicated."); releaseChannel(); return; } } String protocolString; if (!protocols.isEmpty()) protocolString = joinStrings(protocols, subProtocolSeperator()); m_channel->connect(m_url, protocolString); }
void WebSocket::connect(const String& url, const Vector<String>& protocols, ExceptionState& exceptionState) { WTF_LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data()); m_url = KURL(KURL(), url); if (!m_url.isValid()) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL '" + url + "' is invalid."); return; } if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL's scheme must be either 'ws' or 'wss'. '" + m_url.protocol() + "' is not allowed."); return; } if (m_url.hasFragmentIdentifier()) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The URL contains a fragment identifier ('" + m_url.fragmentIdentifier() + "'). Fragment identifiers are not allowed in WebSocket URLs."); return; } if (!portAllowed(m_url)) { m_state = CLOSED; exceptionState.throwSecurityError("The port " + String::number(m_url.port()) + " is not allowed."); return; } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. bool shouldBypassMainWorldContentSecurityPolicy = false; if (executionContext()->isDocument()) { Document* document = toDocument(executionContext()); shouldBypassMainWorldContentSecurityPolicy = document->frame()->script().shouldBypassMainWorldContentSecurityPolicy(); } if (!shouldBypassMainWorldContentSecurityPolicy && !executionContext()->contentSecurityPolicy()->allowConnectToSource(m_url)) { m_state = CLOSED; // The URL is safe to expose to JavaScript, as this check happens synchronously before redirection. exceptionState.throwSecurityError("Refused to connect to '" + m_url.elidedString() + "' because it violates the document's Content Security Policy."); return; } m_channel = createChannel(executionContext(), this); for (size_t i = 0; i < protocols.size(); ++i) { if (!isValidSubprotocolString(protocols[i])) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The subprotocol '" + encodeSubprotocolString(protocols[i]) + "' is invalid."); releaseChannel(); return; } } HashSet<String> visited; for (size_t i = 0; i < protocols.size(); ++i) { if (!visited.add(protocols[i]).isNewEntry) { m_state = CLOSED; exceptionState.throwDOMException(SyntaxError, "The subprotocol '" + encodeSubprotocolString(protocols[i]) + "' is duplicated."); releaseChannel(); return; } } String protocolString; if (!protocols.isEmpty()) protocolString = joinStrings(protocols, subprotocolSeperator()); if (!m_channel->connect(m_url, protocolString)) { m_state = CLOSED; exceptionState.throwSecurityError("An insecure WebSocket connection may not be initiated from a page loaded over HTTPS."); releaseChannel(); return; } }