Added concept of slot types for item devices.

Made slots in computer types.
This commit is contained in:
Florian Nücke
2020-12-28 15:04:20 +01:00
parent 35b67744cd
commit ff08e2fb9b
50 changed files with 422 additions and 155 deletions

View File

@@ -2,6 +2,6 @@ package li.cil.oc2;
public final class Config {
public static long maxAllocatedData = 512 * Constants.MEGABYTE;
public static int maxHddSize = 8 * Constants.MEGABYTE;
public static int maxRamSize = 8 * Constants.MEGABYTE;
public static int maxHardDriveSize = 8 * Constants.MEGABYTE;
public static int maxMemorySize = 8 * Constants.MEGABYTE;
}

View File

@@ -20,8 +20,8 @@ public final class Constants {
public static final String WRENCH_ITEM_NAME = "wrench";
public static final String BUS_INTERFACE_ITEM_NAME = "bus_interface";
public static final String RAM_ITEM_NAME = "ram";
public static final String HDD_ITEM_NAME = "hdd";
public static final String MEMORY_ITEM_NAME = "memory";
public static final String HARD_DRIVE_ITEM_NAME = "hard_drive";
///////////////////////////////////////////////////////////////////
@@ -30,7 +30,7 @@ public final class Constants {
///////////////////////////////////////////////////////////////////
public static final String COMPUTER_BOOT_ERROR_UNKNOWN = "gui.oc2.computer.boot_error.unknown";
public static final String COMPUTER_BOOT_ERROR_NO_RAM = "gui.oc2.computer.boot_error.no_ram";
public static final String COMPUTER_BOOT_ERROR_NO_MEMORY = "gui.oc2.computer.boot_error.no_memory";
public static final String COMPUTER_BUS_STATE_INCOMPLETE = "gui.oc2.computer.bus_state.incomplete";
public static final String COMPUTER_BUS_STATE_TOO_COMPLEX = "gui.oc2.computer.bus_state.too_complex";
public static final String COMPUTER_BUS_STATE_MULTIPLE_CONTROLLERS = "gui.oc2.computer.bus_state.multiple_controllers";

View File

@@ -17,6 +17,7 @@ public final class OpenComputers {
TileEntities.initialize();
Containers.initialize();
Providers.initialize();
DeviceTypes.initialize();
FMLJavaModLoadingContext.get().getModEventBus().addListener(CommonSetup::run);
FMLJavaModLoadingContext.get().getModEventBus().addListener(ClientSetup::run);

View File

@@ -0,0 +1,14 @@
package li.cil.oc2.api.bus.device;
import li.cil.oc2.api.API;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.registries.IForgeRegistryEntry;
public interface DeviceType extends IForgeRegistryEntry<DeviceType> {
ResourceLocation REGISTRY_ID = new ResourceLocation(API.MOD_ID, "device_types");
ResourceLocation getIcon();
ITextComponent getName();
}

View File

@@ -0,0 +1,12 @@
package li.cil.oc2.api.bus.device;
import li.cil.oc2.api.API;
import net.minecraftforge.registries.ObjectHolder;
@ObjectHolder(API.MOD_ID)
public final class DeviceTypes {
@ObjectHolder("eeprom") public static DeviceType EEPROM = null;
@ObjectHolder("memory") public static DeviceType MEMORY = null;
@ObjectHolder("hard_drive") public static DeviceType HARD_DRIVE = null;
@ObjectHolder("card") public static DeviceType CARD = null;
}

View File

@@ -1,6 +1,8 @@
package li.cil.oc2.api.bus.device.provider;
import li.cil.oc2.api.bus.device.Device;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.api.bus.device.ItemDevice;
import net.minecraftforge.registries.IForgeRegistryEntry;
@@ -45,4 +47,8 @@ public interface ItemDeviceProvider extends IForgeRegistryEntry<ItemDeviceProvid
* @return a device for the specified query, if available.
*/
Optional<ItemDevice> getDevice(ItemDeviceQuery query);
default Optional<DeviceType> getDeviceType(final ItemDeviceQuery query) {
return Optional.of(DeviceTypes.CARD);
}
}

View File

@@ -67,7 +67,7 @@ public interface VMContext {
* Allows reserving fixed amounts of memory respecting sandbox constraints.
* <p>
* It is strongly advised to use this allocator to make known large memory
* uses, e.g. when allocating large blobs for RAM or block devices. This
* uses, e.g. when allocating large blobs for memory or block devices. This
* allows respecting the built-in limits for overall memory usage of
* running VMs.
* <p>

View File

@@ -19,7 +19,7 @@ public final class ComputerContainerScreen extends ContainerScreen<ComputerConta
public ComputerContainerScreen(final ComputerContainer container, final PlayerInventory inventory, final ITextComponent title) {
super(container, inventory, title);
xSize = 176;
ySize = 133;
ySize = 197;
playerInventoryTitleY = ySize - 94;
}

View File

@@ -46,6 +46,10 @@ public final class ComputerTileEntityRenderer extends TileEntityRenderer<Compute
@SubscribeEvent
public static void handleTextureStitchEvent(final TextureStitchEvent.Pre event) {
if (event.getMap().getTextureLocation() != PlayerContainer.LOCATION_BLOCKS_TEXTURE) {
return;
}
event.addSprite(OVERLAY_POWER_LOCATION);
event.addSprite(OVERLAY_STATUS_LOCATION);
event.addSprite(OVERLAY_TERMINAL_LOCATION);

View File

@@ -6,6 +6,8 @@ import li.cil.oc2.Constants;
import li.cil.oc2.api.bus.DeviceBusController;
import li.cil.oc2.api.bus.DeviceBusElement;
import li.cil.oc2.api.bus.device.Device;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.api.bus.device.vm.VMContext;
import li.cil.oc2.api.bus.device.vm.VMDevice;
import li.cil.oc2.api.bus.device.vm.VMDeviceLifecycleEventType;
@@ -17,6 +19,7 @@ import li.cil.oc2.common.bus.TileEntityDeviceBusElement;
import li.cil.oc2.common.bus.device.ItemDeviceInfo;
import li.cil.oc2.common.capabilities.Capabilities;
import li.cil.oc2.common.container.DeviceItemStackHandler;
import li.cil.oc2.common.container.TypedDeviceItemStackHandler;
import li.cil.oc2.common.init.TileEntities;
import li.cil.oc2.common.network.Network;
import li.cil.oc2.common.network.message.ComputerBootErrorMessage;
@@ -30,8 +33,6 @@ import li.cil.oc2.common.util.NBTUtils;
import li.cil.oc2.common.vm.Terminal;
import li.cil.oc2.common.vm.VirtualMachine;
import li.cil.oc2.common.vm.VirtualMachineRunner;
import li.cil.sedna.api.device.MemoryMappedDevice;
import li.cil.sedna.api.device.PhysicalMemory;
import li.cil.sedna.api.memory.MemoryAccessException;
import li.cil.sedna.buildroot.Buildroot;
import li.cil.sedna.device.serial.UART16550A;
@@ -52,6 +53,7 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
@@ -70,6 +72,10 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
private static final String TERMINAL_TAG_NAME = "terminal";
private static final String VIRTUAL_MACHINE_TAG_NAME = "virtualMachine";
private static final String RUNNER_TAG_NAME = "runner";
private static final String EEPROM_TAG_NAME = "eeprom";
private static final String MEMORY_TAG_NAME = "memory";
private static final String HARD_DRIVE_TAG_NAME = "hard_drive";
private static final String CARD_TAG_NAME = "card";
private static final String BUS_STATE_TAG_NAME = "busState";
private static final String RUN_STATE_TAG_NAME = "runState";
@@ -77,6 +83,11 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
private static final int DEVICE_LOAD_RETRY_INTERVAL = 10 * 20; // In ticks.
private static final int EEPROM_SLOTS = 1;
private static final int MEMORY_SLOTS = 4;
private static final int HARD_DRIVE_SLOTS = 4;
private static final int CARD_SLOTS = 4;
private static final long ITEM_DEVICE_BASE_ADDRESS = 0x40000000L;
private static final int ITEM_DEVICE_STRIDE = 0x1000;
@@ -99,7 +110,12 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
///////////////////////////////////////////////////////////////////
private final DeviceItemStackHandler itemHandler = new DeviceItemStackHandler(8);
private final DeviceItemStackHandler eepromItemHandler = new TypedDeviceItemStackHandler(EEPROM_SLOTS, DeviceTypes.EEPROM);
private final DeviceItemStackHandler memoryItemHandler = new TypedDeviceItemStackHandler(MEMORY_SLOTS, DeviceTypes.MEMORY);
private final DeviceItemStackHandler hardDriveItemHandler = new TypedDeviceItemStackHandler(HARD_DRIVE_SLOTS, DeviceTypes.HARD_DRIVE);
private final DeviceItemStackHandler cardItemHandler = new TypedDeviceItemStackHandler(CARD_SLOTS, DeviceTypes.CARD);
private final IItemHandler itemHandlers = new CombinedInvWrapper(eepromItemHandler, memoryItemHandler, hardDriveItemHandler, cardItemHandler);
private final Terminal terminal = new Terminal();
private final TileEntityDeviceBusElement busElement = new BusElement();
private final ComputerVirtualMachine virtualMachine;
@@ -121,8 +137,17 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
virtualMachine.vmAdapter.setDefaultAddressProvider(this::getDefaultDeviceAddress);
}
public IItemHandler getItemHandler() {
return itemHandler;
public Optional<IItemHandler> getItemHandler(final DeviceType deviceType) {
if (deviceType == DeviceTypes.EEPROM) {
return Optional.of(eepromItemHandler);
} else if (deviceType == DeviceTypes.MEMORY) {
return Optional.of(memoryItemHandler);
} else if (deviceType == DeviceTypes.HARD_DRIVE) {
return Optional.of(hardDriveItemHandler);
} else if (deviceType == DeviceTypes.CARD) {
return Optional.of(cardItemHandler);
}
return Optional.empty();
}
public Terminal getTerminal() {
@@ -233,7 +258,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
@Override
protected void collectCapabilities(final CapabilityCollector collector, @Nullable final Direction direction) {
collector.offer(Capabilities.ITEM_HANDLER_CAPABILITY, itemHandler);
collector.offer(Capabilities.ITEM_HANDLER_CAPABILITY, itemHandlers);
}
@Override
@@ -285,7 +310,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
// a program that only uses registers. But not supporting that esoteric
// use-case loses out against avoiding people getting confused for having
// forgotten to add some RAM modules.
setBootError(new TranslationTextComponent(Constants.COMPUTER_BOOT_ERROR_NO_RAM));
setBootError(new TranslationTextComponent(Constants.COMPUTER_BOOT_ERROR_NO_MEMORY));
setRunState(RunState.STOPPED);
return;
} catch (final MemoryAccessException e) {
@@ -301,7 +326,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
setRunState(RunState.RUNNING);
// Only start running next tick. This gives loaded devices one tick to do async
// initialization. This is used by RAM to restore data from disk, for example.
// initialization. This is used by devices to restore data from disk, for example.
break;
case RUNNING:
if (!virtualMachine.board.isRunning()) {
@@ -363,7 +388,12 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
NBTUtils.putEnum(compound, RUN_STATE_TAG_NAME, runState);
}
compound.put(Constants.BLOCK_ENTITY_INVENTORY_TAG_NAME, itemHandler.serializeNBT());
final CompoundNBT items = new CompoundNBT();
items.put(EEPROM_TAG_NAME, eepromItemHandler.serializeNBT());
items.put(MEMORY_TAG_NAME, memoryItemHandler.serializeNBT());
items.put(HARD_DRIVE_TAG_NAME, hardDriveItemHandler.serializeNBT());
items.put(CARD_TAG_NAME, cardItemHandler.serializeNBT());
compound.put(Constants.BLOCK_ENTITY_INVENTORY_TAG_NAME, items);
return compound;
}
@@ -398,7 +428,11 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
}
if (compound.contains(Constants.BLOCK_ENTITY_INVENTORY_TAG_NAME, NBTTagIds.TAG_COMPOUND)) {
itemHandler.deserializeNBT(compound.getCompound(Constants.BLOCK_ENTITY_INVENTORY_TAG_NAME));
final CompoundNBT items = compound.getCompound(Constants.BLOCK_ENTITY_INVENTORY_TAG_NAME);
eepromItemHandler.deserializeNBT(items.getCompound(EEPROM_TAG_NAME));
memoryItemHandler.deserializeNBT(items.getCompound(MEMORY_TAG_NAME));
hardDriveItemHandler.deserializeNBT(items.getCompound(HARD_DRIVE_TAG_NAME));
cardItemHandler.deserializeNBT(items.getCompound(CARD_TAG_NAME));
}
}
@@ -487,18 +521,29 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
}
}
private OptionalLong getDefaultDeviceAddress(final VMDevice wrapper, final MemoryMappedDevice device) {
if (device instanceof PhysicalMemory) {
return OptionalLong.empty();
}
private OptionalLong getDefaultDeviceAddress(final VMDevice wrapper) {
long address = ITEM_DEVICE_BASE_ADDRESS;
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
final Collection<ItemDeviceInfo> devices = itemHandler.getBusElement().getDeviceGroup(slot);
for (int slot = 0; slot < hardDriveItemHandler.getSlots(); slot++) {
final Collection<ItemDeviceInfo> devices = hardDriveItemHandler.getBusElement().getDeviceGroup(slot);
for (final ItemDeviceInfo info : devices) {
if (Objects.equals(info.device, wrapper)) {
return OptionalLong.of(ITEM_DEVICE_BASE_ADDRESS + slot * ITEM_DEVICE_STRIDE);
return OptionalLong.of(address);
}
}
address += ITEM_DEVICE_STRIDE;
}
for (int slot = 0; slot < cardItemHandler.getSlots(); slot++) {
final Collection<ItemDeviceInfo> devices = cardItemHandler.getBusElement().getDeviceGroup(slot);
for (final ItemDeviceInfo info : devices) {
if (Objects.equals(info.device, wrapper)) {
return OptionalLong.of(address);
}
}
address += ITEM_DEVICE_STRIDE;
}
return OptionalLong.empty();
@@ -553,7 +598,10 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
public Optional<Collection<LazyOptional<DeviceBusElement>>> getNeighbors() {
return super.getNeighbors().map(neighbors -> {
final ArrayList<LazyOptional<DeviceBusElement>> list = new ArrayList<>(neighbors);
list.add(LazyOptional.of(itemHandler::getBusElement));
list.add(LazyOptional.of(eepromItemHandler::getBusElement));
list.add(LazyOptional.of(memoryItemHandler::getBusElement));
list.add(LazyOptional.of(hardDriveItemHandler::getBusElement));
list.add(LazyOptional.of(cardItemHandler::getBusElement));
return list;
});
}

View File

@@ -16,7 +16,7 @@ import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.UUID;
public abstract class AbstractHardDiskDriveDevice<T extends BlockDevice> extends AbstractItemDevice implements VMDevice, VMDeviceLifecycleListener {
public abstract class AbstractHardDriveDevice<T extends BlockDevice> extends AbstractItemDevice implements VMDevice, VMDeviceLifecycleListener {
private static final String DEVICE_NBT_TAG_NAME = "device";
private static final String ADDRESS_NBT_TAG_NAME = "address";
private static final String INTERRUPT_NBT_TAG_NAME = "interrupt";
@@ -40,7 +40,7 @@ public abstract class AbstractHardDiskDriveDevice<T extends BlockDevice> extends
///////////////////////////////////////////////////////////////
protected AbstractHardDiskDriveDevice(final ItemStack stack) {
protected AbstractHardDriveDevice(final ItemStack stack) {
super(stack);
}

View File

@@ -0,0 +1,26 @@
package li.cil.oc2.common.bus.device;
import li.cil.oc2.api.bus.device.DeviceType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.registries.ForgeRegistryEntry;
public final class DeviceTypeImpl extends ForgeRegistryEntry<DeviceType> implements DeviceType {
private final ResourceLocation icon;
private final ITextComponent name;
public DeviceTypeImpl(final ResourceLocation icon, final ITextComponent name) {
this.icon = icon;
this.name = name;
}
@Override
public ResourceLocation getIcon() {
return icon;
}
@Override
public ITextComponent getName() {
return name;
}
}

View File

@@ -1,6 +1,7 @@
package li.cil.oc2.common.bus.device;
import li.cil.oc2.api.bus.device.Device;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.api.bus.device.ItemDevice;
import li.cil.oc2.api.bus.device.provider.BlockDeviceProvider;
import li.cil.oc2.api.bus.device.provider.BlockDeviceQuery;
@@ -16,9 +17,7 @@ import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.registries.IForgeRegistry;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.*;
public final class Devices {
public static List<LazyOptional<BlockDeviceInfo>> getDevices(final TileEntity tileEntity, final Direction side) {
@@ -38,6 +37,10 @@ public final class Devices {
return getDevices(new ItemQuery(stack));
}
public static Collection<DeviceType> getDeviceTypes(final ItemStack stack) {
return getDeviceTypes(new ItemQuery(stack));
}
///////////////////////////////////////////////////////////////////
private static List<LazyOptional<BlockDeviceInfo>> getDevices(final BlockQuery query) {
@@ -64,6 +67,16 @@ public final class Devices {
return devices;
}
private static Collection<DeviceType> getDeviceTypes(final ItemQuery query) {
final IForgeRegistry<ItemDeviceProvider> registry = Providers.ITEM_DEVICE_PROVIDER_REGISTRY.get();
final HashSet<DeviceType> deviceTypes = new HashSet<>();
for (final ItemDeviceProvider provider : registry.getValues()) {
final Optional<DeviceType> device = provider.getDeviceType(query);
device.ifPresent(deviceTypes::add);
}
return deviceTypes;
}
///////////////////////////////////////////////////////////////////
private static class BlockQuery implements BlockDeviceQuery {

View File

@@ -7,13 +7,13 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.Optional;
public final class HardDiskDriveDevice extends AbstractHardDiskDriveDevice<ByteBufferBlockDevice> {
public final class HardDriveDevice extends AbstractHardDriveDevice<ByteBufferBlockDevice> {
private final int size;
private final boolean readonly;
///////////////////////////////////////////////////////////////////
public HardDiskDriveDevice(final ItemStack stack, final int size, final boolean readonly) {
public HardDriveDevice(final ItemStack stack, final int size, final boolean readonly) {
super(stack);
this.size = size;
this.readonly = readonly;

View File

@@ -2,7 +2,7 @@ package li.cil.oc2.common.bus.device;
import li.cil.oc2.Config;
import li.cil.oc2.api.bus.device.vm.*;
import li.cil.oc2.common.item.RamItem;
import li.cil.oc2.common.item.MemoryItem;
import li.cil.oc2.common.serialization.BlobStorage;
import li.cil.oc2.common.util.NBTTagIds;
import li.cil.sedna.api.device.PhysicalMemory;
@@ -35,7 +35,7 @@ public final class MemoryDevice extends AbstractItemDevice implements VMDevice,
public MemoryDevice(final ItemStack value) {
super(value);
size = MathHelper.clamp(RamItem.getCapacity(value), 0, Config.maxRamSize);
size = MathHelper.clamp(MemoryItem.getCapacity(value), 0, Config.maxMemorySize);
}
///////////////////////////////////////////////////////////////////
@@ -137,7 +137,7 @@ public final class MemoryDevice extends AbstractItemDevice implements VMDevice,
}
private void unload() {
// RAM is volatile, so free up our persisted blob when device is unloaded.
// Memory is volatile, so free up our persisted blob when device is unloaded.
BlobStorage.freeHandle(blobHandle);
blobHandle = null;

View File

@@ -13,11 +13,11 @@ import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Optional;
public final class SparseHardDiskDriveDevice extends AbstractHardDiskDriveDevice<SparseBlockDevice> {
public final class SparseHardDriveDevice extends AbstractHardDriveDevice<SparseBlockDevice> {
private final BlockDevice base;
private final boolean readonly;
public SparseHardDiskDriveDevice(final ItemStack stack, final BlockDevice base, final boolean readonly) {
public SparseHardDriveDevice(final ItemStack stack, final BlockDevice base, final boolean readonly) {
super(stack);
this.base = base;
this.readonly = readonly;

View File

@@ -1,13 +1,15 @@
package li.cil.oc2.common.bus.device.provider;
import li.cil.oc2.Config;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.api.bus.device.ItemDevice;
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
import li.cil.oc2.common.bus.device.HardDiskDriveDevice;
import li.cil.oc2.common.bus.device.SparseHardDiskDriveDevice;
import li.cil.oc2.common.bus.device.HardDriveDevice;
import li.cil.oc2.common.bus.device.SparseHardDriveDevice;
import li.cil.oc2.common.bus.device.provider.util.AbstractItemDeviceProvider;
import li.cil.oc2.common.init.Items;
import li.cil.oc2.common.item.HddItem;
import li.cil.oc2.common.item.HardDriveItem;
import li.cil.oc2.common.util.ItemStackUtils;
import li.cil.sedna.api.device.BlockDevice;
import li.cil.sedna.buildroot.Buildroot;
@@ -44,7 +46,7 @@ public final class HardDriveItemDeviceProvider extends AbstractItemDeviceProvide
///////////////////////////////////////////////////////////////////
public HardDriveItemDeviceProvider() {
super(Items.HDD_ITEM);
super(Items.HARD_DRIVE_ITEM);
}
///////////////////////////////////////////////////////////////////
@@ -58,17 +60,22 @@ public final class HardDriveItemDeviceProvider extends AbstractItemDeviceProvide
return Optional.empty();
}
final boolean readonly = HddItem.isReadonly(stack);
final String baseBlockDevice = HddItem.getBaseBlockDevice(stack);
final boolean readonly = HardDriveItem.isReadonly(stack);
final String baseBlockDevice = HardDriveItem.getBaseBlockDevice(stack);
if (baseBlockDevice != null) {
final BlockDevice base = getBaseBlockDevice(baseBlockDevice);
if (base != null) {
return Optional.of(new SparseHardDiskDriveDevice(stack, base, readonly));
return Optional.of(new SparseHardDriveDevice(stack, base, readonly));
}
}
final int size = MathHelper.clamp(HddItem.getCapacity(stack), 0, Config.maxHddSize);
return Optional.of(new HardDiskDriveDevice(stack, size, readonly));
final int size = MathHelper.clamp(HardDriveItem.getCapacity(stack), 0, Config.maxHardDriveSize);
return Optional.of(new HardDriveDevice(stack, size, readonly));
}
@Override
protected Optional<DeviceType> getItemDeviceType(final ItemDeviceQuery query) {
return Optional.of(DeviceTypes.HARD_DRIVE);
}
///////////////////////////////////////////////////////////////////

View File

@@ -1,5 +1,7 @@
package li.cil.oc2.common.bus.device.provider;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.api.bus.device.ItemDevice;
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
import li.cil.oc2.common.bus.device.MemoryDevice;
@@ -10,7 +12,7 @@ import java.util.Optional;
public final class MemoryItemDeviceProvider extends AbstractItemDeviceProvider {
public MemoryItemDeviceProvider() {
super(Items.RAM_ITEM);
super(Items.MEMORY_ITEM);
}
///////////////////////////////////////////////////////////////////
@@ -19,4 +21,9 @@ public final class MemoryItemDeviceProvider extends AbstractItemDeviceProvider {
protected Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query) {
return Optional.of(new MemoryDevice(query.getItemStack()));
}
@Override
protected Optional<DeviceType> getItemDeviceType(final ItemDeviceQuery query) {
return Optional.of(DeviceTypes.MEMORY);
}
}

View File

@@ -1,5 +1,7 @@
package li.cil.oc2.common.bus.device.provider.util;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.api.bus.device.ItemDevice;
import li.cil.oc2.api.bus.device.provider.ItemDeviceProvider;
import li.cil.oc2.api.bus.device.provider.ItemDeviceQuery;
@@ -27,19 +29,26 @@ public abstract class AbstractItemDeviceProvider extends ForgeRegistryEntry<Item
@Override
public final Optional<ItemDevice> getDevice(final ItemDeviceQuery query) {
final ItemStack stack = query.getItemStack();
if (stack.isEmpty()) {
return Optional.empty();
}
return matches(query) ? getItemDevice(query) : Optional.empty();
}
if (item != null && stack.getItem() != item.get()) {
return Optional.empty();
}
return getItemDevice(query);
@Override
public final Optional<DeviceType> getDeviceType(final ItemDeviceQuery query) {
return matches(query) ? getItemDeviceType(query) : Optional.empty();
}
///////////////////////////////////////////////////////////////////
protected abstract Optional<ItemDevice> getItemDevice(final ItemDeviceQuery query);
protected Optional<DeviceType> getItemDeviceType(final ItemDeviceQuery query) {
return Optional.of(DeviceTypes.CARD);
}
///////////////////////////////////////////////////////////////////
private boolean matches(final ItemDeviceQuery query) {
final ItemStack stack = query.getItemStack();
return !stack.isEmpty() && (item == null || stack.getItem() == item.get());
}
}

View File

@@ -9,19 +9,19 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
public final class Capabilities {
@CapabilityInject(DeviceBusElement.class) @SuppressWarnings("FieldMayBeFinal")
@CapabilityInject(DeviceBusElement.class)
public static Capability<DeviceBusElement> DEVICE_BUS_ELEMENT_CAPABILITY = null;
@CapabilityInject(DeviceBusController.class) @SuppressWarnings("FieldMayBeFinal")
@CapabilityInject(DeviceBusController.class)
public static Capability<DeviceBusController> DEVICE_BUS_CONTROLLER_CAPABILITY = null;
@CapabilityInject(IEnergyStorage.class) @SuppressWarnings("FieldMayBeFinal")
@CapabilityInject(IEnergyStorage.class)
public static Capability<IEnergyStorage> ENERGY_STORAGE_CAPABILITY = null;
@CapabilityInject(IFluidHandler.class) @SuppressWarnings("FieldMayBeFinal")
@CapabilityInject(IFluidHandler.class)
public static Capability<IFluidHandler> FLUID_HANDLER_CAPABILITY = null;
@CapabilityInject(IItemHandler.class) @SuppressWarnings("FieldMayBeFinal")
@CapabilityInject(IItemHandler.class)
public static Capability<IItemHandler> ITEM_HANDLER_CAPABILITY = null;
///////////////////////////////////////////////////////////////////

View File

@@ -1,5 +1,6 @@
package li.cil.oc2.common.container;
import li.cil.oc2.api.bus.device.DeviceTypes;
import li.cil.oc2.common.block.entity.ComputerTileEntity;
import li.cil.oc2.common.init.Blocks;
import li.cil.oc2.common.init.Containers;
@@ -10,8 +11,6 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IWorldPosCallable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import javax.annotation.Nullable;
@@ -38,13 +37,31 @@ public final class ComputerContainer extends AbstractContainer {
this.world = inventory.player.getEntityWorld();
this.pos = tileEntity.getPos();
final IItemHandler itemHandler = tileEntity.getItemHandler();
tileEntity.getItemHandler(DeviceTypes.EEPROM).ifPresent(itemHandler -> {
if (itemHandler.getSlots() > 0) {
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.EEPROM, 0, 64, 78));
}
});
for (int i = 0; i < itemHandler.getSlots(); ++i) {
this.addSlot(new SlotItemHandler(itemHandler, i, 8 + i * SLOT_SIZE, 20));
}
tileEntity.getItemHandler(DeviceTypes.MEMORY).ifPresent(itemHandler -> {
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.MEMORY, slot, 64 + slot * SLOT_SIZE, 24));
}
});
createPlayerInventoryAndHotbarSlots(inventory, 8, 51);
tileEntity.getItemHandler(DeviceTypes.HARD_DRIVE).ifPresent(itemHandler -> {
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.HARD_DRIVE, slot, 100 + (slot % 2) * SLOT_SIZE, 60 + (slot / 2) * SLOT_SIZE));
}
});
tileEntity.getItemHandler(DeviceTypes.CARD).ifPresent(itemHandler -> {
for (int slot = 0; slot < itemHandler.getSlots(); slot++) {
this.addSlot(new TypedSlotItemHandler(itemHandler, DeviceTypes.CARD, slot, 38, 24 + slot * SLOT_SIZE));
}
});
createPlayerInventoryAndHotbarSlots(inventory, 8, 115);
}
@Override

View File

@@ -63,11 +63,6 @@ public class DeviceItemStackHandler extends ItemStackHandler {
return 1;
}
@Override
public boolean isItemValid(final int slot, @NotNull final ItemStack stack) {
return super.isItemValid(slot, stack);
}
///////////////////////////////////////////////////////////////////
@Override

View File

@@ -0,0 +1,19 @@
package li.cil.oc2.common.container;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.common.bus.device.Devices;
import net.minecraft.item.ItemStack;
public class TypedDeviceItemStackHandler extends DeviceItemStackHandler {
private final DeviceType deviceType;
public TypedDeviceItemStackHandler(final int size, final DeviceType deviceType) {
super(size);
this.deviceType = deviceType;
}
@Override
public boolean isItemValid(final int slot, final ItemStack stack) {
return super.isItemValid(slot, stack) && Devices.getDeviceTypes(stack).contains(deviceType);
}
}

View File

@@ -0,0 +1,29 @@
package li.cil.oc2.common.container;
import com.mojang.datafixers.util.Pair;
import li.cil.oc2.api.bus.device.DeviceType;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;
import javax.annotation.Nullable;
public final class TypedSlotItemHandler extends SlotItemHandler {
private final DeviceType deviceType;
public TypedSlotItemHandler(final IItemHandler itemHandler, final DeviceType deviceType, final int index, final int xPosition, final int yPosition) {
super(itemHandler, index, xPosition, yPosition);
this.deviceType = deviceType;
}
@Nullable
@Override
public Pair<ResourceLocation, ResourceLocation> getBackground() {
if (getHasStack()) {
return super.getBackground();
} else {
return Pair.of(PlayerContainer.LOCATION_BLOCKS_TEXTURE, deviceType.getIcon());
}
}
}

View File

@@ -0,0 +1,55 @@
package li.cil.oc2.common.init;
import li.cil.oc2.api.API;
import li.cil.oc2.api.bus.device.DeviceType;
import li.cil.oc2.common.bus.device.DeviceTypeImpl;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.IForgeRegistry;
import net.minecraftforge.registries.RegistryBuilder;
import java.util.function.Supplier;
public final class DeviceTypes {
private static final DeferredRegister<DeviceType> DEVICE_TYPES = DeferredRegister.create(DeviceType.class, API.MOD_ID);
///////////////////////////////////////////////////////////////////
public static final Supplier<IForgeRegistry<DeviceType>> DEVICE_TYPE_REGISTRY = DEVICE_TYPES.makeRegistry(DeviceType.REGISTRY_ID.getPath(), RegistryBuilder::new);
///////////////////////////////////////////////////////////////////
public static void initialize() {
register("eeprom");
register("memory");
register("hard_drive");
register("card");
DEVICE_TYPES.register(FMLJavaModLoadingContext.get().getModEventBus());
FMLJavaModLoadingContext.get().getModEventBus().addListener(DeviceTypes::handleTextureStitchEvent);
}
///////////////////////////////////////////////////////////////////
private static void register(final String name) {
DEVICE_TYPES.register(name, () -> new DeviceTypeImpl(
new ResourceLocation(API.MOD_ID, "gui/icon/" + name),
new TranslationTextComponent("gui.oc2.device_type." + name)
));
}
private static void handleTextureStitchEvent(final TextureStitchEvent.Pre event) {
if (event.getMap().getTextureLocation() != PlayerContainer.LOCATION_BLOCKS_TEXTURE) {
return;
}
for (final DeviceType deviceType : DEVICE_TYPE_REGISTRY.get().getValues()) {
event.addSprite(deviceType.getIcon());
}
}
}

View File

@@ -27,8 +27,8 @@ public final class Items {
public static final RegistryObject<Item> BUS_INTERFACE_ITEM = register(Constants.BUS_INTERFACE_ITEM_NAME, BusInterfaceItem::new);
public static final RegistryObject<Item> WRENCH_ITEM = register(Constants.WRENCH_ITEM_NAME, WrenchItem::new);
public static final RegistryObject<Item> HDD_ITEM = register(Constants.HDD_ITEM_NAME, HddItem::new, new Item.Properties());
public static final RegistryObject<Item> RAM_ITEM = register(Constants.RAM_ITEM_NAME, RamItem::new, new Item.Properties());
public static final RegistryObject<Item> HARD_DRIVE_ITEM = register(Constants.HARD_DRIVE_ITEM_NAME, HardDriveItem::new, new Item.Properties());
public static final RegistryObject<Item> MEMORY_ITEM = register(Constants.MEMORY_ITEM_NAME, MemoryItem::new, new Item.Properties());
///////////////////////////////////////////////////////////////////

View File

@@ -18,8 +18,8 @@ import net.minecraft.util.text.TranslationTextComponent;
import javax.annotation.Nullable;
public class HddItem extends Item {
public static final ResourceLocation CAPACITY_PROPERTY = new ResourceLocation(API.MOD_ID, "hdd_capacity");
public final class HardDriveItem extends Item {
public static final ResourceLocation CAPACITY_PROPERTY = new ResourceLocation(API.MOD_ID, "hard_drive_capacity");
public static final String CAPACITY_TAG_NAME = "size";
public static final String BASE_TAG_NAME = "base";
public static final String READONLY_TAG_NAME = "readonly";
@@ -63,9 +63,9 @@ public class HddItem extends Item {
return modNbt.getBoolean(READONLY_TAG_NAME);
}
public HddItem(final Properties properties) {
public HardDriveItem(final Properties properties) {
super(properties);
ItemModelsProperties.registerProperty(this, CAPACITY_PROPERTY, HddItem::getHddItemProperties);
ItemModelsProperties.registerProperty(this, CAPACITY_PROPERTY, HardDriveItem::getHardDriveItemProperties);
}
@Override
@@ -82,7 +82,7 @@ public class HddItem extends Item {
}
}
private static float getHddItemProperties(final ItemStack stack, final ClientWorld world, final LivingEntity entity) {
private static float getHardDriveItemProperties(final ItemStack stack, final ClientWorld world, final LivingEntity entity) {
return getCapacity(stack);
}
}

View File

@@ -17,14 +17,14 @@ public final class ItemGroup {
public void fill(final NonNullList<ItemStack> items) {
super.fill(items);
items.add(RamItem.withCapacity(new ItemStack(Items.RAM_ITEM.get()), 2 * Constants.MEGABYTE));
items.add(RamItem.withCapacity(new ItemStack(Items.RAM_ITEM.get()), 4 * Constants.MEGABYTE));
items.add(RamItem.withCapacity(new ItemStack(Items.RAM_ITEM.get()), 8 * Constants.MEGABYTE));
items.add(MemoryItem.withCapacity(new ItemStack(Items.MEMORY_ITEM.get()), 2 * Constants.MEGABYTE));
items.add(MemoryItem.withCapacity(new ItemStack(Items.MEMORY_ITEM.get()), 4 * Constants.MEGABYTE));
items.add(MemoryItem.withCapacity(new ItemStack(Items.MEMORY_ITEM.get()), 8 * Constants.MEGABYTE));
items.add(HddItem.withCapacity(new ItemStack(Items.HDD_ITEM.get()), 2 * Constants.MEGABYTE));
items.add(HddItem.withCapacity(new ItemStack(Items.HDD_ITEM.get()), 4 * Constants.MEGABYTE));
items.add(HddItem.withCapacity(new ItemStack(Items.HDD_ITEM.get()), 8 * Constants.MEGABYTE));
items.add(HddItem.withBaseBlockDevice(new ItemStack(Items.HDD_ITEM.get()), "linux"));
items.add(HardDriveItem.withCapacity(new ItemStack(Items.HARD_DRIVE_ITEM.get()), 2 * Constants.MEGABYTE));
items.add(HardDriveItem.withCapacity(new ItemStack(Items.HARD_DRIVE_ITEM.get()), 4 * Constants.MEGABYTE));
items.add(HardDriveItem.withCapacity(new ItemStack(Items.HARD_DRIVE_ITEM.get()), 8 * Constants.MEGABYTE));
items.add(HardDriveItem.withBaseBlockDevice(new ItemStack(Items.HARD_DRIVE_ITEM.get()), "linux"));
}
};
}

View File

@@ -16,8 +16,8 @@ import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
public class RamItem extends Item {
public static final ResourceLocation CAPACITY_PROPERTY = new ResourceLocation(API.MOD_ID, "ram_capacity");
public final class MemoryItem extends Item {
public static final ResourceLocation CAPACITY_PROPERTY = new ResourceLocation(API.MOD_ID, "memory_capacity");
public static final String CAPACITY_TAG_NAME = "size";
public static final int DEFAULT_CAPACITY = 2 * Constants.MEGABYTE;
@@ -35,9 +35,9 @@ public class RamItem extends Item {
return stack;
}
public RamItem(final Properties properties) {
public MemoryItem(final Properties properties) {
super(properties);
ItemModelsProperties.registerProperty(this, CAPACITY_PROPERTY, RamItem::getRamItemProperties);
ItemModelsProperties.registerProperty(this, CAPACITY_PROPERTY, MemoryItem::getMemoryItemProperties);
}
@Override
@@ -47,7 +47,7 @@ public class RamItem extends Item {
.append(new TranslationTextComponent(Constants.TOOLTIP_SUFFIX_FORMAT, TextFormatUtils.formatSize(getCapacity(stack))));
}
private static float getRamItemProperties(final ItemStack stack, final ClientWorld world, final LivingEntity entity) {
private static float getMemoryItemProperties(final ItemStack stack, final ClientWorld world, final LivingEntity entity) {
return getCapacity(stack);
}
}

View File

@@ -6,5 +6,5 @@ import li.cil.sedna.api.device.MemoryMappedDevice;
import java.util.OptionalLong;
public interface DefaultAddressProvider {
OptionalLong getDefaultAddress(final VMDevice wrapper, final MemoryMappedDevice device);
OptionalLong getDefaultAddress(final VMDevice wrapper);
}

View File

@@ -16,7 +16,7 @@ public final class VirtualMachineDeviceBusAdapter {
private final ArrayList<VMDevice> incompleteLoads = new ArrayList<>();
private final HashSet<VMDeviceLifecycleListener> lifecycleEventListeners = new HashSet<>();
private DefaultAddressProvider defaultAddressProvider = (wrapper, device) -> OptionalLong.empty();
private DefaultAddressProvider defaultAddressProvider = unused -> OptionalLong.empty();
///////////////////////////////////////////////////////////////////
@@ -51,7 +51,7 @@ public final class VirtualMachineDeviceBusAdapter {
final ManagedVMContext context = new ManagedVMContext(
board, claimedInterrupts, reservedInterrupts,
(memoryMappedDevice) -> defaultAddressProvider.getDefaultAddress(device, memoryMappedDevice));
(memoryMappedDevice) -> defaultAddressProvider.getDefaultAddress(device));
deviceContexts.put(device, context);

View File

@@ -3,8 +3,8 @@ package li.cil.oc2.data;
import li.cil.oc2.Constants;
import li.cil.oc2.api.API;
import li.cil.oc2.common.init.Items;
import li.cil.oc2.common.item.HddItem;
import li.cil.oc2.common.item.RamItem;
import li.cil.oc2.common.item.HardDriveItem;
import li.cil.oc2.common.item.MemoryItem;
import net.minecraft.data.DataGenerator;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
@@ -22,24 +22,24 @@ public final class ItemModels extends ItemModelProvider {
protected void registerModels() {
simple(Items.WRENCH_ITEM, "items/wrench");
simple(Items.RAM_ITEM, "items/ram1")
simple(Items.MEMORY_ITEM, "items/memory1")
.override()
.predicate(RamItem.CAPACITY_PROPERTY, 4 * Constants.MEGABYTE)
.model(simple(Items.RAM_ITEM, "items/ram2", "2"))
.predicate(MemoryItem.CAPACITY_PROPERTY, 4 * Constants.MEGABYTE)
.model(simple(Items.MEMORY_ITEM, "items/memory2", "2"))
.end()
.override()
.predicate(RamItem.CAPACITY_PROPERTY, 8 * Constants.MEGABYTE)
.model(simple(Items.RAM_ITEM, "items/ram3", "3"))
.predicate(MemoryItem.CAPACITY_PROPERTY, 8 * Constants.MEGABYTE)
.model(simple(Items.MEMORY_ITEM, "items/memory3", "3"))
.end();
simple(Items.HDD_ITEM, "items/hdd1")
simple(Items.HARD_DRIVE_ITEM, "items/hard_drive1")
.override()
.predicate(HddItem.CAPACITY_PROPERTY, 4 * Constants.MEGABYTE)
.model(simple(Items.HDD_ITEM, "items/hdd2", "2"))
.predicate(HardDriveItem.CAPACITY_PROPERTY, 4 * Constants.MEGABYTE)
.model(simple(Items.HARD_DRIVE_ITEM, "items/hard_drive2", "2"))
.end()
.override()
.predicate(HddItem.CAPACITY_PROPERTY, 8 * Constants.MEGABYTE)
.model(simple(Items.HDD_ITEM, "items/hdd3", "3"))
.predicate(HardDriveItem.CAPACITY_PROPERTY, 8 * Constants.MEGABYTE)
.model(simple(Items.HARD_DRIVE_ITEM, "items/hard_drive3", "3"))
.end();
}

View File

@@ -8,14 +8,19 @@
"item.oc2.wrench": "Scrench",
"item.oc2.bus_interface": "Bus Interface",
"item.oc2.ram": "RAM",
"item.oc2.hdd": "HDD",
"item.oc2.memory": "Memory",
"item.oc2.hard_drive": "Hard Drive",
"tooltip.oc2.suffix_format": " (%s)",
"gui.oc2.computer.boot_error.unknown": "Unknown Error",
"gui.oc2.computer.boot_error.no_ram": "Insufficient Memory",
"gui.oc2.computer.boot_error.no_memory": "Insufficient Memory",
"gui.oc2.computer.bus_state.incomplete": "Bus Incomplete",
"gui.oc2.computer.bus_state.too_complex": "Bus Too Complex",
"gui.oc2.computer.bus_state.multiple_controllers": "Multiple Bus Controllers"
"gui.oc2.computer.bus_state.multiple_controllers": "Multiple Bus Controllers",
"gui.oc2.device_type.eeprom": "EEPROM",
"gui.oc2.device_type.memory": "Memory",
"gui.oc2.device_type.hard_drive": "Hard Drive",
"gui.oc2.device_type.card": "Card"
}

View File

@@ -0,0 +1,20 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/hard_drive1"
},
"overrides": [
{
"predicate": {
"oc2:hard_drive_capacity": 4194304.0
},
"model": "oc2:item/hard_drive2"
},
{
"predicate": {
"oc2:hard_drive_capacity": 8388608.0
},
"model": "oc2:item/hard_drive3"
}
]
}

View File

@@ -1,6 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/ram2"
"layer0": "oc2:items/hard_drive2"
}
}

View File

@@ -1,6 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/ram3"
"layer0": "oc2:items/hard_drive3"
}
}

View File

@@ -1,20 +0,0 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/hdd1"
},
"overrides": [
{
"predicate": {
"oc2:hdd_capacity": 4194304.0
},
"model": "oc2:item/hdd2"
},
{
"predicate": {
"oc2:hdd_capacity": 8388608.0
},
"model": "oc2:item/hdd3"
}
]
}

View File

@@ -0,0 +1,20 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/memory1"
},
"overrides": [
{
"predicate": {
"oc2:memory_capacity": 4194304.0
},
"model": "oc2:item/memory2"
},
{
"predicate": {
"oc2:memory_capacity": 8388608.0
},
"model": "oc2:item/memory3"
}
]
}

View File

@@ -1,6 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/hdd2"
"layer0": "oc2:items/memory2"
}
}

View File

@@ -1,6 +1,6 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/hdd3"
"layer0": "oc2:items/memory3"
}
}

View File

@@ -1,20 +0,0 @@
{
"parent": "minecraft:item/handheld",
"textures": {
"layer0": "oc2:items/ram1"
},
"overrides": [
{
"predicate": {
"oc2:ram_capacity": 4194304.0
},
"model": "oc2:item/ram2"
},
{
"predicate": {
"oc2:ram_capacity": 8388608.0
},
"model": "oc2:item/ram3"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 425 B

After

Width:  |  Height:  |  Size: 425 B

View File

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 429 B

View File

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 429 B

View File

Before

Width:  |  Height:  |  Size: 300 B

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

View File

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B