Should be a working bus. Probably real bad quality.

main
Astoria 7 months ago
parent 30d9aaeffb
commit f31f33fbb4

@ -8,35 +8,38 @@ import net.minecraft.world.World;
public class RCBus { public class RCBus {
boolean isValid = false; private boolean isValid = false;
private RedBus redBus; private RedBus redBus;
Peripheral[] peripherals = new Peripheral[256];
public RCBus(RedBus redBus) { public RCBus(RedBus redBus) {
this.redBus = redBus; this.redBus = redBus;
} }
public void write(int address, int data, World world, BlockPos pos) { public void write(int address, int data, World world, BlockPos pos) {
if(isValid) { if(isValid) {
Peripheral peripheral = peripherals[address]; getRedBus().write(address, data);
peripheral.getBus().getRedBus().write(address, data);
} else { } else {
generateBus(world, pos); generateBusWithWrite(address, data, world, pos);
write(address, data, world, pos);
} }
} }
private void generateBusWithWrite(int address, int data, World world, BlockPos pos) {
((NetworkCarrier)(world.getBlockState(pos).getBlock())).generateBusWithWrite(world, pos, address, data);
}
public int read(int address, boolean cpuAccess, World world, BlockPos pos) { public int read(int address, boolean cpuAccess, World world, BlockPos pos) {
if(isValid) { if(isValid) {
Peripheral peripheral = peripherals[address]; return getRedBus().read(address, cpuAccess) & 0xff;
return peripheral.getBus().getRedBus().read(address, cpuAccess) & 0xff;
} else { } else {
generateBus(world, pos); return generateBusWithRead(address, cpuAccess, world, pos);
return read(address, cpuAccess, world, pos);
} }
} }
private int generateBusWithRead(int address, boolean cpuAccess, World world, BlockPos pos) {
return ((NetworkCarrier)(world.getBlockState(pos).getBlock())).generateBusWithRead(world, pos, address, cpuAccess);
}
public void generateBus(World world, BlockPos pos){ public void generateBus(World world, BlockPos pos){
((NetworkCarrier)(world.getBlockState(pos).getBlock())).generateBus(world, pos); ((NetworkCarrier)(world.getBlockState(pos).getBlock())).generateBus(world, pos);
} }
@ -53,11 +56,11 @@ public class RCBus {
this.redBus.updatePeripheral(); this.redBus.updatePeripheral();
} }
public Peripheral[] getPeripherals(){ public boolean getValid(){
return peripherals; return this.isValid;
} }
public void setPeripherals(Peripheral[] peripherals){ public void setValid(boolean validity){
this.peripherals = peripherals; this.isValid = validity;
} }
} }

@ -9,11 +9,14 @@ import net.brokenmoon.redcontrol.api.RCCpu;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BrewingStandBlockEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Date;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
@ -31,7 +34,7 @@ public class CpuEntity extends Peripheral implements Runnable{
}; };
static Timer timer = new Timer(); static Timer timer = new Timer();
boolean notTicked = true;
private boolean running = false; private boolean running = false;
private Semaphore waiInterrupt = new Semaphore(2); private Semaphore waiInterrupt = new Semaphore(2);
private final RCCpu cpu; private final RCCpu cpu;
@ -58,9 +61,22 @@ public class CpuEntity extends Peripheral implements Runnable{
throw new RuntimeException(e); throw new RuntimeException(e);
} }
cpu.getBus().addDevice(ram); cpu.getBus().addDevice(ram);
reset();
}
public static void tick(World world, BlockPos pos, BlockState state, CpuEntity be) {
if(be.notTicked) {
be.reset();
be.notTicked = false;
be.start();
}
} }
public void start(){
timer.schedule(cpuTask, new Date(), 2L);
}
public RCBus getRCBus(){ public RCBus getRCBus(){
return this.rcbus; return this.rcbus;
} }
@ -90,12 +106,6 @@ public class CpuEntity extends Peripheral implements Runnable{
this.defaultMonitorId = id; this.defaultMonitorId = id;
} }
public void signal() {
if (this.waiInterrupt.availablePermits() < 2) {
this.waiInterrupt.release();
}
}
public boolean isRunning() { public boolean isRunning() {
return this.running; return this.running;
} }
@ -119,8 +129,8 @@ public class CpuEntity extends Peripheral implements Runnable{
public void reset() { public void reset() {
stop(); stop();
this.cpu.reset(); this.cpu.reset();
this.getRCBus().write(0, this.defaultDriveId, this.getWorld(), this.getPos()); this.getRCBus().write(0, this.defaultDriveId, getWorld(), this.getPos());
this.getRCBus().write(1, this.defaultMonitorId, this.getWorld(), this.getPos()); this.getRCBus().write(1, this.defaultMonitorId, getWorld(), this.getPos());
} }
public void step() { public void step() {
@ -140,4 +150,18 @@ public class CpuEntity extends Peripheral implements Runnable{
} }
} }
@Override
public void write(int address, int data) {
}
@Override
public int read(int address) {
return 0;
}
@Override
public void update() {
}
} }

