mirror of
https://github.com/gbdev/rgbds.git
synced 2026-10-05 19:56:18 +00:00
Allow negative from-the-end starting indexes in INCBIN (#2181)
This commit is contained in:
1 parent
ad4e399018
commit
c592d665a8
8 files changed
+38
-11
No files matched your search
@@ -103,7 +103,7 @@ void sect_RelBytes(uint32_t n, std::vector<Expression> const &exprs);
|
||||
void sect_RelWord(Expression const &expr, uint32_t pcShift);
|
||||
void sect_RelLong(Expression const &expr, uint32_t pcShift);
|
||||
void sect_PCRelByte(Expression const &expr, uint32_t pcShift);
|
||||
bool sect_BinaryFile(std::string const &name, uint32_t startPos, std::optional<uint32_t> length);
|
||||
bool sect_BinaryFile(std::string const &name, int32_t startPos, std::optional<uint32_t> length);
|
||||
|
||||
void sect_EndSection();
|
||||
void sect_PushSection();
|
||||
|
||||
+2
-1
@@ -1906,13 +1906,14 @@ INCBIN "sprites/hero.bin"
|
||||
.Pp
|
||||
You can also include only part of a file with
|
||||
.Ic INCBIN .
|
||||
The example below includes 256 bytes from data.bin, starting from byte 78.
|
||||
The example below includes 256 bytes from data.bin, starting from byte 78 (byte positions start from 0).
|
||||
.Bd -literal -offset indent
|
||||
INCBIN "data.bin", 78, 256
|
||||
.Ed
|
||||
.Pp
|
||||
The length argument is optional.
|
||||
If only the start position is specified, the bytes from the start position until the end of the file will be included.
|
||||
Negative start positions count from the end of the file, so the last byte is at position -1.
|
||||
.Ss Statically allocating space in RAM
|
||||
.Ic DS
|
||||
statically allocates a number of empty bytes.
|
||||
|
||||
+2
-2
@@ -1052,12 +1052,12 @@ incbin:
|
||||
YYACCEPT;
|
||||
}
|
||||
}
|
||||
| POP_INCBIN string COMMA uconst {
|
||||
| POP_INCBIN string COMMA iconst {
|
||||
if (sect_BinaryFile($2, $4, std::nullopt)) {
|
||||
YYACCEPT;
|
||||
}
|
||||
}
|
||||
| POP_INCBIN string COMMA uconst COMMA uconst {
|
||||
| POP_INCBIN string COMMA iconst COMMA uconst {
|
||||
if (sect_BinaryFile($2, $4, $6)) {
|
||||
YYACCEPT;
|
||||
}
|
||||
|
||||
+26
-5
@@ -998,7 +998,7 @@ void sect_PCRelByte(Expression const &expr, uint32_t pcShift) {
|
||||
}
|
||||
}
|
||||
|
||||
bool sect_BinaryFile(std::string const &name, uint32_t startPos, std::optional<uint32_t> length) {
|
||||
bool sect_BinaryFile(std::string const &name, int32_t startPos, std::optional<uint32_t> length) {
|
||||
if (!requireCodeSection()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1016,18 +1016,31 @@ bool sect_BinaryFile(std::string const &name, uint32_t startPos, std::optional<u
|
||||
Defer closeFile{[&] { xfclose(file); }};
|
||||
|
||||
if (std::optional<uint64_t> fileSize = seekSize(file); fileSize.has_value()) {
|
||||
if (startPos > *fileSize) {
|
||||
// Adjust negative start positions such that -1 is the last byte of a file
|
||||
if (startPos < 0) {
|
||||
startPos += *fileSize;
|
||||
}
|
||||
if (startPos < 0) {
|
||||
error(
|
||||
"Specified start position (%" PRIu32 ") is greater than length of \"%s\" (%" PRIu64
|
||||
"Specified start position (%" PRId32 ") is before the start of \"%s\" (%" PRIu64
|
||||
")",
|
||||
startPos,
|
||||
name.c_str(),
|
||||
*fileSize
|
||||
);
|
||||
return false;
|
||||
} else if (length.has_value() && *length > *fileSize - startPos) {
|
||||
} else if (uint32_t pos = static_cast<uint32_t>(startPos); pos > *fileSize) {
|
||||
error(
|
||||
"Specified range in `INCBIN` file \"%s\" is out of bounds (%" PRIu32 " + %" PRIu32
|
||||
"Specified start position (%" PRId32 ") is greater than length of \"%s\" (%" PRIu64
|
||||
")",
|
||||
startPos,
|
||||
name.c_str(),
|
||||
*fileSize
|
||||
);
|
||||
return false;
|
||||
} else if (length.has_value() && *length > *fileSize - pos) {
|
||||
error(
|
||||
"Specified range in `INCBIN` file \"%s\" is out of bounds (%" PRId32 " + %" PRIu32
|
||||
" > %" PRIu64 ")",
|
||||
name.c_str(),
|
||||
startPos,
|
||||
@@ -1045,6 +1058,14 @@ bool sect_BinaryFile(std::string const &name, uint32_t startPos, std::optional<u
|
||||
"Error determining size of `INCBIN` file \"%s\": %s", name.c_str(), strerror(errno)
|
||||
);
|
||||
}
|
||||
if (startPos < 0) {
|
||||
error(
|
||||
"Specified start position (%" PRId32 ") is negative and size of \"%s\" is unknown",
|
||||
startPos,
|
||||
name.c_str()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// The file isn't seekable, so we'll just skip bytes one at a time
|
||||
while (startPos--) {
|
||||
if (fgetc(file) == EOF) {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
SECTION "Bad", ROM0
|
||||
|
||||
INCBIN "data.bin", -42
|
||||
INCBIN "data.bin", -420
|
||||
@@ -1,2 +1,3 @@
|
||||
FATAL: Constant must not be negative: -42
|
||||
error: Specified start position (-297) is before the start of "data.bin" (123)
|
||||
at incbin-negative-bad.asm(3)
|
||||
Assembly aborted with 1 error
|
||||
@@ -0,0 +1,3 @@
|
||||
section "test", rom0
|
||||
incbin "data.bin", -6 ; b0 9b c1 bd 20 db
|
||||
incbin "data.bin", -123, 10 ; 51 c7 c0 ed 02 f0 2b 29 57 2d
|
||||
@@ -0,0 +1 @@
|
||||
°›Á˝ ŰQÇŔíđ+)W-
|
||||
Reference in new issue
Block a user