void PacketReceiver::createFrames() { frameReceived = avcodec_alloc_frame(); // av_frame_alloc() frameBGR = avcodec_alloc_frame(); // av_frame_alloc() if (frameReceived == NULL || frameBGR == NULL) { exit(); throw NotEnoughSpaceException(); } int numBytes = avpicture_get_size(FRAME_FORMAT_CV, codecCtx->width, codecCtx->height); frameBGRBuffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t)); if (frameBGRBuffer == NULL) { exit(); throw NotEnoughSpaceException(); } int error = avpicture_fill((AVPicture *) frameBGR, frameBGRBuffer, FRAME_FORMAT_CV, codecCtx->width, codecCtx->height); if (error < 0) { exit(); throw KasinoException(avErr2Str(error)); } }
void MetatileStructureSet::exportToROM(WritableROM& rom) { // TODO: support for adding metatile definitions // search freespace &c FreeSpaceList::iterator spaceIt = rom.freeSpace().getFreeSpace( exportSize()); if (spaceIt == rom.freeSpace().freeSpaceList().end()) { throw NotEnoughSpaceException(TALES_SRCANDLINE, "MetatileStructureSet::exportToROM(" "WritableROM&)", exportSize()); } int writeAddress = spaceIt->address(); address_ = spaceIt->address(); rom.freeSpace().claimSpace(spaceIt, exportSize()); // std::cout << "addr: " << writeAddress << std::endl; // Starting address of structure definitions int contentStartAddress = writeAddress + (index_.size() * ByteSizes::uint16Size); // Write the index for (MetatileIndexToStructureMap::iterator it = index_.begin(); it != index_.end(); it++) { int contentIndex = it->second; // Compute the address of the content Taddress contentAddress = (contentStartAddress + (contentIndex * MetatileStructure::dataSize)); // Convert to banked address Taddress contentBankedAddress = LoadedROM ::directToBankedAddress(contentAddress); // Write to index Tbyte buffer[ByteSizes::uint16Size]; ByteConversion::toBytes(contentBankedAddress, buffer, ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); rom.directWrite(writeAddress + (it->first * ByteSizes::uint16Size), buffer, ByteSizes::uint16Size); } // Write content int metatileNum = 0; for (MetatileStructureCollection::iterator it = primaryStorage_.begin(); it != primaryStorage_.end(); it++) { // Write metatile to buffer Tbyte buffer[MetatileStructure::dataSize]; it->writeToData(buffer); // Write buffer to table rom.directWrite(contentStartAddress + (metatileNum * MetatileStructure::dataSize), buffer, MetatileStructure::dataSize); ++metatileNum; } // std::cout << "metatiles: " << metatileNum << std::endl; // std::cout << std::endl; }
Taddress EditableLevelObjectEntryGroups::moveToNewBank(WritableROM& rom) { // std::cout << "Preparing to move to new bank" << std::endl; // More for convenience than anything else, we grab a whole bank of data // for use by this table (and a few bits of associated code). // Note that this basically requires expanding the ROM to 1 MB FreeSpaceList::iterator spaceIt = rom.freeSpace().getFreeSpace(LoadedROM::bankSize); // Throw if a full bank isn't available if (spaceIt == rom.freeSpace().freeSpaceList().end()) { throw NotEnoughSpaceException(TALES_SRCANDLINE, "EditableLevelObjectEntryGroups::" "exportToROM(WritableROM&)", LoadedROM::bankSize); } // std::cout << spaceIt->address() << " " << spaceIt->length() << std::endl; Taddress newBaseAddress = spaceIt->address(); // Claim the bank rom.freeSpace().claimSpace(spaceIt, LoadedROM::bankSize); // std::cout << "New base address: " << newBaseAddress << std::endl; // Copy code segments C1 and C3 to new bank. // C1 and C3 both contain code that references the object table, // so they must (to avoid more complicated hacking) be in the same bank. // After rearranging the code, the new bank will contain C1, C3, and // the object table, in that order, starting from the beginning of the // bank // Copy C1 to start of bank Taddress newC1Address = newBaseAddress; std::memcpy(rom.directWrite(newC1Address), codeSegmentC1, lengthOfC1Segment); // Copy C3 to directly after C1 Taddress newC3Address = newC1Address + lengthOfC1Segment; std::memcpy(rom.directWrite(newC3Address), codeSegmentC3, lengthOfC3Segment); // Set new export address for table (directly after C3) int exportAddress = newBaseAddress + lengthOfC1Segment + lengthOfC3Segment; // std::cout << "New C1 address: " << newC1Address << std::endl; // std::cout << "New C3 address: " << newC3Address << std::endl; // std::cout << "Export address: " << exportAddress << std::endl; // Update all the code that references the old locations of C1 and C3 // Get the banked address for the new direct address of C1 int newC1BankNum = LoadedROM::directToBankNum(newC1Address); int newC1BankedAddress = LoadedROM::directToBankedAddress(newC1Address); // Get the banked address for the new direct address of C3 int newC3BankNum = LoadedROM::directToBankNum(newC3Address); int newC3BankedAddress = LoadedROM::directToBankedAddress(newC3Address); // Update bank number in code that calls C1 ByteConversion::toBytes(newC1BankNum, rom.directWrite(callReferenceToC1Bank), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); // C1's banked address is the same (0000), so we don't need to update it // ... but do anyway for consistency ByteConversion::toBytes(newC1BankedAddress, rom.directWrite(callReferenceToC1Address), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Update banked address in code that calls C3 ByteConversion::toBytes(newC3BankNum, rom.directWrite(callReferenceToC3Bank), ByteSizes::uint8Size, EndiannessTypes::little, SignednessTypes::nosign); // Update bank number in code that calls C3. ByteConversion::toBytes(newC3BankedAddress, rom.directWrite(callReferenceToC3Address), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // C3 contains a hardcoded JP instruction into itself. Since we moved // C3, we have to update the JP to correspond to the new location. // Get new address of the JP instruction's address parameter Taddress addressOfNewJpParameter = newC3Address + offsetOfJpInC3; // Get new address of the JP instruction's jump point base Taddress addressOfNewJpBase = newC3Address + baseOffsetOfJpInC3; // Compute the new target address Taddress newJpTargetAddress = addressOfNewJpBase - absoluteLengthOfJpInC3; // std::cout << "New JP target: " << newJpTargetAddress << std::endl; // Convert to banked form Taddress newJpTargetBankedAddress = LoadedROM::directToBankedAddress(newJpTargetAddress); // Write the new target address to the JP parameter ByteConversion::toBytes(newJpTargetBankedAddress, rom.directWrite(addressOfNewJpParameter), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Get the banked address for the new direct address of the object table // int newTableBankNum // = LoadedROM::directToBankNum(exportAddress); int newTableBankedAddress = LoadedROM::directToBankedAddress(exportAddress); // Update C1 to refer to the new location of the object table ByteConversion::toBytes(newTableBankedAddress, rom.directWrite(newC1Address + offsetOfTableReferenceInC1), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Update C3 to refer to the new location of the object table ByteConversion::toBytes(newTableBankedAddress, rom.directWrite(newC3Address + offsetOfTableReferenceInC3), ByteSizes::uint16Size, EndiannessTypes::little, SignednessTypes::nosign); // Update table information // initialTableAddress_ = exportAddress; // initialTableContentSize_ = spaceIt->length() // - exportAddress // - tableHeaderSize_; // initialTableContentSize_ = exportAddress - spaceIt->address() // - tableHeaderSize_; // initialTableContentSize_ = LoadedROM::bankSize; // std::cout << initialTableContentSize_ << std::endl; // Mark that we've moved to a new bank movedToNewBank_ = true; return exportAddress; }
void PacketReceiver::threadFunc() { init(); mainWindow->log("Empfange Pakete…"); int error; int gotPicture = 0; AVPacket packet; while (!quit) { try { packet = { 0 }; av_init_packet(&packet); error = av_read_frame(formatCtx, &packet); if (error < 0) { throw KasinoException(avErr2Str(error)); } if (packet.stream_index == videoStreamNr) { error = avcodec_decode_video2(codecCtx, frameReceived, &gotPicture, &packet); if (error < 0) { throw KasinoException(avErr2Str(error)); } if (gotPicture != 0) { sws_scale(imgConverter, ((AVPicture*)frameReceived)->data, ((AVPicture*)frameReceived)->linesize, 0, codecCtx->height, ((AVPicture *)frameBGR)->data, ((AVPicture *)frameBGR)->linesize); cv::Mat imgCv; frame2mat(*frameBGR, imgCv); Frame* frame = new Frame(imgCv); if (frame == NULL) { throw NotEnoughSpaceException(); } frame->pts = frameReceived->pkt_pts; // todo welchen Wert hier reinziehen? frame->quali = stream.getQuali(); push(frame); } } } catch(KasinoException& e) { mainWindow->log(e.what(), ERROR); } av_free_packet(&packet); } }