@ -2,11 +2,194 @@ package net.brokenmoon.redcontrol.blockentities;
import net.brokenmoon.redcontrol.RedControl; import net.brokenmoon.redcontrol.RedControl;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
public class MonitorEntity extends Peripheral { public class MonitorEntity extends Peripheral {
public static final int WIDTH = 80;
public static final int HEIGHT = 50;
private int accessRow;
private int cursorX;
private int cursorY;
private int cursorMode = 2; // (0: hidden, 1: solid, 2: blink)
private int keyBufferStart;
private int keyBufferPos;
private int blitMode; // (1: fill, 2: invert; 3: shift)
private int blitXStartOrFill;
private int blitYStart;
private int blitXOffset;
private int blitYOffset;
private int blitWidth;
private int blitHeight;
private byte[] keyBuffer = new byte[0x10];
private byte[][] windowData = new byte[HEIGHT][WIDTH];
private boolean isDisplayDirty;
private boolean isCursorDirty;
public MonitorEntity(BlockPos pos, BlockState state) { public MonitorEntity(BlockPos pos, BlockState state) {
super(RedControl.MONITOR_BLOCK_ENTITY, pos, state, 1); super(RedControl.MONITOR_BLOCK_ENTITY, pos, state, 1);
} }
@Override
public void write(int address, int data) {
switch (address) {
case 0x00:
this.accessRow = data;
break;
case 0x01:
this.isCursorDirty = this.cursorX != data;
this.cursorX = data;
break;
case 0x02:
this.isCursorDirty = this.cursorY != data;
this.cursorY = data;
break;
case 0x03:
this.isCursorDirty = this.cursorMode != data;
this.cursorMode = data;
break;
case 0x04:
this.keyBufferStart = data & 0x0f;
break;
case 0x05:
this.keyBufferPos = data & 0x0f;
break;
case 0x06:
break;
case 0x07:
this.blitMode = data;
break;
case 0x08:
this.blitXStartOrFill = data;
break;
case 0x09:
this.blitYStart = data;
break;
case 0x0A:
this.blitXOffset = data;
break;
case 0x0B:
this.blitYOffset = data;
break;
case 0x0C:
this.blitWidth = data;
break;
case 0x0D:
this.blitHeight = data;
break;
default:
if (address >= 0x10 && address < 0x60) {
this.isDisplayDirty = true;
this.windowData[this.accessRow][address - 0x10] = (byte) data;
}
}
}
@Override
public int read(int address) {
switch (address) {
case 0x00:
return this.accessRow;
case 0x01:
return this.cursorX;
case 0x02:
return this.cursorY;
case 0x03:
return this.cursorMode;
case 0x04:
return this.keyBufferStart;
case 0x05:
return this.keyBufferPos;
case 0x06:
return this.keyBuffer[this.keyBufferStart] & 0xff;
case 0x07:
return this.blitMode;
case 0x08:
return this.blitXStartOrFill;
case 0x09:
return this.blitYStart;
case 0x0A:
return this.blitXOffset;
case 0x0B:
return this.blitYOffset;
case 0x0C:
return this.blitWidth;
case 0x0D:
return this.blitHeight;
default:
if (address >= 0x10 && address < 0x60) {
return this.windowData[this.accessRow][address - 0x10] & 0xff;
}
return 0;
}
}
@Override
public void update() {
int maxWidth = Math.min(WIDTH, this.blitWidth + this.blitXOffset);
int maxHeight = Math.min(HEIGHT, this.blitHeight + this.blitYOffset);
int row = this.blitYOffset;
int col;
this.isDisplayDirty |= this.blitMode != 0;
switch (this.blitMode) {
case 1: // fill
for (; row < maxHeight; row++) {
for (col = this.blitXOffset; col < maxWidth; col++) {
this.windowData[row][col] = (byte) this.blitXStartOrFill;
}
}
break;
case 2: // invert
for (; row < maxHeight; row++) {
for (col = this.blitXOffset; col < maxWidth; col++) {
this.windowData[row][col] ^= 0x80;
}
}
break;
case 3: // shift
int shiftX = this.blitXStartOrFill - this.blitXOffset;
int shiftY = this.blitYStart - this.blitYOffset;
for (; row < maxHeight; row++) {
int srcRow = row + shiftY;
if (srcRow >= 0 & srcRow < HEIGHT) {
for (col = this.blitXOffset; col < maxWidth; col++) {
int srcCol = col + shiftX;
if (srcCol >= 0 && srcCol < WIDTH) {
this.windowData[row][col] = this.windowData[srcRow][srcCol];
}
}
}
}
break;
}
this.blitMode = 0;
if (this.isCursorDirty) {
this.isCursorDirty = false;
this.updateCursor(this.cursorX, this.cursorY, this.cursorMode);
}
}
private void updateCursor(int cursorX, int cursorY, int cursorMode) {
}
/**
* Appends a key code to the key buffer.
*
* @param key The key code
*/
public void onKey(byte key) {
int nextPos = (this.keyBufferPos + 1) & 0x0f;
if (nextPos != this.keyBufferStart) {
this.keyBuffer[this.keyBufferPos] = key;
this.keyBufferPos = nextPos;
}
}
} }

