ReC98/th02/op_06.cpp

372 lines
8.2 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ReC98
* -----
* Code segment #6 of TH02's OP.EXE
*/
extern "C" {
#include "ReC98.h"
#include "x86real.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 東方封魔録 ~浄土曼荼羅",
"NO.2   博麗 Eastern Wind ",
"NO.3   End of Daylight  ",
"NO.4      幻夢界    ",
"NO.5 ひもろぎ、むらさきにもえ",
"NO.6  東方封魔録 ~幽幻乱舞",
"NO.7   She's in a temper!! ",
"NO.8     やみのちから   ",
"NO.9     死を賭して   ",
"NO.10     恋色マジック   ",
"NO.11 Complete Darkness ",
"NO.12   遠野の森    ",
"NO.13 昔話わんだーらんど ",
"NO.14   エキストララブ ",
"NO.15 戦車むすめのみるゆめ ",
"    ",
"    "
};
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);
}
}