Custom Bootloader, Robot still broken

This commit is contained in:
Jackson Abney
2023-05-17 12:35:37 -08:00
parent 238b0c31fa
commit 0bf94fd172
27 changed files with 631 additions and 8 deletions

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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()));

View File

@@ -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)) {

View File

@@ -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();
}

View File

@@ -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)));
}
}

View File

@@ -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);
}
///////////////////////////////////////////////////////////////////

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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
}
}
}

View File

@@ -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]}}}]}

View File

@@ -0,0 +1,3 @@
{
"parent": "oc2:block/flash_memory_flasher"
}

View File

@@ -28,4 +28,4 @@
"result": {
"item": "oc2:disk_drive"
}
}
}

View File

@@ -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"
}
}

View 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