mirror of
https://github.com/Smallhacker/disbrowser.git
synced 2025-01-20 11:31:45 +00:00
Removed a few JDK dependencies
This commit is contained in:
parent
1e2cf6978d
commit
19424abe28
@ -4,8 +4,6 @@ import com.smallhacker.disbrowser.util.UInt24
|
|||||||
import com.smallhacker.disbrowser.util.joinBytes
|
import com.smallhacker.disbrowser.util.joinBytes
|
||||||
import com.smallhacker.disbrowser.util.joinNullableBytes
|
import com.smallhacker.disbrowser.util.joinNullableBytes
|
||||||
import com.smallhacker.disbrowser.util.toUInt24
|
import com.smallhacker.disbrowser.util.toUInt24
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Path
|
|
||||||
|
|
||||||
interface MemorySpace {
|
interface MemorySpace {
|
||||||
val size: UInt
|
val size: UInt
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.smallhacker.disbrowser.asm
|
package com.smallhacker.disbrowser.asm
|
||||||
|
|
||||||
import java.util.HashMap
|
|
||||||
|
|
||||||
import com.smallhacker.disbrowser.asm.Mnemonic.*
|
import com.smallhacker.disbrowser.asm.Mnemonic.*
|
||||||
|
|
||||||
typealias SegmentEnder = Instruction.() -> SegmentEnd?
|
typealias SegmentEnder = Instruction.() -> SegmentEnd?
|
||||||
|
@ -3,8 +3,6 @@ package com.smallhacker.disbrowser.asm
|
|||||||
import com.smallhacker.disbrowser.datatype.MutableRangeMap
|
import com.smallhacker.disbrowser.datatype.MutableRangeMap
|
||||||
import com.smallhacker.disbrowser.datatype.NaiveRangeMap
|
import com.smallhacker.disbrowser.datatype.NaiveRangeMap
|
||||||
import com.smallhacker.disbrowser.util.toUInt24
|
import com.smallhacker.disbrowser.util.toUInt24
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Path
|
|
||||||
|
|
||||||
abstract class SnesMemory: MemorySpace {
|
abstract class SnesMemory: MemorySpace {
|
||||||
override val size = 0x100_0000u
|
override val size = 0x100_0000u
|
||||||
@ -28,9 +26,8 @@ abstract class SnesMemory: MemorySpace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun loadRom(path: Path): SnesMemory {
|
fun loadRom(fileData: UByteArray): SnesMemory {
|
||||||
val bytes = Files.readAllBytes(path).toUByteArray()
|
val romSpace = ArrayMemorySpace(fileData)
|
||||||
val romSpace = ArrayMemorySpace(bytes)
|
|
||||||
// TODO: Auto-detect ROM type
|
// TODO: Auto-detect ROM type
|
||||||
return SnesLoRom(romSpace)
|
return SnesLoRom(romSpace)
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,16 @@ package com.smallhacker.disbrowser.disassembler
|
|||||||
|
|
||||||
import com.smallhacker.disbrowser.asm.*
|
import com.smallhacker.disbrowser.asm.*
|
||||||
import com.smallhacker.disbrowser.game.*
|
import com.smallhacker.disbrowser.game.*
|
||||||
|
import com.smallhacker.disbrowser.util.LifoQueue
|
||||||
import com.smallhacker.disbrowser.util.mutableMultiMap
|
import com.smallhacker.disbrowser.util.mutableMultiMap
|
||||||
import com.smallhacker.disbrowser.util.putSingle
|
import com.smallhacker.disbrowser.util.putSingle
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
object Disassembler {
|
object Disassembler {
|
||||||
fun disassemble(initialState: State, gameData: GameData, global: Boolean): Disassembly {
|
fun disassemble(initialState: State, gameData: GameData, global: Boolean): Disassembly {
|
||||||
val seen = HashSet<SnesAddress>()
|
val seen = HashSet<SnesAddress>()
|
||||||
val queue = ArrayDeque<State>()
|
val queue = LifoQueue<State>()
|
||||||
val origins = mutableMultiMap<SnesAddress, SnesAddress>()
|
val origins = mutableMultiMap<SnesAddress, SnesAddress>()
|
||||||
val instructionMap = HashMap<SnesAddress, MutableInstruction>()
|
val instructionMap = HashMap<SnesAddress, MutableInstruction>()
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ object Disassembler {
|
|||||||
|
|
||||||
val instructions = ArrayList<CodeUnit>()
|
val instructions = ArrayList<CodeUnit>()
|
||||||
while (queue.isNotEmpty()) {
|
while (queue.isNotEmpty()) {
|
||||||
val state = queue.remove()
|
val state = queue.removeNext()
|
||||||
|
|
||||||
val ins = disassembleInstruction(state)
|
val ins = disassembleInstruction(state)
|
||||||
instructions.add(ins)
|
instructions.add(ins)
|
||||||
@ -98,10 +98,10 @@ object Disassembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val fatalSeen = HashSet<SnesAddress>()
|
val fatalSeen = HashSet<SnesAddress>()
|
||||||
val fatalQueue = ArrayDeque<SnesAddress>()
|
val fatalQueue = LifoQueue<SnesAddress>()
|
||||||
fun tryAddFatal(snesAddress: SnesAddress) {
|
fun tryAddFatal(snesAddress: SnesAddress) {
|
||||||
if (fatalSeen.add(snesAddress)) {
|
if (fatalSeen.add(snesAddress)) {
|
||||||
fatalQueue.addLast(snesAddress)
|
fatalQueue.add(snesAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ object Disassembler {
|
|||||||
.forEach { tryAddFatal(it.address) }
|
.forEach { tryAddFatal(it.address) }
|
||||||
|
|
||||||
while (fatalQueue.isNotEmpty()) {
|
while (fatalQueue.isNotEmpty()) {
|
||||||
val badAddress = fatalQueue.removeFirst()!!
|
val badAddress = fatalQueue.removeNext()!!
|
||||||
val instruction = instructionMap[badAddress] ?: continue
|
val instruction = instructionMap[badAddress] ?: continue
|
||||||
val mnemonic = instruction.opcode.mnemonic
|
val mnemonic = instruction.opcode.mnemonic
|
||||||
if (mnemonic == Mnemonic.JSL || mnemonic == Mnemonic.JSR) continue
|
if (mnemonic == Mnemonic.JSL || mnemonic == Mnemonic.JSR) continue
|
||||||
@ -128,7 +128,7 @@ object Disassembler {
|
|||||||
|
|
||||||
fun disassembleSegments(initialState: State): List<Segment> {
|
fun disassembleSegments(initialState: State): List<Segment> {
|
||||||
val mapping = HashMap<SnesAddress, Segment>()
|
val mapping = HashMap<SnesAddress, Segment>()
|
||||||
val queue = ArrayDeque<State>()
|
val queue = LifoQueue<State>()
|
||||||
|
|
||||||
val segments = ArrayList<Segment>()
|
val segments = ArrayList<Segment>()
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ object Disassembler {
|
|||||||
|
|
||||||
|
|
||||||
while (queue.isNotEmpty()) {
|
while (queue.isNotEmpty()) {
|
||||||
val state = queue.remove()
|
val state = queue.removeNext()
|
||||||
|
|
||||||
if (mapping.containsKey(state.address)) {
|
if (mapping.containsKey(state.address)) {
|
||||||
continue
|
continue
|
||||||
@ -169,7 +169,7 @@ object Disassembler {
|
|||||||
val instructions = ArrayList<Instruction>()
|
val instructions = ArrayList<Instruction>()
|
||||||
var lastState = initialState
|
var lastState = initialState
|
||||||
|
|
||||||
val queue = ArrayDeque<State>()
|
val queue = LifoQueue<State>()
|
||||||
val seen = HashSet<SnesAddress>()
|
val seen = HashSet<SnesAddress>()
|
||||||
|
|
||||||
fun finalize(segment: Segment): Segment {
|
fun finalize(segment: Segment): Segment {
|
||||||
@ -187,7 +187,7 @@ object Disassembler {
|
|||||||
tryAdd(initialState)
|
tryAdd(initialState)
|
||||||
|
|
||||||
while (queue.isNotEmpty()) {
|
while (queue.isNotEmpty()) {
|
||||||
val state = queue.remove()
|
val state = queue.removeNext()
|
||||||
|
|
||||||
val ins = disassembleInstruction(state)
|
val ins = disassembleInstruction(state)
|
||||||
instructions.add(ins)
|
instructions.add(ins)
|
||||||
|
@ -3,6 +3,7 @@ package com.smallhacker.disbrowser.game
|
|||||||
import com.smallhacker.disbrowser.asm.SnesMemory
|
import com.smallhacker.disbrowser.asm.SnesMemory
|
||||||
import com.smallhacker.disbrowser.util.jsonFile
|
import com.smallhacker.disbrowser.util.jsonFile
|
||||||
import org.glassfish.jersey.server.ResourceConfig
|
import org.glassfish.jersey.server.ResourceConfig
|
||||||
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@ -34,7 +35,8 @@ class GameSource(private val gameDataDir: Path) {
|
|||||||
|
|
||||||
val gameData = gameDataJsonFile.load()
|
val gameData = gameDataJsonFile.load()
|
||||||
val gamePath = Paths.get(gameData.path)
|
val gamePath = Paths.get(gameData.path)
|
||||||
val rom = SnesMemory.loadRom(gamePath)
|
val romData = Files.readAllBytes(gamePath).toUByteArray()
|
||||||
|
val rom = SnesMemory.loadRom(romData)
|
||||||
Game(name, rom, gameData, gameDataJsonFile)
|
Game(name, rom, gameData, gameDataJsonFile)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
14
src/main/java/com/smallhacker/disbrowser/util/ItemQueue.kt
Normal file
14
src/main/java/com/smallhacker/disbrowser/util/ItemQueue.kt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.smallhacker.disbrowser.util
|
||||||
|
|
||||||
|
// The Kotlin standard library does not contain a counterpart to Java's ArrayDeque<E>, so let's implement a simplistic
|
||||||
|
// one ourselves for portability.
|
||||||
|
|
||||||
|
interface ItemQueue<E> : MutableCollection<E> {
|
||||||
|
fun removeNext(): E
|
||||||
|
}
|
||||||
|
|
||||||
|
class LifoQueue<E> private constructor(private val list: MutableList<E>) : ItemQueue<E>, MutableCollection<E> by list {
|
||||||
|
constructor() : this(ArrayList())
|
||||||
|
|
||||||
|
override fun removeNext(): E = list.removeAt(0)
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package com.smallhacker.disbrowser.util
|
package com.smallhacker.disbrowser.util
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
abstract class UType(val bytes: Int, val name: String) {
|
abstract class UType(val bytes: Int, val name: String) {
|
||||||
val mask = (1 shl (bytes * 8)) - 1
|
val mask = (1 shl (bytes * 8)) - 1
|
||||||
}
|
}
|
||||||
@ -22,7 +20,7 @@ class UVal<U : UType>(value: Int, val type: U) : Comparable<UVal<U>> {
|
|||||||
|
|
||||||
override fun compareTo(other: UVal<U>): Int = Integer.compare(value, other.value)
|
override fun compareTo(other: UVal<U>): Int = Integer.compare(value, other.value)
|
||||||
|
|
||||||
override fun hashCode() = Objects.hash(value, type)
|
override fun hashCode() = hashOf(value, type)
|
||||||
|
|
||||||
//fun value(value: Int) = UVal(value, type)
|
//fun value(value: Int) = UVal(value, type)
|
||||||
//fun mutate(mutator: (Int) -> Int) = UVal(mutator(value), type)
|
//fun mutate(mutator: (Int) -> Int) = UVal(mutator(value), type)
|
||||||
|
@ -86,4 +86,14 @@ fun <K, V> MutableMap<K, V>.removeIf(condition: (K, V) -> Boolean) {
|
|||||||
.map { it.key }
|
.map { it.key }
|
||||||
.toList()
|
.toList()
|
||||||
.forEach { remove(it) }
|
.forEach { remove(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hashOf(vararg values: Any?): Int {
|
||||||
|
return if (values.isEmpty()) {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
values.asSequence()
|
||||||
|
.map { it.hashCode() }
|
||||||
|
.reduce { acc, v -> (acc * 31) + v }
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user