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_RelWord(Expression const &expr, uint32_t pcShift);
|
||||||
void sect_RelLong(Expression const &expr, uint32_t pcShift);
|
void sect_RelLong(Expression const &expr, uint32_t pcShift);
|
||||||
void sect_PCRelByte(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_EndSection();
|
||||||
void sect_PushSection();
|
void sect_PushSection();
|
||||||
|
|||||||
+2
-1
@@ -1906,13 +1906,14 @@ INCBIN "sprites/hero.bin"
|
|||||||
.Pp
|
.Pp
|
||||||
You can also include only part of a file with
|
You can also include only part of a file with
|
||||||
.Ic INCBIN .
|
.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
|
.Bd -literal -offset indent
|
||||||
INCBIN "data.bin", 78, 256
|
INCBIN "data.bin", 78, 256
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
The length argument is optional.
|
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.
|
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
|
.Ss Statically allocating space in RAM
|
||||||
.Ic DS
|
.Ic DS
|
||||||
statically allocates a number of empty bytes.
|
statically allocates a number of empty bytes.
|
||||||
|
|||||||
+2
-2
@@ -1052,12 +1052,12 @@ incbin:
|
|||||||
YYACCEPT;
|
YYACCEPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| POP_INCBIN string COMMA uconst {
|
| POP_INCBIN string COMMA iconst {
|
||||||
if (sect_BinaryFile($2, $4, std::nullopt)) {
|
if (sect_BinaryFile($2, $4, std::nullopt)) {
|
||||||
YYACCEPT;
|
YYACCEPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| POP_INCBIN string COMMA uconst COMMA uconst {
|
| POP_INCBIN string COMMA iconst COMMA uconst {
|
||||||
if (sect_BinaryFile($2, $4, $6)) {
|
if (sect_BinaryFile($2, $4, $6)) {
|
||||||
YYACCEPT;
|
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()) {
|
if (!requireCodeSection()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1016,18 +1016,31 @@ bool sect_BinaryFile(std::string const &name, uint32_t startPos, std::optional<u
|
|||||||
Defer closeFile{[&] { xfclose(file); }};
|
Defer closeFile{[&] { xfclose(file); }};
|
||||||
|
|
||||||
if (std::optional<uint64_t> fileSize = seekSize(file); fileSize.has_value()) {
|
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(
|
error(
|
||||||
"Specified start position (%" PRIu32 ") is greater than length of \"%s\" (%" PRIu64
|
"Specified start position (%" PRId32 ") is before the start of \"%s\" (%" PRIu64
|
||||||
")",
|
")",
|
||||||
startPos,
|
startPos,
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
*fileSize
|
*fileSize
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
} else if (length.has_value() && *length > *fileSize - startPos) {
|
} else if (uint32_t pos = static_cast<uint32_t>(startPos); pos > *fileSize) {
|
||||||
error(
|
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 ")",
|
" > %" PRIu64 ")",
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
startPos,
|
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)
|
"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
|
// The file isn't seekable, so we'll just skip bytes one at a time
|
||||||
while (startPos--) {
|
while (startPos--) {
|
||||||
if (fgetc(file) == EOF) {
|
if (fgetc(file) == EOF) {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
SECTION "Bad", ROM0
|
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)
|
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