@ -8,7 +8,7 @@ import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
public abstract class Peripheral extends BlockEntity { public abstract class Peripheral extends BlockEntity implements RedBus.Peripheral {
private RCBus bus; private RCBus bus;
@ -34,4 +34,8 @@ public abstract class Peripheral extends BlockEntity {
public void setId(int id) { public void setId(int id) {
this.id = id; this.id = id;
} }
public void onJoinBus() {
bus.getRedBus().setPeripheral(this.id, this);
}
} }

@ -1,11 +1,15 @@
package net.brokenmoon.redcontrol.blocks; package net.brokenmoon.redcontrol.blocks;
import com.mojang.serialization.MapCodec;
import com.simon816.j65el02.Cpu;
import net.brokenmoon.redcontrol.RedControl;
import net.brokenmoon.redcontrol.blockentities.CpuEntity; import net.brokenmoon.redcontrol.blockentities.CpuEntity;
import net.minecraft.block.Block; import net.minecraft.block.*;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityTicker;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class CpuBlock extends NetworkCarrier { public class CpuBlock extends NetworkCarrier {
@ -13,9 +17,26 @@ public class CpuBlock extends NetworkCarrier {
super(settings); super(settings);
} }
@Override
protected MapCodec<? extends BlockWithEntity> getCodec() {
return null;
}
@Nullable @Nullable
@Override @Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new CpuEntity(pos, state); 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 <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return validateTicker(type, RedControl.CPU_BLOCK_ENTITY, (world1, pos, state1, be) -> CpuEntity.tick(world1, pos, state1, be));
}
} }

