Skip to content

Commit

Permalink
save-rom: save the diffs on the OAM, such as the new position
Browse files Browse the repository at this point in the history
  • Loading branch information
macabeus committed Oct 3, 2019
1 parent 2a8b9b4 commit 5405a74
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 6 deletions.
13 changes: 11 additions & 2 deletions brush/src/components/Map/OAMLayer/index.js
Expand Up @@ -3,20 +3,27 @@ import PropTypes from 'prop-types'
import { range } from 'ramda'
import PointOam from '../Point/PointOam'

const OAMLayer = ({ setSelectedPointInfos, totalStages, vision }) => {
const OAMLayer = ({
setSelectedPointInfos,
totalStages,
updateOAMDiffMap,
vision,
}) => {
const { oam } = vision

const oamList = oam
.map(oamEntry => oamEntry.data)
.map(oamData =>
.map((oamData, oamIndex) =>
range(1, totalStages + 1).map((i) => {
const x = oamData[`xStage${i}`]
const y = oamData[`yStage${i}`]

return (
<PointOam
onFinishDragAndDrop={updateOAMDiffMap}
key={`${x} ${y} ${i}`}
oamId={oamData.kind}
oamIndex={oamIndex}
stage={i}
showPointInfosHandle={setSelectedPointInfos}
x={x}
Expand All @@ -35,6 +42,7 @@ const OAMLayer = ({ setSelectedPointInfos, totalStages, vision }) => {
OAMLayer.propTypes = {
setSelectedPointInfos: PropTypes.func,
totalStages: PropTypes.number.isRequired,
updateOAMDiffMap: PropTypes.func,
vision: PropTypes.shape({
oam: PropTypes.arrayOf(PropTypes.shape({
data: PropTypes.object.isRequired,
Expand All @@ -45,6 +53,7 @@ OAMLayer.propTypes = {

OAMLayer.defaultProps = {
setSelectedPointInfos: () => {},
updateOAMDiffMap: () => {},
}

export default OAMLayer
11 changes: 11 additions & 0 deletions brush/src/components/Map/Point/PointOam.js
Expand Up @@ -21,6 +21,8 @@ const oamIdToColor = {

const PointOam = ({
oamId,
oamIndex,
onFinishDragAndDrop,
showPointInfosHandle,
stage,
x,
Expand All @@ -35,11 +37,17 @@ const PointOam = ({
y,
})

const saveNewOAMPosition = (newX, newY) => {
onFinishDragAndDrop(oamIndex, `xStage${stage}`, newX)
onFinishDragAndDrop(oamIndex, `yStage${stage}`, newY)
}

return (<Point
color={color}
draggable
hasStroke
onHoverHandle={pipe(getInformations, showPointInfosHandle)}
onFinishDragAndDropHandle={saveNewOAMPosition}
scale={8}
x={x}
y={y}
Expand All @@ -48,13 +56,16 @@ const PointOam = ({

PointOam.propTypes = {
oamId: PropTypes.number.isRequired,
oamIndex: PropTypes.number.isRequired,
onFinishDragAndDrop: PropTypes.func,
showPointInfosHandle: PropTypes.func,
stage: PropTypes.number.isRequired,
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired,
}

PointOam.defaultProps = {
onFinishDragAndDrop: () => {},
showPointInfosHandle: () => {},
}

Expand Down
4 changes: 4 additions & 0 deletions brush/src/components/Map/Point/index.js
Expand Up @@ -9,6 +9,7 @@ const Point = ({
color,
draggable,
hasStroke,
onFinishDragAndDropHandle,
onHoverHandle,
scale,
size,
Expand All @@ -25,7 +26,10 @@ const Point = ({

const hoc = draggable ?
withDraggable(
onFinishDragAndDropHandle,
scale,
rawX,
rawY,
setRawX,
setRawY
)
Expand Down
4 changes: 4 additions & 0 deletions brush/src/components/Map/Point/withDraggable.js
Expand Up @@ -2,7 +2,10 @@ import { useState } from 'react'
import getScaledCoordinates, { SIZE } from './getScaledCoordinates'

const withDraggable = (
onFinishDragAndDropHandle,
scale,
x,
y,
setX,
setY
) => (Point) => {
Expand Down Expand Up @@ -34,6 +37,7 @@ const withDraggable = (
setY(newY)
},
mouseupoutside: () => {
onFinishDragAndDropHandle(x, y)
setDragging(false)
},
},
Expand Down
2 changes: 2 additions & 0 deletions brush/src/components/Map/index.js
Expand Up @@ -21,6 +21,7 @@ const Map = ({
}) => {
const {
getTilemapPoint,
updateOAMDiffMap,
updateTilemapPoint,
vision,
} = useContext(VisionContext)
Expand Down Expand Up @@ -79,6 +80,7 @@ const Map = ({
width={width * 4}
/>
{optShowOAM && <OAMLayer
updateOAMDiffMap={updateOAMDiffMap}
setSelectedPointInfos={setSelectedPointInfos}
totalStages={totalStages}
vision={vision}
Expand Down
19 changes: 16 additions & 3 deletions brush/src/components/MapActionsBar/SaveButton.js
Expand Up @@ -4,8 +4,14 @@ import { saveVision } from 'scissors'
import ROMContext from '../../context/ROMContext'
import VisionContext from '../../context/VisionContext'

const romDownload = (romBufferMemory, world, index, tilemap) => {
const newMemoryROM = saveVision(romBufferMemory, world, index, tilemap)
const romDownload = (romBufferMemory, world, index, tilemap, oamDiffMap) => {
const newMemoryROM = saveVision(
romBufferMemory,
world,
index,
tilemap,
oamDiffMap
)

const blob = new Blob([newMemoryROM])

Expand All @@ -24,6 +30,7 @@ const SaveButton = () => {
const { romBufferMemory } = useContext(ROMContext)
const {
vision: {
oamDiffMap,
state,
tilemap,
},
Expand All @@ -34,7 +41,13 @@ const SaveButton = () => {
return (
<Button
onClick={() => {
romDownload(romBufferMemory, visionWorld, visionIndex, tilemap)
romDownload(
romBufferMemory,
visionWorld,
visionIndex,
tilemap,
oamDiffMap
)
}}
disabled={state === 'noSelected'}
>
Expand Down
11 changes: 11 additions & 0 deletions brush/src/providers/VisionProvider.js
Expand Up @@ -10,6 +10,7 @@ const VisionProvider = (props) => {
const emptyState = {
infos: { index: 0, tilemap: { height: 0, scheme: [], width: 0 }, world: 0 },
oam: [],
oamDiffMap: {},
state: 'noSelected',
tilemap: new Uint8Array(),
}
Expand All @@ -26,6 +27,7 @@ const VisionProvider = (props) => {
newVision.state = 'selected'
newVision.infos.world = world
newVision.infos.index = index
newVision.oamDiffMap = {}
setVision(newVision)
}

Expand All @@ -36,10 +38,19 @@ const VisionProvider = (props) => {
const getTilemapPoint = (x, y) =>
vision.tilemap[x + (y * vision.infos.tilemap.width)]

const updateOAMDiffMap = (index, key, value) => {
if (vision.oamDiffMap[index] === undefined) {
vision.oamDiffMap[index] = {}
}

vision.oamDiffMap[index][key] = value
}

return (
<VisionContext.Provider value={{
getTilemapPoint,
setEmptyState,
updateOAMDiffMap,
updateTilemapPoint,
updateVision,
vision,
Expand Down
37 changes: 36 additions & 1 deletion scissors/src/visionManager.js
Expand Up @@ -2,12 +2,14 @@ import {
filter,
identical,
map,
mapObjIndexed,
not,
pipe,
prop,
splitEvery,
} from 'ramda'
import binary from 'binary'
import splitHexValueIntoBytesArray from './splitHexValueIntoBytesArray'
import { huffmanDecode, huffmanEncode } from './huffman'
import { lzssDecode, lzssEncode } from './lzss'
import { loadVisionInfo } from './visions'
Expand Down Expand Up @@ -121,19 +123,52 @@ const getVision = (romBuffer, world, vision) => {
}
}

const applyOAMDiff = (romBuffer, oamStartAddress, oamDiffs) => {
/* eslint-disable sort-keys */
const mapKeyToOffset = {
xStage1: 0,
yStage1: 2,
xStage2: 8,
yStage2: 10,
xStage3: 16,
yStage3: 18,
xStage4: 24,
yStage4: 26,
xStage5: 32,
yStage5: 34,
}
/* eslint-enable sort-keys */

const updateROM = (diffs, oamIndex) => {
const oamObjectMemoryAddressStart = oamStartAddress + (oamIndex * 44)

mapObjIndexed((value, key) => {
const offset = mapKeyToOffset[key]
const bytes = splitHexValueIntoBytesArray(value, 2)

romBuffer.set(bytes, oamObjectMemoryAddressStart + offset)
}, diffs)
}

mapObjIndexed(updateROM, oamDiffs)
}

const compressTilemap = buffer =>
buffer
|> prop('full')
|> lzssEncode
|> huffmanEncode

const saveVision = (romBuffer, world, index, tilemap) => {
const saveVision = (romBuffer, world, index, tilemap, oamDiffMap) => {
const infos = loadVisionInfo(world, index)
const [customTilemapStartAddress] = infos.rom.customTilemap
const [oamStartAddress] = infos.rom.oam

const encoded = compressTilemap(tilemap)
romBuffer.set(encoded, customTilemapStartAddress)

applyOAMDiff(romBuffer, oamStartAddress, oamDiffMap)

setPatchCustomVisionLoader(romBuffer)

setSign(romBuffer)
Expand Down

0 comments on commit 5405a74

Please sign in to comment.