Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/manage tile alloc #1505

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions appData/src/gb/include/gbs_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ typedef struct background_t {
far_ptr_t cgb_tileset;
far_ptr_t tilemap; // far pointer to array of bytes with map
far_ptr_t cgb_tilemap_attr; // far pointer to array of bytes with CGB attributes (may be NULL)
uint8_t allocation_strat;
} background_t;

typedef struct tileset_t {
Expand Down
44 changes: 19 additions & 25 deletions appData/src/gb/src/core/data_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
#include "data/spritesheet_none.h"
#include "data/data_bootstrap.h"

#define ALLOC_BKG_TILES_TOWARDS_SPR

#define EMOTE_SPRITE_SIZE 4

far_ptr_t current_scene;
Expand Down Expand Up @@ -55,7 +53,7 @@ void load_init(void) BANKED {
scene_stack_ptr = scene_stack;
}

void load_bkg_tileset(const tileset_t* tiles, UBYTE bank) BANKED {
void load_bkg_tileset(const tileset_t* tiles, UBYTE bank, UBYTE allocation_strat) BANKED {
if ((!bank) || (!tiles)) return;

UWORD n_tiles = ReadBankedUWORD(&(tiles->n_tiles), bank);
Expand All @@ -70,26 +68,22 @@ void load_bkg_tileset(const tileset_t* tiles, UBYTE bank) BANKED {
n_tiles -= 128; data += 128 * 16;

// load second background chunk
if (n_tiles < 128) {
if (n_tiles < 65) {
#ifdef ALLOC_BKG_TILES_TOWARDS_SPR
// new allocation style, align to 192-th tile
if ((UBYTE)n_tiles) SetBankedBkgData(192 - n_tiles, n_tiles, data, bank);
#else
// old allocation style, align to 128-th tile
if ((UBYTE)n_tiles) SetBankedBkgData(128, n_tiles, data, bank);
#endif
} else {
// if greater than 64 allow overflow into UI, align to 128-th tile
if ((UBYTE)n_tiles) SetBankedBkgData(128, n_tiles, data, bank);
}
return;
}
SetBankedBkgData(128, 128, data, bank);
n_tiles -= 128; data += 128 * 16;

// if more than 256 - then it's a 360-tile logo, load rest to sprite area
if ((UBYTE)n_tiles) SetBankedSpriteData(0, n_tiles, data, bank);
if (n_tiles <= 128) {
// allocation_strat bit1 : if not set, reverse allocation toward sprites (sprite priorisation)
// allocation_strat bit2: if not set, align to reserved ui tile offset
if (allocation_strat & 1){
if ((UBYTE)n_tiles) SetBankedBkgData(128, ((allocation_strat >> 1) & 1)? n_tiles: MIN(n_tiles, 64), data, bank);
} else {
if ((UBYTE)n_tiles) SetBankedBkgData((((allocation_strat >> 1) & 1) ? 256: 192) - n_tiles, n_tiles, data, bank);
}
}
else
{
// if more than 256 - then it's a 360-tile logo, load rest to sprite area
SetBankedBkgData(128, 128, data, bank);
n_tiles -= 128; data += 128 * 16;
SetBankedSpriteData(0, n_tiles, data, bank);
}
}

void load_background(const background_t* background, UBYTE bank) BANKED {
Expand All @@ -109,11 +103,11 @@ void load_background(const background_t* background, UBYTE bank) BANKED {
image_height = image_tile_height * 8;
scroll_y_max = image_height - ((UINT16)SCREENHEIGHT);

load_bkg_tileset(bkg.tileset.ptr, bkg.tileset.bank);
load_bkg_tileset(bkg.tileset.ptr, bkg.tileset.bank, bkg.allocation_strat);
#ifdef CGB
if ((_is_CGB) && (bkg.cgb_tileset.ptr)) {
VBK_REG = 1;
load_bkg_tileset(bkg.cgb_tileset.ptr, bkg.cgb_tileset.bank);
load_bkg_tileset(bkg.cgb_tileset.ptr, bkg.cgb_tileset.bank, bkg.allocation_strat);
VBK_REG = 0;
}
#endif
Expand Down
44 changes: 41 additions & 3 deletions src/components/editors/SceneEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useMemo, useState } from "react";
import ScriptEditor from "components/script/ScriptEditor";
import { castEventToInt } from "renderer/lib/helpers/castEventValue";
import { castEventToBool, castEventToInt } from "renderer/lib/helpers/castEventValue";
import { WorldEditor } from "./WorldEditor";
import ScriptEditorDropdownButton from "components/script/ScriptEditorDropdownButton";
import BackgroundWarnings from "components/world/BackgroundWarnings";
Expand Down Expand Up @@ -42,6 +42,7 @@ import { SettingsState } from "store/features/settings/settingsState";
import { StickyTabs, TabBar } from "ui/tabs/Tabs";
import { Label } from "ui/form/Label";
import { Button } from "ui/buttons/Button";
import { CheckboxField } from "ui/form/CheckboxField";
import {
LockIcon,
LockOpenIcon,
Expand Down Expand Up @@ -149,7 +150,9 @@ export const SceneEditor = ({ id }: SceneEditorProps) => {
const [commonTilesetOpen, setCommonTilesetOpen] = useState<boolean>(
!!scene?.tilesetId
);

const [allocationStrat, setAllocationStrat] = useState<number>(
(scene?.allocationStrat || 0)
);
const colorsEnabled = useAppSelector(
(state) => state.project.present.settings.colorMode !== "mono"
);
Expand Down Expand Up @@ -386,6 +389,24 @@ export const SceneEditor = ({ id }: SceneEditorProps) => {
})
);
};

const onChangeReverseAllocationEnabled = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const newStrat = castEventToBool(e)? (allocationStrat & ~1): (allocationStrat | 1);
onChangeSceneProp("allocationStrat", newStrat);
setAllocationStrat(newStrat);
},
[allocationStrat, onChangeSceneProp]
);

const onChangeReserveUITilesEnabled = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const newStrat = castEventToBool(e)? (allocationStrat & ~2): (allocationStrat | 2);
onChangeSceneProp("allocationStrat", newStrat);
setAllocationStrat(newStrat);
},
[allocationStrat, onChangeSceneProp]
);

