[Decompilation] [th03] Low-level input

Lovely. Turns out that all it needed to motivate the previous research
was one function that is simply too precious to be kept in ASM…

Part of P0137, funded by [Anonymous].
This commit is contained in:
nmlgc 2021-03-23 16:43:06 +01:00
parent 0f75a77dee
commit f1a8d98dbc
7 changed files with 154 additions and 193 deletions

View File

@ -105,17 +105,17 @@ bin\th03\res_yume.com: th03\res_yume.cpp
$**
| masters.lib
bin\th03\op.exe: th03\op_01.cpp bin\th03\op.obj bin\th03\pi_put.obj bin\th03\snd_kaja.obj bin\th03\initop.obj bin\th03\cdg_load.obj bin\th03\grppsafx.obj bin\th03\pi_load.obj bin\th03\inp_m_w.obj bin\th03\cdg_p_na.obj bin\hfliplut.obj bin\frmdely2.obj
bin\th03\op.exe: th03\op_01.cpp bin\th03\op.obj bin\th03\input_s.obj bin\th03\pi_put.obj bin\th03\snd_kaja.obj bin\th03\initop.obj bin\th03\cdg_load.obj bin\th03\grppsafx.obj bin\th03\pi_load.obj bin\th03\inp_m_w.obj bin\th03\cdg_p_na.obj bin\hfliplut.obj bin\frmdely2.obj
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -3 -Z -DGAME=3 -nbin\th03\ -eOP.EXE @&&|
$**
|
bin\th03\main.exe: bin\th03\main.obj th03\main_01.cpp bin\th03\snd_se.obj bin\th03\snd_kaja.obj bin\th03\initmain.obj bin\th03\pi_load.obj bin\th03\inp_m_w.obj bin\hfliplut.obj th03\mrs.cpp th03\sprite16.cpp
bin\th03\main.exe: bin\th03\main.obj th03\main_01.cpp bin\th03\input_s.obj bin\th03\snd_se.obj bin\th03\snd_kaja.obj bin\th03\initmain.obj bin\th03\pi_load.obj bin\th03\inp_m_w.obj bin\hfliplut.obj th03\mrs.cpp th03\sprite16.cpp
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -Z -DGAME=3 -nbin\th03\ -eMAIN.EXE @&&|
$**
|
bin\th03\mainl.exe: bin\th03\mainl.obj bin\th03\pi_put.obj bin\th03\pi_put_i.obj bin\th03\snd_se.obj bin\th03\snd_kaja.obj bin\th03\initmain.obj bin\th03\cdg_load.obj th03\exitmain.cpp bin\th03\grppsafx.obj bin\th03\snd_dlym.obj bin\th03\inp_wait.obj bin\th03\pi_load.obj bin\th03\pi_put_q.obj bin\th03\inp_m_w.obj bin\th03\cdg_p_na.obj bin\hfliplut.obj
bin\th03\mainl.exe: bin\th03\mainl.obj bin\th03\input_s.obj bin\th03\pi_put.obj bin\th03\pi_put_i.obj bin\th03\snd_se.obj bin\th03\snd_kaja.obj bin\th03\initmain.obj bin\th03\cdg_load.obj th03\exitmain.cpp bin\th03\grppsafx.obj bin\th03\snd_dlym.obj bin\th03\inp_wait.obj bin\th03\pi_load.obj bin\th03\pi_put_q.obj bin\th03\inp_m_w.obj bin\th03\cdg_p_na.obj bin\hfliplut.obj
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -DGAME=3 -nbin\th03\ -eMAINL.EXE @&&|
$**
|

147
th03/hardware/input_s.cpp Normal file
View File

