You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

189 lines
6.7 KiB
Java

package net.brokenmoon.redcontrol.blockentities;
import com.simon816.j65el02.device.DiskDriver;
import net.brokenmoon.redcontrol.RedControl;
import net.brokenmoon.redcontrol.api.DriveFactory;
import net.brokenmoon.redcontrol.api.Peripheral;
import net.brokenmoon.redcontrol.item.FloppyDisk;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.UUID;
import static net.minecraft.item.ItemStack.DISPLAY_KEY;
import static net.minecraft.item.ItemStack.NAME_KEY;
public class DriveEntity extends Peripheral {
private static final int SECTOR_SIZE = 0x80;
private DiskDriver driver = null;
private ByteBuffer buffer = null;
private int sector;
private int command;
private ItemStack disk = ItemStack.EMPTY;
public DriveEntity(BlockPos pos, BlockState state) {
super(RedControl.DRIVE_BLOCK_ENTITY, pos, state, 2);
this.buffer = ByteBuffer.allocateDirect(SECTOR_SIZE);
}
@Override
public void write(int address, int data) {
if(driver != null) {
switch (address) {
case 0x80: // Sector number (lo)
this.sector = (this.sector & 0xff00) | data;
break;
case 0x81: // Sector number (hi)
this.sector = (data << 8) | (this.sector & 0xff);
break;
case 0x82: // Disk command
this.command = data;
break;
default: // Disk sector buffer
if (address >= 0 && address <= 0x7f) {
this.buffer.put(address, (byte) data);
}
}
}
}
@Override
public int read(int address) {
if(driver != null) {
switch (address) {
case 0x80: // Sector number (lo)
return this.sector & 0xff;
case 0x81: // Sector number (hi)
return (this.sector >> 8) & 0xff;
case 0x82: // Disk command
return this.command;
default: // Disk sector buffer
if (address >= 0 && address <= 0x7f) {
return this.buffer.get(address);
}
return 0;
}
}
return 0;
}
@Override
public void update() {
if(driver != null) {
try {
switch (this.command) {
case 0x01: // Read Disk Name
this.buffer.clear();
this.buffer.put(driver.getDriveName());
this.command = 0;
break;
case 0x02: // Write Disk Name
this.buffer.position(0);
byte[] diskName = new byte[SECTOR_SIZE];
this.buffer.get(diskName);
NbtCompound sub_nbt = new NbtCompound();
sub_nbt.putString(NAME_KEY, Text.Serialization.toJsonString(Text.literal(new String(diskName).trim()).setStyle(Style.EMPTY.withItalic(false))));
this.disk.setSubNbt(DISPLAY_KEY, sub_nbt);
this.driver.writeDiskName(diskName);
this.command = 0;
break;
case 0x03: // Read Disk Serial
this.buffer.clear();
this.buffer.put(driver.getDriveSerial());
this.command = 0;
break;
case 0x04: // Read Disk Sector
if (this.sector >= 0x800) {
this.command = 0xff;
break;
}
this.driver.seek(this.sector << 7);
this.buffer.position(0);
this.driver.read(this.buffer);
this.command = 0;
break;
case 0x05: // Write Disk Sector
if (this.sector >= 0x800) {
this.command = 0xff;
break;
}
this.driver.seek(this.sector << 7);
this.buffer.position(0);
this.driver.write(this.buffer);
this.command = 0;
break;
}
} catch (Exception e) {
this.command = 0xff;
//e.printStackTrace();
}
}
}
public ActionResult onUse(PlayerEntity player, Hand hand) {
if(!world.isClient) {
if (disk == ItemStack.EMPTY && player.getStackInHand(hand).getItem() instanceof FloppyDisk) {
return loadDisk(player, hand);
} else if (player.getStackInHand(hand) == ItemStack.EMPTY) {
return ejectDisk(player, hand);
}
}
return ActionResult.PASS;
}
private ActionResult ejectDisk(PlayerEntity player, Hand hand) {
player.setStackInHand(hand, disk.copy());
disk = ItemStack.EMPTY;
this.driver = null;
this.buffer = null;
markDirty();
return ActionResult.SUCCESS;
}
private ActionResult loadDisk(PlayerEntity player, Hand hand) {
disk = player.getStackInHand(hand).copy();
player.setStackInHand(hand, ItemStack.EMPTY);
if(!disk.hasNbt()){
NbtCompound newNbt = new NbtCompound();
String newUUID = UUID.randomUUID().toString();
newNbt.putString("uri", "save://" + newUUID + ".img");
newNbt.putString("serial", newUUID);
disk.setNbt(newNbt);
}
this.driver = DriveFactory.INSTANCE.createDriver(URI.create(disk.getNbt().getString("uri")), String.valueOf(disk.getName()), disk.getNbt().getString("serial"));
this.buffer = ByteBuffer.allocateDirect(SECTOR_SIZE);
markDirty();
return ActionResult.SUCCESS;
}
@Override
protected void writeNbt(NbtCompound nbt) {
//SUPER DUPER NOT DONE TODO: FINISH THIS.
NbtCompound compound = new NbtCompound();
disk.writeNbt(compound);
nbt.put("item",compound);
super.writeNbt(nbt);
}
@Override
public void readNbt(NbtCompound nbt) {
disk = ItemStack.fromNbt(nbt.getCompound("item"));
super.readNbt(nbt);
}
}