From 71669642ae2eda1ebf467a1c02dd142ae801e31a Mon Sep 17 00:00:00 2001 From: Daan Vanden Bosch Date: Tue, 22 Dec 2020 23:05:11 +0100 Subject: [PATCH] Quests can be saved again. --- lib/karma.config.d/karma.config.js | 7 + .../world/phantasmal/lib/asm/BytecodeIr.kt | 34 ++- .../world/phantasmal/lib/buffer/Buffer.kt | 5 + .../phantasmal/lib/fileFormats/Vector.kt | 4 +- .../phantasmal/lib/fileFormats/quest/Bin.kt | 78 +++++++ .../lib/fileFormats/quest/Bytecode.kt | 107 ++++++++- .../phantasmal/lib/fileFormats/quest/Dat.kt | 175 +++++++++++++- .../phantasmal/lib/fileFormats/quest/Qst.kt | 217 +++++++++++++++++- .../phantasmal/lib/fileFormats/quest/Quest.kt | 60 ++++- .../lib/fileFormats/quest/BinTests.kt | 16 ++ .../lib/fileFormats/quest/DatTests.kt | 47 ++++ .../lib/fileFormats/quest/QuestTests.kt | 94 +++++++- .../world/phantasmal/lib/test/TestUtils.kt | 31 ++- lib/src/commonTest/resources/quest118_e.qst | Bin 0 -> 32912 bytes lib/src/commonTest/resources/quest27_e.qst | Bin 0 -> 111056 bytes .../world/phantasmal/lib/buffer/Buffer.kt | 3 + .../world/phantasmal/lib/buffer/Buffer.kt | 3 + .../QuestEditorToolbarController.kt | 96 +++++++- .../web/questEditor/stores/ModelConversion.kt | 68 +++++- .../widgets/QuestEditorToolbarWidget.kt | 87 +++++++ .../world/phantasmal/webui/widgets/Dialog.kt | 38 ++- .../phantasmal/webui/widgets/ResultDialog.kt | 84 +++---- 22 files changed, 1139 insertions(+), 115 deletions(-) create mode 100644 lib/karma.config.d/karma.config.js create mode 100644 lib/src/commonTest/resources/quest118_e.qst create mode 100644 lib/src/commonTest/resources/quest27_e.qst diff --git a/lib/karma.config.d/karma.config.js b/lib/karma.config.d/karma.config.js new file mode 100644 index 00000000..a864626d --- /dev/null +++ b/lib/karma.config.d/karma.config.js @@ -0,0 +1,7 @@ +config.set({ + client: { + mocha: { + timeout: 10_000 + } + } +}); diff --git a/lib/src/commonMain/kotlin/world/phantasmal/lib/asm/BytecodeIr.kt b/lib/src/commonMain/kotlin/world/phantasmal/lib/asm/BytecodeIr.kt index 52b2ff42..4985e718 100644 --- a/lib/src/commonMain/kotlin/world/phantasmal/lib/asm/BytecodeIr.kt +++ b/lib/src/commonMain/kotlin/world/phantasmal/lib/asm/BytecodeIr.kt @@ -10,6 +10,9 @@ class BytecodeIr( ) { fun instructionSegments(): List = segments.filterIsInstance() + + fun copy(): BytecodeIr = + BytecodeIr(segments.map { it.copy() }) } enum class SegmentType { @@ -27,25 +30,40 @@ sealed class Segment( val type: SegmentType, val labels: MutableList, val srcLoc: SegmentSrcLoc, -) +) { + abstract fun copy(): Segment +} class InstructionSegment( labels: MutableList, val instructions: MutableList, srcLoc: SegmentSrcLoc = SegmentSrcLoc(mutableListOf()), -) : Segment(SegmentType.Instructions, labels, srcLoc) +) : Segment(SegmentType.Instructions, labels, srcLoc) { + override fun copy(): InstructionSegment = + InstructionSegment( + ArrayList(labels), + instructions.mapTo(mutableListOf()) { it.copy() }, + srcLoc.copy(), + ) +} class DataSegment( labels: MutableList, val data: Buffer, srcLoc: SegmentSrcLoc = SegmentSrcLoc(mutableListOf()), -) : Segment(SegmentType.Data, labels, srcLoc) +) : Segment(SegmentType.Data, labels, srcLoc) { + override fun copy(): DataSegment = + DataSegment(ArrayList(labels), data.copy(), srcLoc.copy()) +} class StringSegment( labels: MutableList, var value: String, srcLoc: SegmentSrcLoc = SegmentSrcLoc(mutableListOf()), -) : Segment(SegmentType.String, labels, srcLoc) +) : Segment(SegmentType.String, labels, srcLoc) { + override fun copy(): StringSegment = + StringSegment(ArrayList(labels), value, srcLoc.copy()) +} /** * Opcode invocation. @@ -179,6 +197,9 @@ class Instruction( return size } + + fun copy(): Instruction = + Instruction(opcode, args, srcLoc) } /** @@ -207,4 +228,7 @@ class InstructionSrcLoc( /** * Locations of a segment's labels in the source assembly code. */ -class SegmentSrcLoc(val labels: MutableList = mutableListOf()) +class SegmentSrcLoc(val labels: MutableList = mutableListOf()) { + fun copy(): SegmentSrcLoc = + SegmentSrcLoc(ArrayList(labels)) +} diff --git a/lib/src/commonMain/kotlin/world/phantasmal/lib/buffer/Buffer.kt b/lib/src/commonMain/kotlin/world/phantasmal/lib/buffer/Buffer.kt index 76b14060..3339fc6b 100644 --- a/lib/src/commonMain/kotlin/world/phantasmal/lib/buffer/Buffer.kt +++ b/lib/src/commonMain/kotlin/world/phantasmal/lib/buffer/Buffer.kt @@ -107,6 +107,11 @@ expect class Buffer { fun toBase64(): String + /** + * Returns a copy of this buffer of the same size. The copy's capacity will equal its size. + */ + fun copy(): Buffer + companion object { /** * Returns a new buffer the given initial capacity and size 0. diff --git a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/Vector.kt b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/Vector.kt index 74ee2fbf..84e70910 100644 --- a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/Vector.kt +++ b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/Vector.kt @@ -2,9 +2,9 @@ package world.phantasmal.lib.fileFormats import world.phantasmal.lib.cursor.Cursor -class Vec2(val x: Float, val y: Float) +data class Vec2(val x: Float, val y: Float) -class Vec3(val x: Float, val y: Float, val z: Float) +data class Vec3(val x: Float, val y: Float, val z: Float) fun Cursor.vec2Float(): Vec2 = Vec2(float(), float()) diff --git a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Bin.kt b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Bin.kt index ffe5f860..0319e73f 100644 --- a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Bin.kt +++ b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Bin.kt @@ -3,6 +3,7 @@ package world.phantasmal.lib.fileFormats.quest import mu.KotlinLogging import world.phantasmal.lib.buffer.Buffer import world.phantasmal.lib.cursor.Cursor +import world.phantasmal.lib.cursor.cursor private val logger = KotlinLogging.logger {} @@ -116,3 +117,80 @@ fun parseBin(cursor: Cursor): BinFile { shopItems, ) } + +fun writeBin(bin: BinFile): Buffer { + require(bin.questName.length <= 32) { + "questName can't be longer than 32 characters, was ${bin.questName.length}" + } + require(bin.shortDescription.length <= 127) { + "shortDescription can't be longer than 127 characters, was ${bin.shortDescription.length}" + } + require(bin.longDescription.length <= 287) { + "longDescription can't be longer than 287 characters, was ${bin.longDescription.length}" + } + require(bin.shopItems.isEmpty() || bin.format == BinFormat.BB) { + "shopItems is only supported in BlueBurst quests." + } + require(bin.shopItems.size <= 932) { + "shopItems can't be larger than 932, was ${bin.shopItems.size}." + } + + val bytecodeOffset = when (bin.format) { + BinFormat.DC_GC -> DC_GC_OBJECT_CODE_OFFSET + BinFormat.PC -> PC_OBJECT_CODE_OFFSET + BinFormat.BB -> BB_OBJECT_CODE_OFFSET + } + + val fileSize = bytecodeOffset + bin.bytecode.size + 4 * bin.labelOffsets.size + val buffer = Buffer.withCapacity(fileSize) + val cursor = buffer.cursor() + + cursor.writeInt(bytecodeOffset) + cursor.writeInt(bytecodeOffset + bin.bytecode.size) // Label table offset. + cursor.writeInt(fileSize) + cursor.writeInt(-1) + + if (bin.format == BinFormat.DC_GC) { + cursor.writeByte(0) + cursor.writeByte(bin.language.toByte()) + cursor.writeShort(bin.questId.toShort()) + cursor.writeStringAscii(bin.questName, 32) + cursor.writeStringAscii(bin.shortDescription, 128) + cursor.writeStringAscii(bin.longDescription, 288) + } else { + if (bin.format == BinFormat.PC) { + cursor.writeShort(bin.language.toShort()) + cursor.writeShort(bin.questId.toShort()) + } else { + cursor.writeInt(bin.questId) + cursor.writeInt(bin.language) + } + + cursor.writeStringUtf16(bin.questName, 64) + cursor.writeStringUtf16(bin.shortDescription, 256) + cursor.writeStringUtf16(bin.longDescription, 576) + } + + if (bin.format == BinFormat.BB) { + cursor.writeInt(0) + cursor.writeUIntArray(bin.shopItems) + + repeat(932 - bin.shopItems.size) { + cursor.writeUInt(0u) + } + } + + check(cursor.position == bytecodeOffset) { + "Expected to write $bytecodeOffset bytes before bytecode, but wrote ${cursor.position}." + } + + cursor.writeCursor(bin.bytecode.cursor()) + + cursor.writeIntArray(bin.labelOffsets) + + check(cursor.position == fileSize) { + "Expected to write $fileSize bytes, but wrote ${cursor.position}." + } + + return buffer +} diff --git a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Bytecode.kt b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Bytecode.kt index a5a0f884..0a28507c 100644 --- a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Bytecode.kt +++ b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Bytecode.kt @@ -3,6 +3,7 @@ package world.phantasmal.lib.fileFormats.quest import mu.KotlinLogging import world.phantasmal.core.PwResult import world.phantasmal.core.Severity +import world.phantasmal.lib.Endianness import world.phantasmal.lib.asm.* import world.phantasmal.lib.asm.dataFlowAnalysis.ControlFlowGraph import world.phantasmal.lib.asm.dataFlowAnalysis.getRegisterValue @@ -10,6 +11,7 @@ import world.phantasmal.lib.asm.dataFlowAnalysis.getStackValue import world.phantasmal.lib.buffer.Buffer import world.phantasmal.lib.cursor.BufferCursor import world.phantasmal.lib.cursor.Cursor +import world.phantasmal.lib.cursor.cursor import kotlin.math.ceil import kotlin.math.min @@ -118,7 +120,13 @@ fun parseBytecode( is DataSegment -> segment.data.size // String segments should be multiples of 4 bytes. - is StringSegment -> 4 * ceil((segment.value.length + 1) / 2.0).toInt() + is StringSegment -> { + if (dcGcFormat) { + 4 * ceil((segment.value.length + 1) / 4.0).toInt() + } else { + 4 * ceil((segment.value.length + 1) / 2.0).toInt() + } + } } } @@ -558,6 +566,103 @@ private fun parseInstructionArguments( return args } +fun writeBytecode(bytecodeIr: BytecodeIr, dcGcFormat: Boolean): BytecodeAndLabelOffsets { + val buffer = Buffer.withCapacity(100 * bytecodeIr.segments.size, Endianness.Little) + val cursor = buffer.cursor() + // Keep track of label offsets. + val largestLabel = bytecodeIr.segments.asSequence().flatMap { it.labels }.maxOrNull() ?: -1 + val labelOffsets = IntArray(largestLabel + 1) { -1 } + + for (segment in bytecodeIr.segments) { + for (label in segment.labels) { + labelOffsets[label] = cursor.position + } + + when (segment) { + is InstructionSegment -> { + for (instruction in segment.instructions) { + val opcode = instruction.opcode + + if (opcode.size == 2) { + cursor.writeByte((opcode.code ushr 8).toByte()) + } + + cursor.writeByte(opcode.code.toByte()) + + if (opcode.stack != StackInteraction.Pop) { + for (i in opcode.params.indices) { + val param = opcode.params[i] + val args = instruction.getArgs(i) + val arg = args.first() + + when (param.type) { + ByteType -> cursor.writeByte((arg.value as Int).toByte()) + ShortType -> cursor.writeShort((arg.value as Int).toShort()) + IntType -> cursor.writeInt(arg.value as Int) + FloatType -> cursor.writeFloat(arg.value as Float) + // Ensure this case is before the LabelType case because + // ILabelVarType extends LabelType. + ILabelVarType -> { + cursor.writeByte(args.size.toByte()) + + for (a in args) { + cursor.writeShort((a.value as Int).toShort()) + } + } + is LabelType -> cursor.writeShort((arg.value as Int).toShort()) + StringType -> { + val str = arg.value as String + + if (dcGcFormat) cursor.writeStringAscii(str, str.length + 1) + else cursor.writeStringUtf16(str, 2 * str.length + 2) + } + RegRefType, is RegTupRefType -> { + cursor.writeByte((arg.value as Int).toByte()) + } + RegRefVarType -> { + cursor.writeByte(args.size.toByte()) + + for (a in args) { + cursor.writeByte((a.value as Int).toByte()) + } + } + else -> error( + "Parameter type ${param.type::class.simpleName} not supported." + ) + } + } + } + } + } + + is StringSegment -> { + // String segments should be multiples of 4 bytes. + if (dcGcFormat) { + val byteLength = 4 * ceil((segment.value.length + 1) / 4.0).toInt() + cursor.writeStringAscii(segment.value, byteLength) + } else { + val byteLength = 4 * ceil((segment.value.length + 1) / 2.0).toInt() + cursor.writeStringUtf16(segment.value, byteLength) + } + } + + is DataSegment -> { + cursor.writeCursor(segment.data.cursor()) + } + } + } + + return BytecodeAndLabelOffsets(buffer, labelOffsets) +} + +class BytecodeAndLabelOffsets( + val bytecode: Buffer, + val labelOffsets: IntArray, +) { + operator fun component1(): Buffer = bytecode + operator fun component2(): IntArray = labelOffsets +} + private data class LabelAndOffset(val label: Int, val offset: Int) private data class OffsetAndIndex(val offset: Int, val index: Int) private class LabelInfo(val offset: Int, val next: LabelAndOffset?) diff --git a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Dat.kt b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Dat.kt index 31a97e21..909e506f 100644 --- a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Dat.kt +++ b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Dat.kt @@ -1,15 +1,19 @@ package world.phantasmal.lib.fileFormats.quest import mu.KotlinLogging +import world.phantasmal.lib.Endianness import world.phantasmal.lib.buffer.Buffer import world.phantasmal.lib.cursor.Cursor +import world.phantasmal.lib.cursor.WritableCursor +import world.phantasmal.lib.cursor.cursor +import kotlin.math.max private val logger = KotlinLogging.logger {} -private const val EVENT_ACTION_SPAWN_NPCS = 0x8 -private const val EVENT_ACTION_UNLOCK = 0xA -private const val EVENT_ACTION_LOCK = 0xB -private const val EVENT_ACTION_TRIGGER_EVENT = 0xC +private const val EVENT_ACTION_SPAWN_NPCS: Byte = 0x8 +private const val EVENT_ACTION_UNLOCK: Byte = 0xA +private const val EVENT_ACTION_LOCK: Byte = 0xB +private const val EVENT_ACTION_TRIGGER_EVENT: Byte = 0xC const val OBJECT_BYTE_SIZE = 68 const val NPC_BYTE_SIZE = 72 @@ -31,7 +35,7 @@ class DatEvent( var sectionId: Short, var wave: Short, var delay: Short, - val actions: MutableList, + val actions: List, val areaId: Int, val unknown: Short, ) @@ -156,13 +160,13 @@ private fun parseEvents(cursor: Cursor, areaId: Int, events: MutableList = + val actions: List = if (eventActionsOffset < actionsCursor.size) { actionsCursor.seekStart(eventActionsOffset) parseEventActions(actionsCursor) } else { logger.warn { "Invalid event actions offset $eventActionsOffset for event ${id}." } - mutableListOf() + emptyList() } events.add(DatEvent( @@ -200,12 +204,12 @@ private fun parseEvents(cursor: Cursor, areaId: Int, events: MutableList { +private fun parseEventActions(cursor: Cursor): List { val actions = mutableListOf() outer@ while (cursor.hasBytesLeft()) { - when (val type = cursor.uByte().toInt()) { - 1 -> break@outer + when (val type = cursor.byte()) { + (1).toByte() -> break@outer EVENT_ACTION_SPAWN_NPCS -> actions.add(DatEventAction.SpawnNpcs( @@ -237,3 +241,154 @@ private fun parseEventActions(cursor: Cursor): MutableList { return actions } + +fun writeDat(dat: DatFile): Buffer { + val buffer = Buffer.withCapacity( + dat.objs.size * (16 + OBJECT_BYTE_SIZE) + + dat.npcs.size * (16 + NPC_BYTE_SIZE) + + dat.unknowns.sumBy { it.totalSize }, + endianness = Endianness.Little, + ) + val cursor = buffer.cursor() + + writeEntities(cursor, dat.objs, 1, OBJECT_BYTE_SIZE) + writeEntities(cursor, dat.npcs, 2, NPC_BYTE_SIZE) + writeEvents(cursor, dat.events) + + for (unknown in dat.unknowns) { + cursor.writeInt(unknown.entityType) + cursor.writeInt(unknown.totalSize) + cursor.writeInt(unknown.areaId) + cursor.writeInt(unknown.entitiesSize) + cursor.writeByteArray(unknown.data) + } + + // Final header. + cursor.writeInt(0) + cursor.writeInt(0) + cursor.writeInt(0) + cursor.writeInt(0) + + return buffer +} + +private fun writeEntities( + cursor: WritableCursor, + entities: List, + entityType: Int, + entitySize: Int, +) { + val groupedEntities = entities.groupBy { it.areaId } + + for ((areaId, areaEntities) in groupedEntities.entries.sortedBy { it.key }) { + val entitiesSize = areaEntities.size * entitySize + cursor.writeInt(entityType) + cursor.writeInt(16 + entitiesSize) + cursor.writeInt(areaId) + cursor.writeInt(entitiesSize) + val startPos = cursor.position + + for (entity in areaEntities) { + require(entity.data.size == entitySize) { + "Malformed entity in area $areaId, data buffer was of size ${ + entity.data.size + } instead of expected $entitySize." + } + + cursor.writeCursor(entity.data.cursor()) + } + + check(cursor.position == startPos + entitiesSize) { + "Wrote ${ + cursor.position - startPos + } bytes of entity data instead of expected $entitiesSize bytes for area $areaId." + } + } +} + +private fun writeEvents(cursor: WritableCursor, events: List) { + val groupedEvents = events.groupBy { it.areaId } + + for ((areaId, areaEvents) in groupedEvents.entries.sortedBy { it.key }) { + // Standard header. + cursor.writeInt(3) // Entity type + val totalSizeOffset = cursor.position + cursor.writeInt(0) // Placeholder for the total size. + cursor.writeInt(areaId) + val entitiesSizeOffset = cursor.position + cursor.writeInt(0) // Placeholder for the entities size. + + // Event header. + val startPos = cursor.position + // TODO: actual event size is dependent on the event type (challenge mode). + // Absolute offset. + val actionsOffset = startPos + 16 + 20 * areaEvents.size + cursor.size = max(actionsOffset, cursor.size) + + cursor.writeInt(actionsOffset - startPos) + cursor.writeInt(0x10) + cursor.writeInt(areaEvents.size) + cursor.writeInt(0) // TODO: write event type (challenge mode). + + // Relative offset. + var eventActionsOffset = 0 + + for (event in areaEvents) { + cursor.writeInt(event.id) + cursor.writeInt(0x10000) + cursor.writeShort(event.sectionId) + cursor.writeShort(event.wave) + cursor.writeShort(event.delay) + cursor.writeShort(event.unknown) + cursor.writeInt(eventActionsOffset) + val nextEventPos = cursor.position + + cursor.seekStart(actionsOffset + eventActionsOffset) + + for (action in event.actions) { + when (action) { + is DatEventAction.SpawnNpcs -> { + cursor.writeByte(EVENT_ACTION_SPAWN_NPCS) + cursor.writeShort(action.sectionId) + cursor.writeShort(action.appearFlag) + } + is DatEventAction.Unlock -> { + cursor.writeByte(EVENT_ACTION_UNLOCK) + cursor.writeShort(action.doorId) + } + is DatEventAction.Lock -> { + cursor.writeByte(EVENT_ACTION_LOCK) + cursor.writeShort(action.doorId) + } + is DatEventAction.TriggerEvent -> { + cursor.writeByte(EVENT_ACTION_TRIGGER_EVENT) + cursor.writeInt(action.eventId) + } + } + } + + // End of event actions. + cursor.writeByte(1) + + eventActionsOffset = cursor.position - actionsOffset + + cursor.seekStart(nextEventPos) + } + + cursor.seekStart(actionsOffset + eventActionsOffset) + + while ((cursor.position - actionsOffset) % 4 != 0) { + cursor.writeByte(-1) + } + + val endPos = cursor.position + + cursor.seekStart(totalSizeOffset) + cursor.writeInt(16 + endPos - startPos) + + cursor.seekStart(entitiesSizeOffset) + cursor.writeInt(endPos - startPos) + + cursor.seekStart(endPos) + } +} diff --git a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Qst.kt b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Qst.kt index 8ea6cb32..f9173e7c 100644 --- a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Qst.kt +++ b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Qst.kt @@ -12,6 +12,7 @@ import world.phantasmal.lib.cursor.WritableCursor import world.phantasmal.lib.cursor.cursor import kotlin.math.ceil import kotlin.math.max +import kotlin.math.min private val logger = KotlinLogging.logger {} @@ -134,7 +135,8 @@ private fun parseHeaders(cursor: Cursor): List { var prevQuestId: Int? = null var prevFilename: String? = null - // .qst files should have two headers, some malformed files have more. + // .qst files should have two headers. Some malformed files have more, so we tried to detect at + // most 4 headers. repeat(4) { // Detect version and whether it's an online or download quest. val version: Version @@ -407,3 +409,216 @@ private fun parseFiles( } ) } + +fun writeQst(qst: QstContent): Buffer { + val fileHeaderSize: Int + val chunkSize: Int + + when (qst.version) { + Version.DC, Version.GC, Version.PC -> { + fileHeaderSize = DC_GC_PC_HEADER_SIZE + chunkSize = DC_GC_PC_CHUNK_SIZE + } + Version.BB -> { + fileHeaderSize = BB_HEADER_SIZE + chunkSize = BB_CHUNK_SIZE + } + } + + val totalSize = qst.files.sumOf { + fileHeaderSize + ceil(it.data.size.toDouble() / CHUNK_BODY_SIZE).toInt() * chunkSize + } + + val buffer = Buffer.withCapacity(totalSize) + val cursor = buffer.cursor() + + writeFileHeaders(cursor, qst.files, qst.version, qst.online, fileHeaderSize) + writeFileChunks(cursor, qst.files, qst.version) + + check(cursor.position == totalSize) { + "Expected a final file size of $totalSize, but got ${cursor.position}." + } + + return buffer +} + +private fun writeFileHeaders( + cursor: WritableCursor, + files: List, + version: Version, + online: Boolean, + headerSize: Int, +) { + val maxId: Int + val maxQuestNameLength: Int + + if (version == Version.BB) { + maxId = 0xffff + maxQuestNameLength = 23 + } else { + maxId = 0xff + maxQuestNameLength = 31 + } + + for (file in files) { + require(file.id == null || (file.id in 0..maxId)) { + "Quest ID should be between 0 and $maxId, inclusive." + } + require(file.questName == null || file.questName.length <= maxQuestNameLength) { + "File ${file.filename} has a quest name longer than $maxQuestNameLength characters (${file.questName})." + } + require(file.filename.length <= 15) { + "File ${file.filename} has a filename longer than 15 characters." + } + + when (version) { + Version.DC -> { + cursor.writeUByte((if (online) ONLINE_QUEST else DOWNLOAD_QUEST).toUByte()) + cursor.writeUByte(file.id?.toUByte() ?: 0u) + cursor.writeUShort(headerSize.toUShort()) + cursor.writeStringAscii(file.questName ?: file.filename, 32) + cursor.writeByte(0) + cursor.writeByte(0) + cursor.writeByte(0) + cursor.writeStringAscii(file.filename, 16) + cursor.writeByte(0) + cursor.writeInt(file.data.size) + } + + Version.GC -> { + cursor.writeUByte((if (online) ONLINE_QUEST else DOWNLOAD_QUEST).toUByte()) + cursor.writeUByte(file.id?.toUByte() ?: 0u) + cursor.writeUShort(headerSize.toUShort()) + cursor.writeStringAscii(file.questName ?: file.filename, 32) + cursor.writeInt(0) + cursor.writeStringAscii(file.filename, 16) + cursor.writeInt(file.data.size) + } + + Version.PC -> { + cursor.writeUShort(headerSize.toUShort()) + cursor.writeUByte((if (online) ONLINE_QUEST else DOWNLOAD_QUEST).toUByte()) + cursor.writeUByte(file.id?.toUByte() ?: 0u) + cursor.writeStringAscii(file.questName ?: file.filename, 32) + cursor.writeInt(0) + cursor.writeStringAscii(file.filename, 16) + cursor.writeInt(file.data.size) + } + + Version.BB -> { + cursor.writeUShort(headerSize.toUShort()) + cursor.writeUShort((if (online) ONLINE_QUEST else DOWNLOAD_QUEST).toUShort()) + cursor.writeUShort(file.id?.toUShort() ?: 0u) + repeat(38) { cursor.writeByte(0) } + cursor.writeStringAscii(file.filename, 16) + cursor.writeInt(file.data.size) + cursor.writeStringAscii(file.questName ?: file.filename, 24) + } + } + } +} + +private class FileToChunk( + var no: Int, + val data: Cursor, + val name: String, +) + +private fun writeFileChunks( + cursor: WritableCursor, + files: List, + version: Version, +) { + // Files are interleaved in chunks. Each chunk has a header, fixed-size data segment and a + // trailer. + val filesToChunk = files.map { file -> + FileToChunk( + no = 0, + data = file.data.cursor(), + name = file.filename, + ) + } + var done = 0 + + while (done < filesToChunk.size) { + for (fileToChunk in filesToChunk) { + if (fileToChunk.data.hasBytesLeft()) { + if ( + !writeFileChunk( + cursor, + fileToChunk.data, + fileToChunk.no++, + fileToChunk.name, + version, + ) + ) { + done++ + } + } + } + } + + for (fileToChunk in filesToChunk) { + val expectedChunks = ceil(fileToChunk.data.size.toDouble() / CHUNK_BODY_SIZE).toInt() + + check(fileToChunk.no == expectedChunks) { + """Expected to write $expectedChunks chunks for file "${ + fileToChunk.name + }" but ${fileToChunk.no} where written.""" + } + } +} + +/** + * Returns true if there are bytes left to write in [data], false otherwise. + */ +private fun writeFileChunk( + cursor: WritableCursor, + data: Cursor, + chunkNo: Int, + name: String, + version: Version, +): Boolean { + when (version) { + Version.DC, + Version.GC, + -> { + cursor.writeByte(0) + cursor.writeUByte(chunkNo.toUByte()) + cursor.writeShort(0) + } + + Version.PC -> { + cursor.writeByte(0) + cursor.writeByte(0) + cursor.writeByte(0) + cursor.writeUByte(chunkNo.toUByte()) + } + + Version.BB -> { + cursor.writeByte(28) + cursor.writeByte(4) + cursor.writeByte(19) + cursor.writeByte(0) + cursor.writeInt(chunkNo) + } + } + + cursor.writeStringAscii(name, 16) + + val size = min(CHUNK_BODY_SIZE, data.bytesLeft) + cursor.writeCursor(data.take(size)) + + // Padding. + repeat(CHUNK_BODY_SIZE - size) { + cursor.writeByte(0) + } + + cursor.writeInt(size) + + if (version == Version.BB) { + cursor.writeInt(0) + } + + return data.hasBytesLeft() +} diff --git a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Quest.kt b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Quest.kt index 9ffcd1ec..7c028292 100644 --- a/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Quest.kt +++ b/lib/src/commonMain/kotlin/world/phantasmal/lib/fileFormats/quest/Quest.kt @@ -1,16 +1,15 @@ package world.phantasmal.lib.fileFormats.quest import mu.KotlinLogging -import world.phantasmal.core.PwResult -import world.phantasmal.core.PwResultBuilder -import world.phantasmal.core.Severity -import world.phantasmal.core.Success +import world.phantasmal.core.* import world.phantasmal.lib.Episode import world.phantasmal.lib.asm.BytecodeIr import world.phantasmal.lib.asm.InstructionSegment import world.phantasmal.lib.asm.OP_SET_EPISODE import world.phantasmal.lib.asm.dataFlowAnalysis.ControlFlowGraph import world.phantasmal.lib.asm.dataFlowAnalysis.getMapDesignations +import world.phantasmal.lib.buffer.Buffer +import world.phantasmal.lib.compression.prs.prsCompress import world.phantasmal.lib.compression.prs.prsDecompress import world.phantasmal.lib.cursor.Cursor import world.phantasmal.lib.cursor.cursor @@ -233,3 +232,56 @@ private fun extractScriptEntryPoints( return entryPoints } + +/** + * Creates a .qst file from [quest]. + */ +fun writeQuestToQst(quest: Quest, filename: String, version: Version, online: Boolean): Buffer { + val dat = writeDat(DatFile( + objs = quest.objects.map { DatEntity(it.areaId, it.data) }, + npcs = quest.npcs.map { DatEntity(it.areaId, it.data) }, + events = quest.events, + unknowns = quest.datUnknowns, + )) + + val binFormat = when (version) { + Version.DC, Version.GC -> BinFormat.DC_GC + Version.PC -> BinFormat.PC + Version.BB -> BinFormat.BB + } + + val (bytecode, labelOffsets) = writeBytecode(quest.bytecodeIr, binFormat == BinFormat.DC_GC) + + val bin = writeBin(BinFile( + binFormat, + quest.id, + quest.language, + quest.name, + quest.shortDescription, + quest.longDescription, + bytecode, + labelOffsets, + quest.shopItems, + )) + + val baseFilename = (filenameBase(filename) ?: filename).take(11) + + return writeQst(QstContent( + version, + online, + files = listOf( + QstContainedFile( + id = quest.id, + filename = "$baseFilename.dat", + questName = quest.name, + data = prsCompress(dat.cursor()).buffer(), + ), + QstContainedFile( + id = quest.id, + filename = "$baseFilename.bin", + questName = quest.name, + data = prsCompress(bin.cursor()).buffer(), + ), + ), + )) +} diff --git a/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/BinTests.kt b/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/BinTests.kt index f0fa9b40..1f08cda0 100644 --- a/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/BinTests.kt +++ b/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/BinTests.kt @@ -1,6 +1,8 @@ package world.phantasmal.lib.fileFormats.quest +import world.phantasmal.lib.cursor.cursor import world.phantasmal.lib.test.LibTestSuite +import world.phantasmal.lib.test.assertDeepEquals import world.phantasmal.lib.test.readFile import kotlin.test.Test import kotlin.test.assertEquals @@ -20,4 +22,18 @@ class BinTests : LibTestSuite() { bin.longDescription ) } + + @Test + fun parse_and_write_towards_the_future() = parseAndWriteQuest("/quest118_e_decompressed.bin") + + @Test + fun parse_and_write_seat_of_the_heart() = parseAndWriteQuest("/quest27_e_decompressed.bin") + + private fun parseAndWriteQuest(file: String) = asyncTest { + val origBin = readFile(file) + val newBin = writeBin(parseBin(origBin)).cursor() + origBin.seekStart(0) + + assertDeepEquals(origBin, newBin) + } } diff --git a/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/DatTests.kt b/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/DatTests.kt index e19455f7..3fc124bf 100644 --- a/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/DatTests.kt +++ b/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/DatTests.kt @@ -1,6 +1,8 @@ package world.phantasmal.lib.fileFormats.quest +import world.phantasmal.lib.cursor.cursor import world.phantasmal.lib.test.LibTestSuite +import world.phantasmal.lib.test.assertDeepEquals import world.phantasmal.lib.test.readFile import kotlin.test.Test import kotlin.test.assertEquals @@ -13,4 +15,49 @@ class DatTests : LibTestSuite() { assertEquals(277, dat.objs.size) assertEquals(216, dat.npcs.size) } + + /** + * Parse a file, convert the resulting structure to DAT again and check whether the end result + * is byte-for-byte equal to the original. + */ + @Test + fun parse_dat_and_write_dat() = asyncTest { + val origDat = readFile("/quest118_e_decompressed.dat") + val newDat = writeDat(parseDat(origDat)).cursor() + origDat.seekStart(0) + + assertDeepEquals(origDat, newDat) + } + + /** + * Parse a file, modify the resulting structure, convert it to DAT again and check whether the + * end result is byte-for-byte equal to the original except for the bytes that should be + * changed. + */ + @Test + fun parse_modify_write_dat() = asyncTest { + val origDat = readFile("/quest118_e_decompressed.dat") + val parsedDat = parseDat(origDat) + origDat.seekStart(0) + + parsedDat.objs[9].data.setFloat(16, 13f) + parsedDat.objs[9].data.setFloat(20, 17f) + parsedDat.objs[9].data.setFloat(24, 19f) + + val newDat = writeDat(parsedDat).cursor() + + assertEquals(origDat.size, newDat.size) + + while (origDat.hasBytesLeft()) { + if (origDat.position == 16 + 9 * OBJECT_BYTE_SIZE + 16) { + origDat.seek(12) + + assertEquals(13f, newDat.float()) + assertEquals(17f, newDat.float()) + assertEquals(19f, newDat.float()) + } else { + assertEquals(origDat.byte(), newDat.byte()) + } + } + } } diff --git a/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/QuestTests.kt b/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/QuestTests.kt index 73f62280..fe1c8ae3 100644 --- a/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/QuestTests.kt +++ b/lib/src/commonTest/kotlin/world/phantasmal/lib/fileFormats/quest/QuestTests.kt @@ -3,7 +3,10 @@ package world.phantasmal.lib.fileFormats.quest import world.phantasmal.core.Success import world.phantasmal.lib.Episode import world.phantasmal.lib.asm.* +import world.phantasmal.lib.cursor.Cursor +import world.phantasmal.lib.cursor.cursor import world.phantasmal.lib.test.LibTestSuite +import world.phantasmal.lib.test.assertDeepEquals import world.phantasmal.lib.test.readFile import kotlin.test.Test import kotlin.test.assertEquals @@ -17,8 +20,23 @@ class QuestTests : LibTestSuite() { assertTrue(result is Success) assertTrue(result.problems.isEmpty()) - val quest = result.value + testTowardsTheFutureParseResult(result.value) + } + @Test + fun parseQstToQuest_with_towards_the_future() = asyncTest { + val result = parseQstToQuest(readFile("/quest118_e.qst")) + + assertTrue(result is Success) + assertTrue(result.problems.isEmpty()) + + assertEquals(Version.BB, result.value.version) + assertTrue(result.value.online) + + testTowardsTheFutureParseResult(result.value.quest) + } + + private fun testTowardsTheFutureParseResult(quest: Quest) { assertEquals("Towards the Future", quest.name) assertEquals("Challenge the\nnew simulator.", quest.shortDescription) assertEquals( @@ -27,9 +45,8 @@ class QuestTests : LibTestSuite() { ) assertEquals(Episode.I, quest.episode) assertEquals(277, quest.objects.size) - // TODO: Test objects. -// assertEquals(ObjectType.MenuActivation, quest.objects[0]) -// assertEquals(ObjectType.PlayerSet, quest.objects[4]) + assertEquals(ObjectType.MenuActivation, quest.objects[0].type) + assertEquals(ObjectType.PlayerSet, quest.objects[4].type) assertEquals(216, quest.npcs.size) assertEquals(10, quest.mapDesignations.size) assertEquals(0, quest.mapDesignations[0]) @@ -71,4 +88,73 @@ class QuestTests : LibTestSuite() { assertEquals(200, seg4.instructions[0].args[1].value) assertEquals(201, seg4.instructions[0].args[2].value) } + + @Test + fun round_trip_test_with_towards_the_future() = asyncTest { + val filename = "quest118_e.qst" + roundTripTest(filename, readFile("/$filename")) + } + + @Test + fun round_trip_test_with_seat_of_the_heart() = asyncTest { + val filename = "quest27_e.qst" + roundTripTest(filename, readFile("/$filename")) + } + + @Test + fun round_trip_test_with_lost_head_sword_gc() = asyncTest { + val filename = "lost_heat_sword_gc.qst" + roundTripTest(filename, readFile("/$filename")) + } + + /** + * Round-trip tests. + * Parse a QST file, write the resulting Quest object to QST again, then parse that again. + * Then check whether the two Quest objects are deeply equal. + */ + private fun roundTripTest(filename: String, contents: Cursor) { + val origQuestData = parseQstToQuest(contents).unwrap() + val origQuest = origQuestData.quest + val newQuestData = parseQstToQuest( + writeQuestToQst( + origQuest, + filename, + origQuestData.version, + origQuestData.online, + ).cursor() + ).unwrap() + val newQuest = newQuestData.quest + + assertEquals(origQuestData.version, newQuestData.version) + assertEquals(origQuestData.online, newQuestData.online) + + assertEquals(origQuest.name, newQuest.name) + assertEquals(origQuest.shortDescription, newQuest.shortDescription) + assertEquals(origQuest.longDescription, newQuest.longDescription) + assertEquals(origQuest.episode, newQuest.episode) + assertEquals(origQuest.objects.size, newQuest.objects.size) + + for (i in origQuest.objects.indices) { + val origObj = origQuest.objects[i] + val newObj = newQuest.objects[i] + assertEquals(origObj.areaId, newObj.areaId) + assertEquals(origObj.sectionId, newObj.sectionId) + assertEquals(origObj.position, newObj.position) + assertEquals(origObj.type, newObj.type) + } + + assertEquals(origQuest.npcs.size, newQuest.npcs.size) + + for (i in origQuest.npcs.indices) { + val origNpc = origQuest.npcs[i] + val newNpc = newQuest.npcs[i] + assertEquals(origNpc.areaId, newNpc.areaId) + assertEquals(origNpc.sectionId, newNpc.sectionId) + assertEquals(origNpc.position, newNpc.position) + assertEquals(origNpc.type, newNpc.type) + } + + assertDeepEquals(origQuest.mapDesignations, newQuest.mapDesignations, ::assertEquals) + assertDeepEquals(origQuest.bytecodeIr, newQuest.bytecodeIr) + } } diff --git a/lib/src/commonTest/kotlin/world/phantasmal/lib/test/TestUtils.kt b/lib/src/commonTest/kotlin/world/phantasmal/lib/test/TestUtils.kt index 5bf99985..424ac27e 100644 --- a/lib/src/commonTest/kotlin/world/phantasmal/lib/test/TestUtils.kt +++ b/lib/src/commonTest/kotlin/world/phantasmal/lib/test/TestUtils.kt @@ -22,17 +22,36 @@ fun toInstructions(assembly: String): List { fun assertDeepEquals(expected: List, actual: List, assertDeepEquals: (T, T) -> Unit) { assertEquals(expected.size, actual.size) - for (i in actual.indices) { + for (i in expected.indices) { assertDeepEquals(expected[i], actual[i]) } } -fun assertDeepEquals(expected: Buffer, actual: Buffer): Boolean { - if (expected.size != actual.size) return false +fun assertDeepEquals( + expected: Map, + actual: Map, + assertDeepEquals: (V, V) -> Unit, +) { + assertEquals(expected.size, actual.size) + + for ((key, value) in expected) { + assertTrue(key in actual) + assertDeepEquals(value, actual[key]!!) + } +} + +fun assertDeepEquals(expected: Buffer, actual: Buffer) { + assertEquals(expected.size, actual.size) for (i in 0 until expected.size) { - if (expected.getByte(i) != actual.getByte(i)) return false + assertEquals(expected.getByte(i), actual.getByte(i)) + } +} + +fun assertDeepEquals(expected: Cursor, actual: Cursor) { + assertEquals(expected.size, actual.size) + + while (expected.hasBytesLeft()) { + assertEquals(expected.byte(), actual.byte()) } - - return true } diff --git a/lib/src/commonTest/resources/quest118_e.qst b/lib/src/commonTest/resources/quest118_e.qst new file mode 100644 index 0000000000000000000000000000000000000000..ced6fd3e7dd1852f3aa38c3b1ea49b54fbb47f34 GIT binary patch literal 32912 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 aH$6iO;7R}U`40vDLxKM%DX`<8z4~9j-lFgT literal 0 HcmV?d00001 diff --git a/lib/src/commonTest/resources/quest27_e.qst b/lib/src/commonTest/resources/quest27_e.qst new file mode 100644 index 0000000000000000000000000000000000000000..1646d3c7d660f014d6c8c34ee7acb1b4743df517 GIT binary patch literal 111056 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á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 + private val _saveAsDialogVisible = mutableVal(false) + private val _filename = mutableVal("") + private val _version = mutableVal(Version.BB) // Result @@ -44,6 +51,13 @@ class QuestEditorToolbarController( val openFileAccept = ".bin, .dat, .qst" + // Save as + + val saveAsEnabled: Val = questEditorStore.currentQuest.isNotNull() + val saveAsDialogVisible: Val = _saveAsDialogVisible + val filename: Val = _filename + val version: Val = _version + // Undo val undoTooltip: Val = questEditorStore.firstUndo.map { action -> @@ -87,6 +101,10 @@ class QuestEditorToolbarController( openFiles(selectFiles(accept = openFileAccept, multiple = true)) }, + uiStore.onGlobalKeyDown(PwToolType.QuestEditor, "Ctrl-Shift-S") { + saveAs() + }, + uiStore.onGlobalKeyDown(PwToolType.QuestEditor, "Ctrl-Z") { undo() }, @@ -102,14 +120,12 @@ class QuestEditorToolbarController( } suspend fun createNewQuest(episode: Episode) { - // TODO: Set filename and version. - questEditorStore.setCurrentQuest( - convertQuestToModel(questLoader.loadDefaultQuest(episode), areaStore::getVariant) - ) + setFilename("") + setVersion(Version.BB) + setCurrentQuest(questLoader.loadDefaultQuest(episode)) } suspend fun openFiles(files: List) { - // TODO: Set filename and version. try { if (files.isEmpty()) return @@ -120,6 +136,8 @@ class QuestEditorToolbarController( setResult(parseResult) if (parseResult is Success) { + setFilename(filenameBase(qst.name) ?: qst.name) + setVersion(parseResult.value.version) setCurrentQuest(parseResult.value.quest) } } else { @@ -141,6 +159,8 @@ class QuestEditorToolbarController( setResult(parseResult) if (parseResult is Success) { + setFilename(filenameBase(bin.name) ?: filenameBase(dat.name) ?: bin.name) + setVersion(Version.BB) setCurrentQuest(parseResult.value) } } @@ -153,6 +173,64 @@ class QuestEditorToolbarController( } } + fun saveAs() { + if (saveAsEnabled.value) { + _saveAsDialogVisible.value = true + } + } + + fun setFilename(filename: String) { + _filename.value = filename + } + + fun setVersion(version: Version) { + _version.value = version + } + + fun saveAsDialogSave() { + val quest = questEditorStore.currentQuest.value ?: return + var filename = filename.value.trim() + + val buffer = writeQuestToQst( + convertQuestFromModel(quest), + filename, + version.value, + online = true, + ) + + if (!filename.endsWith(".qst")) { + filename += ".qst" + } + + val a = document.createElement("a") as HTMLAnchorElement + val url = URL.createObjectURL( + Blob( + arrayOf(buffer.arrayBuffer), + obj { type = "application/octet-stream" }, + ) + ) + try { + a.href = url + a.download = filename + document.body?.appendChild(a) + a.click() + } catch (e: Exception) { + URL.revokeObjectURL(url) + document.body?.removeChild(a) + throw e + } + + dismissSaveAsDialog() + } + + fun dismissSaveAsDialog() { + _saveAsDialogVisible.value = false + } + + fun dismissResultDialog() { + _resultDialogVisible.value = false + } + fun undo() { questEditorStore.undo() } diff --git a/web/src/main/kotlin/world/phantasmal/web/questEditor/stores/ModelConversion.kt b/web/src/main/kotlin/world/phantasmal/web/questEditor/stores/ModelConversion.kt index 533082aa..c0dc5c0a 100644 --- a/web/src/main/kotlin/world/phantasmal/web/questEditor/stores/ModelConversion.kt +++ b/web/src/main/kotlin/world/phantasmal/web/questEditor/stores/ModelConversion.kt @@ -1,6 +1,7 @@ package world.phantasmal.web.questEditor.stores import world.phantasmal.lib.Episode +import world.phantasmal.lib.fileFormats.quest.DatEvent import world.phantasmal.lib.fileFormats.quest.DatEventAction import world.phantasmal.lib.fileFormats.quest.Quest import world.phantasmal.web.questEditor.models.* @@ -8,8 +9,8 @@ import world.phantasmal.web.questEditor.models.* fun convertQuestToModel( quest: Quest, getVariant: (Episode, areaId: Int, variantId: Int) -> AreaVariantModel?, -): QuestModel { - return QuestModel( +): QuestModel = + QuestModel( quest.id, quest.language, quest.name, @@ -27,22 +28,22 @@ fun convertQuestToModel( event.wave.toInt(), event.delay.toInt(), event.unknown.toInt(), - event.actions.mapTo(mutableListOf()) { - when (it) { + event.actions.mapTo(mutableListOf()) { action -> + when (action) { is DatEventAction.SpawnNpcs -> QuestEventActionModel.SpawnNpcs( - it.sectionId.toInt(), - it.appearFlag.toInt() + action.sectionId.toInt(), + action.appearFlag.toInt() ) is DatEventAction.Unlock -> - QuestEventActionModel.Door.Unlock(it.doorId.toInt()) + QuestEventActionModel.Door.Unlock(action.doorId.toInt()) is DatEventAction.Lock -> - QuestEventActionModel.Door.Lock(it.doorId.toInt()) + QuestEventActionModel.Door.Lock(action.doorId.toInt()) is DatEventAction.TriggerEvent -> - QuestEventActionModel.TriggerEvent(it.eventId) + QuestEventActionModel.TriggerEvent(action.eventId) } } ) @@ -52,4 +53,51 @@ fun convertQuestToModel( quest.shopItems, getVariant, ) -} + +/** + * The returned [Quest] object will reference parts of [quest], so some changes to [quest] will be + * reflected in the returned object. + */ +fun convertQuestFromModel(quest: QuestModel): Quest = + Quest( + quest.id.value, + quest.language.value, + quest.name.value, + quest.shortDescription.value, + quest.longDescription.value, + quest.episode, + quest.objects.value.map { it.entity }, + quest.npcs.value.map { it.entity }, + quest.events.value.map { event -> + DatEvent( + event.id.value, + event.sectionId.value.toShort(), + event.wave.value.id.toShort(), + event.delay.value.toShort(), + event.actions.value.map { action -> + when (action) { + is QuestEventActionModel.SpawnNpcs -> + DatEventAction.SpawnNpcs( + action.sectionId.value.toShort(), + action.appearFlag.value.toShort(), + ) + + is QuestEventActionModel.Door.Unlock -> + DatEventAction.Unlock(action.doorId.value.toShort()) + + is QuestEventActionModel.Door.Lock -> + DatEventAction.Lock(action.doorId.value.toShort()) + + is QuestEventActionModel.TriggerEvent -> + DatEventAction.TriggerEvent(action.eventId.value) + } + }, + event.areaId, + event.unknown.toShort(), + ) + }, + quest.datUnknowns, + quest.bytecodeIr, + quest.shopItems, + quest.mapDesignations.value, + ) diff --git a/web/src/main/kotlin/world/phantasmal/web/questEditor/widgets/QuestEditorToolbarWidget.kt b/web/src/main/kotlin/world/phantasmal/web/questEditor/widgets/QuestEditorToolbarWidget.kt index 0f25833f..fcb12781 100644 --- a/web/src/main/kotlin/world/phantasmal/web/questEditor/widgets/QuestEditorToolbarWidget.kt +++ b/web/src/main/kotlin/world/phantasmal/web/questEditor/widgets/QuestEditorToolbarWidget.kt @@ -2,7 +2,9 @@ package world.phantasmal.web.questEditor.widgets import kotlinx.coroutines.launch import org.w3c.dom.Node +import org.w3c.dom.events.KeyboardEvent import world.phantasmal.lib.Episode +import world.phantasmal.lib.fileFormats.quest.Version import world.phantasmal.observable.value.list.listVal import world.phantasmal.observable.value.value import world.phantasmal.web.questEditor.controllers.QuestEditorToolbarController @@ -32,6 +34,13 @@ class QuestEditorToolbarWidget(private val ctrl: QuestEditorToolbarController) : multiple = true, filesSelected = { files -> scope.launch { ctrl.openFiles(files) } }, ), + Button( + text = "Save as...", + iconLeft = Icon.Save, + enabled = ctrl.saveAsEnabled, + tooltip = value("Save this quest to a new file (Ctrl-Shift-S)"), + onClick = { ctrl.saveAs() }, + ), Button( text = "Undo", iconLeft = Icon.Undo, @@ -55,5 +64,83 @@ class QuestEditorToolbarWidget(private val ctrl: QuestEditorToolbarController) : ), ) )) + + val saveAsDialog = addDisposable(Dialog( + visible = ctrl.saveAsDialogVisible, + title = value("Save As"), + content = { + div { + className = "pw-quest-editor-toolbar-save-as" + + val filenameInput = TextInput( + label = "File name:", + value = ctrl.filename, + onChange = ctrl::setFilename, + ) + addWidget(filenameInput.label!!) + addWidget(filenameInput) + + val versionSelect = Select( + label = "Version:", + items = listVal(Version.GC, Version.BB), + selected = ctrl.version, + itemToString = { + when (it) { + Version.DC -> "Dreamcast" + Version.GC -> "GameCube" + Version.PC -> "PC" + Version.BB -> "BlueBurst" + } + }, + onSelect = ctrl::setVersion, + ) + addWidget(versionSelect.label!!) + addWidget(versionSelect) + } + }, + footer = { + addWidget(Button( + text = "Save", + onClick = { ctrl.saveAsDialogSave() }, + )) + addWidget(Button( + text = "Cancel", + onClick = { ctrl.dismissSaveAsDialog() }, + )) + }, + onDismiss = ctrl::dismissSaveAsDialog, + )) + + saveAsDialog.dialogElement.addEventListener("keydown", { e -> + if ((e as KeyboardEvent).key == "Enter") { + ctrl.saveAsDialogSave() + } + }) + + addDisposable(ResultDialog( + visible = ctrl.resultDialogVisible, + result = ctrl.result, + onDismiss = ctrl::dismissResultDialog, + )) } + + companion object { + init { + @Suppress("CssUnusedSymbol") + // language=css + style(""" + .pw-quest-editor-toolbar-save-as { + display: grid; + grid-template-columns: 100px max-content; + grid-column-gap: 4px; + grid-row-gap: 4px; + align-items: center; + } + + .pw-quest-editor-toolbar-save-as .pw-input { + margin: 1px; + } + """.trimIndent()) + } + } } diff --git a/webui/src/main/kotlin/world/phantasmal/webui/widgets/Dialog.kt b/webui/src/main/kotlin/world/phantasmal/webui/widgets/Dialog.kt index 0a398431..d86a9f2b 100644 --- a/webui/src/main/kotlin/world/phantasmal/webui/widgets/Dialog.kt +++ b/webui/src/main/kotlin/world/phantasmal/webui/widgets/Dialog.kt @@ -8,6 +8,7 @@ import org.w3c.dom.events.KeyboardEvent import org.w3c.dom.get import org.w3c.dom.pointerevents.PointerEvent import world.phantasmal.observable.value.Val +import world.phantasmal.observable.value.emptyStringVal import world.phantasmal.observable.value.isEmpty import world.phantasmal.observable.value.trueVal import world.phantasmal.webui.dom.div @@ -19,14 +20,24 @@ open class Dialog( visible: Val = trueVal(), enabled: Val = trueVal(), private val title: Val, - private val description: Val, - private val content: Val, + private val description: Val = emptyStringVal(), + private val content: Node.() -> Unit = {}, + private val footer: Node.() -> Unit = {}, protected val onDismiss: () -> Unit = {}, ) : Widget(visible, enabled) { private var x = 0 private var y = 0 - private var dialogElement = dom { + private var overlayElement = dom { + div { + className = "pw-dialog-modal-overlay" + tabIndex = -1 + + addEventListener("focus", { this@Dialog.focus() }) + } + } + + val dialogElement = dom { section { className = "pw-dialog" tabIndex = 0 @@ -51,28 +62,15 @@ open class Dialog( } div { className = "pw-dialog-body" - - observe(content) { - textContent = "" - append(it) - } + content() } div { className = "pw-dialog-footer" - addFooterContent(this) + footer() } } } - private var overlayElement = dom { - div { - className = "pw-dialog-modal-overlay" - tabIndex = -1 - - addEventListener("focus", { this@Dialog.focus() }) - } - } - init { observe(visible) { if (it) { @@ -98,10 +96,6 @@ open class Dialog( super.internalDispose() } - protected open fun addFooterContent(footer: Node) { - // Do nothing. - } - private fun onPointerMove(movedX: Int, movedY: Int, e: PointerEvent): Boolean { e.preventDefault() setPosition(this.x + movedX, this.y + movedY) diff --git a/webui/src/main/kotlin/world/phantasmal/webui/widgets/ResultDialog.kt b/webui/src/main/kotlin/world/phantasmal/webui/widgets/ResultDialog.kt index 626f04f3..427ca97a 100644 --- a/webui/src/main/kotlin/world/phantasmal/webui/widgets/ResultDialog.kt +++ b/webui/src/main/kotlin/world/phantasmal/webui/widgets/ResultDialog.kt @@ -4,38 +4,64 @@ import org.w3c.dom.Node import world.phantasmal.core.Failure import world.phantasmal.core.PwResult import world.phantasmal.observable.value.Val +import world.phantasmal.observable.value.emptyStringVal import world.phantasmal.observable.value.trueVal import world.phantasmal.webui.dom.div -import world.phantasmal.webui.dom.dom import world.phantasmal.webui.dom.li import world.phantasmal.webui.dom.ul /** * Shows the details of a result if the result failed or succeeded with problems. Shows a "Dismiss" - * button in the footer which triggers [onDismiss]. + * button in the footer which triggers onDismiss. */ class ResultDialog( visible: Val = trueVal(), enabled: Val = trueVal(), result: Val?>, - message: Val, + message: Val = emptyStringVal(), onDismiss: () -> Unit = {}, -) : Dialog( - visible, - enabled, - title = result.map(::resultToTitle), - description = message, - content = result.map(::resultToContent), - onDismiss, -) { - override fun addFooterContent(footer: Node) { - footer.addChild(Button( +) : Widget(visible, enabled) { + private val dialog = addDisposable( + Dialog( visible, enabled, - text = "Dismiss", - onClick = { onDismiss() } - )) - } + title = result.map { result -> + when { + result is Failure -> "Error" + result?.problems?.isNotEmpty() == true -> "Problems" + else -> "" + } + }, + description = message, + content = { + div { + className = "pw-result-dialog-result" + + ul { + className = "pw-result-dialog-problems" + hidden(result.isNull()) + + bindChildrenTo(result.map { + it?.problems ?: emptyList() + }) { problem, _ -> + li { textContent = problem.uiMessage } + } + } + } + }, + footer = { + addChild(Button( + visible, + enabled, + text = "Dismiss", + onClick = { onDismiss() } + )) + }, + onDismiss = onDismiss, + ) + ) + + override fun Node.createElement() = dialog.element companion object { init { @@ -53,27 +79,3 @@ class ResultDialog( } } } - -private fun resultToTitle(result: PwResult<*>?): String = - when { - result is Failure -> "Error" - result?.problems?.isNotEmpty() == true -> "Problems" - else -> "" - } - -private fun resultToContent(result: PwResult<*>?): Node = - dom { - div { - className = "pw-result-dialog-result" - - result?.let { - ul { - className = "pw-result-dialog-problems" - - result.problems.map { - li { textContent = it.uiMessage } - } - } - } - } - }