ReC98/th02/op_06.cpp

375 lines
8.2 KiB
C++
Raw Normal View History

/* ReC98
* -----
* Code segment #6 of TH02's OP.EXE
*/
extern "C" {
#include <stddef.h>
#include "platform.h"
#include "x86real.h"
#include "pc98.h"
#include "planar.h"
#include "master.hpp"
#include "libs/kaja/kaja.h"
#include "th01/math/polar.hpp"
#include "th01/hardware/grppsafx.h"
#include "th02/math/vector.hpp"
#include "th02/hardware/frmdelay.h"
#include "th02/hardware/input.hpp"
#include "th02/formats/pi.h"
#include "th02/snd/snd.h"
#include "th02/shiftjis/fns.hpp"
static const int MUSIC_CMT_LINE_LEN = 42;
static const int MUSIC_CMT_LINE_COUNT = 20;
#define TRACK_COUNT sizeof(MUSIC_FILES) / sizeof(MUSIC_FILES[0])
#define SEL_QUIT TRACK_COUNT + 1
#define MUSIC_POLYGONS 16
const char *MUSIC_TITLES[] = {
"NO.1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>^<5E>@<40>`<60><><EFBFBD>y<EFBFBD><79><EFBFBD>",
"NO.2 <20>@ <20><><EFBFBD><EFBFBD><EFBFBD>@<40>`Eastern Wind ",
"NO.3 <20>@ End of Daylight<68>@ ",
"NO.4 <20>@<40>@<40>@<40>@<40>@<40><><EFBFBD><EFBFBD><EFBFBD>E<EFBFBD>@<40>@<40>@<40>@",
"NO.5 <20>Ђ<EFBFBD><D082><EFBFBD>A<EFBFBD>ނ炳<DE82><E782B3><EFBFBD>ɂ<EFBFBD><C982><EFBFBD>",
"NO.6 <20>@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>^<5E>@<40>`<60>H<EFBFBD><48><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
"NO.7 <20>@ She's in a temper!! ",
"NO.8 <20>@ <20>@ <20><><EFBFBD>݂̂<DD82><CC82><EFBFBD><EFBFBD><EFBFBD><EFBFBD>@<40>@ ",
"NO.9 <20>@<40>@<40>@<40>@<40><><EFBFBD><EFBFBD><EFBFBD>q<EFBFBD><71><EFBFBD>ā@<40>@<40>@",
"NO.10 <20>@ <20>@ <20><><EFBFBD>F<EFBFBD>}<7D>W<EFBFBD>b<EFBFBD>N <20>@ ",
"NO.11 Complete Darkness ",
"NO.12 <20>@<40>@<40><><EFBFBD><EFBFBD><EFBFBD>̐X<CC90>@<40>@<40>@ ",
"NO.13 <20>̘b<CC98><62><EFBFBD>񂾁[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ",
"NO.14 <20>@ <20>G<EFBFBD>L<EFBFBD>X<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>u ",
"NO.15 <20><><EFBFBD>Ԃނ<D482><DE82>߂݂̂<CC82><DD82><EFBFBD><EFBFBD><EFBFBD> ",
" <20>@<40>@ ",
" <20>@<40>@<40>p<EFBFBD><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "
};
const char *MUSIC_FILES[] = {
"op.m",
"stage0.m",
"stage1.m",
"stage2.m",
"stage3.m",
"stage4.m",
"boss1.m",
"boss4.m",
"boss2.m",
"boss3.m",
"mima.m",
"end1.m",
"ending.m",
"stage5.m",
"boss5.m"
};
// Polygon state
char initialized = 0;
screen_point_t points[10];
screen_point_t pos[MUSIC_POLYGONS];
point_t move_speed[MUSIC_POLYGONS];
char angle[MUSIC_POLYGONS];
char rot_speed[MUSIC_POLYGONS];
unsigned char music_sel;
page_t music_page;
dots8_t *screen_back_B;
Planar<dots8_t far *> cmt_back;
void pascal near draw_track(unsigned char sel, unsigned char color)
{
page_t other_page = (1 - music_page);
graph_accesspage(other_page);
graph_putsa_fx(
16, ((sel + 6) * GLYPH_H), (color | FX_WEIGHT_BOLD), MUSIC_TITLES[sel]
);
graph_accesspage(music_page);
graph_putsa_fx(
16, ((sel + 6) * GLYPH_H), (color | FX_WEIGHT_BOLD), MUSIC_TITLES[sel]
);
}
void pascal near draw_tracks(unsigned char sel)
{
int i;
for(i = 0; i < sizeof(MUSIC_TITLES) / sizeof(MUSIC_TITLES[0]); i++) {
draw_track(i, i == sel ? 15 : 3);
}
}
void pascal near screen_back_B_snap(void)
{
screen_back_B = HMem<dots8_t>::allocbyte(PLANE_SIZE);
plane_dword_blit(screen_back_B, VRAM_PLANE_B);
}
void pascal near screen_back_B_free(void)
{
HMem<dots8_t>::free(screen_back_B);
}
void pascal near screen_back_B_put(void)
{
plane_dword_blit(VRAM_PLANE_B, screen_back_B);
}
void pascal near polygon_build(
screen_point_t near *pts,
screen_x_t x,
screen_y_t y,
int rad,
int npoint,
char angle
)
{
int i;
y >>= 4;
for(i = 0; i < npoint; i++) {
unsigned char point_angle = ((i << 8) / npoint) + angle;
pts[i].x = polar_x_fast(x, rad, point_angle);
pts[i].y = polar_y_fast(y, rad, point_angle);
}
pts[i].x = pts[0].x;
pts[i].y = pts[0].y;
}
#define polygon_init(i, y_, velocity_x) { \
pos[i].x = (rand() % RES_X); \
pos[i].y = y_; \
move_speed[i].x = velocity_x; \
if(move_speed[i].x == 0) { \
move_speed[i].x = 1; \
} \
move_speed[i].y = (((rand() & 3) << 4) + 32); \
angle[i] = rand(); \
rot_speed[i] = 0x04 - (rand() & 0x07); \
if(rot_speed[i] == 0x00) { \
rot_speed[i] = 0x04; \
} \
}
inline int polygon_vertex_count(int i) {
return ((i / 4) + 3);
}
void pascal near polygons_update_and_render(void)
{
int i;
if(!initialized) {
for(i = 0; i < MUSIC_POLYGONS; i++) {
polygon_init(i, (rand() % (RES_Y * 16)), (4 - (rand() & 7)));
}
initialized = 1;
}
for(i = 0; i < MUSIC_POLYGONS; i++) {
polygon_build(
points, pos[i].x, pos[i].y,
(((i & 3) << 4) + 64), polygon_vertex_count(i), angle[i]
);
pos[i].x += move_speed[i].x;
pos[i].y += move_speed[i].y;
angle[i] += rot_speed[i];
if(pos[i].x <= 0 || pos[i].x >= 639) {
move_speed[i].x *= -1;
}
if(pos[i].y >= (RES_Y * 20)) {
polygon_init(i, -(RES_Y * 4), (8 - (rand() & 15)));
}
grcg_polygon_c(
reinterpret_cast<Point *>(points), polygon_vertex_count(i)
);
}
}
void pascal near music_flip(void)
{
screen_back_B_put();
grcg_setcolor(GC_RMW | GC_B, 15);
polygons_update_and_render();
grcg_off();
graph_showpage(music_page);
music_page = 1 - music_page;
graph_accesspage(music_page);
frame_delay(1);
}
#define cmt_bg_put_planar(cmt_bg_p, vo, x, dst, dst_p, src, src_p) \
size_t cmt_bg_p = 0; \
screen_y_t y; \
for(y = 64; y < 80; y++) { \
for(x = 160; x < 480; x += (4 * BYTE_DOTS)) { \
vo = vram_offset_shift(x, y); \
*(long*)(dst[PL_B] + dst_p) = *(long*)(src[PL_B] + src_p); \
*(long*)(dst[PL_R] + dst_p) = *(long*)(src[PL_R] + src_p); \
*(long*)(dst[PL_G] + dst_p) = *(long*)(src[PL_G] + src_p); \
*(long*)(dst[PL_E] + dst_p) = *(long*)(src[PL_E] + src_p); \
cmt_bg_p += 4; \
} \
} \
for(y = 80; y < 384; y++) { \
for(x = 304; x < 624; x += (4 * BYTE_DOTS)) { \
vo = vram_offset_shift(x, y); \
*(long*)(dst[PL_B] + dst_p) = *(long*)(src[PL_B] + src_p); \
*(long*)(dst[PL_R] + dst_p) = *(long*)(src[PL_R] + src_p); \
*(long*)(dst[PL_G] + dst_p) = *(long*)(src[PL_G] + src_p); \
*(long*)(dst[PL_E] + dst_p) = *(long*)(src[PL_E] + src_p); \
cmt_bg_p += 4; \
} \
}
void pascal near cmt_back_snap(void)
{
screen_x_t x;
vram_offset_t vo;
for(int i = 0; i < PLANE_COUNT; i++) {
cmt_back[i] = HMem<dots8_t>::allocbyte(
(304 * (320 / BYTE_DOTS)) + (16 * (320 / BYTE_DOTS))
);
}
cmt_bg_put_planar(cmt_bg_p, vo, x, cmt_back, cmt_bg_p, VRAM_PLANE, vo);
}
#include "th02/op/cmt_load.c"
void pascal near cmt_back_free(void)
{
HMem<dots8_t>::free(cmt_back.B);
HMem<dots8_t>::free(cmt_back.R);
HMem<dots8_t>::free(cmt_back.G);
HMem<dots8_t>::free(cmt_back.E);
}
void pascal near cmt_back_put(void)
{
screen_x_t x;
vram_offset_t vo;
cmt_bg_put_planar(cmt_bg_p, vo, x, VRAM_PLANE, vo, cmt_back, cmt_bg_p);
}
void pascal near draw_cmt(int track)
{
int line;
music_cmt_load(track);
screen_back_B_put();
cmt_back_put();
graph_putsa_fx(160, 64, (15 | FX_WEIGHT_HEAVY), music_cmt[0]);
for(line = 1; line < MUSIC_CMT_LINE_COUNT; line++) {
graph_putsa_fx(
304, ((line + 4) * GLYPH_H), (13 | FX_WEIGHT_HEAVY), music_cmt[line]
);
}
plane_dword_blit(screen_back_B, VRAM_PLANE_B);
}
void pascal musicroom(void)
{
static unsigned char track_playing = 0;
music_page = 1;
palette_black();
graph_showpage(0);
graph_accesspage(0);
graph_clear();
graph_accesspage(1);
pi_load_put_8_free(0, "op3.pi");
music_sel = track_playing;
draw_tracks(music_sel);
graph_copy_page(0);
graph_accesspage(1);
graph_showpage(0);
screen_back_B_snap();
cmt_back_snap();
graph_accesspage(1); draw_cmt(track_playing);
graph_accesspage(0); draw_cmt(track_playing);
palette_100();
do {
input_sense();
if(key_det) {
music_flip();
continue;
}
controls:
input_sense();
if(key_det & INPUT_UP) {
draw_track(music_sel, 3);
if(music_sel > 0) {
music_sel--;
} else {
music_sel = SEL_QUIT;
}
if(music_sel == TRACK_COUNT) {
music_sel--;
}
draw_track(music_sel, 15);
}
if(key_det & INPUT_DOWN) {
draw_track(music_sel, 3);
if(music_sel < SEL_QUIT) {
music_sel++;
} else {
music_sel = 0;
}
if(music_sel == TRACK_COUNT) {
music_sel++;
}
draw_track(music_sel, 15);
}
if(key_det & INPUT_SHOT || key_det & INPUT_OK) {
if(music_sel != SEL_QUIT) {
bool midi_active = snd_midi_active;
snd_midi_active = snd_midi_possible;
snd_load(MUSIC_FILES[music_sel], SND_LOAD_SONG);
snd_midi_active = 0;
snd_load(MUSIC_FILES[music_sel], SND_LOAD_SONG);
snd_midi_active = midi_active;
snd_kaja_func(KAJA_SONG_PLAY, 0);
track_playing = music_sel;
draw_cmt(music_sel);
music_flip();
draw_cmt(music_sel);
} else {
break;
}
}
if(key_det & INPUT_CANCEL) {
break;
}
if(!key_det) {
music_flip();
goto controls;
}
} while(1);
while(1) {
input_sense();
if(key_det) {
music_flip();
} else {
break;
}
};
screen_back_B_free();
cmt_back_free();
graph_showpage(0);
graph_accesspage(0);
graph_clear();
graph_accesspage(1);
pi_load_put_8_free(0, "op2.pi");
palette_entry_rgb_show("op.rgb");
graph_copy_page(0);
graph_accesspage(0);
}
}