const onFetchClipboard = useCallback(() => {
dispatch(clipboardActions.fetchClipboard());
Expand Down Expand Up @@ -647,6 +668,7 @@ export const SceneEditor = ({ id }: SceneEditorProps) => {
tilesetId={scene.tilesetId}
onChange={onChangeBackgroundId}
is360={scene.type === "LOGO"}
allocationStrat={scene.allocationStrat}
includeInfo
/>
<div style={{ display: "flex", flexDirection: "column" }}>
Expand Down Expand Up @@ -687,6 +709,22 @@ export const SceneEditor = ({ id }: SceneEditorProps) => {
</div>
</FormField>
</FormRow>
{(scene.type !== "LOGO") && (
<FormRow>
<CheckboxField
name="allocationStrat_reverseAllocation"
label={l10n("FIELD_PRIORITIZE_SPRITE_ALLOC")}
checked={!(scene.allocationStrat & 1)}
onChange={onChangeReverseAllocationEnabled}
/>
<CheckboxField
name="allocationStrat_reserveUITiles"
label={l10n("FIELD_RESERVE_UI_TILES")}
checked={!(scene.allocationStrat & 2)}
onChange={onChangeReserveUITilesEnabled}
/>
</FormRow>
)}

{commonTilesetOpen && (
<FormRow>
Expand Down Expand Up @@ -717,7 +755,7 @@ export const SceneEditor = ({ id }: SceneEditorProps) => {
</Alert>
)}
</FormRow>

{/* <FormDivider /> */}
</FormContainer>
</SidebarColumn>
Expand Down
11 changes: 7 additions & 4 deletions src/components/forms/BackgroundSelectButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { RelativePortal } from "ui/layout/RelativePortal";
import { BackgroundSelect } from "./BackgroundSelect";
import { assetURLStyleProp } from "shared/lib/helpers/assets";
import { useAppDispatch, useAppSelector } from "store/hooks";
import { MAX_BACKGROUND_TILES, MAX_BACKGROUND_TILES_CGB } from "consts";
import { MAX_BACKGROUND_TILES, MAX_BACKGROUND_TILES_CGB, UI_TILE_LENGTH } from "consts";
import { monoOverrideForFilename } from "shared/lib/assets/backgrounds";
import { FlexGrow } from "ui/spacing/Spacing";

Expand All @@ -21,6 +21,7 @@ interface BackgroundSelectProps {
value?: string;
is360: boolean;
tilesetId: string;
allocationStrat: number;
includeInfo?: boolean;
onChange?: (newId: string) => void;
}
Expand Down Expand Up @@ -166,6 +167,7 @@ export const BackgroundSelectButton: FC<BackgroundSelectProps> = ({
onChange,
is360,
tilesetId,
allocationStrat,
includeInfo,
}) => {
const buttonRef = useRef<HTMLButtonElement>(null);
Expand Down Expand Up @@ -193,10 +195,11 @@ export const BackgroundSelectButton: FC<BackgroundSelectProps> = ({
backgroundId: value,
tilesetId,
is360,
allocationStrat,
})
);
}
}, [dispatch, value, is360, tilesetId]);
}, [dispatch, value, is360, tilesetId, allocationStrat]);