@ -0,0 +1,147 @@
#pragma option -WX -zCSHARED -k-
extern "C" {
#include "platform.h"
#include "x86real.h"
#include "decomp.hpp"
#include "pc98kbd.h"
#include "master.hpp"
#include "th03/hardware/input.h"
void input_reset_sense_key_held(void)
{
js_stat[0] = input_sp = input_mp_p2 = input_mp_p1 = INPUT_NONE;
_DX = _DX; // This moves [loops] to BL. Just remove this line.
__asm { jmp sense; } sense: // And this one.
// The key state is checked twice, 614.4 µs apart, to ignore the momentary
// "key released" events sent by PC-98 keyboards at the typematic rate if
// a key is held down. This ensures that the game consistently sees that
// specific input being pressed. See the HOLDKEY example in the
// `Research/` subdirectory for more explanation and sample code showing
// off this effect.
register unsigned char loops = 2;
_ES = 0;
do {
_AH = peekb(_ES, KEYGROUP_7);
if(_AH & K7_ARROW_UP) {
input_sp |= INPUT_UP;
}
if(_AH & K7_ARROW_DOWN) {
input_sp |= INPUT_DOWN;
}
if(_AH & K7_ARROW_LEFT) {
input_mp_p2 |= INPUT_SHOT;
input_sp |= INPUT_LEFT;
}
if(_AH & K7_ARROW_RIGHT) {
input_mp_p2 |= INPUT_BOMB;
input_sp |= INPUT_RIGHT;
}
_AH = peekb(_ES, KEYGROUP_9);
if(_AH & K9_NUM_6) {
input_mp_p2 |= INPUT_RIGHT;
input_sp |= INPUT_RIGHT;
}
if(_AH & K9_NUM_1) {
input_mp_p2 |= INPUT_DOWN_LEFT;
input_sp |= INPUT_DOWN_LEFT;
}
if(_AH & K9_NUM_2) {
input_mp_p2 |= INPUT_DOWN;
input_sp |= INPUT_DOWN;
}
if(_AH & K9_NUM_3) {
input_mp_p2 |= INPUT_DOWN_RIGHT;
input_sp |= INPUT_DOWN_RIGHT;
}
_AH = peekb(_ES, KEYGROUP_8);
if(_AH & K8_NUM_4) {
input_mp_p2 |= INPUT_LEFT;
input_sp |= INPUT_LEFT;
}
if(_AH & K8_NUM_7) {
input_mp_p2 |= INPUT_UP_LEFT;
input_sp |= INPUT_UP_LEFT;
}
if(_AH & K8_NUM_8) {
input_mp_p2 |= INPUT_UP;
input_sp |= INPUT_UP;
}
if(_AH & K8_NUM_9) {
input_mp_p2 |= INPUT_UP_RIGHT;
input_sp |= INPUT_UP_RIGHT;
}
_AH = peekb(_ES, KEYGROUP_5);
if(_AH & K5_Z) {
input_mp_p1 |= INPUT_SHOT;
input_sp |= INPUT_SHOT;
}
if(_AH & K5_X) {
input_mp_p1 |= INPUT_BOMB;
input_sp |= INPUT_BOMB;
}
if(_AH & K5_V) {
input_mp_p1 |= INPUT_DOWN_LEFT;
}
if(_AH & K5_B) {
input_mp_p1 |= INPUT_DOWN;
}
if(_AH & K5_N) {
input_mp_p1 |= INPUT_DOWN_RIGHT;
}
_AH = peekb(_ES, KEYGROUP_4);
if(_AH & K4_F) {
input_mp_p1 |= INPUT_LEFT;
}
if(_AH & K4_H) {
input_mp_p1 |= INPUT_RIGHT;
}
_AH = peekb(_ES, KEYGROUP_2);
if(_AH & K2_R) {
input_mp_p1 |= INPUT_UP_LEFT;
}
if(_AH & K2_T) {
input_mp_p1 |= INPUT_UP;
}
if(_AH & K2_Y) {
input_mp_p1 |= INPUT_UP_RIGHT;
}
if(_AH & K2_Q) {
input_sp |= INPUT_Q;
}
_AH = peekb(_ES, KEYGROUP_0);
if(_AH & K0_ESC) {
input_sp |= INPUT_CANCEL;
}
_AH = peekb(_ES, KEYGROUP_3);
if(_AH & K3_RETURN) {
input_sp |= INPUT_OK;
}
_AH = peekb(_ES, KEYGROUP_6);
if(_AH & K6_SPACE) {
input_sp |= INPUT_SHOT;
}
loops--;
if(FLAGS_ZERO) {
break;
}
_CX = 1024; // * 0.6 µs
delay_loop: __asm {
out 0x5F, al;
loop delay_loop;
}
} while(1);
}
#pragma codestring "\x90"
}

View File

