Custom Bootloader, Robot still broken
This commit is contained in:
@@ -20,6 +20,7 @@ public final class Blocks {
|
||||
public static final RegistryObject<ComputerBlock> COMPUTER = BLOCKS.register("computer", ComputerBlock::new);
|
||||
public static final RegistryObject<CreativeEnergyBlock> CREATIVE_ENERGY = BLOCKS.register("creative_energy", CreativeEnergyBlock::new);
|
||||
public static final RegistryObject<DiskDriveBlock> DISK_DRIVE = BLOCKS.register("disk_drive", DiskDriveBlock::new);
|
||||
public static final RegistryObject<FlashMemoryFlasherBlock> FLASH_MEMORY_FLASHER = BLOCKS.register("flash_memory_flasher", FlashMemoryFlasherBlock::new);
|
||||
public static final RegistryObject<KeyboardBlock> KEYBOARD = BLOCKS.register("keyboard", KeyboardBlock::new);
|
||||
public static final RegistryObject<NetworkConnectorBlock> NETWORK_CONNECTOR = BLOCKS.register("network_connector", NetworkConnectorBlock::new);
|
||||
public static final RegistryObject<NetworkHubBlock> NETWORK_HUB = BLOCKS.register("network_hub", NetworkHubBlock::new);
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
package li.cil.oc2.common.block;
|
||||
|
||||
import li.cil.oc2.common.blockentity.BlockEntities;
|
||||
import li.cil.oc2.common.blockentity.DiskDriveBlockEntity;
|
||||
import li.cil.oc2.common.blockentity.FlashMemoryFlasherBlockEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class FlashMemoryFlasherBlock extends HorizontalDirectionalBlock implements EntityBlock {
|
||||
public FlashMemoryFlasherBlock() {
|
||||
super(Properties
|
||||
.of(Material.METAL)
|
||||
.sound(SoundType.METAL)
|
||||
.strength(1.5f, 6.0f));
|
||||
registerDefaultState(getStateDefinition().any().setValue(FACING, Direction.NORTH));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(final BlockPlaceContext context) {
|
||||
return super.defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public InteractionResult use(final BlockState state, final Level level, final BlockPos pos, final Player player, final InteractionHand hand, final BlockHitResult hit) {
|
||||
final BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||
if (!(blockEntity instanceof final FlashMemoryFlasherBlockEntity diskDrive)) {
|
||||
return super.use(state, level, pos, player, hand, hit);
|
||||
}
|
||||
|
||||
final ItemStack heldStack = player.getItemInHand(hand);
|
||||
if (player.isShiftKeyDown()) {
|
||||
if (diskDrive.canEject()) {
|
||||
if (!level.isClientSide()) {
|
||||
diskDrive.eject(player);
|
||||
}
|
||||
return InteractionResult.sidedSuccess(level.isClientSide());
|
||||
}
|
||||
} else {
|
||||
if (diskDrive.canInsert(heldStack)) {
|
||||
if (!level.isClientSide()) {
|
||||
player.setItemInHand(hand, diskDrive.insert(heldStack, player));
|
||||
}
|
||||
return InteractionResult.sidedSuccess(level.isClientSide());
|
||||
}
|
||||
}
|
||||
|
||||
return super.use(state, level, pos, player, hand, hit);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// EntityBlock
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(final BlockPos pos, final BlockState state) {
|
||||
return BlockEntities.FLASH_MEMORY_FLASHER.get().create(pos, state);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> builder) {
|
||||
super.createBlockStateDefinition(builder);
|
||||
builder.add(FACING);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ public final class BlockEntities {
|
||||
public static final RegistryObject<BlockEntityType<ComputerBlockEntity>> COMPUTER = register(Blocks.COMPUTER, ComputerBlockEntity::new);
|
||||
public static final RegistryObject<BlockEntityType<CreativeEnergyBlockEntity>> CREATIVE_ENERGY = register(Blocks.CREATIVE_ENERGY, CreativeEnergyBlockEntity::new);
|
||||
public static final RegistryObject<BlockEntityType<DiskDriveBlockEntity>> DISK_DRIVE = register(Blocks.DISK_DRIVE, DiskDriveBlockEntity::new);
|
||||
public static final RegistryObject<BlockEntityType<FlashMemoryFlasherBlockEntity>> FLASH_MEMORY_FLASHER = register(Blocks.FLASH_MEMORY_FLASHER, FlashMemoryFlasherBlockEntity::new);
|
||||
public static final RegistryObject<BlockEntityType<KeyboardBlockEntity>> KEYBOARD = register(Blocks.KEYBOARD, KeyboardBlockEntity::new);
|
||||
public static final RegistryObject<BlockEntityType<NetworkConnectorBlockEntity>> NETWORK_CONNECTOR = register(Blocks.NETWORK_CONNECTOR, NetworkConnectorBlockEntity::new);
|
||||
public static final RegistryObject<BlockEntityType<NetworkHubBlockEntity>> NETWORK_HUB = register(Blocks.NETWORK_HUB, NetworkHubBlockEntity::new);
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
package li.cil.oc2.common.blockentity;
|
||||
|
||||
import li.cil.oc2.common.Constants;
|
||||
import li.cil.oc2.common.block.DiskDriveBlock;
|
||||
import li.cil.oc2.common.block.FlashMemoryFlasherBlock;
|
||||
import li.cil.oc2.common.bus.device.vm.block.FlashMemoryFlasherContainer;
|
||||
import li.cil.oc2.common.bus.device.vm.block.FlashMemoryFlasherDevice;
|
||||
import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import li.cil.oc2.common.container.TypedItemStackHandler;
|
||||
import li.cil.oc2.common.network.Network;
|
||||
import li.cil.oc2.common.network.message.DiskDriveFloppyMessage;
|
||||
import li.cil.oc2.common.network.message.FirmwareFlasherMessage;
|
||||
import li.cil.oc2.common.tags.ItemTags;
|
||||
import li.cil.oc2.common.util.ItemStackUtils;
|
||||
import li.cil.oc2.common.util.LocationSupplierUtils;
|
||||
import li.cil.oc2.common.util.SoundEvents;
|
||||
import li.cil.oc2.common.util.ThrottledSoundEmitter;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.time.Duration;
|
||||
|
||||
public final class FlashMemoryFlasherBlockEntity extends ModBlockEntity implements FlashMemoryFlasherContainer {
|
||||
private static final String DATA_TAG_NAME = "data";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final FlashMemoryItemStackHandler itemHandler = new FlashMemoryItemStackHandler();
|
||||
private final FlashMemoryFlasherDevice<FlashMemoryFlasherBlockEntity> device = new FlashMemoryFlasherDevice<>(this);
|
||||
private final ThrottledSoundEmitter accessSoundEmitter;
|
||||
private final ThrottledSoundEmitter insertSoundEmitter;
|
||||
private final ThrottledSoundEmitter ejectSoundEmitter;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public FlashMemoryFlasherBlockEntity(final BlockPos pos, final BlockState state) {
|
||||
super(BlockEntities.FLASH_MEMORY_FLASHER.get(), pos, state);
|
||||
|
||||
this.accessSoundEmitter = new ThrottledSoundEmitter(LocationSupplierUtils.of(this),
|
||||
SoundEvents.FLOPPY_ACCESS.get()).withMinInterval(Duration.ofSeconds(1));
|
||||
this.insertSoundEmitter = new ThrottledSoundEmitter(LocationSupplierUtils.of(this),
|
||||
SoundEvents.FLOPPY_INSERT.get()).withMinInterval(Duration.ofMillis(100));
|
||||
this.ejectSoundEmitter = new ThrottledSoundEmitter(LocationSupplierUtils.of(this),
|
||||
SoundEvents.FLOPPY_EJECT.get()).withMinInterval(Duration.ofMillis(100));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean canInsert(final ItemStack stack) {
|
||||
return !stack.isEmpty() && stack.is(ItemTags.DEVICES_FLASH_MEMORY);
|
||||
}
|
||||
|
||||
public ItemStack insert(final ItemStack stack, @Nullable final Player player) {
|
||||
if (!canInsert(stack)) {
|
||||
return stack;
|
||||
}
|
||||
|
||||
eject(player);
|
||||
|
||||
insertSoundEmitter.play();
|
||||
return itemHandler.insertItem(0, stack, false);
|
||||
}
|
||||
|
||||
public boolean canEject() {
|
||||
return !itemHandler.extractItem(0, 1, true).isEmpty();
|
||||
}
|
||||
|
||||
public void eject(@Nullable final Player player) {
|
||||
if (level == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack stack = itemHandler.extractItem(0, 1, false);
|
||||
if (!stack.isEmpty()) {
|
||||
final Direction facing = getBlockState().getValue(FlashMemoryFlasherBlock.FACING);
|
||||
ejectSoundEmitter.play();
|
||||
ItemStackUtils.spawnAsEntity(level, getBlockPos().relative(facing), stack, facing).ifPresent(entity -> {
|
||||
if (player != null) {
|
||||
entity.setNoPickUpDelay();
|
||||
entity.setOwner(player.getUUID());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ItemStack getFloppy() {
|
||||
return itemHandler.getStackInSlot(0);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void setFloppyClient(final ItemStack stack) {
|
||||
itemHandler.setStackInSlot(0, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void collectCapabilities(final CapabilityCollector collector, @Nullable final Direction direction) {
|
||||
collector.offer(Capabilities.itemHandler(), itemHandler);
|
||||
|
||||
if (direction == getBlockState().getValue(FlashMemoryFlasherBlock.FACING).getOpposite()) {
|
||||
collector.offer(Capabilities.device(), device);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getUpdateTag() {
|
||||
final CompoundTag tag = super.getUpdateTag();
|
||||
tag.put(Constants.ITEMS_TAG_NAME, itemHandler.serializeNBT());
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUpdateTag(final CompoundTag tag) {
|
||||
super.handleUpdateTag(tag);
|
||||
itemHandler.deserializeNBT(tag.getCompound(Constants.ITEMS_TAG_NAME));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveAdditional(final CompoundTag tag) {
|
||||
super.saveAdditional(tag);
|
||||
|
||||
tag.put(Constants.ITEMS_TAG_NAME, itemHandler.serializeNBT());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(final CompoundTag tag) {
|
||||
super.load(tag);
|
||||
|
||||
itemHandler.deserializeNBT(tag.getCompound(Constants.ITEMS_TAG_NAME));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getDiskItemStack() {
|
||||
return itemHandler.getStackInSlotRaw(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDataAccess() {
|
||||
accessSoundEmitter.play();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final class FlashMemoryItemStackHandler extends TypedItemStackHandler {
|
||||
public FlashMemoryItemStackHandler() {
|
||||
super(1, ItemTags.DEVICES_FLASH_MEMORY);
|
||||
}
|
||||
|
||||
public ItemStack getStackInSlotRaw(final int slot) {
|
||||
return super.getStackInSlot(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemStack getStackInSlot(final int slot) {
|
||||
final ItemStack stack = getStackInSlotRaw(slot);
|
||||
exportDeviceDataToItemStack(stack);
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemStack extractItem(final int slot, final int amount, final boolean simulate) {
|
||||
if (slot == 0 && !simulate && amount > 0) {
|
||||
exportDeviceDataToItemStack(getStackInSlotRaw(0));
|
||||
}
|
||||
|
||||
return super.extractItem(slot, amount, simulate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(final int slot) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag serializeNBT() {
|
||||
exportDeviceDataToItemStack(getStackInSlotRaw(0));
|
||||
return super.serializeNBT();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContentsChanged(final int slot) {
|
||||
super.onContentsChanged(slot);
|
||||
|
||||
if (level == null || level.isClientSide()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack stack = getStackInSlotRaw(slot);
|
||||
if (stack.isEmpty()) {
|
||||
device.removeBlockDevice();
|
||||
} else {
|
||||
final CompoundTag tag = ItemStackUtils.getOrCreateModDataTag(stack).getCompound(DATA_TAG_NAME);
|
||||
device.updateBlockDevice(tag);
|
||||
}
|
||||
|
||||
Network.sendToClientsTrackingBlockEntity(new FirmwareFlasherMessage(FlashMemoryFlasherBlockEntity.this), FlashMemoryFlasherBlockEntity.this);
|
||||
|
||||
setChanged();
|
||||
}
|
||||
|
||||
private void exportDeviceDataToItemStack(final ItemStack stack) {
|
||||
if (stack.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (level == null || level.isClientSide()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
device.exportToItemStack(tag);
|
||||
ItemStackUtils.getOrCreateModDataTag(stack).put(DATA_TAG_NAME, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import net.minecraftforge.registries.RegistryObject;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class BlockDeviceDataRegistry {
|
||||
@@ -36,7 +37,11 @@ public final class BlockDeviceDataRegistry {
|
||||
|
||||
@Nullable
|
||||
public static ResourceLocation getKey(final BlockDeviceData data) {
|
||||
return INITIALIZER.getRegistryName();
|
||||
ResourceLocation location = REGISTRY.get().getKey(data);
|
||||
if (location == null) {
|
||||
location = FileSystems.getKeyByValue(data);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -3,18 +3,22 @@
|
||||
package li.cil.oc2.common.bus.device.data;
|
||||
|
||||
import li.cil.oc2.api.bus.device.data.Firmware;
|
||||
import li.cil.sedna.api.Sizes;
|
||||
import li.cil.sedna.api.memory.MemoryMap;
|
||||
import li.cil.sedna.elf.*;
|
||||
import li.cil.sedna.buildroot.Buildroot;
|
||||
import li.cil.sedna.memory.MemoryMaps;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public final class BuildrootFirmware implements Firmware {
|
||||
@Override
|
||||
public boolean run(final MemoryMap memory, final long startAddress) {
|
||||
try {
|
||||
MemoryMaps.store(memory, startAddress, Buildroot.getFirmware());
|
||||
//MemoryMaps.store(memory, startAddress + 0x200000, BuildrootFirmware.class.getClassLoader().getResourceAsStream("generated/ociivrkernel.bin"));
|
||||
MemoryMaps.store(memory, startAddress + 0x200000, Buildroot.getLinuxImage());
|
||||
return true;
|
||||
} catch (final IOException e) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraftforge.event.AddReloadListenerEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppedEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
@@ -43,6 +44,15 @@ public final class FileSystems {
|
||||
return LAYERED_FILE_SYSTEM;
|
||||
}
|
||||
|
||||
public static ResourceLocation getKeyByValue(BlockDeviceData value) {
|
||||
for (Map.Entry<ResourceLocation, BlockDeviceData> entry : BLOCK_DEVICE_DATA.entrySet()) {
|
||||
if (Objects.equals(value, entry.getValue())) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Map<ResourceLocation, BlockDeviceData> getBlockData() {
|
||||
return BLOCK_DEVICE_DATA;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
package li.cil.oc2.common.bus.device.vm.block;
|
||||
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public interface FlashMemoryFlasherContainer {
|
||||
ItemStack getDiskItemStack();
|
||||
|
||||
void handleDataAccess();
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
package li.cil.oc2.common.bus.device.vm.block;
|
||||
|
||||
import li.cil.oc2.common.bus.device.vm.item.AbstractBlockStorageDevice;
|
||||
import li.cil.oc2.common.item.FlashMemoryItem;
|
||||
import li.cil.oc2.common.item.FloppyItem;
|
||||
import li.cil.oc2.common.serialization.BlobStorage;
|
||||
import li.cil.sedna.api.device.BlockDevice;
|
||||
import li.cil.sedna.device.block.ByteBufferBlockDevice;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public final class FlashMemoryFlasherDevice<T extends BlockEntity & FlashMemoryFlasherContainer> extends AbstractBlockStorageDevice<BlockDevice, T> {
|
||||
private static final ByteBufferBlockDevice EMPTY_BLOCK_DEVICE = ByteBufferBlockDevice.create(0, false);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
public FlashMemoryFlasherDevice(final T container) {
|
||||
super(container, false);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
public void updateBlockDevice(final CompoundTag tag) {
|
||||
joinOpenJob();
|
||||
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
device.setBlock(EMPTY_BLOCK_DEVICE);
|
||||
} catch (final IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
||||
if (blobHandle != null) {
|
||||
BlobStorage.close(blobHandle);
|
||||
blobHandle = null;
|
||||
}
|
||||
|
||||
importFromItemStack(tag);
|
||||
|
||||
setOpenJob(createBlockDevice().thenAcceptAsync(blockDevice -> {
|
||||
try {
|
||||
device.setBlock(blockDevice);
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}, WORKERS));
|
||||
}
|
||||
|
||||
public void removeBlockDevice() {
|
||||
joinOpenJob();
|
||||
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
device.setBlock(EMPTY_BLOCK_DEVICE);
|
||||
} catch (final IOException e) {
|
||||
LOGGER.error(e);
|
||||
}
|
||||
|
||||
if (blobHandle != null) {
|
||||
BlobStorage.close(blobHandle);
|
||||
blobHandle = null;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<BlockDevice> createBlockDevice() {
|
||||
final ItemStack stack = identity.getDiskItemStack();
|
||||
if (stack.isEmpty() || !(stack.getItem() instanceof final FlashMemoryItem floppy)) {
|
||||
return CompletableFuture.completedFuture(EMPTY_BLOCK_DEVICE);
|
||||
}
|
||||
|
||||
final int capacity = floppy.getCapacity(stack);
|
||||
if (capacity <= 0) {
|
||||
return CompletableFuture.completedFuture(EMPTY_BLOCK_DEVICE);
|
||||
}
|
||||
|
||||
blobHandle = BlobStorage.validateHandle(blobHandle);
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
final FileChannel channel = BlobStorage.getOrOpen(blobHandle);
|
||||
final MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, capacity);
|
||||
return ByteBufferBlockDevice.wrap(buffer, false);
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}, WORKERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleDataAccess() {
|
||||
identity.handleDataAccess();
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ import li.cil.oc2.api.bus.device.vm.event.VMInitializingEvent;
|
||||
import li.cil.oc2.common.Constants;
|
||||
import li.cil.oc2.common.bus.device.util.IdentityProxy;
|
||||
import li.cil.oc2.common.bus.device.util.OptionalAddress;
|
||||
import li.cil.oc2.common.item.AbstractStorageItem;
|
||||
import li.cil.oc2.common.serialization.BlobStorage;
|
||||
import li.cil.oc2.common.util.ItemStackUtils;
|
||||
import li.cil.sedna.api.memory.MemoryAccessException;
|
||||
import li.cil.sedna.api.memory.MemoryMap;
|
||||
import li.cil.sedna.device.flash.FlashMemoryDevice;
|
||||
@@ -99,19 +102,32 @@ public final class ByteBufferFlashStorageDevice extends IdentityProxy<ItemStack>
|
||||
@Override
|
||||
public void deserializeNBT(final CompoundTag tag) {
|
||||
final byte[] data = tag.getByteArray(DATA_TAG_NAME);
|
||||
final ByteBuffer bufferData = device.getData();
|
||||
final ByteBuffer bufferData = ByteBuffer.allocate(size);
|
||||
bufferData.clear();
|
||||
bufferData.put(data, 0, Math.min(bufferData.limit(), data.length));
|
||||
this.data = bufferData;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
private boolean allocateDevice(final VMContext context) {
|
||||
if (!context.getMemoryAllocator().claimMemory(size)) {
|
||||
if (!context.getMemoryAllocator().claimMemory(12*Constants.MEGABYTE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = ByteBuffer.allocate(size);
|
||||
if (data == null) {
|
||||
try {
|
||||
data = ByteBuffer.allocate(12*Constants.MEGABYTE);
|
||||
data.clear();
|
||||
CompoundTag tag = ItemStackUtils.getModDataTag(identity).getCompound(DATA_TAG_NAME);
|
||||
if (tag.hasUUID("blob")) {
|
||||
BlobStorage.getOrOpen(tag.getUUID("blob")).read(data, 0);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
System.out.println("Error message: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
device = new FlashMemoryDevice(data);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -18,6 +18,7 @@ import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import li.cil.oc2.common.container.FixedSizeItemStackHandler;
|
||||
import li.cil.oc2.common.container.RobotInventoryContainer;
|
||||
import li.cil.oc2.common.container.RobotTerminalContainer;
|
||||
import li.cil.oc2.common.energy.EnergyStorageItemStack;
|
||||
import li.cil.oc2.common.energy.FixedEnergyStorage;
|
||||
import li.cil.oc2.common.entity.robot.*;
|
||||
import li.cil.oc2.common.integration.Wrenches;
|
||||
@@ -393,7 +394,9 @@ public final class Robot extends Entity implements li.cil.oc2.api.capabilities.R
|
||||
|
||||
public void importFromItemStack(final ItemStack stack) {
|
||||
final CompoundTag itemsTag = NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME, ITEMS_TAG_NAME);
|
||||
|
||||
deviceItems.loadItems(itemsTag);
|
||||
|
||||
inventory.deserializeNBT(itemsTag.getCompound(INVENTORY_TAG_NAME));
|
||||
|
||||
energy.deserializeNBT(NBTUtils.getChildTag(stack.getTag(), MOD_TAG_NAME, ENERGY_TAG_NAME));
|
||||
@@ -416,6 +419,14 @@ public final class Robot extends Entity implements li.cil.oc2.api.capabilities.R
|
||||
tag.put(TERMINAL_TAG_NAME, NBTSerialization.serialize(terminal));
|
||||
}
|
||||
|
||||
System.out.println("Action processor: " + actionProcessor.serialize().toString());
|
||||
System.out.println("Bus element: " + busElement.serialize().toString());
|
||||
System.out.println("Items: " + deviceItems.saveItems().toString());
|
||||
System.out.println("Devices: " + deviceItems.saveDevices().toString());
|
||||
System.out.println("Energy: " + energy.serializeNBT().toString());
|
||||
System.out.println("Inventory: " + inventory.serializeNBT().toString());
|
||||
System.out.println("Selected Slot: " + getEntityData().get(SELECTED_SLOT).toString());
|
||||
|
||||
tag.put(COMMAND_PROCESSOR_TAG_NAME, actionProcessor.serialize());
|
||||
tag.put(BUS_ELEMENT_TAG_NAME, busElement.serialize());
|
||||
tag.put(ITEMS_TAG_NAME, deviceItems.saveItems());
|
||||
@@ -427,6 +438,18 @@ public final class Robot extends Entity implements li.cil.oc2.api.capabilities.R
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(final CompoundTag tag) {
|
||||
System.out.println("VM State: " + tag.getCompound(STATE_TAG_NAME).toString());
|
||||
System.out.println("Terminal: " + tag.getCompound(TERMINAL_TAG_NAME).toString());
|
||||
System.out.println("Action processor: " + tag.getCompound(COMMAND_PROCESSOR_TAG_NAME).toString());
|
||||
System.out.println("Bus element: " + tag.getCompound(BUS_ELEMENT_TAG_NAME).toString());
|
||||
System.out.println("Items: " + tag.getCompound(ITEMS_TAG_NAME).toString());
|
||||
System.out.println("Devices: " + tag.getCompound(DEVICES_TAG_NAME).toString());
|
||||
System.out.println("Energy: " + tag.getCompound(ENERGY_TAG_NAME).toString());
|
||||
System.out.println("Inventory: " + tag.getCompound(INVENTORY_TAG_NAME).toString());
|
||||
System.out.println("Selected Slot: " + tag.getCompound(SELECTED_SLOT_TAG_NAME).toString());
|
||||
|
||||
|
||||
|
||||
virtualMachine.deserialize(tag.getCompound(STATE_TAG_NAME));
|
||||
NBTSerialization.deserialize(tag.getCompound(TERMINAL_TAG_NAME), terminal);
|
||||
actionProcessor.deserialize(tag.getCompound(COMMAND_PROCESSOR_TAG_NAME));
|
||||
|
||||
@@ -4,6 +4,7 @@ package li.cil.oc2.common.item;
|
||||
|
||||
import li.cil.oc2.api.bus.device.data.BlockDeviceData;
|
||||
import li.cil.oc2.common.bus.device.data.BlockDeviceDataRegistry;
|
||||
import li.cil.oc2.common.bus.device.data.FileSystems;
|
||||
import li.cil.oc2.common.util.ItemStackUtils;
|
||||
import net.minecraft.ResourceLocationException;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
@@ -4,6 +4,7 @@ package li.cil.oc2.common.item;
|
||||
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.common.bus.device.vm.item.ByteBufferFlashStorageDevice;
|
||||
import li.cil.oc2.common.util.ItemStackUtils;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
@@ -7,9 +7,13 @@ import li.cil.oc2.common.bus.device.data.FirmwareRegistry;
|
||||
import li.cil.oc2.common.util.ItemStackUtils;
|
||||
import net.minecraft.ResourceLocationException;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.StringUtil;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -30,6 +30,7 @@ public final class Items {
|
||||
public static final RegistryObject<Item> COMPUTER = register(Blocks.COMPUTER);
|
||||
public static final RegistryObject<Item> CREATIVE_ENERGY = register(Blocks.CREATIVE_ENERGY);
|
||||
public static final RegistryObject<Item> DISK_DRIVE = register(Blocks.DISK_DRIVE);
|
||||
public static final RegistryObject<Item> FLASH_MEMORY_FLASHER = register(Blocks.FLASH_MEMORY_FLASHER);
|
||||
public static final RegistryObject<Item> KEYBOARD = register(Blocks.KEYBOARD);
|
||||
public static final RegistryObject<Item> NETWORK_CONNECTOR = register(Blocks.NETWORK_CONNECTOR);
|
||||
public static final RegistryObject<Item> NETWORK_HUB = register(Blocks.NETWORK_HUB);
|
||||
@@ -61,7 +62,7 @@ public final class Items {
|
||||
new HardDriveWithExternalDataItem(BlockDeviceDataRegistry.BUILDROOT.getId(), DyeColor.BROWN));
|
||||
|
||||
public static final RegistryObject<FlashMemoryItem> FLASH_MEMORY = register("flash_memory", () ->
|
||||
new FlashMemoryItem(4 * Constants.KILOBYTE));
|
||||
new FlashMemoryItem(12 * Constants.MEGABYTE));
|
||||
public static final RegistryObject<FlashMemoryWithExternalDataItem> FLASH_MEMORY_CUSTOM = register("flash_memory_custom", () ->
|
||||
new FlashMemoryWithExternalDataItem(FirmwareRegistry.BUILDROOT.getId()));
|
||||
|
||||
|
||||
@@ -44,6 +44,11 @@ import static li.cil.oc2.common.util.NBTUtils.makeInventoryTag;
|
||||
import static li.cil.oc2.common.util.RegistryUtils.key;
|
||||
|
||||
public final class RobotItem extends ModItem {
|
||||
@Override
|
||||
public void fillItemCategory(final CreativeModeTab tab, final NonNullList<ItemStack> items) {
|
||||
items.add(getRobotWithFlash());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendHoverText(final ItemStack stack, @Nullable final Level level, final List<Component> tooltip, final TooltipFlag flag) {
|
||||
super.appendHoverText(stack, level, tooltip, flag);
|
||||
@@ -79,6 +84,8 @@ public final class RobotItem extends ModItem {
|
||||
return InteractionResult.FAIL;
|
||||
}
|
||||
|
||||
System.out.println("Created successfully");
|
||||
|
||||
robot.moveTo(position.x, position.y - robot.getBbHeight() * 0.5f, position.z,
|
||||
Direction.fromYRot(context.getRotation()).getOpposite().toYRot(), 0);
|
||||
if (!level.noCollision(robot)) {
|
||||
|
||||
@@ -61,6 +61,8 @@ public final class Network {
|
||||
registerMessage(OpenRobotTerminalMessage.class, OpenRobotTerminalMessage::new, NetworkDirection.PLAY_TO_SERVER);
|
||||
|
||||
registerMessage(DiskDriveFloppyMessage.class, DiskDriveFloppyMessage::new, NetworkDirection.PLAY_TO_CLIENT);
|
||||
registerMessage(FirmwareFlasherMessage.class, FirmwareFlasherMessage::new, NetworkDirection.PLAY_TO_CLIENT);
|
||||
|
||||
|
||||
registerMessage(BusInterfaceNameMessage.ToClient.class, BusInterfaceNameMessage.ToClient::new, NetworkDirection.PLAY_TO_CLIENT);
|
||||
registerMessage(BusInterfaceNameMessage.ToServer.class, BusInterfaceNameMessage.ToServer::new, NetworkDirection.PLAY_TO_SERVER);
|
||||
@@ -138,7 +140,7 @@ public final class Network {
|
||||
INSTANCE.messageBuilder(type, getNextPacketId(), direction)
|
||||
.encoder(AbstractMessage::toBytes)
|
||||
.decoder(decoder)
|
||||
.consumer(AbstractMessage::handleMessage)
|
||||
.consumerNetworkThread(AbstractMessage::handleMessage)
|
||||
.add();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
package li.cil.oc2.common.network.message;
|
||||
|
||||
import li.cil.oc2.common.blockentity.DiskDriveBlockEntity;
|
||||
import li.cil.oc2.common.blockentity.FlashMemoryFlasherBlockEntity;
|
||||
import li.cil.oc2.common.network.MessageUtils;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
public final class FirmwareFlasherMessage extends AbstractMessage {
|
||||
private BlockPos pos;
|
||||
private CompoundTag data;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public FirmwareFlasherMessage(final FlashMemoryFlasherBlockEntity diskDrive) {
|
||||
this.pos = diskDrive.getBlockPos();
|
||||
this.data = diskDrive.getFloppy().serializeNBT();
|
||||
}
|
||||
|
||||
public FirmwareFlasherMessage(final FriendlyByteBuf buffer) {
|
||||
super(buffer);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void fromBytes(final FriendlyByteBuf buffer) {
|
||||
pos = buffer.readBlockPos();
|
||||
data = buffer.readNbt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(final FriendlyByteBuf buffer) {
|
||||
buffer.writeBlockPos(pos);
|
||||
buffer.writeNbt(data);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
protected void handleMessage(final NetworkEvent.Context context) {
|
||||
MessageUtils.withClientBlockEntityAt(pos, DiskDriveBlockEntity.class,
|
||||
diskDrive -> diskDrive.setFloppyClient(ItemStack.of(data)));
|
||||
}
|
||||
}
|
||||
@@ -78,6 +78,7 @@ public abstract class AbstractVirtualMachine implements VirtualMachine {
|
||||
state.board.getCpu().setFrequency(Constants.CPU_FREQUENCY);
|
||||
state.board.setBootArguments("root=/dev/vda rw");
|
||||
state.board.setStandardOutputDevice(state.builtinDevices.uart);
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -13,6 +13,7 @@ import li.cil.sedna.device.serial.UART16550A;
|
||||
import li.cil.sedna.device.virtio.VirtIOConsoleDevice;
|
||||
import li.cil.sedna.device.virtio.VirtIOFileSystemDevice;
|
||||
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class BuiltinDevices {
|
||||
|
||||
@@ -811,8 +811,8 @@ public final class Terminal {
|
||||
|
||||
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
|
||||
|
||||
renderForeground(matrix, builder, row);
|
||||
renderBackground(matrix, builder, row);
|
||||
renderForeground(matrix, builder, row);
|
||||
|
||||
BufferBuilder.RenderedBuffer rb = builder.end();
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"variants": {
|
||||
"facing=north": {
|
||||
"model": "oc2:block/flash_memory_flasher"
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "oc2:block/flash_memory_flasher",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "oc2:block/flash_memory_flasher",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east": {
|
||||
"model": "oc2:block/flash_memory_flasher",
|
||||
"y": 90
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"parent":"block/block","textures":{"atlas0":"oc2:block/disk_drive/disk_drive_atlas0","atlas1":"oc2:block/disk_drive/disk_drive_atlas1","atlas2":"oc2:block/disk_drive/disk_drive_atlas2","atlas3":"oc2:block/disk_drive/disk_drive_atlas3","particle":"#atlas0"},"elements":[{"from":[0,0,0],"to":[16,6,16],"faces":{"east":{"texture":"atlas0","cullface":"east","uv":[0.0,0.0,8.0,3.0]},"west":{"texture":"atlas0","cullface":"west","uv":[0.0,3.0,8.0,6.0]},"up":{"texture":"atlas0","uv":[0.0,6.0,8.0,14.0]},"down":{"texture":"atlas0","cullface":"down","uv":[8.0,6.0,16.0,14.0]},"north":{"texture":"atlas0","cullface":"north","uv":[8.0,3.0,16.0,6.0]},"south":{"texture":"atlas0","cullface":"south","uv":[8.0,0.0,16.0,3.0]}}},{"from":[0,6,15],"to":[6,10,16],"faces":{"east":{"texture":"atlas2","uv":[14.0,0.0,14.5,2.0]},"west":{"texture":"atlas2","cullface":"west","uv":[14.5,0.0,15.0,2.0]},"up":{"texture":"atlas2","uv":[8.0,15.5,11.0,16.0]},"down":{"texture":"atlas2","uv":[11.0,15.5,14.0,16.0]},"south":{"texture":"atlas2","cullface":"south","uv":[8.0,0.0,11.0,2.0]}}},{"from":[10,6,15],"to":[16,10,16],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[15.0,0.0,15.5,2.0]},"west":{"texture":"atlas2","uv":[15.5,0.0,16.0,2.0]},"up":{"texture":"atlas2","uv":[8.0,13.5,11.0,14.0]},"down":{"texture":"atlas2","uv":[11.0,13.5,14.0,14.0]},"south":{"texture":"atlas2","cullface":"south","uv":[11.0,0.0,14.0,2.0]}}},{"from":[0,6,0],"to":[16,9,15],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[8.0,14.0,15.5,15.5]},"west":{"texture":"atlas2","cullface":"west","uv":[8.0,12.0,15.5,13.5]},"up":{"texture":"atlas1","uv":[0.0,0.0,8.0,7.5]},"north":{"texture":"atlas0","cullface":"north","uv":[0.0,14.0,8.0,15.5]},"south":{"texture":"atlas0","uv":[8.0,14.0,16.0,15.5]}}},{"from":[0,9,1],"to":[16,10,15],"faces":{"east":{"texture":"atlas1","cullface":"east","uv":[0.0,15.5,7.0,16.0]},"west":{"texture":"atlas1","cullface":"west","uv":[7.0,15.5,14.0,16.0]},"up":{"texture":"atlas1","uv":[0.0,7.5,8.0,14.5]},"down":{"texture":"atlas1","uv":[8.0,7.5,16.0,14.5]},"north":{"texture":"atlas0","uv":[0.0,15.5,8.0,16.0]},"south":{"texture":"atlas0","uv":[8.0,15.5,16.0,16.0]}}},{"from":[0,9,0],"to":[3,12,1],"faces":{"east":{"texture":"atlas2","uv":[15.5,12.0,16.0,13.5]},"west":{"texture":"atlas2","cullface":"west","uv":[15.5,14.0,16.0,15.5]},"up":{"texture":"atlas1","uv":[14.0,15.5,15.5,16.0]},"down":{"texture":"atlas2","uv":[14.0,15.5,15.5,16.0]},"north":{"texture":"atlas3","cullface":"north","uv":[0.0,0.0,1.5,1.5]}}},{"from":[13,9,0],"to":[16,12,1],"faces":{"east":{"texture":"atlas3","cullface":"east","uv":[1.5,0.0,2.0,1.5]},"west":{"texture":"atlas3","uv":[2.0,0.0,2.5,1.5]},"up":{"texture":"atlas2","uv":[14.0,13.5,15.5,14.0]},"down":{"texture":"atlas3","uv":[0.0,1.5,1.5,2.0]},"north":{"texture":"atlas3","cullface":"north","uv":[0.0,2.0,1.5,3.5]}}},{"from":[0,10,1],"to":[16,12,16],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[8.0,2.0,15.5,3.0]},"west":{"texture":"atlas2","cullface":"west","uv":[8.0,3.0,15.5,4.0]},"down":{"texture":"atlas1","uv":[8.0,0.0,16.0,7.5]},"north":{"texture":"atlas1","uv":[0.0,14.5,8.0,15.5]},"south":{"texture":"atlas1","cullface":"south","uv":[8.0,14.5,16.0,15.5]}}},{"from":[0,12,0],"to":[16,16,16],"faces":{"east":{"texture":"atlas2","cullface":"east","uv":[0.0,0.0,8.0,2.0]},"west":{"texture":"atlas2","cullface":"west","uv":[0.0,2.0,8.0,4.0]},"up":{"texture":"atlas2","cullface":"up","uv":[0.0,4.0,8.0,12.0]},"down":{"texture":"atlas2","uv":[8.0,4.0,16.0,12.0]},"north":{"texture":"atlas2","cullface":"north","uv":[0.0,12.0,8.0,14.0]},"south":{"texture":"atlas2","cullface":"south","uv":[0.0,14.0,8.0,16.0]}}}]}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"parent": "oc2:block/flash_memory_flasher"
|
||||
}
|
||||
@@ -28,4 +28,4 @@
|
||||
"result": {
|
||||
"item": "oc2:disk_drive"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"IUI",
|
||||
"XTD",
|
||||
"IBI"
|
||||
],
|
||||
"key": {
|
||||
"I": {
|
||||
"tag": "forge:ingots/iron"
|
||||
},
|
||||
"U": {
|
||||
"tag": "minecraft:buttons"
|
||||
},
|
||||
"T": {
|
||||
"item": "oc2:transistor"
|
||||
},
|
||||
"X": {
|
||||
"item": "oc2:bus_interface"
|
||||
},
|
||||
"D": {
|
||||
"item": "minecraft:dropper"
|
||||
},
|
||||
"B": {
|
||||
"item": "oc2:circuit_board"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "oc2:flash_memory_flasher"
|
||||
}
|
||||
}
|
||||
7
src/main/scripts/bin/flash.sh
Normal file
7
src/main/scripts/bin/flash.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
dd ibs=$(echo "12*1024*1024" | bc) count=1 if=/dev/zero of=$1
|
||||
if [ "$3" = "yes" ]; then
|
||||
dd if=fw_jump.bin of=$1
|
||||
dd if=$2 of=$1 seek=2097152 oflag=seek_bytes
|
||||
else
|
||||
dd if=$2 of=$1
|
||||
fi
|
||||
Reference in New Issue
Block a user