useEffect(() => {
if (buttonFocus) {
Expand Down Expand Up @@ -308,8 +311,8 @@ export const BackgroundSelectButton: FC<BackgroundSelectProps> = ({
</SpriteInfoRow>
<SpriteInfoRow
error={
(numTiles > MAX_BACKGROUND_TILES_CGB ||
(!isCGBOnly && numTiles > MAX_BACKGROUND_TILES)) &&
(numTiles > (MAX_BACKGROUND_TILES_CGB - (((allocationStrat >> 1) & 1)? 0: (UI_TILE_LENGTH * 2))) ||
(!isCGBOnly && numTiles > (MAX_BACKGROUND_TILES - (((allocationStrat >> 1) & 1)? 0: (UI_TILE_LENGTH))))) &&
!is360
}
>
Expand Down
5 changes: 4 additions & 1 deletion src/components/world/SceneInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ const SceneInfo = () => {
const backgroundNumTiles = useAppSelector(
(state) => state.assets.backgrounds[scene?.backgroundId || ""]?.numTiles
);
const backgroundAllocationStrat = useAppSelector(
(state) => state.assets.backgrounds[scene?.backgroundId || ""]?.allocationStrat
);
const isCGBOnly = useAppSelector(
(state) => state.project.present.settings.colorMode === "color"
);
Expand Down Expand Up @@ -399,7 +402,7 @@ const SceneInfo = () => {
const triggerCount = scene.triggers.length;
const maxSpriteTiles =
scene.type !== "LOGO"
? maxSpriteTilesForBackgroundTilesLength(backgroundNumTiles, isCGBOnly)
? maxSpriteTilesForBackgroundTilesLength(backgroundNumTiles, isCGBOnly, backgroundAllocationStrat)
: MAX_LOGO_SPRITE_TILES;

return (
Expand Down
5 changes: 3 additions & 2 deletions src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ const MAX_TRIGGERS = 30;
const MAX_FRAMES = 25;
const MAX_SPRITE_TILES = 64;

export const MAX_BACKGROUND_TILES = 16 * 12;
export const MAX_BACKGROUND_TILES_CGB = 16 * 12 * 2;
export const MAX_BACKGROUND_TILES = 256;
export const MAX_BACKGROUND_TILES_CGB = 512;
export const UI_TILE_LENGTH = 64;

const SCREEN_WIDTH = 20;
const SCREEN_HEIGHT = 18;
Expand Down
2 changes: 2 additions & 0 deletions src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,8 @@
"FIELD_COPY_VALUE": "Copy Value",
"FIELD_PASTE_VALUE": "Paste Value",
"FIELD_STACK": "Stack",
"FIELD_PRIORITIZE_SPRITE_ALLOC": "Prioritize Sprite Allocation",
"FIELD_RESERVE_UI_TILES": "Reserve UI Tiles",
"FIELD_COMMON_TILESET": "Common Tileset",
"FIELD_COMMON_TILESET_DESC": "Setting a common tileset for a scene will cause the selected tileset tiles to always be loaded in the same order. Careful use of this on two scenes will allow you to seamlessly switch between the scenes with no transition and no tile glitching.",
"FIELD_AUTO_COLOR": "Auto Color",
Expand Down
18 changes: 14 additions & 4 deletions src/lib/compiler/compileData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,12 @@ import { ProjectResources } from "shared/lib/resources/types";
type CompiledTilemapData = {
symbol: string;
data: number[] | Uint8Array;
is360: boolean;
is360: boolean;
};

type CompiledTilesetData = {
symbol: string;
data: number[] | Uint8Array;
data: number[] | Uint8Array;
};

export type SceneMapData = {
Expand Down Expand Up @@ -288,11 +288,20 @@ export const precompileBackgrounds = async (
)
)
.map((background) => background.id);

const allocationStratLookup = scenes.reduce((memo, scene) => {
if (!scene.backgroundId || !scene.allocationStrat){
return memo;
}
memo[scene.backgroundId] = scene.allocationStrat;
return memo;
}, {} as Record<string, number>);

const backgroundsData = await compileImages(
usedBackgrounds,
commonTilesetsLookup,
generate360Ids,
allocationStratLookup,
colorMode,
projectRoot,
{
Expand All @@ -315,7 +324,7 @@ export const precompileBackgrounds = async (
tileset1Index = usedTilesets.length;
usedTilesets.push({
symbol: `${background.symbol}_tileset`,
data: background.vramData[0],
data: background.vramData[0],
});
}

Expand Down Expand Up @@ -344,7 +353,7 @@ export const precompileBackgrounds = async (
usedTilemapAttrs.push({
symbol: `${background.symbol}_tilemap_attr`,
data: background.attr,
is360: generate360Ids.includes(background.id),
is360: generate360Ids.includes(background.id),
});
}

Expand All @@ -354,6 +363,7 @@ export const precompileBackgrounds = async (
cgbTileset: usedTilesets[tileset2Index],
tilemap: usedTilemaps[tilemapIndex],
tilemapAttr: usedTilemapAttrs[tilemapAttrIndex],
allocationStrat: (generate360Ids.includes(background.id))? 3: (allocationStratLookup[background.id] ?? 0),
};
}
);
Expand Down
Loading