[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
/* ReC98
|
|
|
|
* -----
|
|
|
|
* SPRITE16 display calls
|
|
|
|
*/
|
|
|
|
|
2021-03-21 18:35:04 +00:00
|
|
|
#pragma option -zCSHARED -k-
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
|
|
|
|
extern "C" {
|
2020-08-20 19:59:45 +00:00
|
|
|
#include "platform.h"
|
2021-02-07 20:03:00 +00:00
|
|
|
#include "x86real.h"
|
2020-08-20 19:59:45 +00:00
|
|
|
#include "pc98.h"
|
2020-09-06 11:14:43 +00:00
|
|
|
#include "planar.h"
|
2021-03-07 12:07:29 +00:00
|
|
|
#include "decomp.hpp"
|
2021-01-26 15:33:06 +00:00
|
|
|
#include "master.hpp"
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
#include "libs/sprite16/sprite16.h"
|
|
|
|
#include "th03/sprite16.hpp"
|
|
|
|
|
2020-09-06 11:14:43 +00:00
|
|
|
void pascal sprite16_sprites_commit(void)
|
|
|
|
{
|
|
|
|
sprite16_sprites_copy_page(1);
|
|
|
|
graph_accesspage(0);
|
|
|
|
_AH = SPRITE16_GENERATE_ALPHA;
|
|
|
|
geninterrupt(SPRITE16);
|
|
|
|
}
|
|
|
|
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
// Register variables; declare them as local ones and remove this block when
|
|
|
|
// porting away from 16-bit x86
|
|
|
|
#define sprite_offset_local (_DI)
|
|
|
|
#define putpos_left static_cast<int>(_DX)
|
|
|
|
#define putpos_right static_cast<int>(_BX)
|
|
|
|
#define clip_left static_cast<int>(_SI)
|
|
|
|
#define clip_right static_cast<int>(_CX)
|
|
|
|
#define put_w_words (_AL)
|
|
|
|
#define should_draw_column (_SI)
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
#define SETUP_VARS(left, top, sprite_offset) \
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
sprite_offset_local = sprite_offset; \
|
|
|
|
putpos_left = left; \
|
|
|
|
put_w_words = sprite16_put_w.v; \
|
|
|
|
_BH ^= _BH; /* upper 8 bits of putpos_right */ \
|
|
|
|
static_cast<char>(putpos_right) = put_w_words; \
|
|
|
|
putpos_right <<= 4; \
|
|
|
|
putpos_right += putpos_left; \
|
|
|
|
clip_left = sprite16_clip_left; \
|
|
|
|
clip_right = sprite16_clip_right;
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
#define CALL_PUT(left, top, put_w_words, sprite_offset) \
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
_AH = SPRITE16_PUT; \
|
2022-03-11 23:48:15 +00:00
|
|
|
_DX = left; \
|
2020-08-20 19:59:45 +00:00
|
|
|
_BX = top; \
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
static_cast<int>(_BX) >>= 1; \
|
|
|
|
_AL = put_w_words; \
|
|
|
|
_CX = sprite16_put_h; \
|
2022-03-11 23:48:15 +00:00
|
|
|
_DI = sprite_offset; \
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
geninterrupt(SPRITE16); \
|
|
|
|
|
|
|
|
#define CLIP_LEFT_PART \
|
|
|
|
do { \
|
|
|
|
putpos_left += 16; \
|
|
|
|
put_w_words--; \
|
2020-09-05 16:51:10 +00:00
|
|
|
if(FLAGS_ZERO) { \
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
sprite_offset_local += (16 / 8); \
|
|
|
|
} while(putpos_left < clip_left);
|
|
|
|
|
|
|
|
#define CLIP_RIGHT_PART \
|
|
|
|
do { \
|
|
|
|
putpos_right -= 16; \
|
|
|
|
put_w_words--; \
|
2020-09-05 16:51:10 +00:00
|
|
|
if(FLAGS_ZERO) { \
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
} while(putpos_right >= clip_right);
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
void pascal sprite16_put(screen_x_t left, screen_y_t top, int sprite_offset)
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
{
|
2020-08-20 19:59:45 +00:00
|
|
|
SETUP_VARS(left, top, sprite_offset);
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
if(putpos_right < clip_right) {
|
|
|
|
if(putpos_left >= clip_left) {
|
|
|
|
put:
|
2020-08-20 19:59:45 +00:00
|
|
|
CALL_PUT(putpos_left, top, put_w_words, sprite_offset_local);
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
return;
|
|
|
|
} else if(putpos_right < clip_left) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Sprite starts left of `clip_left`
|
|
|
|
CLIP_LEFT_PART;
|
|
|
|
goto put;
|
|
|
|
} else if(putpos_left >= clip_right) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Sprite ends right of `clip_right`
|
|
|
|
CLIP_RIGHT_PART;
|
|
|
|
goto put;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma codestring "\x90"
|
|
|
|
|
|
|
|
void pascal sprite16_putx(
|
2020-08-20 19:59:45 +00:00
|
|
|
screen_x_t left, screen_y_t top, int sprite_offset, sprite16_put_func_t func
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
)
|
|
|
|
{
|
2020-08-20 19:59:45 +00:00
|
|
|
SETUP_VARS(left, top, sprite_offset);
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
if(putpos_right < clip_right) {
|
|
|
|
if(putpos_left >= clip_left) {
|
|
|
|
put:
|
|
|
|
_AH = SPRITE16_PUT;
|
|
|
|
_DX = putpos_left;
|
2020-08-20 19:59:45 +00:00
|
|
|
_BX = top;
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
static_cast<int>(_BX) >>= 1;
|
|
|
|
_AL = put_w_words;
|
|
|
|
_CX = sprite16_put_h;
|
|
|
|
_DI = sprite_offset_local;
|
|
|
|
while(1) {
|
|
|
|
should_draw_column = func;
|
|
|
|
geninterrupt(SPRITE16);
|
|
|
|
should_draw_column--;
|
2020-09-05 16:51:10 +00:00
|
|
|
if(FLAGS_ZERO) {
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
_BX += _CX;
|
2022-02-12 16:29:37 +00:00
|
|
|
asm { cmp bx, SPRITE16_RES_Y; }
|
|
|
|
asm { jge end; }
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
}
|
|
|
|
} else if(putpos_right < clip_left) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Sprite starts left of `clip_left`
|
|
|
|
CLIP_LEFT_PART;
|
|
|
|
goto put;
|
|
|
|
} else if(putpos_left >= clip_right) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Sprite ends right of `clip_right`
|
|
|
|
CLIP_RIGHT_PART;
|
|
|
|
goto put;
|
|
|
|
end:
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma codestring "\x90"
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
void pascal sprite16_put_noclip(
|
|
|
|
screen_x_t left, screen_y_t top, int sprite_offset
|
|
|
|
)
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
{
|
|
|
|
// A completely useless SETUP_VARS variant without the `put_w_words`
|
|
|
|
// assignment, which actually makes it incorrect...
|
|
|
|
sprite_offset_local = sprite_offset;
|
|
|
|
putpos_left = left;
|
|
|
|
_BH ^= _BH; /* upper 8 bits of putpos_right */
|
|
|
|
static_cast<char>(putpos_right) = put_w_words;
|
|
|
|
putpos_right <<= 4;
|
|
|
|
putpos_right += putpos_left;
|
|
|
|
|
2020-08-20 19:59:45 +00:00
|
|
|
CALL_PUT(putpos_left, top, sprite16_put_w.v, sprite_offset_local);
|
[Decompilation] [th03] Sprite display calls
Yes, decompilation, of something that was so obviously originally
written in ASM. We're still left with two un-decompilable instructions
here, but I'm amazed at how nicely I was able to abstract away all of
the gory register details, leading to pretty clear, readable, and dare
I say *portable* code?! Turbo C++ was once again pretty helpful here:
• `static_cast<char>(_BX) = _AL` actually compiles into `MOV BL, AL`,
as you would have intended,
• and no-op assignments like _DI = _DI are optimized away, allowing
us to leave them in for clarity, so that we can have all parameter
assignments for the SPRITE16 display call in a single place.
I love this compiler.
Part of P0060, funded by Touhou Patch Center.
2019-11-22 21:25:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|