Skip to content

Commit

Permalink
Experimental monochrome compatibility setting for "Color Only" games …
Browse files Browse the repository at this point in the history
…allowing some sprites and backgrounds to still be used
  • Loading branch information
chrismaltby committed Apr 3, 2024
1 parent c85275f commit 249178f
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 13 deletions.
5 changes: 1 addition & 4 deletions src/app/project/initProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { initKeyBindings } from "renderer/lib/keybindings/keyBindings";
import { TRACKER_REDO, TRACKER_UNDO } from "consts";
import API from "renderer/lib/api";
import { NavigationSection } from "store/features/navigation/navigationState";
import { Background } from "shared/lib/entities/entitiesTypes";
import { isZoomSection } from "store/features/editor/editorHelpers";

const urlParams = new URLSearchParams(window.location.search);
Expand Down Expand Up @@ -166,9 +165,7 @@ API.events.watch.sprite.removed.subscribe((_, filename, plugin) => {
// Watch Backgrounds

API.events.watch.background.changed.subscribe((_, _filename, data) => {
store.dispatch(
entitiesActions.loadBackground({ data: data as unknown as Background })
);
store.dispatch(entitiesActions.loadBackground({ data }));
});

API.events.watch.background.removed.subscribe((_, filename, plugin) => {
Expand Down
32 changes: 32 additions & 0 deletions src/components/backgrounds/BackgroundPreviewSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "store/features/entities/entitiesState";
import editorActions from "store/features/editor/editorActions";
import electronActions from "store/features/electron/electronActions";
import entitiesActions from "store/features/entities/entitiesActions";
import { SceneSelect } from "components/forms/SceneSelect";
import { SelectMenu, selectMenuStyleProps } from "ui/form/Select";
import { RelativePortal } from "ui/layout/RelativePortal";
Expand All @@ -14,6 +15,7 @@ import l10n from "shared/lib/lang/l10n";
import { sceneName } from "shared/lib/entities/entitiesHelpers";
import { useAppDispatch, useAppSelector } from "store/hooks";
import { assetPath } from "shared/lib/helpers/assets";
import { CheckboxField } from "ui/form/CheckboxField";

interface BackgroundPreviewSettingsProps {
backgroundId: string;
Expand Down Expand Up @@ -45,6 +47,11 @@ const Pill = styled.button`
}
`;

const CheckboxWrapper = styled.div`
margin-left: 5px;
margin-top: -3px;
`;

const ButtonCover = styled.div`
position: absolute;
top: 0;
Expand Down Expand Up @@ -76,6 +83,9 @@ const BackgroundPreviewSettings = ({
const colorsEnabled = useAppSelector(
(state) => state.project.present.settings.colorMode !== "mono"
);
const isCGBOnly = useAppSelector(
(state) => state.project.present.settings.colorMode === "color"
);

useEffect(() => {
if (buttonFocus) {
Expand Down Expand Up @@ -158,6 +168,17 @@ const BackgroundPreviewSettings = ({
}
}, [background, dispatch]);

const onChangeDMGCompatible = useCallback(() => {
dispatch(
entitiesActions.editBackgroundSettings({
backgroundId,
changes: {
dmgCompatible: !background?.settings?.dmgCompatible,
},
})
);
}, [dispatch, background?.settings?.dmgCompatible, backgroundId]);

return (
<Wrapper>
{isOpen && <ButtonCover onMouseDown={delayedButtonFocus} />}
Expand Down Expand Up @@ -198,6 +219,17 @@ const BackgroundPreviewSettings = ({
<Pill ref={buttonRef} onClick={onEdit}>
{l10n("FIELD_EDIT_IMAGE")}
</Pill>
{isCGBOnly && (
<CheckboxWrapper>
<CheckboxField
name="dmgCompatible"
label={l10n("FIELD_MONOCHROME_COMPATIBLE")}
title={l10n("FIELD_MONOCHROME_COMPATIBLE_INFO")}
checked={background?.settings?.dmgCompatible ?? false}
onChange={onChangeDMGCompatible}
/>
</CheckboxWrapper>
)}
</Wrapper>
);
};
Expand Down
35 changes: 33 additions & 2 deletions src/components/sprites/MetaspriteEditorPreviewSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";
import styled from "styled-components";
import {
metaspriteSelectors,
sceneSelectors,
spriteSheetSelectors,
} from "store/features/entities/entitiesState";
import editorActions from "store/features/editor/editorActions";
import entitiesActions from "store/features/entities/entitiesActions";
import l10n from "shared/lib/lang/l10n";
import { SceneSelect } from "components/forms/SceneSelect";
import { SelectMenu, selectMenuStyleProps } from "ui/form/Select";
Expand All @@ -14,6 +15,7 @@ import { TooltipWrapper } from "ui/tooltips/Tooltip";
import { FixedSpacer } from "ui/spacing/Spacing";
import { sceneName } from "shared/lib/entities/entitiesHelpers";
import { useAppDispatch, useAppSelector } from "store/hooks";
import { CheckboxField } from "ui/form/CheckboxField";

interface MetaspriteEditorPreviewSettingsProps {
spriteSheetId: string;
Expand Down Expand Up @@ -46,6 +48,11 @@ const Pill = styled.button`
}
`;

const CheckboxWrapper = styled.div`
margin-left: 5px;
margin-top: -3px;
`;

const Info = styled.div`
color: ${(props) => props.theme.colors.secondaryText};
padding: 0 5px;
Expand Down Expand Up @@ -91,6 +98,9 @@ const MetaspriteEditorPreviewSettings = ({
const colorsEnabled = useAppSelector(
(state) => state.project.present.settings.colorMode !== "mono"
);
const isCGBOnly = useAppSelector(
(state) => state.project.present.settings.colorMode === "color"
);

useEffect(() => {
if (buttonFocus) {
Expand Down Expand Up @@ -162,6 +172,17 @@ const MetaspriteEditorPreviewSettings = ({
dispatch(editorActions.setPreviewAsSceneId(newValue));
};

const onChangeDMGCompatible = useCallback(() => {
dispatch(
entitiesActions.editSpriteSheetSettings({
spriteSheetId,
changes: {
dmgCompatible: !spriteSheet?.settings?.dmgCompatible,
},
})
);
}, [dispatch, spriteSheet?.settings?.dmgCompatible, spriteSheetId]);

if (!spriteSheet || !metasprite) {
return null;
}
Expand Down Expand Up @@ -214,7 +235,17 @@ const MetaspriteEditorPreviewSettings = ({
{l10n("FIELD_UNIQUE")}={spriteSheet.numTiles}
</Info>
</TooltipWrapper>
<FixedSpacer width={5} />
{isCGBOnly && (
<CheckboxWrapper>
<CheckboxField
name="dmgCompatible"
label={l10n("FIELD_MONOCHROME_COMPATIBLE")}
title={l10n("FIELD_MONOCHROME_COMPATIBLE_INFO")}
checked={spriteSheet?.settings?.dmgCompatible ?? false}
onChange={onChangeDMGCompatible}
/>
</CheckboxWrapper>
)}
</Wrapper>
);
};
Expand Down
2 changes: 2 additions & 0 deletions src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,8 @@
"FIELD_SUPPORTED_PLATFORMS": "Supported Platforms",
"FIELD_MONOCHROME_ONLY": "Monochrome only",
"FIELD_SGB_UNAVAILABLE": "Super GB Mode is not supported for 'Color Only' games",
"FIELD_MONOCHROME_COMPATIBLE": "Monochrome Compatible",
"FIELD_MONOCHROME_COMPATIBLE_INFO": "As your game is set to 'Color Only' this asset may get placed in memory not available on incompatible devices. Setting this option allows keeping compatiblity with older devices for this asset, for example this could be useful to display a message that your game is only supported on color hardware.",

"// 7": "Asset Viewer ---------------------------------------------",
"ASSET_SEARCH": "Search...",
Expand Down
7 changes: 4 additions & 3 deletions src/lib/compiler/compileImages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ const compileImage = async (
};
}

const tileAllocationStrategy = cgbOnly
? imageTileAllocationColorOnly
: imageTileAllocationDefault;
const tileAllocationStrategy =
cgbOnly && !img.settings?.dmgCompatible
? imageTileAllocationColorOnly
: imageTileAllocationDefault;

const tilesetLookup = toTileLookup(tileData) ?? {};
const uniqueTiles = Object.values(tilesetLookup);
Expand Down
7 changes: 4 additions & 3 deletions src/lib/compiler/compileSprites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,10 @@ export const compileSprite = async (
): Promise<PrecompiledSpriteSheetData> => {
const filename = assetFilename(projectRoot, "sprites", spriteSheet);

const tileAllocationStrategy = cgbOnly
? spriteTileAllocationColorOnly
: spriteTileAllocationDefault;
const tileAllocationStrategy =
cgbOnly && !spriteSheet.settings?.dmgCompatible
? spriteTileAllocationColorOnly
: spriteTileAllocationDefault;

const metasprites = spriteSheet.states
.map((state) => state.animations)
Expand Down
8 changes: 8 additions & 0 deletions src/lib/project/loadBackgroundData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export interface BackgroundAssetData {
imageWidth: number;
imageHeight: number;
plugin?: string;
tileColors: number[];
settings: {
dmgCompatible: boolean;
};
inode: string;
_v: number;
}
Expand Down Expand Up @@ -50,6 +54,10 @@ const loadBackgroundData =
imageWidth: width,
imageHeight: height,
filename: file,
tileColors: [],
settings: {
dmgCompatible: false,
},
inode,
_v: Date.now(),
};
Expand Down
9 changes: 9 additions & 0 deletions src/lib/project/loadProjectData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,20 @@ const loadProject = async (
oldBackground?.tileColors !== undefined
? oldBackground.tileColors
: [],
settings:
oldBackground.settings !== undefined
? oldBackground.settings
: {
dmgCompatible: false,
},
};
}
return {
...background,
tileColors: [],
settings: {
dmgCompatible: false,
},
};
})
.sort(sortByName);
Expand Down
6 changes: 6 additions & 0 deletions src/lib/project/loadSpriteData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export interface SpriteAssetData {
animSpeed: number | null;
states: string[];
numFrames: number;
settings: {
dmgCompatible: boolean;
};
}

const loadSpriteData =
Expand Down Expand Up @@ -70,6 +73,9 @@ const loadSpriteData =
boundsWidth: 16,
boundsHeight: 16,
animSpeed: 15,
settings: {
dmgCompatible: false,
},
_v: Date.now(),
};
} catch (e) {
Expand Down
10 changes: 10 additions & 0 deletions src/shared/lib/entities/entitiesTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ export type TriggerNormalized = Omit<Trigger, "script" | "leaveScript"> & {
leaveScript: string[];
};

export type BackgroundSettings = {
dmgCompatible?: boolean;
};

export type Background = {
id: string;
name: string;
Expand All @@ -148,6 +152,7 @@ export type Background = {
imageWidth: number;
imageHeight: number;
tileColors: number[];
settings: BackgroundSettings;
plugin?: string;
inode: string;
_v: number;
Expand Down Expand Up @@ -317,6 +322,10 @@ export type SpriteAnimationData = Omit<SpriteAnimation, "frames"> & {
frames: MetaspriteData[];
};

export type SpriteSettings = {
dmgCompatible?: boolean;
};

export type SpriteSheet = {
id: string;
name: string;
Expand All @@ -337,6 +346,7 @@ export type SpriteSheet = {
boundsHeight: number;
animSpeed: number | null;
states: string[];
settings: SpriteSettings;
};

export type SpriteSheetData = Omit<SpriteSheet, "states" | "_v" | "inode"> & {
Expand Down
Loading

0 comments on commit 249178f

Please sign in to comment.