@ -1,9 +1,11 @@
package net.brokenmoon.redcontrol.blocks; package net.brokenmoon.redcontrol.blocks;
import com.mojang.serialization.MapCodec;
import net.brokenmoon.redcontrol.blockentities.MonitorEntity; import net.brokenmoon.redcontrol.blockentities.MonitorEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.BlockWithEntity;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -13,6 +15,11 @@ public class MonitorBlock extends NetworkCarrier {
super(settings); super(settings);
} }
@Override
protected MapCodec<? extends BlockWithEntity> getCodec() {
return null;
}
@Nullable @Nullable
@Override @Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {

@ -6,14 +6,14 @@ import net.brokenmoon.redcontrol.blockentities.Peripheral;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.BlockWithEntity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public abstract class NetworkCarrier extends Block implements BlockEntityProvider { public abstract class NetworkCarrier extends BlockWithEntity implements BlockEntityProvider {
public NetworkCarrier(Settings settings) { public NetworkCarrier(Settings settings) {
super(settings); super(settings);
} }
@ -46,9 +46,48 @@ public abstract class NetworkCarrier extends Block implements BlockEntityProvide
Block worldBlock = world.getBlockState(pos).getBlock(); Block worldBlock = world.getBlockState(pos).getBlock();
if(world.getBlockEntity(pos) instanceof Peripheral){ if(world.getBlockEntity(pos) instanceof Peripheral){
Peripheral entityBlock = (Peripheral) world.getBlockEntity(pos); Peripheral entityBlock = (Peripheral) world.getBlockEntity(pos);
entityBlock.getBus().setPeripherals(new Peripheral[255]); if(entityBlock.getBus() == null)
entityBlock.getBus().getPeripherals()[entityBlock.getId()] = entityBlock; entityBlock.setBus(new RCBus(new RedBus()));
entityBlock.getBus().getRedBus().setPeripheral(entityBlock.getId(), entityBlock);
entityBlock.getBus().setValid(true);
floodBus(entityBlock.getBus(), world, pos);
} }
} }
private void floodBus(RCBus bus, World world, BlockPos pos) {
replaceBus(bus, world, pos.north());
replaceBus(bus, world, pos.south());
replaceBus(bus, world, pos.east());
replaceBus(bus, world, pos.west());
replaceBus(bus, world, pos.up());
replaceBus(bus, world, pos.down());
}
private void replaceBus(RCBus bus, World world, BlockPos pos) {
if(world.getBlockEntity(pos) instanceof Peripheral && ((Peripheral) world.getBlockEntity(pos)).getBus() != bus){
((Peripheral) world.getBlockEntity(pos)).setBus(bus);
((Peripheral) world.getBlockEntity(pos)).onJoinBus();
floodBus(bus, world, pos);
}
}
public void generateBusWithWrite(World world, BlockPos pos, int address, int data) {
if(world.getBlockEntity(pos) instanceof Peripheral){
Peripheral entityBlock = (Peripheral) world.getBlockEntity(pos);
generateBus(world,pos);
floodBus(entityBlock.getBus(), world, pos);
entityBlock.getBus().write(address, data, world, pos);
}
}
public int generateBusWithRead(World world, BlockPos pos, int address, boolean cpuAccess) {
if(world.getBlockEntity(pos) instanceof Peripheral){
Peripheral entityBlock = (Peripheral) world.getBlockEntity(pos);
generateBus(world,pos);
floodBus(entityBlock.getBus(), world, pos);
return entityBlock.getBus().read(address, cpuAccess, world, pos);
}
return 0;
}
} }

@ -1,25 +0,0 @@
package net.brokenmoon.redcontrol.driver;
import com.simon816.j65el02.device.RPMonitor;
public class MonitorBlockDriver implements RCMonitorDriver{
@Override
public void setMonitor(RPMonitor monitor) {
}
@Override
public void setMonitor(RCMonitor monitor) {
}
@Override
public void updateCursor(int cursorX, int cursorY, int cursorMode) {
}
@Override
public void update(byte[][] windowData) {
}
}

@ -1,20 +0,0 @@
package net.brokenmoon.redcontrol.driver;
import com.simon816.j65el02.device.RedBus;
public class RCMonitor implements RedBus.Peripheral {
@Override
public void write(int address, int data) {
}
@Override
public int read(int address) {
return 0;
}
@Override
public void update() {
}
}

@ -1,36 +0,0 @@
package net.brokenmoon.redcontrol.driver;
import com.simon816.j65el02.device.MonitorDriver;
import com.simon816.j65el02.device.RPMonitor;
public interface RCMonitorDriver extends MonitorDriver {
/**
* Called when the {@link RPMonitor} is constructed in order to associate the monitor with the
* driver.
*
* @param monitor The monitor
*/
public void setMonitor(RCMonitor monitor);
/**
* Called when the cursor data is changed.
*
* @param cursorX
* @param cursorY
* @param cursorMode
*/
public void updateCursor(int cursorX, int cursorY, int cursorMode);
/**
* Called when the display data has changed. The array is a 2D array of size
* [{@link RPMonitor#HEIGHT}][{@link RPMonitor#WIDTH}].
*
* The display data is character data (not pixels). The lower 7 bits is the character while the
* MSB is a flag whether the color should be inverted (i.e. foreground and background color
* should be switched). Mapping for the 7 bit value to character is defined by a charset, which
* must be agreed upon by the display driver and programs written for the device.
*
* @param windowData The character data
*/
public void update(byte[][] windowData);
}
Loading…
Cancel
Save