diff --git a/src/main/java/net/brokenmoon/redcontrol/RedControl.java b/src/main/java/net/brokenmoon/redcontrol/RedControl.java index 5c39292..550beea 100644 --- a/src/main/java/net/brokenmoon/redcontrol/RedControl.java +++ b/src/main/java/net/brokenmoon/redcontrol/RedControl.java @@ -1,8 +1,10 @@ package net.brokenmoon.redcontrol; import net.brokenmoon.redcontrol.blockentities.CpuEntity; +import net.brokenmoon.redcontrol.blockentities.DriveEntity; import net.brokenmoon.redcontrol.blockentities.MonitorEntity; import net.brokenmoon.redcontrol.blocks.CpuBlock; +import net.brokenmoon.redcontrol.blocks.DriveBlock; import net.brokenmoon.redcontrol.blocks.MonitorBlock; import net.fabricmc.api.ModInitializer; @@ -27,11 +29,13 @@ public class RedControl implements ModInitializer { //Blocks public static final CpuBlock CPU = new CpuBlock(FabricBlockSettings.create().strength(4.0f)); public static final MonitorBlock MONITOR = new MonitorBlock(FabricBlockSettings.create().strength(4.0f)); + public static final DriveBlock DRIVE = new DriveBlock(FabricBlockSettings.create().strength(4.0f)); //Items //Block Entities public static final BlockEntityType CPU_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, new Identifier("redcontrol", "cpu_block_entity"), FabricBlockEntityTypeBuilder.create(CpuEntity::new, CPU).build()); public static final BlockEntityType MONITOR_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, new Identifier("redcontrol", "monitor_block_entity"), FabricBlockEntityTypeBuilder.create(MonitorEntity::new, MONITOR).build()); + public static final BlockEntityType DRIVE_BLOCK_ENTITY = Registry.register(Registries.BLOCK_ENTITY_TYPE, new Identifier("redcontrol", "drive_block_entity"), FabricBlockEntityTypeBuilder.create(DriveEntity::new, DRIVE).build()); @Override public void onInitialize() { @@ -42,8 +46,10 @@ public class RedControl implements ModInitializer { LOGGER.info("Initializing RedControl!"); Registry.register(Registries.BLOCK, new Identifier("redcontrol", "cpu"), CPU); Registry.register(Registries.BLOCK, new Identifier("redcontrol", "monitor"), MONITOR); + Registry.register(Registries.BLOCK, new Identifier("redcontrol", "drive"), DRIVE); Registry.register(Registries.ITEM, new Identifier("redcontrol", "cpu"), new BlockItem(CPU, new FabricItemSettings())); Registry.register(Registries.ITEM, new Identifier("redcontrol", "monitor"), new BlockItem(MONITOR, new FabricItemSettings())); + Registry.register(Registries.ITEM, new Identifier("redcontrol", "drive"), new BlockItem(DRIVE, new FabricItemSettings())); } } \ No newline at end of file diff --git a/src/main/java/net/brokenmoon/redcontrol/api/RCBus.java b/src/main/java/net/brokenmoon/redcontrol/api/RCBus.java index aa29fa9..6f05e12 100644 --- a/src/main/java/net/brokenmoon/redcontrol/api/RCBus.java +++ b/src/main/java/net/brokenmoon/redcontrol/api/RCBus.java @@ -1,24 +1,28 @@ package net.brokenmoon.redcontrol.api; +import com.simon816.j65el02.Bus; import com.simon816.j65el02.device.RedBus; +import net.brokenmoon.redcontrol.RedControl; import net.brokenmoon.redcontrol.blockentities.Peripheral; import net.brokenmoon.redcontrol.blocks.NetworkCarrier; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -public class RCBus { +public class RCBus extends Bus { private boolean isValid = false; private RedBus redBus; public RCBus(RedBus redBus) { + super(redBus); this.redBus = redBus; } public void write(int address, int data, World world, BlockPos pos) { if(isValid) { - getRedBus().write(address, data); + RedControl.LOGGER.info("Writing! " + address + " " + data); + getRedBus().write(address, data); } else { generateBusWithWrite(address, data, world, pos); } @@ -30,6 +34,7 @@ public class RCBus { public int read(int address, boolean cpuAccess, World world, BlockPos pos) { if(isValid) { + RedControl.LOGGER.info("Reading! " + address + " " + cpuAccess); return getRedBus().read(address, cpuAccess) & 0xff; } else { return generateBusWithRead(address, cpuAccess, world, pos); diff --git a/src/main/java/net/brokenmoon/redcontrol/api/RCCpu.java b/src/main/java/net/brokenmoon/redcontrol/api/RCCpu.java index 1e9bb05..2cb7080 100644 --- a/src/main/java/net/brokenmoon/redcontrol/api/RCCpu.java +++ b/src/main/java/net/brokenmoon/redcontrol/api/RCCpu.java @@ -1,20 +1,17 @@ package net.brokenmoon.redcontrol.api; import com.simon816.j65el02.Cpu; +import com.simon816.j65el02.CpuState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; public class RCCpu extends Cpu { - - private RCBus rcbus; - - public RCCpu() { - } - - public RCBus getRCBus() { - return rcbus; - } + private final World world; + private final BlockPos pos; - public void setRCBus(RCBus rcbus) { - this.rcbus = rcbus; + public RCCpu(World world, BlockPos pos) { + this.world = world; + this.pos = pos; } } diff --git a/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java b/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java index 7af514c..90f5b4c 100644 --- a/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java +++ b/src/main/java/net/brokenmoon/redcontrol/blockentities/CpuEntity.java @@ -1,15 +1,11 @@ package net.brokenmoon.redcontrol.blockentities; import com.simon816.j65el02.Bus; -import com.simon816.j65el02.Cpu; import com.simon816.j65el02.device.*; import net.brokenmoon.redcontrol.RedControl; import net.brokenmoon.redcontrol.api.RCBus; import net.brokenmoon.redcontrol.api.RCCpu; -import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BrewingStandBlockEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -37,7 +33,7 @@ public class CpuEntity extends Peripheral implements Runnable{ boolean notTicked = true; private boolean running = false; private Semaphore waiInterrupt = new Semaphore(2); - private final RCCpu cpu; + private RCCpu cpu; private RCBus rcbus; private Path bootloader; @@ -50,22 +46,22 @@ public class CpuEntity extends Peripheral implements Runnable{ public CpuEntity(BlockPos pos, BlockState state) { super(RedControl.CPU_BLOCK_ENTITY, pos, state, 0); RedControl.LOGGER.info("Making CpuEntity"); - this.cpu = new RCCpu(); - this.setRCBus(new RCBus(new RedBus())); - this.cpu.setRCBus(this.getRCBus()); - this.cpu.setBus(new Bus(this.getRCBus().getRedBus())); - Memory ram = new Memory(0x0000, 0x2000); - try { - ram.loadFromFile(bootloader, 0x400, 0x100); - } catch (IOException e) { - throw new RuntimeException(e); - } - cpu.getBus().addDevice(ram); } public static void tick(World world, BlockPos pos, BlockState state, CpuEntity be) { if(be.notTicked) { + be.cpu = new RCCpu(world, pos); + be.setRCBus(new RCBus(new RedBus())); + be.cpu.setBus(be.getRCBus()); + be.cpu.setBus(new Bus(be.getRCBus().getRedBus())); + Memory ram = new Memory(0x0000, 0x2000); + try { + ram.loadFromFile(be.bootloader, 0x400, 0x100); + } catch (IOException e) { + throw new RuntimeException(e); + } + be.cpu.getBus().addDevice(ram); be.reset(); be.notTicked = false; be.start(); diff --git a/src/main/java/net/brokenmoon/redcontrol/blockentities/DriveEntity.java b/src/main/java/net/brokenmoon/redcontrol/blockentities/DriveEntity.java new file mode 100644 index 0000000..b5dbff1 --- /dev/null +++ b/src/main/java/net/brokenmoon/redcontrol/blockentities/DriveEntity.java @@ -0,0 +1,124 @@ +package net.brokenmoon.redcontrol.blockentities; + +import com.simon816.j65el02.device.DiskDriver; +import com.simon816.j65el02.device.FileDiskDriver; +import net.brokenmoon.redcontrol.RedControl; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.util.math.BlockPos; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.file.Paths; + +public class DriveEntity extends Peripheral{ + + private static final int SECTOR_SIZE = 0x80; + + private final DiskDriver driver; + private final byte[] diskName = new byte[SECTOR_SIZE]; + private final byte[] diskSerial = new byte[SECTOR_SIZE]; + private final ByteBuffer buffer; + + private int sector; + private int command; + + public DriveEntity(BlockPos pos, BlockState state) { + super(RedControl.DRIVE_BLOCK_ENTITY, pos, state, 2); + + try { + this.driver = new FileDiskDriver(Paths.get("/home/astoria/code/java/mods/RedControl/src/main/resources/assets/redcontrol/image/redforth.img"), "Forth", "FORTH", false); + } catch (IOException e) { + throw new RuntimeException(e); + } + this.buffer = ByteBuffer.allocateDirect(SECTOR_SIZE); + byte[] name = driver.getDriveName(); + byte[] serial = driver.getDriveSerial(); + System.arraycopy(name, 0, this.diskName, 0, name.length); + System.arraycopy(serial, 0, this.diskSerial, 0, serial.length); + } + + @Override + public void write(int address, int data) { + 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) { + RedControl.LOGGER.info("Drive Reading"); + 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; + } + } + + @Override + public void update() { + try { + switch (this.command) { + case 0x01: // Read Disk Name + this.buffer.clear(); + this.buffer.put(this.diskName); + this.command = 0; + break; + case 0x02: // Write Disk Name + this.buffer.position(0); + this.buffer.get(this.diskName); + this.driver.writeDiskName(this.diskName); + this.command = 0; + break; + case 0x03: // Read Disk Serial + this.buffer.clear(); + this.buffer.put(this.diskSerial); + 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; + } + } +} diff --git a/src/main/java/net/brokenmoon/redcontrol/blockentities/MonitorEntity.java b/src/main/java/net/brokenmoon/redcontrol/blockentities/MonitorEntity.java index 5e3b4e1..0c6d554 100644 --- a/src/main/java/net/brokenmoon/redcontrol/blockentities/MonitorEntity.java +++ b/src/main/java/net/brokenmoon/redcontrol/blockentities/MonitorEntity.java @@ -26,6 +26,18 @@ public class MonitorEntity extends Peripheral { private byte[] keyBuffer = new byte[0x10]; private byte[][] windowData = new byte[HEIGHT][WIDTH]; + public String[] getText(){ + String[] l = new String[HEIGHT]; + for(int y = 0; y < HEIGHT; y++) { + String temp = ""; + for (int x = 0; x < WIDTH; x++) { + temp += (char) windowData[y][x]; + } + l[y] = temp; + } + return l; + } + private boolean isDisplayDirty; private boolean isCursorDirty; @@ -35,6 +47,7 @@ public class MonitorEntity extends Peripheral { @Override public void write(int address, int data) { + RedControl.LOGGER.info("Monitor Writing"); switch (address) { case 0x00: this.accessRow = data; @@ -85,6 +98,10 @@ public class MonitorEntity extends Peripheral { this.isDisplayDirty = true; this.windowData[this.accessRow][address - 0x10] = (byte) data; } + if (this.isDisplayDirty) { + this.isDisplayDirty = false; + this.update(); + } } } diff --git a/src/main/java/net/brokenmoon/redcontrol/blockentities/Peripheral.java b/src/main/java/net/brokenmoon/redcontrol/blockentities/Peripheral.java index 0ca4909..e6ef6d6 100644 --- a/src/main/java/net/brokenmoon/redcontrol/blockentities/Peripheral.java +++ b/src/main/java/net/brokenmoon/redcontrol/blockentities/Peripheral.java @@ -6,7 +6,13 @@ import net.brokenmoon.redcontrol.api.RCBus; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; public abstract class Peripheral extends BlockEntity implements RedBus.Peripheral { diff --git a/src/main/java/net/brokenmoon/redcontrol/blocks/CpuBlock.java b/src/main/java/net/brokenmoon/redcontrol/blocks/CpuBlock.java index c1a1b58..9b54b55 100644 --- a/src/main/java/net/brokenmoon/redcontrol/blocks/CpuBlock.java +++ b/src/main/java/net/brokenmoon/redcontrol/blocks/CpuBlock.java @@ -28,12 +28,6 @@ public class CpuBlock extends NetworkCarrier { return new CpuEntity(pos, state); } - @Override - public BlockRenderType getRenderType(BlockState state) { - // With inheriting from BlockWithEntity this defaults to INVISIBLE, so we need to change that! - return BlockRenderType.MODEL; - } - @Override public BlockEntityTicker getTicker(World world, BlockState state, BlockEntityType type) { return validateTicker(type, RedControl.CPU_BLOCK_ENTITY, (world1, pos, state1, be) -> CpuEntity.tick(world1, pos, state1, be)); diff --git a/src/main/java/net/brokenmoon/redcontrol/blocks/DriveBlock.java b/src/main/java/net/brokenmoon/redcontrol/blocks/DriveBlock.java new file mode 100644 index 0000000..8521c7c --- /dev/null +++ b/src/main/java/net/brokenmoon/redcontrol/blocks/DriveBlock.java @@ -0,0 +1,27 @@ +package net.brokenmoon.redcontrol.blocks; + +import com.mojang.serialization.MapCodec; +import net.brokenmoon.redcontrol.blockentities.DriveEntity; +import net.brokenmoon.redcontrol.blockentities.MonitorEntity; +import net.minecraft.block.BlockState; +import net.minecraft.block.BlockWithEntity; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.Nullable; + +public class DriveBlock extends NetworkCarrier{ + public DriveBlock(Settings settings) { + super(settings); + } + + @Override + protected MapCodec getCodec() { + return null; + } + + @Nullable + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new DriveEntity(pos, state); + } +} diff --git a/src/main/java/net/brokenmoon/redcontrol/blocks/MonitorBlock.java b/src/main/java/net/brokenmoon/redcontrol/blocks/MonitorBlock.java index ef16d4f..197df5c 100644 --- a/src/main/java/net/brokenmoon/redcontrol/blocks/MonitorBlock.java +++ b/src/main/java/net/brokenmoon/redcontrol/blocks/MonitorBlock.java @@ -7,7 +7,13 @@ import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockState; import net.minecraft.block.BlockWithEntity; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; public class MonitorBlock extends NetworkCarrier { @@ -25,4 +31,18 @@ public class MonitorBlock extends NetworkCarrier { public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { return new MonitorEntity(pos, state); } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + if (!world.isClient) { + MonitorEntity monitor = (MonitorEntity) world.getBlockEntity(pos); + player.sendMessage(Text.literal(String.valueOf(monitor.getBus().hashCode())), false); + String[] text = monitor.getText(); + for(int i = 0; i < text.length; i++){ + player.sendMessage(Text.literal(text[i]), false); + } + } + + return ActionResult.SUCCESS; + } } diff --git a/src/main/java/net/brokenmoon/redcontrol/blocks/NetworkCarrier.java b/src/main/java/net/brokenmoon/redcontrol/blocks/NetworkCarrier.java index 1597c77..ee99809 100644 --- a/src/main/java/net/brokenmoon/redcontrol/blocks/NetworkCarrier.java +++ b/src/main/java/net/brokenmoon/redcontrol/blocks/NetworkCarrier.java @@ -3,12 +3,14 @@ package net.brokenmoon.redcontrol.blocks; import com.simon816.j65el02.device.RedBus; import net.brokenmoon.redcontrol.api.RCBus; import net.brokenmoon.redcontrol.blockentities.Peripheral; -import net.minecraft.block.Block; -import net.minecraft.block.BlockEntityProvider; -import net.minecraft.block.BlockState; -import net.minecraft.block.BlockWithEntity; +import net.minecraft.block.*; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; @@ -33,15 +35,21 @@ public abstract class NetworkCarrier extends BlockWithEntity implements BlockEnt @Override public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { + if(world.getBlockEntity(pos) instanceof Peripheral){ + ((Peripheral) world.getBlockEntity(pos)).getBus().setValid(false); + } if (state.hasBlockEntity() && !state.isOf(newState.getBlock())) { world.removeBlockEntity(pos); } } - public void invalidateBus(World world, BlockPos pos){ - + @Override + public BlockRenderType getRenderType(BlockState state) { + // With inheriting from BlockWithEntity this defaults to INVISIBLE, so we need to change that! + return BlockRenderType.MODEL; } + public void generateBus(World world, BlockPos pos){ Block worldBlock = world.getBlockState(pos).getBlock(); if(world.getBlockEntity(pos) instanceof Peripheral){ @@ -90,4 +98,14 @@ public abstract class NetworkCarrier extends BlockWithEntity implements BlockEnt } return 0; } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + if (!world.isClient) { + Peripheral peripheral = (Peripheral) world.getBlockEntity(pos); + player.sendMessage(Text.literal(String.valueOf(peripheral.getBus().hashCode())), false); + } + + return ActionResult.SUCCESS; + } } diff --git a/src/main/resources/assets/redcontrol/image/redforth.img b/src/main/resources/assets/redcontrol/image/redforth.img new file mode 100644 index 0000000..a0536b5 Binary files /dev/null and b/src/main/resources/assets/redcontrol/image/redforth.img differ