@ -1,185 +0,0 @@
include pc98kbd.inc
; The key state is checked twice, 614.4 µs apart, to ignore the momentary "key
; released" events sent by PC-98 keyboards at the typematic rate if a key is
; held down. This ensures that the game consistently sees that specific input
; being pressed. See the HOLDKEY example in the Research/ subdirectory for
; more explanation and sample code showing off this effect.
public _input_reset_sense_key_held
_input_reset_sense_key_held proc far
xor ax, ax
mov _input_mp_p1, ax
mov _input_mp_p2, ax
mov _input_sp, ax
mov js_stat, ax
jmp short $+2
mov bl, 2
xor ax, ax
mov es, ax
@@up?:
mov ah, byte ptr es:[KEYGROUP_7]
test ah, 4
jz short @@down?
or _input_sp, INPUT_UP
@@down?:
test ah, 20h
jz short @@left?
or _input_sp, INPUT_DOWN
@@left?:
test ah, 8
jz short @@right?
or _input_mp_p2, INPUT_SHOT
or _input_sp, INPUT_LEFT
@@right?:
test ah, 10h
jz short @@num6?
or _input_mp_p2, INPUT_BOMB
or _input_sp, INPUT_RIGHT
@@num6?:
mov ah, byte ptr es:[KEYGROUP_9]
test ah, 1
jz short @@num1?
or _input_mp_p2, INPUT_RIGHT
or _input_sp, INPUT_RIGHT
@@num1?:
test ah, 4
jz short @@num2?
or _input_mp_p2, INPUT_DOWN_LEFT
or _input_sp, INPUT_DOWN_LEFT
@@num2?:
test ah, 8
jz short @@num3?
or _input_mp_p2, INPUT_DOWN
or _input_sp, INPUT_DOWN
@@num3?:
test ah, 10h
jz short @@num4?
or _input_mp_p2, INPUT_DOWN_RIGHT
or _input_sp, INPUT_DOWN_RIGHT
@@num4?:
mov ah, byte ptr es:[KEYGROUP_8]
test ah, 40h
jz short @@num7?
or _input_mp_p2, INPUT_LEFT
or _input_sp, INPUT_LEFT
@@num7?:
test ah, 4
jz short @@num8?
or _input_mp_p2, INPUT_UP_LEFT
or _input_sp, INPUT_UP_LEFT
@@num8?:
test ah, 8
jz short @@num9?
or _input_mp_p2, INPUT_UP
or _input_sp, INPUT_UP
@@num9?:
test ah, 10h
jz short @@z?
or _input_mp_p2, INPUT_UP_RIGHT
or _input_sp, INPUT_UP_RIGHT
@@z?:
mov ah, byte ptr es:[KEYGROUP_5]
test ah, 2
jz short @@x?
or _input_mp_p1, INPUT_SHOT
or _input_sp, INPUT_SHOT
@@x?:
test ah, 4
jz short @@v?
or _input_mp_p1, INPUT_BOMB
or _input_sp, INPUT_BOMB
@@v?:
test ah, 10h
jz short @@b?
or _input_mp_p1, INPUT_DOWN_LEFT
@@b?:
test ah, 20h
jz short @@n?
or _input_mp_p1, INPUT_DOWN
@@n?:
test ah, 40h
jz short @@f?
or _input_mp_p1, INPUT_DOWN_RIGHT
@@f?:
mov ah, byte ptr es:[KEYGROUP_4]
test ah, 1
jz short @@h?
or _input_mp_p1, INPUT_LEFT
@@h?:
test ah, 4
jz short @@r?
or _input_mp_p1, INPUT_RIGHT
@@r?:
mov ah, byte ptr es:[KEYGROUP_2]
test ah, 8
jz short @@t?
or _input_mp_p1, INPUT_UP_LEFT
@@t?:
test ah, 10h
jz short @@y?
or _input_mp_p1, INPUT_UP
@@y?:
test ah, 20h
jz short @@q?
or _input_mp_p1, INPUT_UP_RIGHT
@@q?:
test ah, 1
jz short @@esc?
or _input_sp, INPUT_Q
@@esc?:
mov ah, byte ptr es:[KEYGROUP_0]
test ah, 1
jz short @@return?
or _input_sp, INPUT_CANCEL
@@return?:
mov ah, byte ptr es:[KEYGROUP_3]
test ah, 10h
jz short @@space?
or _input_sp, INPUT_OK
@@space?:
mov ah, byte ptr es:[KEYGROUP_6]
test ah, 10h
jz short @@wait?
or _input_sp, INPUT_SHOT
@@wait?:
dec bl
jz short @@ret
mov cx, 1024
@@wait:
out 5Fh, al
loop @@wait
jmp @@up?
@@ret:
retf
_input_reset_sense_key_held endp
even

1
th03/input_s.cpp Normal file
View File

@ -0,0 +1 @@
#include "th03/hardware/input_s.cpp"

View File

@ -8886,7 +8886,7 @@ include th03/math/vector2_between_plus.asm
include th02/exit.asm
include th03/math/vector1_at.asm
include th02/hardware/frame_delay.asm
include th03/hardware/input_sense.asm
extern _input_reset_sense_key_held:proc
extern _snd_se_reset:proc
extern SND_SE_PLAY:proc
extern _snd_se_update:proc

View File

@ -5527,8 +5527,7 @@ include th02/exit.asm
include th03/formats/cdg_put.asm
include th03/formats/cdg_put_hflip.asm
include th02/hardware/frame_delay.asm
db 0
include th03/hardware/input_sense.asm
extern _input_reset_sense_key_held:proc
extern PI_PALETTE_APPLY:proc
extern PI_PUT_8:proc
extern PI_PUT_INTERLACE_8:proc

View File

@ -3620,8 +3620,7 @@ include th03/math/vector1_at.asm
include th03/formats/cdg_put.asm
include th03/formats/cdg_put_hflip.asm
include th02/hardware/frame_delay.asm
db 0
include th03/hardware/input_sense.asm
extern _input_reset_sense_key_held:proc
extern PI_PALETTE_APPLY:proc
extern PI_PUT_8:proc
extern SND_KAJA_INTERRUPT:proc