Added CPUs with integrated graphics capabilities, closes #1154.

This commit is contained in:
Florian Nücke 2015-05-20 22:58:36 +02:00
parent e67587ae60
commit 0f0953f981
19 changed files with 230 additions and 85 deletions

Binary file not shown.

View File

@ -0,0 +1,7 @@
# APU
![Awesomest Probability Unifier.](oredict:oc:apu1)
These parts are the merry marriage of a [CPU](cpu1.md) and [graphics card](graphicsCard1.md). Using one of these essentially gives you one more card slot to work with. Like a normal CPU, it defines the architecture of the [computer](../general/computer.md), and the number of components that can be connected to the [computer](../general/computer.md) before it stops working. In addition it also provides basic graphical capabilities.
Do note that due to the limited space on the chip, these CPUs are slightly slower than their "pure" equivalents, and provide comparatively low-fidelty graphics. So while the tier one APU can control as many components as a tier two CPU, it only runs as fast as a tier one CPU, and only provides the graphical fidelity of a tier one graphics card.

View File

@ -0,0 +1 @@
#REDIRECT apu1.md

View File

@ -43,6 +43,8 @@ item.oc.AbstractBusCard.name=Abstract Bus Card
item.oc.Acid.name=Grog
item.oc.ALU.name=Arithmetic Logic Unit (ALU)
item.oc.Analyzer.name=Analyzer
item.oc.APU0.name=Accelerated Processing Unit (APU) (Tier 1)
item.oc.APU1.name=Accelerated Processing Unit (APU) (Tier 2)
item.oc.ArrowKeys.name=Arrow Keys
item.oc.ButtonGroup.name=Button Group
item.oc.CardBase.name=Card Base
@ -239,6 +241,7 @@ oc:tooltip.Acid=A highly toxic pseudo-liquid, usually only consumed by certain p
oc:tooltip.Adapter=Used to control non-component blocks, such as vanilla blocks or blocks from other mods.
oc:tooltip.ALU=Adds numbers so you don't have to. It might be better this way.
oc:tooltip.Analyzer=Used to display information about blocks, such as their §faddress§7 and §fcomponent name§7.[nl] Also displays the error that caused a computer to crash if it did not shut down normally.
oc:tooltip.APU=This is a CPU with an integrated GPU (or IGP), when you just need that extra card slot.[nl] Supported components: §f%s§7[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7[nl] Operations/tick: §f%s§7
oc:tooltip.Assembler=Allows constructing robots and other devices from a number of different computer parts.
oc:tooltip.Cable=A cheap way of connecting blocks.
oc:tooltip.Capacitor=Stores energy for later use. Can be filled and emptied very quickly.

View File

@ -419,6 +419,16 @@ alu {
["oc:materialTransistor", "oc:circuitChip1", "oc:materialTransistor"]
[nuggetIron, "oc:materialTransistor", nuggetIron]]
}
apu1 {
input: [[nuggetGold, "oc:circuitChip1", nuggetGold]
["oc:cpu2", "oc:componentBus1", "oc:graphicsCard1"]
[nuggetGold, "oc:circuitChip1", nuggetGold]]
}
apu2 {
input: [[diamond, "oc:circuitChip2", diamond]
["oc:cpu3", "oc:componentBus2", "oc:graphicsCard2"]
[diamond, "oc:circuitChip2", diamond]]
}
componentBus1 {
input: [[nuggetIron, redstone, nuggetIron]
["oc:circuitChip1", "oc:materialCU", ""]

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 B

View File

@ -0,0 +1,18 @@
{
"animation": {
"frametime": 1,
"frames": [
{ "index": 0, "time": 3 },
{ "index": 1, "time": 3 },
{ "index": 2, "time": 3 },
{ "index": 3, "time": 3 },
{ "index": 4, "time": 3 },
{ "index": 5, "time": 3 },
{ "index": 4, "time": 3 },
{ "index": 3, "time": 3 },
{ "index": 2, "time": 3 },
{ "index": 1, "time": 3 },
{ "index": 0, "time": 3 }
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

View File

@ -0,0 +1,18 @@
{
"animation": {
"frametime": 1,
"frames": [
{ "index": 0, "time": 3 },
{ "index": 1, "time": 3 },
{ "index": 2, "time": 3 },
{ "index": 3, "time": 3 },
{ "index": 4, "time": 3 },
{ "index": 5, "time": 3 },
{ "index": 4, "time": 3 },
{ "index": 3, "time": 3 },
{ "index": 2, "time": 3 },
{ "index": 1, "time": 3 },
{ "index": 0, "time": 3 }
]
}
}

View File

@ -49,6 +49,8 @@ object Constants {
final val Alu = "alu"
final val Analyzer = "analyzer"
final val AngelUpgrade = "angelUpgrade"
final val APUTier1 = "apu1"
final val APUTier2 = "apu2"
final val ArrowKeys = "arrowKeys"
final val BatteryUpgradeTier1 = "batteryUpgrade1"
final val BatteryUpgradeTier2 = "batteryUpgrade2"

View File

@ -513,5 +513,9 @@ object Items extends ItemAPI {
// 1.5.8
Recipes.addSubItem(new item.UpgradeHover(multi, Tier.One), Constants.ItemName.HoverUpgradeTier1, "oc:hoverUpgrade1")
Recipes.addSubItem(new item.UpgradeHover(multi, Tier.Two), Constants.ItemName.HoverUpgradeTier2, "oc:hoverUpgrade2")
// 1.5.10
Recipes.addSubItem(new item.APU(multi, Tier.One), Constants.ItemName.APUTier1, "oc:apu1")
Recipes.addSubItem(new item.APU(multi, Tier.Two), Constants.ItemName.APUTier2, "oc:apu2")
}
}

View File

@ -0,0 +1,17 @@
package li.cil.oc.common.item
import scala.language.existentials
class APU(val parent: Delegator, val tier: Int) extends Delegate with ItemTier with traits.CPULike with traits.GPULike {
override val unlocalizedName = super[Delegate].unlocalizedName + tier
override def cpuTier = tier + 1
override def gpuTier = tier
override protected def tooltipName = Option(super[Delegate].unlocalizedName)
override protected def tooltipData: Seq[Any] = {
super[CPULike].tooltipData ++ super[GPULike].tooltipData
}
}

View File

@ -1,69 +1,11 @@
package li.cil.oc.common.item
import java.util
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.machine.Architecture
import li.cil.oc.util.Tooltip
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.ChatComponentTranslation
import net.minecraft.world.World
import scala.collection.convert.WrapAsScala._
import scala.language.existentials
class CPU(val parent: Delegator, val tier: Int) extends Delegate with ItemTier {
class CPU(val parent: Delegator, val tier: Int) extends Delegate with ItemTier with traits.CPULike {
override val unlocalizedName = super.unlocalizedName + tier
override def cpuTier = tier
override protected def tooltipName = Option(super.unlocalizedName)
override protected def tooltipData = Seq(Settings.get.cpuComponentSupport(tier))
override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) {
(if (stack.hasTagCompound) {
Option(stack.getTagCompound.getString(Settings.namespace + "archName"))
}
else {
val architectures = allArchitectures
architectures.headOption.map(_._2)
}) match {
case Some(archName) => tooltip.addAll(Tooltip.get("CPU.Architecture", archName))
case _ => // No architecture.
}
}
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = {
if (player.isSneaking) {
if (!world.isRemote) {
val architectures = allArchitectures
if (architectures.length > 0) {
val currentIndex = if (stack.hasTagCompound) {
val currentArch = stack.getTagCompound.getString(Settings.namespace + "archClass")
architectures.indexWhere(_._1.getName == currentArch)
}
else {
stack.setTagCompound(new NBTTagCompound())
-1
}
val index = (currentIndex + 1) % architectures.length
val (archClass, archName) = architectures(index)
stack.getTagCompound.setString(Settings.namespace + "archClass", archClass.getName)
stack.getTagCompound.setString(Settings.namespace + "archName", archName)
player.addChatMessage(new ChatComponentTranslation(Settings.namespace + "tooltip.CPU.Architecture", archName))
}
player.swingItem()
}
}
stack
}
private def allArchitectures = api.Machine.architectures.map { arch =>
arch.getAnnotation(classOf[Architecture.Name]) match {
case annotation: Architecture.Name => (arch, annotation.value)
case _ => (arch, arch.getSimpleName)
}
}.toArray
}

View File

@ -1,21 +1,9 @@
package li.cil.oc.common.item
import li.cil.oc.Settings
import li.cil.oc.util.PackedColor
class GraphicsCard(val parent: Delegator, val tier: Int) extends Delegate with ItemTier {
class GraphicsCard(val parent: Delegator, val tier: Int) extends Delegate with ItemTier with traits.GPULike {
override val unlocalizedName = super.unlocalizedName + tier
override protected def tooltipName = Option(super.unlocalizedName)
override def gpuTier = tier
override protected def tooltipData = {
val (w, h) = Settings.screenResolutionsByTier(tier)
val depth = PackedColor.Depth.bits(Settings.screenDepthsByTier(tier))
Seq(w, h, depth,
tier match {
case 0 => "1/1/4/2/2"
case 1 => "2/4/8/4/4"
case 2 => "4/8/16/8/8"
})
}
override protected def tooltipName = Option(super.unlocalizedName)
}

View File

@ -0,0 +1,70 @@
package li.cil.oc.common.item.traits
import java.util
import li.cil.oc.Settings
import li.cil.oc.api
import li.cil.oc.api.machine.Architecture
import li.cil.oc.common.item.Delegate
import li.cil.oc.util.Tooltip
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.ChatComponentTranslation
import net.minecraft.world.World
import scala.collection.convert.WrapAsScala._
import scala.language.existentials
trait CPULike extends Delegate {
def cpuTier: Int
override protected def tooltipData: Seq[Any] = Seq(Settings.get.cpuComponentSupport(cpuTier))
override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) {
(if (stack.hasTagCompound) {
Option(stack.getTagCompound.getString(Settings.namespace + "archName"))
}
else {
val architectures = allArchitectures
architectures.headOption.map(_._2)
}) match {
case Some(archName) if !archName.isEmpty => tooltip.addAll(Tooltip.get("CPU.Architecture", archName))
case _ => allArchitectures.headOption.collect {
case ((_, name)) => tooltip.addAll(Tooltip.get("CPU.Architecture", name))
}
}
}
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = {
if (player.isSneaking) {
if (!world.isRemote) {
val architectures = allArchitectures
if (architectures.length > 0) {
val currentIndex = if (stack.hasTagCompound) {
val currentArch = stack.getTagCompound.getString(Settings.namespace + "archClass")
architectures.indexWhere(_._1.getName == currentArch)
}
else {
stack.setTagCompound(new NBTTagCompound())
-1
}
val index = (currentIndex + 1) % architectures.length
val (archClass, archName) = architectures(index)
stack.getTagCompound.setString(Settings.namespace + "archClass", archClass.getName)
stack.getTagCompound.setString(Settings.namespace + "archName", archName)
player.addChatMessage(new ChatComponentTranslation(Settings.namespace + "tooltip.CPU.Architecture", archName))
}
player.swingItem()
}
}
stack
}
private def allArchitectures = api.Machine.architectures.map { arch =>
arch.getAnnotation(classOf[Architecture.Name]) match {
case annotation: Architecture.Name => (arch, annotation.value)
case _ => (arch, arch.getSimpleName)
}
}.toArray
}

View File

@ -0,0 +1,20 @@
package li.cil.oc.common.item.traits
import li.cil.oc.Settings
import li.cil.oc.common.item.Delegate
import li.cil.oc.util.PackedColor
trait GPULike extends Delegate {
def gpuTier: Int
override protected def tooltipData: Seq[Any] = {
val (w, h) = Settings.screenResolutionsByTier(gpuTier)
val depth = PackedColor.Depth.bits(Settings.screenDepthsByTier(gpuTier))
Seq(w, h, depth,
gpuTier match {
case 0 => "1/1/4/2/2"
case 1 => "2/4/8/4/4"
case 2 => "4/8/16/8/8"
})
}
}

View File

@ -0,0 +1,39 @@
package li.cil.oc.integration.opencomputers
import li.cil.oc.Constants
import li.cil.oc.api
import li.cil.oc.api.driver.EnvironmentAware
import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.driver.item.HostAware
import li.cil.oc.common
import li.cil.oc.common.Tier
import li.cil.oc.common.item.Delegator
import li.cil.oc.server.component
import net.minecraft.item.ItemStack
object DriverAPU extends DriverCPU with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = isOneOf(stack,
api.Items.get(Constants.ItemName.APUTier1),
api.Items.get(Constants.ItemName.APUTier2))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
gpuTier(stack) match {
case Tier.One => new component.GraphicsCard.Tier1()
case Tier.Two => new component.GraphicsCard.Tier2()
case _ => null
}
override def cpuTier(stack: ItemStack) =
Delegator.subItem(stack) match {
case Some(apu: common.item.APU) => apu.tier
case _ => Tier.One
}
def gpuTier(stack: ItemStack) =
Delegator.subItem(stack) match {
case Some(apu: common.item.APU) => apu.gpuTier
case _ => Tier.One
}
override def providedEnvironment(stack: ItemStack) = classOf[component.GraphicsCard]
}

View File

@ -7,6 +7,7 @@ import li.cil.oc.api
import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.driver.item.Processor
import li.cil.oc.api.machine.Architecture
import li.cil.oc.api.network.ManagedEnvironment
import li.cil.oc.common.Slot
import li.cil.oc.common.Tier
import li.cil.oc.common.item
@ -15,32 +16,32 @@ import net.minecraft.item.ItemStack
import scala.collection.convert.WrapAsScala._
object DriverCPU extends Item with Processor {
object DriverCPU extends DriverCPU
abstract class DriverCPU extends Item with Processor {
override def worksWith(stack: ItemStack) = isOneOf(stack,
api.Items.get(Constants.ItemName.CPUTier1),
api.Items.get(Constants.ItemName.CPUTier2),
api.Items.get(Constants.ItemName.CPUTier3))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = null
override def createEnvironment(stack: ItemStack, host: EnvironmentHost): ManagedEnvironment = null
override def slot(stack: ItemStack) = Slot.CPU
override def tier(stack: ItemStack) =
override def tier(stack: ItemStack) = cpuTier(stack)
def cpuTier(stack: ItemStack): Int =
Delegator.subItem(stack) match {
case Some(cpu: item.CPU) => cpu.tier
case _ => Tier.One
}
override def supportedComponents(stack: ItemStack) =
Delegator.subItem(stack) match {
case Some(cpu: item.CPU) => Settings.get.cpuComponentSupport(cpu.tier)
case _ => Tier.One
}
override def supportedComponents(stack: ItemStack) = Settings.get.cpuComponentSupport(cpuTier(stack))
override def architecture(stack: ItemStack): Class[_ <: Architecture] = {
if (stack.hasTagCompound) {
val archClass = stack.getTagCompound.getString(Settings.namespace + "archClass")
try return Class.forName(archClass).asSubclass(classOf[Architecture]) catch {
if (!archClass.isEmpty) try return Class.forName(archClass).asSubclass(classOf[Architecture]) catch {
case t: Throwable =>
OpenComputers.log.warn("Failed getting class for CPU architecture. Resetting CPU to use the default.", t)
stack.getTagCompound.removeTag(Settings.namespace + "archClass")

View File

@ -87,6 +87,7 @@ object ModOpenComputers extends ModProxy {
api.Driver.add(DriverBlockEnvironments)
api.Driver.add(DriverAPU)
api.Driver.add(DriverComponentBus)
api.Driver.add(DriverCPU)
api.Driver.add(DriverDebugCard)
@ -150,6 +151,8 @@ object ModOpenComputers extends ModProxy {
Constants.ItemName.TractorBeamUpgrade,
Constants.ItemName.LeashUpgrade)
blacklistHost(classOf[internal.Drone],
Constants.ItemName.APUTier1,
Constants.ItemName.APUTier2,
Constants.ItemName.GraphicsCardTier1,
Constants.ItemName.GraphicsCardTier2,
Constants.ItemName.GraphicsCardTier3,
@ -162,6 +165,8 @@ object ModOpenComputers extends ModProxy {
Constants.ItemName.HoverUpgradeTier1,
Constants.ItemName.HoverUpgradeTier2)
blacklistHost(classOf[internal.Microcontroller],
Constants.ItemName.APUTier1,
Constants.ItemName.APUTier2,
Constants.ItemName.GraphicsCardTier1,
Constants.ItemName.GraphicsCardTier2,
Constants.ItemName.GraphicsCardTier3,