diff --git a/README.md b/README.md index 816ef284..e9b2d06a 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ The following additional, and reimplemented, arguments have been added to Hypseu -grabmouse [ Capture mouse in SDL window ] -ignore_aspect_ratio [ Ignore MPEG aspect ratio header [01B3] ] -keymapfile [ Specify an alternate hypinput.ini file ] - -nolinear_scale [ Disable bilinear scaling ] + -linear_scale [ Enable linear filtering when scaling ] -novsync [ Disable VSYNC presentation on Renderer [crt] ] -original_overlay [ Enable daphne style overlays (lair,ace,lair2) ] -scalefactor <50-100> [ Scale video display area [50-100]% ] @@ -213,22 +213,21 @@ The following additional, and reimplemented, arguments have been added to Hypseu -scorebezel [ Bezel layer software scoreboard ] -scorepanel [ Enable software scoreboard in lair/ace/tq ] -scorepanel_position [ Adjust position of software_scorepanel ] + -shiftx <-100 to 100> [ Shift x-axis on video window [%] ] + -shifty <-100 to 100> [ Shift y-axis on video window [%] ] -tiphat [ Invert joystick SDL_HAT_UP and SDL_HAT_DOWN ] -usbscoreboard [ Enable USB serial support for scoreboard: ] [ Arguments: (i)mplementation, (p)ort, (b)aud ] - -vertical_stretch <1-24> [ Overlay stretch implemented for (cliff) only ] + -vertical_screen [ Reorient calculations in logical fullscreen ] + -vertical_stretch <1-24> [ Overlay stretch (cliff/gtg only) ] -8bit_overlay [ Restore original 8bit Singe overlays ] -blend_sprites [ Restore BLENDMODE outline on Singe sprites ] - -bootsilent [ Mute sound during initVLDP() if possible ] + -bootsilent [ Mute sound during initVLDP() - if possible ] -js_range <1-20> [ Adjust Singe joystick sensitivity: [def:5] ] -manymouse [ Enable ABS mouse input [lightguns] [gungames] ] -nocrosshair [ Request game does not display crosshairs ] -retropath [ Singe data path rewrites [.daphne] ] - -set_overlay [ Enforce overlay size (full, half, oversize) ] - [ (full): Set to full video resolution [Singe2] ] - [ (half): Set to half video resolution [Singe2] ] - [ (oversize): Use with HD gungame video sources ] -sinden <1-10> [ Enable software border for lightguns ] [ Color: (w)hite, (r)ed, (g)reen, (b)lue or (x) ] diff --git a/doc/bezels.txt b/doc/bezels.txt index e8afb4d0..0d0876e4 100644 --- a/doc/bezels.txt +++ b/doc/bezels.txt @@ -4,8 +4,8 @@ Arguments related to bezels -bezel [ Specify a png bezel in 'bezels' sub-folder ] -scalefactor <50-100> [ Scale video image [50-100]% ] --scale_shiftx <-100 - 100> [ Position scaled video window - horizontally ] --scale_shifty <-100 - 100> [ Position scaled video window - vertically ] +-shiftx <-100 to 100> [ Position video window - horizontally ] +-shifty <-100 to 100> [ Position video window - vertically ] Built-in bezels relating to 'lair/ace/tq' @@ -16,6 +16,7 @@ Built-in bezels relating to 'lair/ace/tq' -annunbezel_alpha <1-2> [ Built-in bezel: alpha transparency ] -annunbezel_scale <1-25> [ Built-in bezel: scale option ] -annunbezel_position [ Built-in bezel: position options ] +-annunlamps [ Built-in bezel: staggered: lamps only [conv] ] -scorebezel [ Built-in bezel: ace/lair/tq scoreboard ] -scorebezel_alpha <1-2> [ Built-in bezel: alpha transparency ] -scorebezel_scale <1-25> [ Built-in bezel: scale option ] @@ -48,4 +49,6 @@ Built-in overrides - bezels/offcaptain.bmp - bezels/offcadet.bmp +- bezels/shoot.bmp + diff --git a/pics/shoot.bmp b/pics/shoot.bmp new file mode 100644 index 00000000..1dc6a333 Binary files /dev/null and b/pics/shoot.bmp differ diff --git a/scripts/run.sh b/scripts/run.sh index 607761fd..20d93a10 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -26,8 +26,8 @@ while [[ $# -gt 0 ]]; do GAMEPAD="-gamepad" shift ;; - -nolinear) - NEAREST="-nolinear_scale" + -linear) + LINEAR="-linear_scale" shift ;; -nolog) @@ -74,7 +74,7 @@ set -- "${POSITIONAL[@]}" if [ -z "$1" ] ; then echo "Specify a game to try: " | STDERR echo - echo -e "$0 [-fullscreen] [-blanking] [-gamepad] [-nolinear] [-prototype] [-scanlines] [-scoreboard] " | STDERR + echo -e "$0 [-fullscreen] [-blanking] [-gamepad] [-linear] [-prototype] [-scanlines] [-scoreboard] " | STDERR for game in ace astron badlands badlandp bega blazer cliff cliffalt cliffalt2 cobra cobraab cobraconv cobram3 dle21 esh eshalt eshalt2 galaxy galaxyp gpworld gtg interstellar lair lair2 mach3 roadblaster sae sdq sdqshort sdqshortalt tq tq_alt tq_swear uvt; do if ls $HYPSEUS_SHARE/vldp*/$game >/dev/null 2>&1; then @@ -113,9 +113,13 @@ case "$1" in VLDP_DIR="vldp" KEYINPUT="-keymapfile flightkey.ini" ;; - badlands|badlandp) + badlands) VLDP_DIR="vldp" - BANKS="-bank 1 10000001 -bank 0 00000000" + BANKS="-blank_searches -blank_skips -min_seek_delay 600" + ;; + badlandp) + VLDP_DIR="vldp" + BANKS="-spritelite -preset 1" ;; bega) VLDP_DIR="vldp" @@ -152,9 +156,9 @@ case "$1" in FASTBOOT="-fastboot" if [ "$PROTOTYPE" ]; then - BANKS="-bank 1 10110111 -bank 0 11011001" + BANKS="-bank 1 10110111 -bank 0 11011000" else - BANKS="-bank 1 00110111 -bank 0 11011001" + BANKS="-bank 1 00110111 -bank 0 11011000" fi ;; esh|eshalt|eshalt2) @@ -227,7 +231,7 @@ $HYPSEUS_BIN $1 vldp \ $FASTBOOT \ $FULLSCREEN \ $GAMEPAD \ -$NEAREST \ +$LINEAR \ $BLANK \ $OVERLAY \ $LOG \ diff --git a/scripts/singe.sh b/scripts/singe.sh index 073a35f9..98302f99 100755 --- a/scripts/singe.sh +++ b/scripts/singe.sh @@ -38,26 +38,14 @@ while [[ $# -gt 0 ]]; do GAMEPAD="-gamepad" shift ;; - -nolinear) - NEAREST="-nolinear_scale" + -linear) + LINEAR="-linear_scale" shift ;; -nolog) LOG="-nolog" shift ;; - -fulloverlay) - OVERLAY="-set_overlay full" - shift - ;; - -halfoverlay) - OVERLAY="-set_overlay half" - shift - ;; - -oversize) - OVERLAY="-set_overlay oversize -manymouse" - shift - ;; -scale) SCALE="-scalefactor 50" shift @@ -79,7 +67,7 @@ set -- "${POSITIONAL[@]}" if [ -z $1 ] ; then echo "Specify a game to try: " | STDERR echo - echo "$0 [-fullscreen] [-8bit] [-blanking] [-blend] [-nolinear] [-gamepad] [-oversize] [-fulloverlay] [-halfoverlay] [-scanlines] [-scale] " | STDERR + echo "$0 [-fullscreen] [-8bit] [-blanking] [-blend] [-linear] [-gamepad] [-scanlines] [-scale] " | STDERR echo echo "Games available: " @@ -107,7 +95,7 @@ $HYPSEUS_BIN singe vldp \ -homedir $HYPSEUS_SHARE \ -datadir $HYPSEUS_SHARE \ $FULLSCREEN \ -$NEAREST \ +$LINEAR \ $BLANK \ $BLEND \ $GAMEPAD \ diff --git a/sound/gp_count.wav b/sound/gp_count.wav new file mode 100644 index 00000000..511aa1cd Binary files /dev/null and b/sound/gp_count.wav differ diff --git a/sound/gp_crash.wav b/sound/gp_crash.wav new file mode 100644 index 00000000..00467202 Binary files /dev/null and b/sound/gp_crash.wav differ diff --git a/sound/gp_engine1.wav b/sound/gp_engine1.wav new file mode 100644 index 00000000..fdfd5e09 Binary files /dev/null and b/sound/gp_engine1.wav differ diff --git a/sound/gp_engine2.wav b/sound/gp_engine2.wav new file mode 100644 index 00000000..864004e9 Binary files /dev/null and b/sound/gp_engine2.wav differ diff --git a/sound/gp_roar.wav b/sound/gp_roar.wav new file mode 100644 index 00000000..4b34fc96 Binary files /dev/null and b/sound/gp_roar.wav differ diff --git a/sound/gp_signal.wav b/sound/gp_signal.wav new file mode 100644 index 00000000..2228efe5 Binary files /dev/null and b/sound/gp_signal.wav differ diff --git a/sound/gp_tires.wav b/sound/gp_tires.wav new file mode 100644 index 00000000..8fbe0378 Binary files /dev/null and b/sound/gp_tires.wav differ diff --git a/src/3rdparty/retropie/RETROPIE.md b/src/3rdparty/retropie/RETROPIE.md index 22e8757f..debadf4d 100644 --- a/src/3rdparty/retropie/RETROPIE.md +++ b/src/3rdparty/retropie/RETROPIE.md @@ -41,8 +41,6 @@ Lightguns will require the ``-manymouse`` argument passed to Singe to enable abs See discussion here: [Discussions](https://github.com/DirtBagXon/hypseus-singe/discussions/) -Using Gun Game HD video content (_above 720x480_) will require the ``-set_overlay oversize`` argument. - ## Compilation * For compilation the following packages are required: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 960d0a8f..fb90735e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0) -set(PKG_VERSION "v2.10.4") +set(PKG_VERSION "v2.11.1") project(hypseus) diff --git a/src/HyperseusManifest.xml b/src/HyperseusManifest.xml index a892244d..a43364df 100644 --- a/src/HyperseusManifest.xml +++ b/src/HyperseusManifest.xml @@ -1,7 +1,7 @@ 2 - 10 - 4 + 11 + 1 diff --git a/src/game/badlands.cpp b/src/game/badlands.cpp index 9dbc8fee..883d6da2 100644 --- a/src/game/badlands.cpp +++ b/src/game/badlands.cpp @@ -75,11 +75,12 @@ badlands::badlands() firq_on = false; irq_on = false; nmi_on = false; - transparent = true; + yuv_on = false; m_num_sounds = 1; m_sound_name[S_BL_SHOT] = "bl_shot.wav"; + m_sprite_lite = false; shoot_led = false; shoot_led_overlay = false; shoot_led_numlock = false; @@ -87,6 +88,8 @@ badlands::badlands() charx_offset = 6; chary_offset = 2; + banks[2] = 0x7D; + // this must be static const static struct rom_def badlands_roms[] = {// main 6809 program @@ -114,6 +117,9 @@ badlandp::badlandp() // needed for this version m_game_type = GAME_BADLANDP; + banks[1] = 0xDF; + banks[2] = 0xFF; + // this must be static const static struct rom_def badlandp_roms[] = {// main 6809 program @@ -154,9 +160,13 @@ void badlands::do_nmi() { mc6809_nmi = 1; } -#ifdef LINUX - if (!transparent && video::get_yuv_overlay_ready()) video::set_yuv_video_blank(true); -#endif + + if (!yuv_on) + if (video::get_yuv_overlay_ready()) { + video::set_video_blank(true); + yuv_on = true; + } + blit(); // the NMI runs at the same period as the monitor vsync } @@ -219,12 +229,13 @@ void badlands::cpu_mem_write(Uint16 addr, Uint8 value) // DSP On else if (addr == 0x1003) { - if (value) { - palette::set_transparency(0, false); - transparent = false; - } else { - palette::set_transparency(0, true); - transparent = true; + + if (yuv_on) { + if (value) { + video::set_video_blank(true); + } else { + video::set_video_blank(false); + } } } @@ -294,7 +305,7 @@ void badlands::cpu_mem_write(Uint16 addr, Uint8 value) } else { - LOGW << fmt("Write to %x with %x", addr, value); + LOGD << fmt("Write to %x with %x", addr, value); } m_cpumem[addr] = value; @@ -325,7 +336,7 @@ Uint8 badlandp::cpu_mem_read(Uint16 addr) // ROM else if (addr >= 0xc000) { } else { - LOGW << fmt("Read from %x", addr); + LOGD << fmt("Read from %x", addr); } return result; @@ -349,12 +360,13 @@ void badlandp::cpu_mem_write(Uint16 addr, Uint8 value) } // display disable else if (addr == 0x0803) { - if (value) { - palette::set_transparency(0, false); // disable laserdisc video - transparent = false; - } else { - palette::set_transparency(0, true); // enable laserdisc video - transparent = true; + + if (yuv_on) { + if (value) { + video::set_video_blank(true); + } else { + video::set_video_blank(false); + } } } // ? @@ -426,6 +438,9 @@ void badlands::palette_calculate() palette::set_color(i, temp_color); } + + if (m_sprite_lite) + palette::set_transparency(3, true); } // updates badlands's video @@ -454,13 +469,8 @@ void badlands::repaint() } } - if (shoot_led) { - const char *t = "SHOOT!"; - Uint8 x = 24; - - if (get_use_old_overlay()) x = 20; - video::draw_string(t, x, 220, m_video_overlay[m_active_video_overlay]); - } + if (shoot_led) + video::draw_shoot(294, 215, m_video_overlay[m_active_video_overlay]); } // this gets called when the user presses a key or moves the joystick @@ -491,7 +501,7 @@ void badlands::input_enable(Uint8 move, Sint8 mouseID) case SWITCH_TEST: break; default: - LOGW << "bug in move enable"; + LOGD << "bug in move enable"; break; } } @@ -526,7 +536,7 @@ void badlands::input_disable(Uint8 move, Sint8 mouseID) // during boot break; default: - LOGW << "bug in move enable"; + LOGD << "bug in move disable"; break; } } @@ -556,6 +566,7 @@ void badlands::reset() { cpu::reset(); ldv1000::reset(); + yuv_on = false; } void badlands::set_preset(int preset) @@ -596,3 +607,14 @@ void badlands::update_shoot_led(Uint8 value) } } } + +bool badlandp::handle_cmdline_arg(const char *arg) +{ + bool bRes = false; + + if (strcasecmp(arg, "-spritelite") == 0) { + m_sprite_lite = bRes = true; + } + + return bRes; +} diff --git a/src/game/badlands.h b/src/game/badlands.h index 1dbd375c..23832642 100644 --- a/src/game/badlands.h +++ b/src/game/badlands.h @@ -64,7 +64,8 @@ class badlands : public game bool firq_on; bool irq_on; bool nmi_on; - bool transparent; + bool yuv_on; + bool m_sprite_lite; Uint8 character[0x2000]; Uint8 color_prom[0x20]; Uint8 banks[3]; // badlands's banks @@ -79,4 +80,5 @@ class badlandp : public badlands badlandp(); Uint8 cpu_mem_read(Uint16 addr); // memory read routine void cpu_mem_write(Uint16 addr, Uint8 value); // memory write routine + bool handle_cmdline_arg(const char *arg); }; diff --git a/src/game/bega.cpp b/src/game/bega.cpp index 4809f2d6..52541291 100644 --- a/src/game/bega.cpp +++ b/src/game/bega.cpp @@ -178,14 +178,14 @@ void bega::set_version(int version) {NULL}}; m_rom_list = bega_roms; } else { - LOGW << "Unsupported -version paramter, ignoring..."; + LOGW << "Unsupported -version parameter, ignoring..."; } } cobra::cobra() // dedicated version of Cobra Command { m_shortgamename = "cobra"; - m_game_issues = "Game does not wook properly (graphics ploblems)"; + m_game_issues = "Game has graphic issues"; const static struct rom_def cobra_roms[] = {// main cpu roms @@ -213,7 +213,7 @@ cobra::cobra() // dedicated version of Cobra Command // we need to override bega::set_version so we don't load the wrong roms void cobra::set_version(int version) { - LOGW << "Unsupported -version paramter, ignoring..."; + LOGW << "Unsupported -version parameter, ignoring..."; } roadblaster::roadblaster() // dedicated version of Cobra Command @@ -687,7 +687,7 @@ void bega::input_enable(Uint8 move, Sint8 mouseID) case SWITCH_TEST: break; default: - LOGW << "Error, bug in move enable"; + LOGD << "Error, bug in move enable"; break; } } @@ -736,7 +736,7 @@ void bega::input_disable(Uint8 move, Sint8 mouseID) case SWITCH_TEST: break; default: - LOGW << "Error, bug in move enable"; + LOGD << "Error, bug in move disable"; break; } } diff --git a/src/game/cliff.cpp b/src/game/cliff.cpp index b1bf5d8b..bb8b9822 100644 --- a/src/game/cliff.cpp +++ b/src/game/cliff.cpp @@ -120,17 +120,16 @@ gtg::gtg() { m_shortgamename = "gtg"; m_game_type = GAME_GTG; - //m_game_issues = "Overlay colors..."; disc_side = 1; // default to side 1 if no -preset is used e1ba_accesscount = 0; - //m_banks[1] = 0x5C; + m_banks[1] = 0x01; m_banks[3] = 0x1F; // this must be static! const static struct rom_def roms[] = - {{"gtg.rm0", NULL, &m_cpumem[0], 0x2000, 0xD8EFDDEA}, + {{"gtg.rm0", NULL, &m_cpumem[0x0000], 0x2000, 0xD8EFDDEA}, {"gtg.rm1", NULL, &m_cpumem[0x2000], 0x2000, 0x69953D38}, {"gtg.rm2", NULL, &m_cpumem[0x4000], 0x2000, 0xB043E205}, {"gtg.rm3", NULL, &m_cpumem[0x6000], 0x2000, 0xEC305F5E}, @@ -641,12 +640,16 @@ void cliff::repaint() tms9128nl_video_repaint(); } -bool cliff::handle_cmdline_arg(const char *arg) +bool gtg::handle_cmdline_arg(const char *arg) { bool bRes = false; - if (strcasecmp(arg, "-spritelite") == 0) { - game::set_console_flag(true); + tms9128nl_set_spritelite(); + bRes = true; + } + + if (strcasecmp(arg, "-compact") == 0) { + tms9128nl_set_nostretch(); bRes = true; } @@ -729,6 +732,7 @@ void gtg::patch_roms() m_cpumem[0x9] = 0; m_cpumem[0xB] = 0; } + tms9128nl_set_conv_12a563(); } void gtg::set_preset(int val) diff --git a/src/game/cliff.h b/src/game/cliff.h index a6234a74..cf8cc9cf 100644 --- a/src/game/cliff.h +++ b/src/game/cliff.h @@ -100,7 +100,6 @@ class cliff : public game void palette_calculate(); void repaint(); // function to repaint video void patch_roms(); - bool handle_cmdline_arg(const char *arg); protected: char m_frame_str[FRAME_ARRAY_SIZE]; // current frame of laserdisc in string @@ -146,6 +145,7 @@ class gtg : public cliff void set_preset(int val); // gets disc side from command line void reset(); void patch_roms(); + bool handle_cmdline_arg(const char *arg); protected: int e1ba_accesscount; // for tracking frame/chapter reads diff --git a/src/game/cobraconv.cpp b/src/game/cobraconv.cpp index 9a020c79..e0579fe9 100644 --- a/src/game/cobraconv.cpp +++ b/src/game/cobraconv.cpp @@ -501,7 +501,7 @@ void cobraconv::input_enable(Uint8 move, Sint8 mouseID) // for tilt detector) break; default: - LOGW << "bug in move enable"; + LOGD << "bug in move enable"; break; } } @@ -551,7 +551,7 @@ void cobraconv::input_disable(Uint8 move, Sint8 mouseID) banks[3] &= ~0x01; break; default: - LOGW << "bug in move enable"; + LOGD << "bug in move disable"; break; } } diff --git a/src/game/esh.cpp b/src/game/esh.cpp index ea0c7726..dbdaa0e6 100644 --- a/src/game/esh.cpp +++ b/src/game/esh.cpp @@ -162,7 +162,7 @@ void esh::set_version(int version) {NULL}}; m_rom_list = roms; } else { - LOGW << "Unsupported -version paramter, ignoring..."; + LOGW << "Unsupported -version parameter, ignoring..."; } } @@ -551,7 +551,7 @@ void esh::input_enable(Uint8 move, Sint8 mouseID) banks[0] &= ~0x10; break; default: - LOGW << "bug in move enable"; + LOGD << "bug in move enable"; break; } } @@ -593,7 +593,7 @@ void esh::input_disable(Uint8 move, Sint8 mouseID) banks[0] |= 0x10; break; default: - LOGW << "bug in move disable"; + LOGD << "bug in move disable"; break; } } diff --git a/src/game/game.cpp b/src/game/game.cpp index 5573607c..cefe5425 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -136,12 +136,12 @@ game::game() m_software_scoreboard = false; // old style overlays - m_use_old_overlay = false; + m_old_overlay = false; // overlay depth and size m_overlay_depth = GAME_OVERLAY_DEPTH; m_overlay_upgrade = false; - m_fullsize_overlay = false; + m_dynamic_overlay = false; // running on retro console m_run_on_console = false; @@ -192,15 +192,6 @@ bool game::pre_init() bool game::init() { bool result = true; -#ifdef LINUX - const int min = 200; - - if (get_game_type() == GAME_BADLANDS || - get_game_type() == GAME_BADLANDP) { - if (g_ldp->get_min_seek_delay() < min) - g_ldp->set_min_seek_delay(min); - } -#endif cpu::init(); return result; @@ -343,7 +334,7 @@ void game::OnLDV1000LineChange(bool bIsStatus, bool bIsEnabled) bool game::init_video() { static unsigned int m_area = 0; - static unsigned char vinit = 0; + static unsigned char v_init = 0; bool result = false; int index = 0; @@ -352,15 +343,15 @@ bool game::init_video() // Set up SDL display (create window, renderer, surfaces, textures...) if (m_area < area || m_overlay_depth == GAME_OVERLAY_DEPTH) { - if (video::get_video_resized() && vinit > 1) { - LOGE << "-x and -y do not support overlay switching."; + if ((video::get_video_resized() || video::get_rotated_state()) && v_init > 1) { + LOGE << "Rotation and resizing [-x/-y] do not support overlay switching."; set_quitflag(); } else if (video::get_yuv_overlay_ready()) video::reset_yuv_overlay(); video::init_display(); m_area = area; - vinit++; + v_init++; } // if this particular game uses video overlay (most do) @@ -394,6 +385,9 @@ bool game::init_video() palette::finalize(); } } + + video::set_overlay_offset(m_video_row_offset); + } // end if video overlay is used // if the game has not explicitely specified those variables that we @@ -412,7 +406,7 @@ bool game::init_video() } // Log some stats - video::notify_stats(m_video_overlay_width, m_video_overlay_height); + video::notify_stats(m_video_overlay_width, m_video_overlay_height, "o"); return (result); } @@ -562,11 +556,11 @@ short game::get_game_errors() { return m_game_error; } bool game::get_console_flag() { return m_run_on_console; } -bool game::get_use_old_overlay() { return m_use_old_overlay; } +bool game::use_old_overlay() { return m_old_overlay; } bool game::get_overlay_upgrade() { return m_overlay_upgrade; } -bool game::get_fullsize_overlay() { return m_fullsize_overlay; } +bool game::get_dynamic_overlay() { return m_dynamic_overlay; } bool game::get_manymouse() { return m_manymouse; } @@ -587,7 +581,7 @@ void game::set_manymouse(bool value) { m_manymouse = value; } void game::switch_scoreboard_display() { video::vid_scoreboard_switch(); } -void game::set_fullsize_overlay(bool value) { m_fullsize_overlay = value; } +void game::set_dynamic_overlay(bool value) { m_dynamic_overlay = value; } void game::set_32bit_overlay(bool value) { @@ -597,7 +591,11 @@ void game::set_32bit_overlay(bool value) m_overlay_upgrade = value; } -void game::set_stretch_value(int value) { m_stretch = m_stretch - value; } +void game::set_stretch_value(int value) { + + if (m_stretch == TMS_VERTICAL_OFFSET) + m_stretch = m_stretch - value; +} // generic preset function, does nothing void game::set_preset(int preset) diff --git a/src/game/game.h b/src/game/game.h index 68ead43a..7b910d65 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -198,10 +198,10 @@ class game short get_game_errors(); - bool get_use_old_overlay(); + bool use_old_overlay(); bool get_overlay_upgrade(); - bool get_fullsize_overlay(); + bool get_dynamic_overlay(); bool get_console_flag(); @@ -212,7 +212,7 @@ class game virtual void set_manymouse(bool); virtual void set_32bit_overlay(bool); - virtual void set_fullsize_overlay(bool); + virtual void set_dynamic_overlay(bool); virtual void set_console_flag(bool); @@ -292,13 +292,13 @@ class game bool m_software_scoreboard; - bool m_use_old_overlay; + bool m_old_overlay; Uint8 m_overlay_depth; bool m_overlay_upgrade; - bool m_fullsize_overlay; + bool m_dynamic_overlay; bool m_run_on_console; diff --git a/src/game/gpworld.cpp b/src/game/gpworld.cpp index 2f788893..4140840c 100644 --- a/src/game/gpworld.cpp +++ b/src/game/gpworld.cpp @@ -41,12 +41,14 @@ #include #include "gpworld.h" +#include #include "../io/conout.h" #include "../ldp-in/ldv1000.h" #include "../ldp-out/ldp.h" #include "../video/palette.h" #include "../video/video.h" #include "../sound/sound.h" +#include "../sound/samples.h" #include "../cpu/cpu.h" #include "../cpu/generic_z80.h" @@ -57,8 +59,8 @@ gpworld::gpworld() m_shortgamename = "gpworld"; memset(&cpu, 0, sizeof(struct cpu::def)); memset(banks, 0xff, 7); // fill banks with 0xFF's - banks[5] = 0; - banks[6] = 0; + banks[5] = 0x00; + banks[6] = 0x00; memset(sprite, 0x00, 0x30000); // making sure sprite[] is zero'd out memset(m_cpumem, 0x00, 0x10000); // making sure m_cpumem[] is zero'd out palette_modified = true; @@ -78,12 +80,25 @@ gpworld::gpworld() cpu.mem = m_cpumem; cpu::add(&cpu); // add a z80 - m_video_row_offset = 8; // shift video up by 16 pixels (8 rows) + m_video_row_offset = 0; // shift video up by 16 pixels (8 rows) m_transparent_color = 0; ldp_output_latch = 0xff; nmie = false; + m_num_sounds = 10; + // With the lack of any hardware reference.... + m_sound_name[S_GP_ENGINE1] = "gp_engine1.wav"; + m_sound_name[S_GP_ENGINE2] = "gp_engine2.wav"; + m_sound_name[S_GP_COUNT] = "gp_count.wav"; + m_sound_name[S_GP_START] = "gp_signal.wav"; + m_sound_name[S_GP_TIRE] = "gp_tires.wav"; + m_sound_name[S_GP_REV] = "gp_roar.wav"; + m_sound_name[S_GP_CRASH] = "gp_crash.wav"; + m_sound_name[S_GP_COIN] = "dl_credit.wav"; + m_sound_name[S_GP_DINK] = "dl2_bad.wav"; + m_sound_name[S_GP_GEAR] = "gr_alarm4.wav"; + const static struct rom_def gpworld_roms[] = {// main z80 rom {"gpw_6162a.bin", NULL, &m_cpumem[0x0000], 0x4000, 0}, @@ -140,7 +155,6 @@ void gpworld::do_nmi() Uint8 gpworld::cpu_mem_read(Uint16 addr) { Uint8 result = m_cpumem[addr]; - char s[81] = {0}; // main rom if (addr <= 0xbfff) { @@ -165,8 +179,7 @@ Uint8 gpworld::cpu_mem_read(Uint16 addr) // ld-v1000 laserdisc player else if (addr == 0xd800) { result = read_ldp(addr); - // sprintf(s, "LDP read %x", result); - // printline(s); + LOGD << fmt("LDP read %x", result); } // unknown @@ -202,8 +215,7 @@ Uint8 gpworld::cpu_mem_read(Uint16 addr) } else { - snprintf(s, sizeof(s), "Unmapped read from %x (PC is %x)", addr, Z80_GET_PC); - printline(s); + LOGW << fmt("Unmapped read from %x (PC is %x)", addr, Z80_GET_PC); } return result; @@ -213,12 +225,10 @@ Uint8 gpworld::cpu_mem_read(Uint16 addr) void gpworld::cpu_mem_write(Uint16 addr, Uint8 value) { m_cpumem[addr] = value; - char s[81] = {0}; // main rom if (addr <= 0xbfff) { - snprintf(s, sizeof(s), "Attempted write to main ROM! at %x with value %x", addr, value); - printline(s); + LOGW << fmt("Attempted write to main ROM! at %x with value %x", addr, value); } // sprite @@ -242,8 +252,7 @@ void gpworld::cpu_mem_write(Uint16 addr, Uint8 value) // disc else if (addr == 0xd800) { - // sprintf(s, "LDP write %x", value); - // printline(s); + LOGD << fmt("LDP write %x", value); write_ldp(value, addr); } @@ -251,11 +260,64 @@ void gpworld::cpu_mem_write(Uint16 addr, Uint8 value) else if (addr == 0xda00) { } - // sound (uses analog hardware) + // sound (uses analog hardware) - unsupported - sound with samples else if (addr == 0xda01) { + if (value != 0xff) { - // sprintf(s, "da01 write %x", value); - // printline(s); + + static Uint8 lastbeep[0xFF] = {0}; + + // audio streams (primitive control) + if (++lastbeep[value] > 6) { + switch (value) { + case 0xDC: + case 0xDE: + sound::play(S_GP_TIRE); + break; + case 0xEC: + case 0xEE: + samples::flush_queue(); + sound::play(S_GP_START); + break; + case 0xF4: + samples::flush_queue(); + sound::play(S_GP_COUNT); + break; + case 0xF5: + sound::play(S_GP_REV); + break; + break; + case 0xF9: + case 0xFB: + sound::play(S_GP_COIN); + break; + case 0xFE: + if (++ign > 0x0A) { + if (banks[2]) + sound::play(S_GP_ENGINE2); + else sound::play(S_GP_ENGINE1); + } + break; + default: + LOGD << fmt("%x write %x", addr, value); + break; + } + lastbeep[value] = 0; + } + } + } + else if (addr == 0xdac0 || addr == 0xdae0) { + + switch (value) { + case 0x90: + ign = 0; + samples::flush_queue(); + sound::play(S_GP_CRASH); + break; + default: + sound::play(S_GP_DINK); + LOGD << fmt("%x write %x", addr, value); + break; } } // bit 0 selects whether brake or accelerater are read through 0xda20 @@ -279,36 +341,27 @@ void gpworld::cpu_mem_write(Uint16 addr, Uint8 value) else { m_cpumem[addr] = value; - snprintf(s, sizeof(s), "Unmapped write to %x with value %x (PC is %x)", addr, value, Z80_GET_PC); - printline(s); + LOGW << fmt("Unmapped write to %x with value %x (PC is %x)", addr, value, Z80_GET_PC); } } Uint8 gpworld::read_ldp(Uint16 addr) { - // char s[81] = {0}; - Uint8 result = ldp_input_latch; - // sprintf(s, "Read from player %x at pc: %x", result, Z80_GET_PC); - // printline(s); + LOGD << fmt("Read from player %x at pc: %x", result, Z80_GET_PC); return result; } void gpworld::write_ldp(Uint8 value, Uint16 addr) { - // char s[81] = {0}; - - // sprintf(s, "Write to player %x at pc %x", value, Z80_GET_PC); - // printline(s); + LOGD << fmt("Write to player %x at pc %x", value, Z80_GET_PC); ldp_output_latch = value; } // reads a byte from the cpu's port Uint8 gpworld::port_read(Uint16 port) { - char s[81] = {0}; - port &= 0xFF; switch (port) { @@ -329,10 +382,8 @@ Uint8 gpworld::port_read(Uint16 port) return banks[4]; break; default: - snprintf(s, sizeof(s), "ERROR: CPU port %x read requested, but this function is " - "unimplemented!", - port); - printline(s); + LOGW << fmt("ERROR: CPU port %x read requested, but this function is " + "unimplemented!", port); } return (0); @@ -341,8 +392,6 @@ Uint8 gpworld::port_read(Uint16 port) // writes a byte to the cpu's port void gpworld::port_write(Uint16 port, Uint8 value) { - char s[82] = {0}; - port &= 0xFF; switch (port) { @@ -352,15 +401,18 @@ void gpworld::port_write(Uint16 port, Uint8 value) case 0x01: if (value & 0x40) nmie = true; - else + else { nmie = false; + if (value == 0x00) { + ldv1000::write(0xA3); + ign = 0; + } + } break; default: - snprintf(s, sizeof(s), "ERROR: CPU port %x write requested (value %x) but this " - "function is unimplemented!", - port, value); - printline(s); + LOGW << fmt("ERROR: CPU port %x write requested (value %x) but this " + "function is unimplemented!", port, value); break; } } @@ -403,7 +455,6 @@ void gpworld::recalc_palette() { if (palette_modified) { m_video_overlay_needs_update = true; - Uint8 used_tile_colors[4096] = {0}; // int used_colors = 0; int i; @@ -471,6 +522,11 @@ void gpworld::repaint() // This should be much faster SDL_FillRect(m_video_overlay[m_active_video_overlay], NULL, m_transparent_color); + // draw low or high depending on the state of the shifter + const char *t = "HIGH"; + if (banks[2]) t = "LOW"; + video::draw_string(t, 1, 225, m_video_overlay[m_active_video_overlay]); + // The sprites are bottom priority so we draw them first // START modified Mame code // check if sprites need to be drawn @@ -524,7 +580,7 @@ void gpworld::repaint() for (int x = 0; x < 8; x++) { if (pixel[x]) { *((Uint8 *)m_video_overlay[m_active_video_overlay]->pixels + - ((chary * 8 + y) * GPWORLD_OVERLAY_W) + ((charx - 19) * 7 + x + p)) = + ((chary * 8 + y + p) * GPWORLD_OVERLAY_W) + ((charx - 19) * 7 + x + p)) = tile_color_pointer[(pixel[x]) | ((m_cpumem[current_character]) & 0xfc)]; } } @@ -542,10 +598,6 @@ void gpworld::repaint() // } // } - // draw low or high depending on the state of the shifter - const char *t = "HIGH"; - if (banks[2]) t = "LOW"; - video::draw_string(t, 2, 222, m_video_overlay[m_active_video_overlay]); } // this gets called when the user presses a key or moves the joystick @@ -566,7 +618,7 @@ void gpworld::input_enable(Uint8 move, Sint8 mouseID) banks[0] &= ~0x10; break; case SWITCH_BUTTON1: // space on keyboard - banks[2] = ~banks[2]; + banks[2] = ~banks[2]; m_video_overlay_needs_update = true; break; case SWITCH_BUTTON2: // left shift @@ -609,6 +661,7 @@ void gpworld::input_disable(Uint8 move, Sint8 mouseID) banks[0] |= 0x10; break; case SWITCH_BUTTON1: // space on keyboard + sound::play(S_GP_GEAR); break; case SWITCH_BUTTON2: // left shift banks[5] = 0x00; @@ -655,6 +708,7 @@ bool gpworld::set_bank(Uint8 which_bank, Uint8 value) // START modified Mame code void gpworld::draw_sprite(int spr_number) { + int p = 12; int sx, sy, row, height, src, sprite_color, sprite_bank; Uint8 *sprite_base; int skip; /* bytes to skip before drawing each row (can be negative) */ @@ -675,12 +729,15 @@ void gpworld::draw_sprite(int spr_number) sprite_bank = (sprite_base[SPR_X_HI] >> 1) & 0x07; - // char s[81]; - // sprintf(s, "Draw Sprite #%x with src %x, skip %x, width %x, height %x, y - //%x, x %x", spr_number, src, skip, width, height, sy, sx); - // printline(s); + if (spr_number == 0x1) { + if (sy < 0x4) p -= 0x0b; + else p -= 0x06; + } + + LOGD << fmt( "Draw Sprite #%x with src %x, skip %x, height %x, y %x, x %x", + spr_number, src, skip, height, sy, sx); - for (row = 0; row < height; row++) { + for (row = p; row < height + p; row++) { int x, y; int src2; diff --git a/src/game/gpworld.h b/src/game/gpworld.h index 76e3e5d9..6f26d5f3 100644 --- a/src/game/gpworld.h +++ b/src/game/gpworld.h @@ -47,6 +47,19 @@ #define SPR_GFXOFS_HI 7 // END modified Mame code +enum { + S_GP_ENGINE1, + S_GP_ENGINE2, + S_GP_CRASH, + S_GP_COUNT, + S_GP_START, + S_GP_COIN, + S_GP_DINK, + S_GP_TIRE, + S_GP_GEAR, + S_GP_REV +}; + class gpworld : public game { public: @@ -78,6 +91,7 @@ class gpworld : public game bool palette_modified; // has our palette been modified? Uint8 ldp_output_latch; // holds data to be sent to the LDV1000 Uint8 ldp_input_latch; // holds data that was retrieved from the LDV1000 + Uint8 ign; bool nmie; Uint8 banks[7]; }; diff --git a/src/game/lair.cpp b/src/game/lair.cpp index 0c74c813..21e5f609 100644 --- a/src/game/lair.cpp +++ b/src/game/lair.cpp @@ -248,7 +248,7 @@ void dle2::set_version(int version) m_rom_list = roms; } else { - LOGW << "Unsupported -version paramter, ignoring..."; + LOGW << "Unsupported -version parameter, ignoring..."; } } @@ -329,7 +329,7 @@ void ace::set_version(int version) {NULL}}; m_rom_list = ace_roms; } else { - LOGW << "Unsupported -version paramter, ignoring..."; + LOGW << "Unsupported -version parameter, ignoring..."; } } diff --git a/src/game/laireuro.cpp b/src/game/laireuro.cpp index f246d50e..77bc4f3c 100644 --- a/src/game/laireuro.cpp +++ b/src/game/laireuro.cpp @@ -728,7 +728,7 @@ void laireuro::set_version(int version) m_rom_list = lair_d2_roms; } else { - printline("Unsupported -version paramter, ignoring..."); + printline("Unsupported -version parameter, ignoring..."); } } diff --git a/src/game/mach3.cpp b/src/game/mach3.cpp index 62113adc..c0d2761a 100644 --- a/src/game/mach3.cpp +++ b/src/game/mach3.cpp @@ -609,7 +609,13 @@ void mach3::cpu_mem_write(Uint32 Addr, Uint8 Value) { // whether laserdisc video can be seen m_ldvideo_enabled = ((Value & 8) == 8); - palette::set_transparency(0, m_ldvideo_enabled); + if (m_cpumem[0x8000] == 0x60) { + if (m_ldvideo_enabled) + m_cpumem[0x5001] = 0x00; + else m_cpumem[0x5001] = 0x36; + m_palette_updated = true; + } else + palette::set_yuv_transparency(m_ldvideo_enabled); } if ((Value & 0x04) != (m_cpumem[0x5803] & 0x04)) // enable display bit // has changed diff --git a/src/game/singe.cpp b/src/game/singe.cpp index 93b28f9c..fc9e6fa4 100644 --- a/src/game/singe.cpp +++ b/src/game/singe.cpp @@ -81,7 +81,6 @@ singe::singe() : m_pScoreboard(NULL) m_bezel_scoreboard = false; m_overlay_size = 0; - m_fullsize_overlay = false; m_upgrade_overlay = false; m_muteinit = false; m_notarget = false; @@ -180,7 +179,6 @@ bool singe::init() g_SingeIn.cfm_get_fvalue = gfm_get_fvalue; g_SingeIn.cfm_get_overlaysize = gfm_get_overlaysize; g_SingeIn.cfm_set_overlaysize = gfm_set_overlaysize; - g_SingeIn.cfm_set_upgradeoverlay = gfm_set_upgradeoverlay; g_SingeIn.cfm_set_custom_overlay = gfm_set_custom_overlay; // Active bezel @@ -244,12 +242,11 @@ void singe::start() g_pSingeOut->sep_set_static_pointers(&m_disc_fps, &m_uDiscFPKS); g_pSingeOut->sep_startup(m_strGameScript.c_str()); bool blanking = g_local_info.blank_during_searches | g_local_info.blank_during_skips; - int delay = g_ldp->get_min_seek_delay() >> 6; + int delay = g_ldp->get_min_seek_delay() >> 4; g_ldp->set_seek_frames_per_ms(0); g_ldp->set_min_seek_delay(0); if (m_upgrade_overlay) g_pSingeOut->sep_upgrade_overlay(); - if (m_fullsize_overlay) g_pSingeOut->sep_overlay_resize(); if (m_muteinit) g_pSingeOut->sep_mute_vldp_init(); if (m_notarget) g_pSingeOut->sep_no_crosshair(); if (singe_oc) g_pSingeOut->sep_alter_lua_clock(singe_ocv); @@ -268,9 +265,9 @@ void singe::start() } if (blanking) { - if (video::get_video_timer_blank()) { + if (video::get_video_blank()) { if (intTimer > delay) - video::set_video_timer_blank(false); + video::set_video_blank(false); intTimer++; } else intTimer = 0; } @@ -396,6 +393,7 @@ bool singe::handle_cmdline_arg(const char *arg) if (!bInit) { game::set_32bit_overlay(true); + game::set_dynamic_overlay(true); m_upgrade_overlay = bInit = true; } @@ -438,51 +436,17 @@ bool singe::handle_cmdline_arg(const char *arg) singe_ocv = false; bResult = true; } - else if (strcasecmp(arg, "-oversize_overlay") == 0) { - - if (m_overlay_size) { - printerror("SINGE: Only one overlay argument allowed"); - return false; - } - printline("NOTE : -oversize_overlay is obsolete use '-set_overlay oversize'"); - m_overlay_size = SINGE_OVERLAY_OVERSIZE; - bResult = true; - } else if (strcasecmp(arg, "-8bit_overlay") == 0) { game::set_32bit_overlay(false); m_upgrade_overlay = false; bResult = true; } - else if (strcasecmp(arg, "-set_overlay") == 0) { - - if (m_overlay_size) { - printerror("SINGE: Only one overlay argument allowed"); - return false; - } - - uint8_t r = 0; - get_next_word(s, sizeof(s)); + else if (strcasecmp(arg, "-set_overlay") == 0 + || strcasecmp(arg, "-oversize_overlay") == 0) { - if (strcasecmp(s, "half") == 0) r = SINGE_OVERLAY_HALF; - if (strcasecmp(s, "full") == 0) r = SINGE_OVERLAY_FULL; - if (strcasecmp(s, "oversize") == 0) r = SINGE_OVERLAY_OVERSIZE; - - switch(r) { - case SINGE_OVERLAY_HALF: - case SINGE_OVERLAY_FULL: - m_overlay_size = r; - game::set_fullsize_overlay(true); - m_fullsize_overlay = true; - bResult = true; - break; - case SINGE_OVERLAY_OVERSIZE: - m_overlay_size = r; - bResult = true; - break; - default: - printerror("SINGE: -set_overlay expects argument 'full', 'half' or 'oversize'"); - break; - } + if (strcasecmp(arg, "-set_overlay") == 0) get_next_word(s, sizeof(s)); + printline("NOTE : Overlay arguments are now obsolete"); + bResult = true; } else if (strcasecmp(arg, "-nocrosshair") == 0) { m_notarget = true; @@ -493,7 +457,7 @@ bool singe::handle_cmdline_arg(const char *arg) i = atoi(s); if ((i > 0) && (i < 11)) { - game::set_sinden_border(i<<1); + game::set_sinden_border(i<<2); game::set_manymouse(true); bResult = true; } else { @@ -713,7 +677,6 @@ double singe::get_yratio() { return singe_yratio; } double singe::get_fvalue() { return singe_fvalue; } uint8_t singe::get_overlaysize() { return m_overlay_size; } -void singe::set_upgradeoverlay(bool bEnable) { game::set_fullsize_overlay(bEnable); } void singe::set_overlaysize(uint8_t thisVal) { m_overlay_size = thisVal; } diff --git a/src/game/singe.h b/src/game/singe.h index 0c5f834e..c331f351 100644 --- a/src/game/singe.h +++ b/src/game/singe.h @@ -39,7 +39,7 @@ using namespace std; // by rdg2010 -#define SINGE_VERSION 1.81 // Update this number whenever you issue a major change +#define SINGE_VERSION 1.82 // Update this number whenever you issue a major change #define SDL_MOUSE 100 #define MANY_MOUSE 200 @@ -209,12 +209,6 @@ class singe : public game pSingeInstance->set_overlaysize(thisVal); } - static void gfm_set_upgradeoverlay(void *pInstance, bool bEnable) - { - singe *pSingeInstance = (singe *)pInstance; - pSingeInstance->set_upgradeoverlay(bEnable); - } - static void gfm_set_custom_overlay(void *pInstance, uint16_t w, uint16_t h) { singe *pSingeInstance = (singe *)pInstance; @@ -313,7 +307,6 @@ class singe : public game struct singeJoyStruct g_js; struct singeScoreboard g_bezelboard; - void set_upgradeoverlay(bool); void set_overlaysize(uint8_t); void set_custom_overlay(uint16_t, uint16_t); @@ -335,7 +328,6 @@ class singe : public game bool bezel_is_enabled(); bool m_bezel_scoreboard; - bool m_fullsize_overlay; bool m_upgrade_overlay; bool singe_alt_pressed; bool singe_joymouse; diff --git a/src/game/singe/luretro.c b/src/game/singe/luretro.c index da416441..176eb3c4 100644 --- a/src/game/singe/luretro.c +++ b/src/game/singe/luretro.c @@ -27,6 +27,7 @@ enum { PATH_DAPHNE, + PATH_SINGE, PATH_FRAMEWORK, PATH_END }; @@ -46,16 +47,19 @@ unsigned char inPath(const char* src, char* path) void lua_retropath(const char *src, char *dst, int len) { - unsigned char r = 0, fin = 0, path = PATH_DAPHNE; + unsigned char r = 0, fin = 0, folder = 0, path = PATH_DAPHNE; if (inPath(src, "Framework")) path = PATH_FRAMEWORK; + if (inPath(src, "singe/")) folder = PATH_SINGE; + else r++; for (int i = 0; i < (len - 2); src++, i++) { - if (!fin) { + if (fin != PATH_END) { if (*src == '\0') { fin = PATH_END; } - if (i == 6) { + if (i == 0 && *src == '/') continue; + if (folder == PATH_SINGE && i == 6) { memcpy(dst, "/../", 4); dst += 4; } diff --git a/src/game/singe/singe_interface.h b/src/game/singe/singe_interface.h index 9533a1cb..0a3f57cb 100644 --- a/src/game/singe/singe_interface.h +++ b/src/game/singe/singe_interface.h @@ -2,7 +2,7 @@ #define SINGE_INTERFACE_H // increase this number every time you change something in this file!!! -#define SINGE_INTERFACE_API_VERSION 7 +#define SINGE_INTERFACE_API_VERSION 8 #define SINGE_ERROR_INIT 0xA0 #define SINGE_ERROR_RUNTIME 0xA1 @@ -75,7 +75,6 @@ struct singe_in_info uint8_t (*cfm_get_overlaysize)(void *); void (*cfm_set_overlaysize)(void *, uint8_t); - void (*cfm_set_upgradeoverlay)(void *, bool); void (*cfm_set_custom_overlay)(void *, uint16_t, uint16_t); void (*cfm_bezel_enable)(void *, bool); @@ -131,7 +130,6 @@ struct singe_out_info void (*sep_mute_vldp_init)(void); void (*sep_no_crosshair)(void); void (*sep_upgrade_overlay)(void); - void (*sep_overlay_resize)(void); //////////////////////////////////////////////////////////// }; diff --git a/src/game/singe/singeproxy.cpp b/src/game/singe/singeproxy.cpp index 4d990890..5dfa4455 100644 --- a/src/game/singe/singeproxy.cpp +++ b/src/game/singe/singeproxy.cpp @@ -44,6 +44,8 @@ typedef struct g_soundType { // These are pointers and values needed by the script engine to interact with Hypseus lua_State *g_se_lua_context; SDL_Surface *g_se_surface = NULL; +SDL_Renderer *g_se_renderer = NULL; +SDL_Texture *g_se_texture = NULL; int g_se_overlay_width; int g_se_overlay_height; double *g_se_disc_fps; @@ -71,9 +73,8 @@ double g_sep_overlay_scale_y = 1; bool g_pause_state = false; // by RDG2010 bool g_init_mute = false; bool g_upgrade_overlay = false; -bool g_fullsize_overlay = false; bool g_show_crosshair = true; -bool g_not_cursor = true; +bool g_blend_sprite = false; int (*g_original_prepare_frame)(uint8_t *Yplane, uint8_t *Uplane, uint8_t *Vplane, int Ypitch, int Upitch, int Vpitch); @@ -103,7 +104,6 @@ SINGE_EXPORT const struct singe_out_info *singeproxy_init(const struct singe_in_ g_SingeOut.sep_mute_vldp_init = sep_mute_vldp_init; g_SingeOut.sep_no_crosshair = sep_no_crosshair; g_SingeOut.sep_upgrade_overlay = sep_upgrade_overlay; - g_SingeOut.sep_overlay_resize = sep_overlay_resize; result = &g_SingeOut; @@ -349,7 +349,7 @@ void sep_set_static_pointers(double *m_disc_fps, unsigned int *m_uDiscFPKS) void sep_set_surface(int width, int height) { bool createSurface = false; - + g_se_overlay_height = height; g_se_overlay_width = width; @@ -606,9 +606,7 @@ void sep_startup(const char *script) lua_register(g_se_lua_context, "vldpSetVerbose", sep_ldp_verbose); // Singe 2 - lua_register(g_se_lua_context, "overlaySetResolution", sep_singe_two_pseudo_call_true); lua_register(g_se_lua_context, "singeSetGameName", sep_singe_two_pseudo_call_true); - lua_register(g_se_lua_context, "onOverlayUpdate", sep_singe_two_pseudo_call_true); lua_register(g_se_lua_context, "singeWantsCrosshairs", sep_singe_wants_crosshair); lua_register(g_se_lua_context, "mouseHowMany", sep_get_number_of_mice); @@ -618,6 +616,7 @@ void sep_startup(const char *script) lua_register(g_se_lua_context, "getFValue", sep_get_fvalue); lua_register(g_se_lua_context, "setOverlaySize", sep_set_overlaysize); lua_register(g_se_lua_context, "setOverlayResolution", sep_set_custom_overlay); + lua_register(g_se_lua_context, "overlaySetResolution", sep_set_custom_overlay); lua_register(g_se_lua_context, "takeScreenshot", sep_screenshot); lua_register(g_se_lua_context, "scoreBezelEnable", sep_bezel_enable); @@ -649,6 +648,8 @@ void sep_startup(const char *script) if (g_pSingeIn->get_retro_path()) sep_set_retropath(); + g_blend_sprite = video::get_singe_blend_sprite(); + if (luaL_dofile(g_se_lua_context, script) != 0) { sep_error("error compiling script: %s", lua_tostring(g_se_lua_context, -1)); @@ -660,40 +661,40 @@ void sep_startup(const char *script) void sep_unload_fonts(void) { - int x; + if (g_fontList.size() > 0) { - if (g_fontList.size() > 0) - { - for (x=0; x<(int)g_fontList.size(); x++) - TTF_CloseFont(g_fontList[x]); - g_fontList.clear(); - } + for (int x = 0; x < (int)g_fontList.size(); x++) + TTF_CloseFont(g_fontList[x]); + + g_fontList.clear(); + } } void sep_unload_sounds(void) { - int x; - g_pSingeIn->samples_flush_queue(); - if (g_soundList.size() > 0) - { - for (x=0; x<(int)g_soundList.size(); x++) - SDL_FreeWAV(g_soundList[x].buffer); - g_soundList.clear(); - } + if (g_soundList.size() > 0) { + + for (int x = 0; x < (int)g_soundList.size(); x++) + SDL_FreeWAV(g_soundList[x].buffer); + + g_soundList.clear(); + } } void sep_unload_sprites(void) { - int x; + if (g_spriteList.size() > 0) { - if (g_spriteList.size() > 0) - { - for (x=0; x<(int)g_spriteList.size(); x++) - SDL_FreeSurface(g_spriteList[x]); - g_spriteList.clear(); - } + for (int x = 0; x < (int)g_spriteList.size(); x++) + { + SDL_FreeSurface(g_spriteList[x]); + g_spriteList[x] = NULL; + } + + g_spriteList.clear(); + } } void sep_alter_lua_clock(bool s) @@ -720,11 +721,6 @@ void sep_upgrade_overlay(void) g_upgrade_overlay = true; } -void sep_overlay_resize(void) -{ - g_fullsize_overlay = true; -} - //////////////////////////////////////////////////////////////////////////////// // Singe API Calls @@ -968,9 +964,7 @@ static int sep_mpeg_get_pixel(lua_State *L) int32_t n = lua_gettop(L); bool result = false; static bool ex = false; - SDL_Renderer *g_renderer = video::get_renderer(); - SDL_Texture *g_texture = video::get_yuv_screen(); - SDL_QueryTexture(g_texture, &format, NULL, NULL, NULL); + SDL_QueryTexture(g_se_texture, &format, NULL, NULL, NULL); unsigned char pixel[SDL_BYTESPERPIXEL(format)]; unsigned char R; unsigned char G; @@ -991,8 +985,8 @@ static int sep_mpeg_get_pixel(lua_State *L) / (double)g_se_overlay_width)); rect.y = (int)((double)lua_tonumber(L, 2) * ((double)g_pSingeIn->g_vldp_info->h / (double)g_se_overlay_height)); - if (g_renderer && g_texture) { - if (SDL_SetRenderTarget(g_renderer, g_texture) < 0) { + if (g_se_renderer && g_se_texture) { + if (SDL_SetRenderTarget(g_se_renderer, g_se_texture) < 0) { if (!ex) { sep_print("get_pixel unsupported texture: Targets disabled"); sep_print("Could not RenderTarget in get_pixel: %s", SDL_GetError()); @@ -1003,13 +997,16 @@ static int sep_mpeg_get_pixel(lua_State *L) lua_pushstring(X, "Targets disabled"); sep_say_font(X); } else { - if (SDL_RenderReadPixels(g_renderer, &rect, format, + if (SDL_RenderReadPixels(g_se_renderer, &rect, format, pixel, SDL_BYTESPERPIXEL(format)) < 0) sep_die("Could not ReadPixel in get_pixel: %s", SDL_GetError()); } - SDL_SetRenderTarget(g_renderer, NULL); + SDL_SetRenderTarget(g_se_renderer, NULL); } else { - sep_die("Could not initialize get_pixel"); + if (!ex) { + g_se_renderer = video::get_renderer(); + g_se_texture = video::get_yuv_screen(); + } else sep_die("Could not initialize get_pixel"); } Y = pixel[0] - 16; U = (int)rand()% 6 + (-3); @@ -1079,12 +1076,7 @@ static int sep_set_overlaysize(lua_State *L) switch (size) { case SINGE_OVERLAY_FULL: case SINGE_OVERLAY_HALF: - g_fullsize_overlay = true; - g_pSingeIn->cfm_set_upgradeoverlay(g_pSingeIn->pSingeInstance, true); - break; case SINGE_OVERLAY_OVERSIZE: - g_fullsize_overlay = false; - g_pSingeIn->cfm_set_upgradeoverlay(g_pSingeIn->pSingeInstance, false); break; case SINGE_OVERLAY_CUSTOM: if (n == 3) { @@ -1096,9 +1088,7 @@ static int sep_set_overlaysize(lua_State *L) f = lua_tonumber(L, 3); int h = (int)f; if (w && h) { - g_fullsize_overlay = true; g_pSingeIn->cfm_set_custom_overlay(g_pSingeIn->pSingeInstance, w, h); - g_pSingeIn->cfm_set_upgradeoverlay(g_pSingeIn->pSingeInstance, true); } else size = SINGE_OVERLAY_EMPTY; } } @@ -1135,7 +1125,6 @@ static int sep_get_fvalue(lua_State *L) static int sep_singe_wants_crosshair(lua_State *L) { lua_pushboolean(L, g_show_crosshair); - if (g_show_crosshair) g_not_cursor = false; return 1; } @@ -1212,36 +1201,14 @@ static int sep_say_font(lua_State *L) SDL_Rect dest; dest.w = textsurface->w; dest.h = textsurface->h; - - if (g_fullsize_overlay) { - - dest.x = lua_tonumber(L, 1) + g_sep_overlay_scale_x; - dest.y = lua_tonumber(L, 2) + g_sep_overlay_scale_y; - - } else { // Deal with legacy stuff - TODO: remove - - dest.x = lua_tonumber(L, 1); - dest.y = lua_tonumber(L, 2); - - if (dest.x == 0x05 && dest.y == 0x05 && dest.h == 0x17) // AM SCORE SHUNT - dest.x+=20; - - if (g_se_overlay_width > SINGE_OVERLAY_STD_W) { - if (dest.h == 0x16 && dest.y == 0xcf) { // JR SCOREBOARD - dest.x = dest.x - (double)((g_se_overlay_width + dest.x + dest.w) / 22); - if (dest.x <(SINGE_OVERLAY_STD_W>>2)) dest.x-=4; - if (dest.x >(SINGE_OVERLAY_STD_W>>1)) dest.x+=4; - } - else - dest.x = dest.x - (double)(((g_se_overlay_width) + (dest.x * 32) - + (dest.w * 26)) / SINGE_OVERLAY_STD_W); - } - } + dest.x = lua_tonumber(L, 1) + g_sep_overlay_scale_x; + dest.y = lua_tonumber(L, 2) + g_sep_overlay_scale_y; SDL_SetSurfaceRLE(textsurface, SDL_TRUE); SDL_SetColorKey(textsurface, SDL_TRUE, 0x0); - if (!video::get_singe_blend_sprite()) - SDL_SetSurfaceBlendMode(textsurface, SDL_BLENDMODE_NONE); + + if (!g_blend_sprite) + SDL_SetSurfaceBlendMode(textsurface, SDL_BLENDMODE_NONE); SDL_BlitSurface(textsurface, NULL, g_se_surface, &dest); SDL_FreeSurface(textsurface); @@ -1282,7 +1249,7 @@ static int sep_search(lua_State *L) if (g_pSingeIn->g_local_info->blank_during_searches) if (debounced) - video::set_video_timer_blank(true); + video::set_video_blank(true); debounced = true; } @@ -1331,7 +1298,7 @@ static int sep_skip_backward(lua_State *L) if (lua_isnumber(L, 1)) { if (g_pSingeIn->g_local_info->blank_during_skips) - video::set_video_timer_blank(true); + video::set_video_blank(true); g_pSingeIn->pre_skip_backward(lua_tonumber(L, 1)); } @@ -1360,7 +1327,7 @@ static int sep_skip_forward(lua_State *L) if (lua_isnumber(L, 1)) { if (g_pSingeIn->g_local_info->blank_during_skips) - video::set_video_timer_blank(true); + video::set_video_blank(true); g_pSingeIn->pre_skip_forward(lua_tonumber(L, 1)); } @@ -1388,7 +1355,7 @@ static int sep_skip_to_frame(lua_State *L) if (g_pSingeIn->g_local_info->blank_during_skips) if (debounced) - video::set_video_timer_blank(true); + video::set_video_blank(true); g_pSingeIn->framenum_to_frame(lua_tonumber(L, 1), s); g_pSingeIn->pre_search(s, true); @@ -1465,35 +1432,11 @@ static int sep_sprite_draw(lua_State *L) SDL_Rect dest; dest.w = g_spriteList[sprite]->w; dest.h = g_spriteList[sprite]->h; + dest.x = lua_tonumber(L, 1) + g_sep_overlay_scale_x; + dest.y = lua_tonumber(L, 2) + g_sep_overlay_scale_y; - if (g_fullsize_overlay) { - - dest.x = lua_tonumber(L, 1) + g_sep_overlay_scale_x; - dest.y = lua_tonumber(L, 2) + g_sep_overlay_scale_y; - - } else { // Deal with legacy stuff - TODO: remove - - dest.x = lua_tonumber(L, 1); - dest.y = lua_tonumber(L, 2); - - if (g_se_overlay_width > SINGE_OVERLAY_STD_W) { - if (g_not_cursor && dest.y > 0xbe && dest.y <= 0xde) - dest.x = dest.x - (double)((g_se_overlay_width + dest.x + dest.w) / 26); - else - dest.x = dest.x - (double)((g_se_overlay_width + (dest.x * 32) - + (dest.w * 26)) / SINGE_OVERLAY_STD_W); - } - } - - if (dest.w == 0x89 && dest.h == 0x1c) { // SP - SDL_SetColorKey(g_spriteList[sprite], SDL_TRUE, 0x000000ff); - dest.x+=3; - } - - if ((!video::get_singe_blend_sprite()) && - (dest.w != 0xcc && dest.h != 0x15) && - (dest.w != 0x0b && dest.h != 0x0b)) // JR / AM - SDL_SetSurfaceBlendMode(g_spriteList[sprite], SDL_BLENDMODE_NONE); + if (!g_blend_sprite) + SDL_SetSurfaceBlendMode(g_spriteList[sprite], SDL_BLENDMODE_NONE); SDL_BlitSurface(g_spriteList[sprite], NULL, g_se_surface, &dest); } @@ -1501,7 +1444,6 @@ static int sep_sprite_draw(lua_State *L) } } } - g_not_cursor = true; return 0; } @@ -1544,7 +1486,6 @@ static int sep_sprite_load(lua_State *L) SDL_Surface *temp = IMG_Load(filepath.c_str()); if (temp) { - // free old surface? temp = SDL_ConvertSurface(temp, g_se_surface->format, 0); SDL_SetSurfaceRLE(temp, SDL_TRUE); SDL_SetColorKey(temp, SDL_TRUE, 0x0); diff --git a/src/game/singe/singeproxy.h b/src/game/singe/singeproxy.h index fac2d66b..c396233b 100644 --- a/src/game/singe/singeproxy.h +++ b/src/game/singe/singeproxy.h @@ -72,7 +72,6 @@ void sep_alter_lua_clock(bool); void sep_mute_vldp_init(void); void sep_no_crosshair(void); void sep_upgrade_overlay(void); -void sep_overlay_resize(void); bool sep_format_srf32(SDL_Surface *src, SDL_Surface *dst); bool sep_srf32_to_srf8(SDL_Surface *src, SDL_Surface *dst); diff --git a/src/game/superd.cpp b/src/game/superd.cpp index 62930ce5..92bbbcd7 100644 --- a/src/game/superd.cpp +++ b/src/game/superd.cpp @@ -39,6 +39,7 @@ #include #include #include "superd.h" +#include #include "../cpu/generic_z80.h" #include "../ldp-in/ldv1000.h" #include "../ldp-out/ldp.h" @@ -567,7 +568,7 @@ void superd::input_enable(Uint8 move, Sint8 mouseID) banks[1] &= ~0x02; break; default: - printline("Error, bug in move enable"); + LOGD << "Error, bug in move enable"; break; } } @@ -611,7 +612,7 @@ void superd::input_disable(Uint8 move, Sint8 mouseID) banks[1] |= 0x02; break; default: - printline("Error, bug in move enable"); + LOGD << "Error, bug in move disable"; break; } } diff --git a/src/game/thayers.cpp b/src/game/thayers.cpp index f3a2d32f..79cea2ba 100644 --- a/src/game/thayers.cpp +++ b/src/game/thayers.cpp @@ -234,7 +234,7 @@ void thayers::set_version(int version) m_rom_list = tq_roms; } else { - printline("TQ: Unsupported -version paramter, ignoring..."); + printline("TQ: Unsupported -version parameter, ignoring..."); } } @@ -672,10 +672,12 @@ void thayers::process_keydown(SDL_Keycode key) default: // else we recognized no keys so print an error +#ifdef DEBUG char s[81] = {0}; snprintf(s, sizeof(s), "THAYERS: Unhandled keypress: %x", key); printline(s); +#endif break; } } diff --git a/src/hypseus.cpp b/src/hypseus.cpp index 95f938e9..8e62b5fb 100644 --- a/src/hypseus.cpp +++ b/src/hypseus.cpp @@ -279,7 +279,6 @@ int main(int argc, char **argv) // if command line was bogus, quit else { printerror("Bad command line or initialization problem."); - printusage(); } // if our g_game class was allocated diff --git a/src/io/cmdline.cpp b/src/io/cmdline.cpp index a5d14803..08adce67 100644 --- a/src/io/cmdline.cpp +++ b/src/io/cmdline.cpp @@ -394,6 +394,7 @@ bool parse_game_type() } else { snprintf(e, sizeof(e), "ERROR: Unknown game type specified : %s", s); printerror(e); + printusage(); result = false; } @@ -530,7 +531,8 @@ bool parse_cmd_line(int argc, char **argv) } // Ignore some deprecated arguments (Rather than error) else if (strcasecmp(s, "-noserversend") == 0 || - strcasecmp(s, "-fullscale") == 0) { + strcasecmp(s, "-nolinear_scale") == 0 || + strcasecmp(s, "-fullscale") == 0) { char e[460]; snprintf(e, sizeof(e), "NOTE : Ignoring deprecated argument: %s", s); @@ -839,7 +841,8 @@ bool parse_cmd_line(int argc, char **argv) video::set_tq_keyboard(true); } else if (strcasecmp(s, "-annunbezel") == 0 || - strcasecmp(s, "-dedannunbezel") == 0) { + strcasecmp(s, "-dedannunbezel") == 0 || + strcasecmp(s, "-annunlamps") == 0) { lair *game_ace = dynamic_cast(g_game); if (game_ace) { @@ -847,6 +850,8 @@ bool parse_cmd_line(int argc, char **argv) enable_bannun(true); if (strcasecmp(s, "-dedannunbezel") == 0) video::set_ded_annun_bezel(true); + if (strcasecmp(s, "-annunlamps") == 0) + video::set_annun_lamponly(true); } } // used to modify the dip switch settings of the game in question @@ -977,9 +982,9 @@ bool parse_cmd_line(int argc, char **argv) else if (strcasecmp(s, "-manymouse") == 0) { g_game->set_manymouse(true); } - // Disable SDL_HINT_RENDER_SCALE_QUALITY(linear) - else if (strcasecmp(s, "-nolinear_scale") == 0) { - video::set_fullscreen_scale_nearest(true); + // Enable SDL_HINT_RENDER_SCALE_QUALITY(linear) + else if (strcasecmp(s, "-linear_scale") == 0) { + video::set_scale_linear(true); } // disable log file else if (strcasecmp(s, "-nolog") == 0) { @@ -1024,7 +1029,10 @@ bool parse_cmd_line(int argc, char **argv) result = false; } } - + // by DBX - This switches logical axis calculations + else if (strcasecmp(s, "-vertical_screen") == 0) { + video::set_vertical_orientation(true); + } // by RDG2010 // Scales video image to something smaller than the window size. // Helpful for users with overscan issues on arcade monitors or CRT @@ -1043,12 +1051,12 @@ bool parse_cmd_line(int argc, char **argv) result = false; } } - else if ((strcasecmp(s, "-scale_shiftx") == 0) || - (strcasecmp(s, "-scale_shifty") == 0)) { + else if ((strcasecmp(s, "-shiftx") == 0) || + (strcasecmp(s, "-shifty") == 0)) { bool x = false, f = false; - if (strcasecmp(s, "-scale_shiftx") == 0) + if (strcasecmp(s, "-shiftx") == 0) x = true; get_next_word(s, sizeof(s)); @@ -1058,7 +1066,7 @@ bool parse_cmd_line(int argc, char **argv) f = true; // print help } i = atoi(s); - if (i >= -100 && i <= 100 && !f) { + if (i >= -100 && i != 0 && i <= 100 && !f) { i = i + 0x64; if (i == 0x0) i = 0x1; if (x) @@ -1162,7 +1170,7 @@ bool parse_cmd_line(int argc, char **argv) } // Use old style overlays (lair, ace, lair2 & tq) else if (strcasecmp(s, "-original_overlay") == 0) { - g_game->m_use_old_overlay = true; + g_game->m_old_overlay = true; } // this switch only supported by the ldp-vldp player class. else if (strcasecmp(s, "-useoverlaysb") == 0) { diff --git a/src/io/error.cpp b/src/io/error.cpp index 1a9399ca..2c68cede 100644 --- a/src/io/error.cpp +++ b/src/io/error.cpp @@ -34,9 +34,12 @@ #include "../sound/sound.h" +static bool g_usage = false; + // notifies the user of an error that has occurred void printerror(const char *s) { + if (g_usage) return; static bool alert = true; if (alert && sound::get_initialized()) { @@ -61,23 +64,23 @@ void printerror(const char *s) #endif } -// notifies user that the game does not work correctly and gives a reason -// this should be called after video has successfully been initialized -void printnowookin(const char *s) +// prints a notice to the screen +void printnotice(const char *s) { - LOGE << s; + LOGW << s; } -// prints a notice to the screen -void printnotice(const char *s) +// notifies user that the game does not work correctly and gives a reason +// this should be called after video has successfully been initialized +void printnowookin(const char *s) { - LOGE << s; + printnotice(s); } void printusage() { const char * usage = R"USAGE( - Hypseus Singe (C)2023 DirtBagXon + Hypseus Singe (c) 2023 DirtBagXon Usage: hypseus vldp -framefile ... @@ -94,7 +97,7 @@ void printusage() -fastboot -fullscreen -gamepad - -nolinear_scale + -linear_scale - Common Singe arguments: @@ -111,8 +114,12 @@ void printusage() )USAGE"; #ifdef WIN32 - MessageBox(NULL, usage, "Usage", MB_OK | MB_ICONINFORMATION); + MessageBox(NULL, usage, "Usage", MB_OK | MB_ICONINFORMATION); +#elif __APPLE__ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Usage", usage, NULL); #else - fprintf(stdout, "%s", usage); + fprintf(stdout, "%s", usage); #endif + + g_usage = true; } diff --git a/src/ldp-in/ldp1000.cpp b/src/ldp-in/ldp1000.cpp index b44bcdb1..2e783a0d 100644 --- a/src/ldp-in/ldp1000.cpp +++ b/src/ldp-in/ldp1000.cpp @@ -270,7 +270,7 @@ void write(unsigned char value) // Display LDP1450 overlay for (i = 0; i < 3; i++) { - if (g_game->get_use_old_overlay()) { + if (g_game->use_old_overlay()) { video::draw_singleline_LDP1450(g_LDP1450_Strings[i].String, overlay_ldp1450_x, overlay_ldp1450_y); } else { diff --git a/src/ldp-in/ldv1000.cpp b/src/ldp-in/ldv1000.cpp index bae8b9f9..9f297ef3 100644 --- a/src/ldp-in/ldv1000.cpp +++ b/src/ldp-in/ldv1000.cpp @@ -427,7 +427,7 @@ void write(unsigned char value) g_output |= 0x80; // set highbit just in case break; default: // Unsupported Command - LOGW << fmt("Unsupported LD-V1000 Command Received: %x", value); + LOGD << fmt("Unsupported LD-V1000 Command Received: %x", value); break; } } @@ -448,10 +448,10 @@ void write(unsigned char value) } // As you can see we are currently not supporting display disable -void pre_display_disable() { LOGW << "Display disable received (unsupported)"; } +void pre_display_disable() { LOGD << "Display disable received (unsupported)"; } // We are not currently supporting display enable -void pre_display_enable() { LOGW << "Display enable received (unsupported)"; } +void pre_display_enable() { LOGD << "Display enable received (unsupported)"; } // Make the LD-V1000 appear to perform instantaneous searches // NOTE : Doesn't work with all games diff --git a/src/ldp-out/ldp-vldp.cpp b/src/ldp-out/ldp-vldp.cpp index 04ae63fb..2770c4dd 100644 --- a/src/ldp-out/ldp-vldp.cpp +++ b/src/ldp-out/ldp-vldp.cpp @@ -1510,8 +1510,8 @@ void update_parse_meter(const string &strFilename) if (remaining_s > 0) { SDL_Renderer *renderer = video::get_renderer(); FC_Font *g_font = video::get_font(); - int h = video::get_draw_height(); - int w = video::get_draw_width(); + int h = video::get_logical_height(); + int w = video::get_logical_width(); int len; char s[160]; char f[160]; diff --git a/src/scoreboard/overlay_scoreboard.cpp b/src/scoreboard/overlay_scoreboard.cpp index ceb9c571..d9d30e49 100644 --- a/src/scoreboard/overlay_scoreboard.cpp +++ b/src/scoreboard/overlay_scoreboard.cpp @@ -34,7 +34,7 @@ bool OverlayScoreboard::RepaintIfNeeded() if (!m_bThayers) { // Draw all DL/SA scoreboard labels. - if (video::get_use_old_osd()) { + if (video::use_old_font()) { video::draw_string("Credits", pSurface->w / 12 - (pSurface->w == 360 ? 4 : 3), 0, pSurface); video::draw_string("Player 1: ", 1, 0, pSurface); video::draw_string("Player 2: ", (pSurface->w / 6 - 19), 0, pSurface); @@ -61,7 +61,7 @@ bool OverlayScoreboard::RepaintIfNeeded() else { // Thayer's Quest only uses "Credits" portion of the DL/SA // scoreboard. - if (video::get_use_old_osd()) + if (video::use_old_font()) video::draw_string("Time", pSurface->w / 12 - 2, 0, pSurface); else video::draw_string("Time", pSurface->w / 12 + 3, 1, pSurface); diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp index 03aa9c82..da37688c 100644 --- a/src/sound/sound.cpp +++ b/src/sound/sound.cpp @@ -334,9 +334,9 @@ int load_waves() } // load "saveme" sound in - if (!SDL_LoadWAV("sound/saveme.wav", &spec, &g_sample_saveme.pu8Buf, + if (!SDL_LoadWAV("sound/grumble.wav", &spec, &g_sample_saveme.pu8Buf, &g_sample_saveme.uLength)) { - LOGW << "Loading 'saveme.wav' failed..."; + LOGW << "Loading 'grumble.wav' failed..."; result = 0; } diff --git a/src/video/palette.cpp b/src/video/palette.cpp index bea19e48..d4ab151e 100644 --- a/src/video/palette.cpp +++ b/src/video/palette.cpp @@ -176,9 +176,10 @@ void shutdown(void) } } -// this function is here temporarily while the game drivers are switch to this -// new method -t_yuv_color *get_yuv(void) { return g_yuv; } +void set_yuv_transparency(bool transparent) +{ + if (video::get_yuv_overlay_ready()) + video::set_video_blank(!transparent); +} -Uint32 *get_rgba(void) { return g_uRGBAPalette; } } diff --git a/src/video/palette.h b/src/video/palette.h index efe72597..d7f2eb98 100644 --- a/src/video/palette.h +++ b/src/video/palette.h @@ -40,10 +40,9 @@ bool initialize(unsigned int num_colors); // The default is for color #0 to be transparent, and this will be // set in initialize. void set_transparency(unsigned int uColorIndex, bool transparent); +void set_yuv_transparency(bool transparent); void set_color(unsigned int color_num, SDL_Color color_value); void finalize(); void shutdown(void); -t_yuv_color *get_yuv(void); -Uint32 *get_rgba(void); } diff --git a/src/video/tms9128nl.cpp b/src/video/tms9128nl.cpp index 9aca936a..ae49bd9b 100644 --- a/src/video/tms9128nl.cpp +++ b/src/video/tms9128nl.cpp @@ -62,6 +62,7 @@ unsigned char g_tms_background_color = 0; // black (3 bit) bool g_tms_interrupt_enabled = false; // whether NMI is on or off bool g_conv_12a563 = false; bool g_alpha_latch = false; +bool g_nostretch = false; int g_transparency_enabled = 0; int g_transparency_latch = 0; @@ -70,7 +71,6 @@ static int stretch_offset = TMS_VERTICAL_OFFSET; static int offset_shunt = 0; // BARBADEL: Added -int introHack = 0; int prevg_vidmode = 0; void tms9128nl_clear_overlay(); //////////////////////////////////////////////////////////////////////////// @@ -99,13 +99,14 @@ void tms9128nl_reset() g_tms_interrupt_enabled = false; g_transparency_enabled = 0; g_transparency_latch = 0; - introHack = 0; prevg_vidmode = 0; stretch_offset = g_game->get_stretch_value(); offset_shunt = (TMS_VERTICAL_OFFSET - g_game->get_stretch_value()) / TMS_ROW_HEIGHT; } +bool tms9128nl_bordchar(unsigned char value) { return (value > 0x5F && value < 0x69); } + bool tms9128nl_int_enabled() { return (g_tms_interrupt_enabled); } void tms9128nl_writechar(unsigned char value) @@ -113,10 +114,11 @@ void tms9128nl_writechar(unsigned char value) // this is the same as writing to register #0 on a TMS chip { unsigned int row = 0, col = 0; + unsigned char tile = 0, s = 0; int base = 0; + if (g_nostretch) s += TMS_ROW_HEIGHT >> 1; if (viddisp == 0) return; // video display is off - // if (g_vidmode!=1) return; //only text mode 1 for now // MODE 1 (bitmapped text) if (g_vidmode == 1) { @@ -133,15 +135,10 @@ void tms9128nl_writechar(unsigned char value) { case 0x0: if ((int)row == offset_shunt) - tms9128nl_drawchar(0, col, 0); - break; - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x67: + tms9128nl_drawchar(0, col, 0, 0); break; default: + if (tms9128nl_bordchar(value)) break; if ((int)row == offset_shunt) row = 0x0; break; @@ -152,7 +149,7 @@ void tms9128nl_writechar(unsigned char value) return; // problems with col31? or bug in fancyclearscreen // routine? - tms9128nl_drawchar(value, col, row); + tms9128nl_drawchar(value, col, row, 0); } // else, they're outside the viewable area, so draw nothing } // end mode 1 @@ -166,6 +163,8 @@ void tms9128nl_writechar(unsigned char value) base = 0x3c01; rowdiv = 32; // 32*24 + if (g_conv_12a563) --base; + row = (wvidindex - base - 1) / rowdiv; col = (wvidindex - base - 1) % rowdiv; @@ -179,18 +178,49 @@ void tms9128nl_writechar(unsigned char value) } } + if (g_conv_12a563) { + switch (value) + { + case 0x38: + if (wvidindex != 0x3D95) + tile = 1; + break; + case 0x1C: + case 0x1E: + case 0x3E: + case 0x40: + if (!g_transparency_enabled) + tile = 1; + break; + case 0x71: + case 0x72: + case 0x73: + if (col == 0x16 && row > 0xD) + tms9128nl_drawchar(TMS_TAG_TICK, 0x10 + s, + (0xF + offset_shunt), 3); + tile = 1; + break; + } + + if (tms9128nl_bordchar(value)) + if (g_transparency_latch) + tile = 2; + + row += offset_shunt; + --col; + } + if ((col == 31) && (rowdiv == 32)) return; // problems with col31? or bug in fancyclearscreen // routine? - tms9128nl_drawchar(value, col, row); + tms9128nl_drawchar(value, col + s, row, tile); } // BARBADEL: Added else { if (g_conv_12a563) { - g_tms_foreground_color = 0x5; - g_tms_background_color = 0x1; - if (wvidindex == 0x3802) tms9128nl_drawchar(0x0A, (value >> 3), 0x13); + if (wvidindex == 0x3802) tms9128nl_drawchar(0x5F, s + (value >> 3), + (0x13 + offset_shunt), 1); } else { g_tms_foreground_color = (unsigned char)((value & 0xF0) >> 4); g_tms_background_color = (unsigned char)(value & 0x0F); @@ -526,6 +556,9 @@ void tms9128nl_convert_color(unsigned char color_src, SDL_Color *color) case 3: tms9128nl_convert_color(0x4, color); return; + case 5: + color->r = color->g = color->b = 0xF0; + return; case 2: case 12: tms9128nl_convert_color(0x1, color); @@ -624,6 +657,16 @@ void tms9128nl_convert_color(unsigned char color_src, SDL_Color *color) color->g = 255; color->b = 255; break; + case TMS_LAY1: + color->r = 155; + color->g = 34; + color->b = 34; + break; + case TMS_LAY2: + color->r = 45; + color->g = 45; + color->b = 45; + break; default: LOGW << fmt("UNSUPPORTED COLOR passed into convert color : %d", color_src); break; @@ -633,19 +676,35 @@ void tms9128nl_convert_color(unsigned char color_src, SDL_Color *color) // draws a character to the Cliff video display // 40 columns by 24 rows // uses Cliffy's video memory to retrieve 8x8 character bitmap -void tms9128nl_drawchar(unsigned char ch, int col, int row) +void tms9128nl_drawchar(unsigned char ch, int col, int row, unsigned char tile) { - const int CHAR_WIDTH = 8; - const int CHAR_HEIGHT = 8; + const int CharWidth = 8; + const int CharHeight = 8; + int FGColor = TMS_FG_COLOR; int bmp_index = (ch * 8) + (g_tms_pgt_addr << 11); // index in vid mem where // bmp data is located int i = 0, j = 0; // temp indices - int x = col * CHAR_WIDTH; - int y = row * CHAR_HEIGHT; + int x = col * CharWidth; + int y = row * CharHeight; unsigned char line = 0; unsigned char background_color = TMS_BG_COLOR; + switch (tile) + { + case 0x01: + FGColor = TMS_LAY1; + break; + case 0x02: + FGColor = TMS_LAY2; + break; + case 0x03: + x -= 0x02; + break; + } + + if (g_tms_pgt_addr == 0x03) x += (CharWidth >> 1); + // if character is 0 and we're in transparency mode, make bitmap transparent if (g_transparency_latch) { static bool latched = true; @@ -693,15 +752,15 @@ void tms9128nl_drawchar(unsigned char ch, int col, int row) } // draw each line of character into new surface - for (i = 0; i < CHAR_HEIGHT; i++) { + for (i = 0; i < CharHeight; i++) { line = vidmem[bmp_index + i]; // get a line // handle each pixel across - for (j = CHAR_WIDTH - 1; j >= 0; j--) { + for (j = CharWidth - 1; j >= 0; j--) { // if rightmost bit is 1, it means draw the pixel if (line & 1) { *((Uint8 *)g_vidbuf + ((y + i + stretch_offset) * TMS9128NL_OVERLAY_W) + - (x + j)) = TMS_FG_COLOR; + (x + j)) = FGColor; } // else draw the background else { @@ -716,18 +775,20 @@ void tms9128nl_drawchar(unsigned char ch, int col, int row) // character after it non-transparent // This seems to be how Cliff Hanger behaves. I haven't found it documented // anywhere though. - if ((!g_alpha_latch) && (g_transparency_latch) && (ch != 0) && (ch != 0xFF)) { - Uint8 *ptr = ((Uint8 *)g_vidbuf) + - ((y + stretch_offset) * TMS9128NL_OVERLAY_W) + x + CHAR_WIDTH; - for (int nrow = 0; nrow < CHAR_HEIGHT; nrow++) { - for (int ncol = 0; ncol < CHAR_WIDTH; ncol++) { - // make it non-transparent if it is - if (*ptr == TMS_TRANSPARENT_COLOR) { - *ptr = TMS_BG_COLOR; + if (!g_alpha_latch) { + if ((g_transparency_latch) && (ch != 0) && (ch != 0xFF)) { + Uint8 *ptr = ((Uint8 *)g_vidbuf) + + ((y + stretch_offset) * TMS9128NL_OVERLAY_W) + x + CharWidth; + for (int r = 0; r < CharHeight; r++) { + for (int c = 0; c < CharWidth; c++) { + // make it non-transparent if it is + if (*ptr == TMS_TRANSPARENT_COLOR) { + *ptr = TMS_BG_COLOR; + } + ptr++; } - ptr++; + ptr += (TMS9128NL_OVERLAY_W - CharWidth); // move to the next line } - ptr += (TMS9128NL_OVERLAY_W - CHAR_WIDTH); // move to the next line } } @@ -761,10 +822,12 @@ void tms9128nl_outcommand(char *s, int col, int row) // initialization requirement void tms9128nl_palette_update() { - SDL_Color fore, back; // the foreground and background colors + SDL_Color fore, back, grid, tag; // the foreground and background colors tms9128nl_convert_color(g_tms_foreground_color, &fore); tms9128nl_convert_color(g_tms_background_color, &back); + tms9128nl_convert_color(TMS_LAY1, &tag); + tms9128nl_convert_color(TMS_LAY2, &grid); palette::set_color(0, back); palette::set_color(255, fore); @@ -772,7 +835,7 @@ void tms9128nl_palette_update() // if we should do extra calculations for stretching if (g_vidmode == 2) { SDL_Color fore75back25, fore5back5, - fore25back75; // mixtures of the foreground and background colors + fore25back75, tagfade; // mixtures of the foreground and background colors // (for stretching) MIX_COLORS_75_25(fore75back25, fore, back); // 3/4, 1/4 MIX_COLORS_50(fore5back5, fore, back); // average @@ -780,6 +843,11 @@ void tms9128nl_palette_update() palette::set_color(1, fore25back75); palette::set_color(2, fore5back5); palette::set_color(3, fore75back25); + + MIX_COLORS_75_25(tagfade, tag, back); + palette::set_color(TMS_LAY1, tag); + palette::set_color(TMS_LAY1 + 1, tagfade); + palette::set_color(TMS_LAY2, grid); } palette::finalize(); @@ -800,10 +868,6 @@ void tms9128nl_palette_calculate() // :) palette::set_color(TMS_TRANSPARENT_COLOR, color); - if (g_game->get_game_type() == GAME_GTG) g_conv_12a563 = true; - - g_alpha_latch = g_game->get_console_flag(); - tms9128nl_palette_update(); tms9128nl_reset(); } @@ -852,7 +916,7 @@ void tms9128nl_video_repaint() // if we're in video mode 2, we have to display our stretched overlay // instead of our regular one - if (g_vidmode == 2) { + if (g_vidmode == 2 && !g_nostretch) { tms9128nl_video_repaint_stretched(); } @@ -894,7 +958,8 @@ void tms9128nl_video_repaint_stretched() for (int i = 1; i < 4; i++) { // if prev pixel is not the same as cur pixel, blending is // required - if (*(ptr256 + i - 1) != *(ptr256 + i)) { + if ((*(ptr256 + i - 1) != *(ptr256 + i)) && + (*(ptr256 + i) != TMS_LAY1)) { // if prev pixel is background color, cur pixel must be // foreground if (*(ptr256 + i - 1) == 0) { @@ -903,10 +968,15 @@ void tms9128nl_video_repaint_stretched() // else prev pixel is foreground, and therefore cur pixel // must be background else { - *(ptr320 + i) = blend[i][1]; + if ((*(ptr256 + i - 1)) == TMS_LAY1) + *(ptr320 + i) = TMS_LAY1 + 1; + else *(ptr320 + i) = blend[i][1]; } - } else - *(ptr320 + i) = *(ptr256 + i); // else no blending required + } else { + if ((*(ptr256 - 1)) == TMS_LAY1 && (*(ptr256)) == 0) + *(ptr320 - 1) = TMS_LAY1 + 1; + *(ptr320 + i) = *(ptr256 + i); // else no blending required + } } // PIXEL +4 @@ -964,3 +1034,6 @@ void tms9128nl_clear_overlay() // sets the "transparency value" for one NMI tick (it gets cleared at each NMI // tick) void tms9128nl_set_transparency() { g_transparency_enabled = 1; } +void tms9128nl_set_conv_12a563() { g_conv_12a563 = true; } +void tms9128nl_set_nostretch() { g_nostretch = true; } +void tms9128nl_set_spritelite() { g_alpha_latch = true; } diff --git a/src/video/tms9128nl.h b/src/video/tms9128nl.h index 0ea9d6c0..5259476c 100644 --- a/src/video/tms9128nl.h +++ b/src/video/tms9128nl.h @@ -31,7 +31,10 @@ #define TMS_BG_COLOR 0 #define TMS_TRANSPARENT_COLOR 0x7F #define TMS_FG_COLOR 0xFF -#define TMS_ROW_HEIGHT 0x8 +#define TMS_ROW_HEIGHT 0x08 +#define TMS_TAG_TICK 0x1A +#define TMS_LAY1 0x40 +#define TMS_LAY2 0x44 #define TMS_COLOR_COUNT 256 @@ -56,12 +59,15 @@ void tms9128nl_write_port1(unsigned char); void tms9128nl_write_port0(unsigned char Value); int tms9128nl_setvidmem(unsigned char); void tms9128nl_convert_color(unsigned char, SDL_Color *); -void tms9128nl_drawchar(unsigned char, int, int); +void tms9128nl_drawchar(unsigned char, int, int, unsigned char); void tms9128nl_outcommand(char *s, int col, int row); void tms9128nl_palette_update(); void tms9128nl_palette_calculate(); void tms9128nl_video_repaint(); void tms9128nl_video_repaint_stretched(); void tms9128nl_set_transparency(); +void tms9128nl_set_conv_12a563(); +void tms9128nl_set_nostretch(); +void tms9128nl_set_spritelite(); #endif diff --git a/src/video/video.cpp b/src/video/video.cpp index 6ff3bee8..9bcabdef 100644 --- a/src/video/video.cpp +++ b/src/video/video.cpp @@ -66,11 +66,12 @@ void LogicalPosition(SDL_Rect *port, SDL_Rect *dst, int x, int y) namespace video { int g_vid_width = 640, g_vid_height = 480; // default video dimensions -unsigned int g_draw_width = g_vid_width, g_probe_width = g_vid_width; -unsigned int g_draw_height = g_vid_height, g_probe_height = g_vid_height; +const int g_bw = g_vid_width >> 1, g_bh = g_vid_height >> 1; +unsigned int g_probe_width = g_vid_width; +unsigned int g_probe_height = g_vid_height; const int g_an_w = 220, g_an_h = 128; const int g_sb_w = 340, g_sb_h = 480; -int s_alpha = 64; +int s_alpha = 128; int s_shunt = 2; int g_viewport_width = g_vid_width, g_viewport_height = g_vid_height; @@ -95,8 +96,8 @@ SDL_Renderer *g_renderer = NULL; SDL_Renderer *g_sb_renderer = NULL; SDL_Texture *g_overlay_texture = NULL; // The OVERLAY texture, excluding LEDs wich are a special case SDL_Texture *g_yuv_texture = NULL; // The YUV video texture, registered from ldp-vldp.cpp -SDL_Surface *g_screen_blitter = NULL; // The main blitter surface -SDL_Surface *g_leds_surface = NULL; +SDL_Surface *g_overlay_blitter = NULL; // The main blitter surface +SDL_Surface *g_blit_surface = NULL; SDL_Surface *g_sb_surface = NULL; SDL_Texture *g_sb_texture = NULL; SDL_Surface *g_sb_blit_surface = NULL; @@ -110,14 +111,16 @@ SDL_Rect g_overlay_size_rect; SDL_Rect g_scaling_rect = {0, 0, 0, 0}; SDL_Rect g_logical_rect = {0, 0, 0, 0}; SDL_Rect g_sb_bezel_rect = {0, 0, 0, 0}; -SDL_Rect g_leds_size_rect = {0, 0, 320, 240}; -SDL_Rect g_render_size_rect = g_leds_size_rect; +SDL_Rect g_blit_size_rect = {0, 0, g_bw, g_bh}; +SDL_Rect g_render_size_rect = g_blit_size_rect; SDL_Rect g_annu_rect = { 0, 0, g_an_w, g_an_h }; +SDL_DisplayMode g_displaymode; + LDP1450_CharStruct LDP1450_CharSet[OVERLAY_LDP1450_LINES]; bool queue_take_screenshot = false; -bool g_fs_scale_nearest = false; +bool g_scale_linear = false; bool g_singe_blend_sprite = false; bool g_scanlines = false; bool g_fakefullscreen = false; @@ -134,12 +137,14 @@ bool g_bIgnoreAspectRatio = false; bool g_LDP1450_overlay = false; bool g_fullscreen = false; // initialize video in fullscreen bool g_bezel_toggle = false; -bool g_scale_view = false; bool g_sb_bezel = false; bool g_rotate = false; +bool g_rotated_state = false; bool g_keyboard_bezel = false; bool g_annun_bezel = false; bool g_ded_annun_bezel = false; +bool g_annun_lamps = false; +bool g_vertical_orientation = false; int g_scalefactor = 100; // by RDG2010 -- scales the image to this percentage int g_aspect_ratio = 0; @@ -151,12 +156,13 @@ int8_t g_annun_bezel_alpha = 0; int g_sb_bezel_scale = 14; int g_an_bezel_scale = 12; +int g_bezel_scalewidth = 0; // Move subtitle rendering to SDL_RenderPresent(g_renderer); bool g_bSubtitleShown = false; char *subchar = NULL; -string g_bezel_file = ""; +string g_bezel_file; // degrees in clockwise rotation SDL_RendererFlip g_flipState = SDL_FLIP_NONE; @@ -181,7 +187,7 @@ bool g_softsboard_needs_update = false; bool g_overlay_needs_update = false; bool g_yuv_video_needs_update = false; bool g_yuv_video_needs_blank = false; -bool g_yuv_video_timer_blank = false; +bool g_yuv_video_blank = false; bool g_aux_needs_update = false; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -190,25 +196,22 @@ bool g_aux_needs_update = false; // returns true if successful, false if failure bool init_display() { - bool result = false; // whether video initialization is successful or not - Uint32 sdl_flags = 0; - Uint32 sdl_sb_flags = 0; - Uint8 sdl_render_flags = 0; - Uint8 sdl_sb_render_flags = 0; + bool result = false; static bool notify = false; - char bezelpath[96] = {0}; - char title[50] = "HYPSEUS Singe: Multiple Arcade Laserdisc Emulator"; + constexpr char title[] = "HYPSEUS Singe: Multiple Arcade Laserdisc Emulator"; SDL_SysWMinfo info; - sdl_flags = SDL_WINDOW_SHOWN; - sdl_sb_flags = SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_BORDERLESS; - sdl_render_flags = SDL_RENDERER_TARGETTEXTURE; + Uint32 sdl_flags = SDL_WINDOW_SHOWN; + Uint32 sdl_sb_flags = SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_BORDERLESS; + Uint8 sdl_render_flags = SDL_RENDERER_TARGETTEXTURE; // if we were able to initialize the video properly if (SDL_InitSubSystem(SDL_INIT_VIDEO) >= 0) { - if (g_fullscreen) sdl_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - else if (g_fakefullscreen) sdl_flags |= SDL_WINDOW_MAXIMIZED | SDL_WINDOW_BORDERLESS; + if (g_fullscreen) + sdl_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + else if (g_fakefullscreen) + sdl_flags |= SDL_WINDOW_MAXIMIZED | SDL_WINDOW_BORDERLESS; if (g_opengl) { sdl_flags |= SDL_WINDOW_OPENGL; @@ -226,60 +229,39 @@ bool init_display() if ((int)g_probe_height < g_vid_height) g_probe_height = g_vid_height; if (g_vid_resized) { - g_draw_width = g_viewport_width = g_vid_width; - g_draw_height = g_viewport_height = g_vid_height; + g_viewport_width = g_vid_width; + g_viewport_height = g_vid_height; } else { - g_draw_width = g_probe_width; - g_draw_height = g_probe_height; - if (!g_bIgnoreAspectRatio && g_aspect_width > 0) { g_viewport_width = g_aspect_width; g_viewport_height = g_aspect_height; + } else { - g_viewport_width = g_draw_width; - g_viewport_height = g_draw_height; + g_viewport_width = g_probe_width; + g_viewport_height = g_probe_height; } } // Enforce 4:3 aspect ratio if (g_bForceAspectRatio) { - double dCurAspectRatio = (double)g_draw_width / g_draw_height; + double dCurAspectRatio = (double)g_viewport_width / g_viewport_height; const double dTARGET_ASPECT_RATIO = 4.0 / 3.0; if (dCurAspectRatio < dTARGET_ASPECT_RATIO) { - g_draw_height = (g_draw_width * 3) / 4; g_viewport_height = (g_viewport_width * 3) / 4; } else if (dCurAspectRatio > dTARGET_ASPECT_RATIO) { - g_draw_width = (g_draw_height * 4) / 3; g_viewport_width = (g_viewport_height * 4) / 3; } } - // if we're supposed to scale the image... - if (g_scalefactor < 100) { - g_scaling_rect.w = (g_viewport_width * g_scalefactor) / 100; - g_scaling_rect.h = (g_viewport_height * g_scalefactor) / 100; - g_scaling_rect.x = ((g_viewport_width - g_scaling_rect.w) >> 1); - g_scaling_rect.y = ((g_viewport_height - g_scaling_rect.h) >> 1); - - if (g_keyboard_bezel) - g_scaling_rect.y = g_scaling_rect.y >> 2; - else { - g_scaling_rect.x = (g_scaling_rect.x * g_scale_h_shift) / 100; - g_scaling_rect.y = (g_scaling_rect.y * g_scale_v_shift) / 100; - } - } - - if (!SDL_RectEmpty(&g_scaling_rect)) g_scale_view = true; - if (g_window) resize_cleanup(); if (g_fRotateDegrees != 0) { if (g_fRotateDegrees != 180.0) { - if (!notify) { LOGW << "Screen rotation enabled, aspect ratios will be ignored"; } + if (!notify) { LOGW << "Screen rotation: Just a ruse..."; } g_viewport_height = g_viewport_width; } } @@ -299,7 +281,7 @@ bool init_display() sdl_render_flags |= SDL_RENDERER_ACCELERATED; } - sdl_sb_render_flags = sdl_render_flags; + Uint8 sdl_sb_render_flags = sdl_render_flags; if (g_vsync && (sdl_render_flags & SDL_RENDERER_ACCELERATED)) sdl_render_flags |= SDL_RENDERER_PRESENTVSYNC; @@ -314,20 +296,15 @@ bool init_display() } else { if (g_keyboard_bezel) { + string tqkeys = "bezels/tqkeys.png"; + if (!mpo_file_exists(tqkeys.c_str())) + tqkeys = "pics/tqkeys.png"; - char tqkeys[18]; - char png[11] = "tqkeys.png"; - - snprintf(tqkeys, sizeof(tqkeys), "bezels/%s", png); - - if (!mpo_file_exists(tqkeys)) - snprintf(tqkeys, sizeof(tqkeys), "pics/%s", png); - - g_aux_texture = IMG_LoadTexture(g_renderer, tqkeys); + g_aux_texture = IMG_LoadTexture(g_renderer, tqkeys.c_str()); if (!g_aux_texture) { LOGE << fmt("Failed to load keyboard graphic: %s - %s", - tqkeys, SDL_GetError()); + tqkeys.c_str(), SDL_GetError()); set_quitflag(); } } else if (g_annun_bezel) { @@ -341,24 +318,23 @@ bool init_display() SDL_SetTextureBlendMode(g_aux_texture, SDL_BLENDMODE_BLEND); } - if (g_bezel_file.length() > 0) { - snprintf(bezelpath, sizeof(bezelpath), "bezels/%s", g_bezel_file.c_str()); - - g_bezel_texture = IMG_LoadTexture(g_renderer, bezelpath); + if (!g_bezel_file.empty()) { + string bezelpath = "bezels/" + g_bezel_file; + g_bezel_texture = IMG_LoadTexture(g_renderer, bezelpath.c_str()); if (!notify) { if (g_bezel_texture) { - LOGI << fmt("Loaded bezel file: %s", bezelpath); + LOGI << fmt("Loaded bezel file: %s", bezelpath.c_str()); } else { - LOGW << fmt("Failed to load bezel: %s", bezelpath); + LOGW << fmt("Failed to load bezel: %s", bezelpath.c_str()); } } } SDL_VERSION(&info.version); - // Set bilinear filtering by default - if (!g_fs_scale_nearest) + // Set linear filtering + if (g_scale_linear) SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); // Create a 32-bit surface with alpha component. @@ -384,14 +360,6 @@ bool init_display() if (g_sb_bezel) { - double scale = 9.0f - double((g_sb_bezel_scale << 1) / 10.0f); - double ratio = (float)g_sb_h / (float)g_sb_w; - - g_sb_bezel_rect.x = sb_window_pos_x; - g_sb_bezel_rect.y = sb_window_pos_y; - g_sb_bezel_rect.w = (g_viewport_width / scale); - g_sb_bezel_rect.h = (g_sb_bezel_rect.w * ratio); - if (!g_sb_bezel_alpha) SDL_FillRect(g_sb_blit_surface, NULL, 0x000000ff); @@ -433,23 +401,31 @@ bool init_display() } else if (!notify) { LOGE << "Cannot create a Scoreboard entity..."; } } - // MAC: If we start in fullscreen mode, we have to set the logical - // render size to get the desired aspect ratio. + // DBX: Fullscreen mode, get the logical render stats if ((sdl_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0 || (sdl_flags & SDL_WINDOW_MAXIMIZED) != 0) { - SDL_RenderSetLogicalSize(g_renderer, g_viewport_width, g_viewport_height); - - // Get and store logical viewport dimensions if ((sdl_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) { SDL_RenderSetViewport(g_renderer, NULL); SDL_RenderGetViewport(g_renderer, &g_logical_rect); - SDL_RenderSetLogicalSize(g_renderer, g_viewport_width, g_viewport_height); + + } else { + + if (SDL_GetDesktopDisplayMode(0, &g_displaymode) != 0) { + LOGE << fmt("SDL_GetDesktopDisplayMode failed: %s", SDL_GetError()); + set_quitflag(); + goto exit; + } + g_logical_rect.w = g_displaymode.w; + g_logical_rect.h = g_displaymode.h; } - if (g_bezel_texture || !SDL_RectEmpty(&g_sb_bezel_rect)) - g_bezel_toggle = true; - } + if (g_bezel_texture) g_bezel_toggle = true; + + format_fullscreen_render(); + + } else + format_window_render(); if (g_aux_texture) { @@ -460,7 +436,7 @@ bool init_display() double ratio = (float)size.y / (float)size.x; - g_aux_rect.w = (g_viewport_width / 2.25f); + g_aux_rect.w = (g_bezel_scalewidth / 2.25f); g_aux_rect.h = (g_aux_rect.w * ratio); LogicalPosition(&g_logical_rect, &g_aux_rect, 50, 100); @@ -485,7 +461,7 @@ bool init_display() if (g_annun_bezel_alpha > 1) SDL_SetColorKey(g_aux_blit_surface, SDL_TRUE, 0x000000ff); - g_aux_rect.w = (g_viewport_width / scale); + g_aux_rect.w = (g_bezel_scalewidth / scale); g_aux_rect.h = (g_aux_rect.w * ratio); if (g_ded_annun_bezel) @@ -514,49 +490,15 @@ bool init_display() if (g_scanlines) SDL_SetRenderDrawBlendMode(g_renderer, SDL_BLENDMODE_BLEND); - // Calculate font sizes - int ffs; - int fs = get_draw_width() / 36; - if (g_aspect_ratio == ASPECTWS) ffs = get_draw_width() / 24; - else ffs = get_draw_width() / 18; - - char font[32]="fonts/default.ttf"; - char fixfont[32] = "fonts/timewarp.ttf"; - char ttfont[32]; - - if (g_game->get_use_old_overlay()) - strncpy(ttfont, "fonts/daphne.ttf", sizeof(ttfont)); - else strncpy(ttfont, "fonts/digital.ttf", sizeof(ttfont)); - - g_font = FC_CreateFont(); - FC_LoadFont(g_font, g_renderer, font, fs, - FC_MakeColor(0xff, 0xff, 0xff, 0xff), TTF_STYLE_NORMAL); - - g_fixfont = FC_CreateFont(); - FC_LoadFont(g_fixfont, g_renderer, fixfont, ffs, - FC_MakeColor(0xff, 0xff, 0xff, 0xff), TTF_STYLE_NORMAL); - - if (g_game->get_use_old_overlay()) - g_ttfont = TTF_OpenFont(ttfont, 12); - else - g_ttfont = TTF_OpenFont(ttfont, 14); - - if (g_ttfont == NULL) { - LOG_ERROR << fmt("Cannot load TTF font: '%s'", (char*)ttfont); - g_game->set_game_errors(SDL_ERROR_FONT); - set_quitflag(); - goto exit; - } - - g_screen_blitter = + g_overlay_blitter = SDL_CreateRGBSurface(SDL_SWSURFACE, g_overlay_width, g_overlay_height, surfacebpp, Rmask, Gmask, Bmask, Amask); // Check for game overlay enhancements (depth and size) g_enhance_overlay = g_game->get_overlay_upgrade(); - g_overlay_resize = g_game->get_fullsize_overlay(); + g_overlay_resize = g_game->get_dynamic_overlay(); - g_leds_surface = + g_blit_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 320, 240, surfacebpp, Rmask, Gmask, Bmask, Amask); @@ -564,16 +506,16 @@ bool init_display() // blitting, and set it's color key to NOT copy 0x000000ff pixels. We // couldn't do it earlier in load_bmps() because we need the // g_screen_blitter format. - ConvertSurface(&g_other_bmps[B_OVERLAY_LEDS], g_screen_blitter->format); + ConvertSurface(&g_other_bmps[B_OVERLAY_LEDS], g_overlay_blitter->format); SDL_SetColorKey(g_other_bmps[B_OVERLAY_LEDS], SDL_TRUE, 0x000000ff); if (g_aux_blit_surface) { - ConvertSurface(&g_aux_blit_surface, g_screen_blitter->format); + ConvertSurface(&g_aux_blit_surface, g_overlay_blitter->format); } - if (g_game->get_use_old_overlay()) { + if (g_game->use_old_overlay()) { ConvertSurface(&g_other_bmps[B_OVERLAY_LDP1450], - g_screen_blitter->format); + g_overlay_blitter->format); SDL_SetColorKey(g_other_bmps[B_OVERLAY_LDP1450], SDL_TRUE, 0x000000ff); } @@ -654,11 +596,11 @@ bool deinit_display() g_sb_blit_surface = NULL; g_aux_blit_surface = NULL; - SDL_FreeSurface(g_screen_blitter); - SDL_FreeSurface(g_leds_surface); + SDL_FreeSurface(g_overlay_blitter); + SDL_FreeSurface(g_blit_surface); - g_screen_blitter = NULL; - g_leds_surface = NULL; + g_overlay_blitter = NULL; + g_blit_surface = NULL; FC_FreeFont(g_font); FC_FreeFont(g_fixfont); @@ -690,12 +632,12 @@ void resize_cleanup() g_rotate = false; - if (g_screen_blitter) SDL_FreeSurface(g_screen_blitter); - if (g_leds_surface) SDL_FreeSurface(g_leds_surface); + if (g_overlay_blitter) SDL_FreeSurface(g_overlay_blitter); + if (g_blit_surface) SDL_FreeSurface(g_blit_surface); if (g_aux_blit_surface) SDL_FreeSurface(g_aux_blit_surface); - g_screen_blitter = NULL; - g_leds_surface = NULL; + g_overlay_blitter = NULL; + g_blit_surface = NULL; g_aux_blit_surface = NULL; if (g_bezel_texture) SDL_DestroyTexture(g_bezel_texture); @@ -785,6 +727,8 @@ bool load_bmps() g_other_bmps[B_ANUN_ON] = load_one_png("annunon.png"); g_other_bmps[B_ANUN_OFF] = load_one_png("annunoff.png"); + g_other_bmps[B_SHOOT] = load_one_bmp("shoot.bmp", true); + // check to make sure they all loaded for (index = 0; index < B_EMPTY; index++) { if (g_other_bmps[index] == NULL && index != B_MIA) { @@ -797,18 +741,18 @@ bool load_bmps() SDL_Surface *load_one_bmp(const char *filename, bool bezel) { - char filepath[64] = {0}; + string filepath; if (bezel) - snprintf(filepath, sizeof(filepath), "bezels/%s", filename); + filepath = fmt("bezels/%s", filename); - if (!mpo_file_exists(filepath)) - snprintf(filepath, sizeof(filepath), "pics/%s", filename); + if (!mpo_file_exists(filepath.c_str())) + filepath = fmt("pics/%s", filename); - SDL_Surface *result = SDL_LoadBMP(filepath); + SDL_Surface *result = SDL_LoadBMP(filepath.c_str()); if (!result) { - LOGE << fmt("Could not load bitmap: %s", filepath); + LOGE << fmt("Could not load bitmap: %s", filepath.c_str()); } return (result); @@ -816,17 +760,15 @@ SDL_Surface *load_one_bmp(const char *filename, bool bezel) SDL_Surface *load_one_png(const char *filename) { - char filepath[64]; - - snprintf(filepath, sizeof(filepath), "bezels/%s", filename); + string filepath = fmt("bezels/%s", filename); - if (!mpo_file_exists(filepath)) - snprintf(filepath, sizeof(filepath), "pics/%s", filename); + if (!mpo_file_exists(filepath.c_str())) + filepath = fmt("pics/%s", filename); - SDL_Surface *result = IMG_Load(filepath); + SDL_Surface *result = IMG_Load(filepath.c_str()); if (!result) { - LOGE << fmt("Could not load png: %s", filepath); + LOGE << fmt("Could not load png: %s", filepath.c_str()); } return (result); @@ -877,6 +819,8 @@ bool draw_annunciator(int which) bool draw_ranks() { + if (g_annun_lamps) return false; + SDL_Rect dest; dest.x = 10; dest.y = dest.x - 1; @@ -909,12 +853,14 @@ bool draw_annunciator1(int which) for (int i = 0; i < ANUN_LEVELS; i++) { dest.y = ((dest.h + ANUN_CHAR_HEIGHT) * i) + spacer; + if (g_annun_lamps) dest.x = 110 - (-i * 15); SDL_FillRect(g_aux_blit_surface, &dest, 0x00000000); SDL_BlitSurface(g_sb_surface, NULL, g_aux_blit_surface, &dest); } if (which) { g_sb_surface = g_other_bmps[B_ANUN_ON]; + if (g_annun_lamps) dest.x = 110 - ((-which + 1) * 15); dest.y = ((dest.h + ANUN_CHAR_HEIGHT) * --which) + spacer; SDL_BlitSurface(g_sb_surface, NULL, g_aux_blit_surface, &dest); } @@ -931,7 +877,7 @@ bool draw_annunciator2(int which) dest.h = 40; dest.w = 220; - for (int i = B_ACE_OFF; i < B_EMPTY; i++) { + for (int i = B_ACE_OFF; i < B_SHOOT; i++) { g_sb_surface = g_other_bmps[i]; dest.y = (ANUN_RANK_HEIGHT * (i - B_ACE_OFF)); SDL_FillRect(g_aux_blit_surface, &dest, 0x00000000); @@ -973,8 +919,8 @@ void draw_overlay_leds(unsigned int values[], int num_digits, // Also, note that SDL_BlitSurface() won't blit the 0x000000ff pixels because we set up a color key // using SDL_SetColorKey() in init_display(). See notes there on why we don't do it in load_bmps(). // If scoreboard transparency problems appear, look there. - SDL_FillRect(g_leds_surface, &dest, 0x00000000); - SDL_BlitSurface(g_other_bmps[B_OVERLAY_LEDS], &src, g_leds_surface, &dest); + SDL_FillRect(g_blit_surface, &dest, 0x00000000); + SDL_BlitSurface(g_other_bmps[B_OVERLAY_LEDS], &src, g_blit_surface, &dest); dest.x += OVERLAY_LED_WIDTH; } @@ -992,6 +938,7 @@ void draw_charline_LDP1450(char *LDP1450_String, int start_x, int y) float x; int i, j = 0; int LDP1450_strlen; + int fontwidth = FC_GetWidth(g_fixfont, "0123456789"); int index = (int)((y / OVERLAY_LDP1450_HEIGHT) + 0.5f); LDP1450_CharSet[index].enable = false; @@ -1013,18 +960,7 @@ void draw_charline_LDP1450(char *LDP1450_String, int start_x, int y) g_LDP1450_overlay = true; - switch(g_aspect_ratio) - { - case ASPECTWS: - x = (((double)g_draw_width / 225) * start_x); - break; - default: - if (g_draw_width == NOSQUARE) - x = (((double)g_draw_width / 384) * start_x); - else - x = (((double)g_draw_width / 256) * start_x); - break; - } + x = (double)((g_scaling_rect.w - fontwidth) >> 1) + g_scaling_rect.x; for (i = 0; i < LDP1450_strlen; i++) { @@ -1037,7 +973,8 @@ void draw_charline_LDP1450(char *LDP1450_String, int start_x, int y) if (j > 0) { LDP1450_CharSet[index].enable = true; LDP1450_CharSet[index].x = x; - LDP1450_CharSet[index].y = (y * (double)(get_draw_height() * 0.004f)); + LDP1450_CharSet[index].y = (y * (double)(g_scaling_rect.h * 0.004f)) + + g_scaling_rect.y; LDP1450_CharSet[index].OVERLAY_LDP1450_String = LDP1450_String; } } @@ -1052,8 +989,8 @@ void draw_singleline_LDP1450(char *LDP1450_String, int start_x, int y) g_scoreboard_needs_update = true; if (g_aspect_ratio == ASPECTSD && - g_draw_width == NOSQUARE) - start_x = (start_x - (start_x / 4)); + g_probe_width == NOSQUARE) + start_x = (start_x - (start_x >> 2)); dest.x = start_x; dest.y = y; @@ -1092,8 +1029,8 @@ void draw_singleline_LDP1450(char *LDP1450_String, int start_x, int y) else value = 0x31; src.x = value * OVERLAY_LDP1450_WIDTH; - SDL_FillRect(g_leds_surface, &dest, 0x00000000); - SDL_BlitSurface(g_other_bmps[B_OVERLAY_LDP1450], &src, g_leds_surface, &dest); + SDL_FillRect(g_blit_surface, &dest, 0x00000000); + SDL_BlitSurface(g_other_bmps[B_OVERLAY_LDP1450], &src, g_blit_surface, &dest); dest.x += OVERLAY_LDP1450_CHARACTER_SPACING; } } @@ -1144,9 +1081,9 @@ void free_one_bmp(SDL_Surface *candidate) { SDL_Window *get_window() { return g_window; } SDL_Renderer *get_renderer() { return g_renderer; } SDL_Texture *get_screen() { return g_overlay_texture; } -SDL_Surface *get_screen_blitter() { return g_screen_blitter; } +SDL_Surface *get_screen_blitter() { return g_overlay_blitter; } SDL_Texture *get_yuv_screen() { return g_yuv_texture; } -SDL_Surface *get_screen_leds() { return g_leds_surface; } +SDL_Surface *get_screen_leds() { return g_blit_surface; } FC_Font *get_font() { return g_font; } @@ -1155,16 +1092,16 @@ Uint16 get_video_height() { return g_vid_height; } int get_textureaccess() { return g_texture_access; } int get_scalefactor() { return g_scalefactor; } -unsigned int get_draw_width() { return g_draw_width; } -unsigned int get_draw_height() { return g_draw_height; } +unsigned int get_logical_width() { return g_logical_rect.w; } +unsigned int get_logical_height() { return g_logical_rect.h; } bool get_opengl() { return g_opengl; } bool get_vulkan() { return g_vulkan; } -bool get_fullscreen() { return g_fullscreen; } bool get_singe_blend_sprite() { return g_singe_blend_sprite; } -bool get_use_old_osd() { return g_game->get_use_old_overlay(); } -bool get_video_timer_blank() { return g_yuv_video_timer_blank; } +bool get_video_blank() { return g_yuv_video_blank; } bool get_video_resized() { return g_vid_resized; } +bool get_rotated_state() { return g_rotated_state; } +bool use_old_font() { return g_game->use_old_overlay(); } void set_fullscreen(bool value) { g_fullscreen = value; } void set_fakefullscreen(bool value) { g_fakefullscreen = value; } @@ -1177,17 +1114,16 @@ void set_yuv_blue(bool value) { g_yuv_blue = value; } void set_scanlines(bool value) { g_scanlines = value; } void set_shunt(int value) { s_shunt = value; } void set_alpha(int value) { s_alpha = value; } +void set_vertical_orientation(bool value) { g_vertical_orientation = value; } void set_queue_screenshot(bool value) { queue_take_screenshot = value; } -void set_fullscreen_scale_nearest(bool value) { g_fs_scale_nearest = value; } +void set_scale_linear(bool value) { g_scale_linear = value; } void set_singe_blend_sprite(bool value) { g_singe_blend_sprite = value; } void set_yuv_video_blank(bool value) { g_yuv_video_needs_blank = value; } -void set_video_timer_blank(bool value) { g_yuv_video_timer_blank = value; } -void set_rotate_degrees(float fDegrees) { g_fRotateDegrees = fDegrees; } +void set_video_blank(bool value) { g_yuv_video_blank = value; } void set_sboverlay_characterset(int value) { sboverlay_characterset = value; } -void set_subtitle_enabled(bool bEnabled) { g_bSubtitleShown = bEnabled; } void set_subtitle_display(char *s) { subchar = strdup(s); } -void set_force_aspect_ratio(bool bEnabled) { g_bForceAspectRatio = bEnabled; } -void set_ignore_aspect_ratio(bool bEnabled) { g_bIgnoreAspectRatio = bEnabled; } +void set_force_aspect_ratio(bool value) { g_bForceAspectRatio = value; } +void set_ignore_aspect_ratio(bool value) { g_bIgnoreAspectRatio = value; } void set_aspect_ratio(int fRatio) { g_aspect_ratio = fRatio; } void set_detected_height(int pHeight) { g_probe_height = pHeight; } void set_detected_width(int pWidth) { g_probe_width = pWidth; } @@ -1196,12 +1132,18 @@ void set_score_bezel_alpha(int8_t value) { g_sb_bezel_alpha = value; } void set_score_bezel_scale(int value) { g_sb_bezel_scale = value; } void set_ace_annun_scale(int value) { g_an_bezel_scale = value; } void set_annun_bezel_alpha(int8_t value) { g_annun_bezel_alpha = value; } -void set_ded_annun_bezel(bool bEnabled) { g_ded_annun_bezel = bEnabled; } +void set_ded_annun_bezel(bool value) { g_ded_annun_bezel = value; } void set_scale_h_shift(int value) { g_scale_h_shift = value; } void set_scale_v_shift(int value) { g_scale_v_shift = value; } void set_scalefactor(int value) { g_scalefactor = value; } void set_score_screen(int value) { g_score_screen = value; } +void set_rotate_degrees(float fDegrees) +{ + g_fRotateDegrees = fDegrees; + if (fDegrees != 0) g_rotated_state = true; +} + void set_score_bezel(bool bEnabled) { if (bEnabled) { @@ -1219,6 +1161,14 @@ void set_annun_bezel(bool bEnabled) g_annun_bezel = bEnabled; } +void set_annun_lamponly(bool bEnabled) +{ + if (bEnabled) { + g_annun_lamps = true; + g_annun_bezel_alpha = 2; + } +} + void set_tq_keyboard(bool bEnabled) { if (bEnabled) { @@ -1281,37 +1231,46 @@ void draw_string(const char *t, int col, int row, SDL_Surface *surface) SDL_Surface *text_surface; - if (g_game->get_use_old_overlay()) dest.x = (short)((col * 6)); + if (g_game->use_old_overlay()) dest.x = (short)((col * 6)); else dest.x = (short)((col * 5)); SDL_FillRect(surface, &dest, 0x00000000); - SDL_Color color={0xe1, 0xe1, 0xe1}; + SDL_Color color={0xf0, 0xf0, 0xf0}; text_surface=TTF_RenderText_Solid(g_ttfont, t, color); SDL_BlitSurface(text_surface, NULL, surface, &dest); SDL_FreeSurface(text_surface); } +void draw_shoot(int col, int row, SDL_Surface *surface) +{ + g_sb_surface = g_other_bmps[B_SHOOT]; + + SDL_Rect dest; + dest.x = (short)(col); + dest.y = (short)(row); + dest.w = (unsigned short) g_sb_surface->w; + dest.h = (unsigned short) g_sb_surface->h; + + SDL_SetColorKey(g_sb_surface, SDL_TRUE, 0x00000000); + SDL_BlitSurface(g_sb_surface, NULL, surface, &dest); +} + void draw_subtitle(char *s, bool insert) { double h = 0.92, w = 0.97; - if (g_keyboard_bezel) { - h = 0.72; - w = 0.86; - } - - int x = (int)(g_draw_width - (g_draw_width * w)); - int y = (int)(g_draw_height * h); + int x = (int)((g_scaling_rect.w) - (g_scaling_rect.w * w)) + g_scaling_rect.x; + int y = (int)(g_scaling_rect.h * h) + g_scaling_rect.y; static int m_message_timer; const int timeout = 200; if (insert) { m_message_timer = 0; - set_subtitle_enabled(true); + g_bSubtitleShown = true; set_subtitle_display(s); } else if (m_message_timer > timeout) { - set_subtitle_enabled(false); + g_bSubtitleShown = false; } FC_Draw(g_font, g_renderer, x, y, s); @@ -1332,27 +1291,35 @@ void draw_LDP1450_overlay() // toggles fullscreen mode void vid_toggle_fullscreen() { - if (!g_fakefullscreen) g_bezel_toggle = false; + if (!SDL_RectEmpty(&g_rotate_rect)) return; + + g_bezel_toggle = false; Uint32 flags = (SDL_GetWindowFlags(g_window) ^ SDL_WINDOW_FULLSCREEN_DESKTOP); if (SDL_SetWindowFullscreen(g_window, flags) < 0) { LOGW << fmt("Toggle fullscreen failed: %s", SDL_GetError()); return; } - if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) { - if (SDL_RectEmpty(&g_logical_rect)) { - SDL_RenderSetLogicalSize(g_renderer, g_viewport_width, g_viewport_height); + if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0 || + (flags & SDL_WINDOW_MAXIMIZED) != 0) { + + if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) { SDL_RenderSetViewport(g_renderer, NULL); SDL_RenderGetViewport(g_renderer, &g_logical_rect); + } else { + g_logical_rect.w = g_displaymode.w; + g_logical_rect.h = g_displaymode.h; } - SDL_RenderSetLogicalSize(g_renderer, g_viewport_width, g_viewport_height); g_fullscreen = true; + format_fullscreen_render(); + notify_stats(g_overlay_width, g_overlay_height, "u"); - if (g_bezel_texture || !SDL_RectEmpty(&g_sb_bezel_rect)) - g_bezel_toggle = true; + if (g_bezel_texture) g_bezel_toggle = true; return; } g_fullscreen = false; + format_window_render(); + notify_stats(g_overlay_width, g_overlay_height, "u"); SDL_SetWindowSize(g_window, g_viewport_width, g_viewport_height); SDL_SetWindowPosition(g_window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); @@ -1360,7 +1327,8 @@ void vid_toggle_fullscreen() void vid_toggle_scanlines() { - char s[16]; + char s[16] = "scanlines off"; + SDL_BlendMode mode; SDL_GetRenderDrawBlendMode(g_renderer, &mode); if (mode != SDL_BLENDMODE_BLEND && !g_scanlines) @@ -1377,7 +1345,7 @@ void vid_toggle_scanlines() } else g_scanlines = true; if (g_scanlines) snprintf(s, sizeof(s), "shunt: %d", s_shunt); - else snprintf(s, sizeof(s), "scanlines off"); + draw_subtitle(s, true); } @@ -1385,6 +1353,7 @@ void vid_scoreboard_switch() { if (!g_sb_window) return; + char s[16] = "screen: 0"; int displays = SDL_GetNumVideoDisplays(); if (displays > 1) { @@ -1395,6 +1364,7 @@ void vid_scoreboard_switch() SDL_GetDisplayBounds(i, &displayDimensions[i]); if (++winId == displays) winId = 0; + snprintf(s, sizeof(s), "screen: %d", (unsigned char)winId); SDL_SetWindowPosition(g_sb_window, displayDimensions[winId].x + sb_window_pos_x, @@ -1402,6 +1372,8 @@ void vid_scoreboard_switch() } else SDL_SetWindowPosition(g_sb_window, sb_window_pos_x, sb_window_pos_y); + + draw_subtitle(s, true); } void vid_setup_yuv_overlay (int width, int height) { @@ -1469,14 +1441,14 @@ int vid_update_yuv_overlay ( uint8_t *Yplane, uint8_t *Uplane, uint8_t *Vplane, // until the mutex is free and we can lock(=get) it here. SDL_LockMutex(g_yuv_surface->mutex); - if (g_yuv_video_timer_blank) { + if (g_yuv_video_blank) { vid_blank_yuv_texture(false); } else if (g_yuv_video_needs_blank) { vid_blank_yuv_texture(false); - set_yuv_video_blank(false); + g_yuv_video_needs_blank = false; } else { @@ -1517,14 +1489,14 @@ void vid_update_overlay_surface (SDL_Surface *tx, int x, int y) { // DBX: 32bit overlay from Singe SDL_SetColorKey (tx, SDL_TRUE, 0x00000000); - SDL_FillRect(g_screen_blitter, NULL, 0x00000000); - SDL_BlitSurface(tx, NULL, g_screen_blitter, NULL); + SDL_FillRect(g_overlay_blitter, NULL, 0x00000000); + SDL_BlitSurface(tx, NULL, g_overlay_blitter, NULL); } else { // MAC: 8bpp to RGBA8888 conversion. Black pixels are considered totally transparent so they become 0x00000000; for (int i = 0; i < (tx->w * tx->h); i++) { - *((uint32_t*)(g_screen_blitter->pixels)+i) = + *((uint32_t*)(g_overlay_blitter->pixels)+i) = (0x00000000 | tx->format->palette->colors[*((uint8_t*)(tx->pixels)+i)].r) << 24 | (0x00000000 | tx->format->palette->colors[*((uint8_t*)(tx->pixels)+i)].g) << 16 | (0x00000000 | tx->format->palette->colors[*((uint8_t*)(tx->pixels)+i)].b) << 8 | @@ -1561,7 +1533,8 @@ void vid_blit () { // create it now. Dimensions were passed to the video object (this) by the vldp object earlier, // using vid_setup_yuv_texture() if (!g_yuv_texture) { - g_yuv_texture = vid_create_yuv_texture(g_yuv_surface->width, g_yuv_surface->height); + g_yuv_texture = vid_create_yuv_texture(g_yuv_surface->width, + g_yuv_surface->height); } SDL_UpdateYUVTexture(g_yuv_texture, NULL, @@ -1575,35 +1548,27 @@ void vid_blit () { // Does OVERLAY texture need update from the scoreboard surface? if (g_scoreboard_needs_update) { - SDL_UpdateTexture(g_overlay_texture, &g_leds_size_rect, - (void *)g_leds_surface->pixels, g_leds_surface->pitch); + SDL_UpdateTexture(g_overlay_texture, &g_blit_size_rect, + (void *)g_blit_surface->pixels, g_blit_surface->pitch); } // Does OVERLAY texture need update from the overlay surface? if (g_overlay_needs_update) { SDL_UpdateTexture(g_overlay_texture, &g_overlay_size_rect, - (void *)g_screen_blitter->pixels, g_screen_blitter->pitch); + (void *)g_overlay_blitter->pixels, g_overlay_blitter->pitch); g_overlay_needs_update = false; } // Sadly, we have to RenderCopy the YUV texture on every blitting strike, because // the image on the renderer gets "dirty" with previous overlay frames on top of the yuv. - if (g_yuv_texture) { - if (!g_scale_view) - SDL_RenderCopy(g_renderer, g_yuv_texture, NULL, NULL); - else - SDL_RenderCopy(g_renderer, g_yuv_texture, NULL, &g_scaling_rect); - } + if (g_yuv_texture) + SDL_RenderCopy(g_renderer, g_yuv_texture, NULL, &g_scaling_rect); // If there's an overlay texture, it means we are using some kind of overlay, // be it LEDs or any other thing, so RenderCopy it to the renderer ON TOP of the YUV video. - if (g_overlay_texture) { - if (!g_scale_view) - SDL_RenderCopy(g_renderer, g_overlay_texture, &g_render_size_rect, NULL); - else + if (g_overlay_texture) SDL_RenderCopy(g_renderer, g_overlay_texture, &g_render_size_rect, &g_scaling_rect); - } if (g_aux_needs_update) { SDL_UpdateTexture(g_aux_texture, &g_annu_rect, @@ -1616,34 +1581,35 @@ void vid_blit () { if (g_LDP1450_overlay) draw_LDP1450_overlay(); if (g_scanlines) - draw_scanlines(g_viewport_width, g_viewport_height, s_shunt); + draw_scanlines(s_shunt); // If there's a subtitle overlay if (g_bSubtitleShown) draw_subtitle(subchar, false); if (g_fRotateDegrees != 0) { + if (!g_rotate) { + int8_t ar = 2; + if (g_aspect_ratio == ASPECTWS && g_overlay_resize) ar--; + SDL_RenderSetLogicalSize(g_renderer, g_viewport_width, g_viewport_height); + g_rotate_rect.w = g_render_size_rect.h + (g_render_size_rect.w >> ar); + g_rotate_rect.h = g_render_size_rect.h; + g_rotate_rect.y = g_render_size_rect.y; + g_rotate_rect.x = 0; + g_bezel_toggle = false; + g_rotate = true; + } + SDL_RenderClear(g_renderer); if (g_yuv_texture) SDL_RenderCopyEx(g_renderer, g_yuv_texture, NULL, NULL, g_fRotateDegrees, NULL, g_flipState); - if (g_overlay_texture) { - if (!g_rotate) { - int8_t ar = 2; - if (g_aspect_ratio == ASPECTWS && g_overlay_resize) ar--; - g_rotate_rect.w = g_render_size_rect.h + (g_render_size_rect.w >> ar); - g_rotate_rect.h = g_render_size_rect.h; - g_rotate_rect.x = g_rotate_rect.y = 0; - g_rotate = true; - } + if (g_overlay_texture) SDL_RenderCopyEx(g_renderer, g_overlay_texture, &g_rotate_rect, NULL, g_fRotateDegrees, NULL, g_flipState); - } } else if (g_game->get_sinden_border()) - if (!g_bezel_texture) draw_border(g_game->get_sinden_border(), g_game->get_sinden_border_color()); if (g_bezel_toggle) { - SDL_RenderSetViewport(g_renderer, NULL); if (g_bezel_texture) { SDL_RenderCopy(g_renderer, g_bezel_texture, NULL, NULL); } @@ -1653,7 +1619,6 @@ void vid_blit () { if (g_sb_bezel) { SDL_RenderCopy(g_renderer, g_sb_texture, NULL, &g_sb_bezel_rect); } - SDL_RenderSetLogicalSize(g_renderer, g_viewport_width, g_viewport_height); } SDL_RenderPresent(g_renderer); @@ -1664,28 +1629,32 @@ void vid_blit () { } if (queue_take_screenshot) { - set_queue_screenshot(false); + queue_take_screenshot = false; take_screenshot(); } } int get_yuv_overlay_width() { - if (g_yuv_surface) { - return g_yuv_surface->width; - } - else return 0; + + if (g_yuv_surface) return g_yuv_surface->width; + return 0; } int get_yuv_overlay_height() { - if (g_yuv_surface) { - return g_yuv_surface->height; - } - else return 0; + + if (g_yuv_surface) return g_yuv_surface->height; + return 0; } bool get_yuv_overlay_ready() { + if (g_yuv_surface && g_yuv_texture) return true; - else return false; + return false; +} + +void set_overlay_offset(int offset) { + + g_render_size_rect.y = abs(offset); } void take_screenshot() @@ -1693,7 +1662,6 @@ void take_screenshot() struct stat info; char filename[64]; int32_t screenshot_num = 0; - bool fullscreen = false; const char dir[12] = "screenshots"; if (stat(dir, &info ) != 0 ) @@ -1701,39 +1669,19 @@ void take_screenshot() else if (!(info.st_mode & S_IFDIR)) { LOGW << fmt("'%s' is not a directory.", dir); return; } - int flags = SDL_GetWindowFlags(g_window); - SDL_Rect screenshot; - SDL_Surface *surface = NULL; + SDL_Surface *screenshot = NULL; - if (flags & SDL_WINDOW_FULLSCREEN_DESKTOP || flags & SDL_WINDOW_MAXIMIZED) - fullscreen = true; + SDL_GetRendererOutputSize(g_renderer, &g_logical_rect.w, &g_logical_rect.h); - if (g_renderer) { + screenshot = SDL_CreateRGBSurface(0, g_logical_rect.w, g_logical_rect.h, 32, 0, 0, 0, 0); - if (fullscreen) - SDL_RenderSetViewport(g_renderer, NULL); - - SDL_RenderGetViewport(g_renderer, &screenshot); - - if (fullscreen) - SDL_GetRendererOutputSize(g_renderer, &screenshot.w, &screenshot.h); - - surface = SDL_CreateRGBSurface(0, screenshot.w, screenshot.h, 32, 0, 0, 0, 0); + if (!screenshot) { LOGE << "Cannot allocate screenshot surface"; return; } - if (!surface) { LOGE << "Cannot allocate surface"; return; } - - if (SDL_RenderReadPixels(g_renderer, &screenshot, surface->format->format, - surface->pixels, surface->pitch) != 0) - { LOGE << fmt("Cannot ReadPixels - Something bad happened: %s", SDL_GetError()); - g_game->set_game_errors(SDL_ERROR_SCREENSHOT); - set_quitflag(); } - } else { - LOGE << "Could not allocate renderer"; - return; - } - - if (fullscreen) - SDL_RenderSetLogicalSize(g_renderer, g_viewport_width, g_viewport_height); + if (SDL_RenderReadPixels(g_renderer, &g_logical_rect, screenshot->format->format, + screenshot->pixels, screenshot->pitch) != 0) + { LOGE << fmt("Cannot ReadPixels - Something bad happened: %s", SDL_GetError()); + g_game->set_game_errors(SDL_ERROR_SCREENSHOT); + set_quitflag(); } for (;;) { screenshot_num++; @@ -1744,32 +1692,142 @@ void take_screenshot() break; } - if (IMG_SavePNG(surface, filename) == 0) { + if (IMG_SavePNG(screenshot, filename) == 0) { LOGI << fmt("Wrote screenshot: %s", filename); } else { LOGE << fmt("Could not write screenshot: %s !!", filename); } - SDL_FreeSurface(surface); + SDL_FreeSurface(screenshot); +} + +void load_fonts() { + + const char *ttfont; + int fs = g_scaling_rect.w / 36; + int ffs = g_aspect_ratio == ASPECTWS ? g_scaling_rect.w / 24 : g_scaling_rect.w / 18; + + FC_FreeFont(g_font); + g_font = FC_CreateFont(); + FC_LoadFont(g_font, g_renderer, "fonts/default.ttf", fs, + FC_MakeColor(0xff, 0xff, 0xff, 0xff), TTF_STYLE_NORMAL); + + FC_FreeFont(g_fixfont); + g_fixfont = FC_CreateFont(); + FC_LoadFont(g_fixfont, g_renderer, "fonts/timewarp.ttf", ffs, + FC_MakeColor(0xff, 0xff, 0xff, 0xff), TTF_STYLE_NORMAL); + + TTF_CloseFont(g_ttfont); + if (g_game->use_old_overlay()) { + ttfont = "fonts/daphne.ttf"; + g_ttfont = TTF_OpenFont(ttfont, 12); + } else { + ttfont = "fonts/digital.ttf"; + g_ttfont = TTF_OpenFont(ttfont, 14); + } + + if (g_ttfont == NULL) { + LOG_ERROR << fmt("Cannot load TTF font: '%s'", (char*)ttfont); + g_game->set_game_errors(SDL_ERROR_FONT); + set_quitflag(); + } } -void draw_scanlines(int w, int h, int l) { +void format_window_render() { + + g_scaling_rect.w = (g_viewport_width * g_scalefactor) / 100; + g_scaling_rect.h = (g_viewport_height * g_scalefactor) / 100; + g_scaling_rect.x = ((g_viewport_width - g_scaling_rect.w) >> 1); + g_scaling_rect.y = ((g_viewport_height - g_scaling_rect.h) >> 1); + + g_scaling_rect.x = (g_scaling_rect.x * g_scale_h_shift) / 100; + g_scaling_rect.y = (g_scaling_rect.y * g_scale_v_shift) / 100; + + g_logical_rect.w = g_scaling_rect.w; + g_logical_rect.h = g_scaling_rect.h; + + load_fonts(); +} + +void format_fullscreen_render() { + + int w, h; + + if (g_vid_resized) { + + w = g_viewport_width; + h = g_viewport_height; + + } else { + + if (g_vertical_orientation) + h = g_logical_rect.w; + else h = g_logical_rect.h; + + switch (g_aspect_ratio) { + case ASPECTWS: + w = (h * 16) / 9; + break; + case ASPECTSD: + w = (h * 4) / 3; + break; + default: + double ratio = (double)g_viewport_width / + (double)g_viewport_height; + w = h * ratio; + break; + } + } + + g_bezel_scalewidth = w; + g_scaling_rect.w = (w * g_scalefactor) / 100; + g_scaling_rect.h = (h * g_scalefactor) / 100; + g_scaling_rect.x = ((g_logical_rect.w - g_scaling_rect.w) >> 1); + g_scaling_rect.y = ((g_logical_rect.h - g_scaling_rect.h) >> 1); + + if (g_keyboard_bezel) + g_scaling_rect.y = g_scaling_rect.y >> 2; + else + { + g_scaling_rect.x = (g_scaling_rect.x * g_scale_h_shift) / 100; + g_scaling_rect.y = (g_scaling_rect.y * g_scale_v_shift) / 100; + } + + if (g_sb_bezel) { + + double ratio = (float)g_sb_h / (float)g_sb_w; + double scale = 9.0f - double((g_sb_bezel_scale << 1) / 10.0f); + + g_sb_bezel_rect.x = sb_window_pos_x; + g_sb_bezel_rect.y = sb_window_pos_y; + g_sb_bezel_rect.w = (g_bezel_scalewidth / scale); + g_sb_bezel_rect.h = (g_sb_bezel_rect.w * ratio); + g_bezel_toggle = true; + } + + load_fonts(); +} + +void draw_scanlines(int l) { SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, s_alpha); - for (int i = 0; i < h; i+=l) { - SDL_RenderDrawLine(g_renderer, 0, i, w, i); + for (int i = 0; i < g_logical_rect.h; i+=l) { + SDL_RenderDrawLine(g_renderer, 0, i, g_logical_rect.w, i); } SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); } -void notify_stats( int overlaywidth, int overlayheight) { +void notify_stats(int overlaywidth, int overlayheight, const char* input) { + + char s[4] = {0}; + if (!g_overlay_resize) snprintf(s, sizeof(s), "[s]"); - LOGI << fmt("Viewport Stats:|w:%dx%d|v:%dx%d|o:%dx%d|l:%dx%d|", + LOGI << fmt("Viewport Stats:|w:%dx%d|v:%dx%d|o:%dx%d%s|l:%dx%d|%s", g_viewport_width, g_viewport_height, g_probe_width, - g_probe_height, overlaywidth, overlayheight, - g_logical_rect.w, g_logical_rect.h); + g_probe_height, overlaywidth, overlayheight, s, + g_logical_rect.w, g_logical_rect.h, input); } void draw_border(int s, int c) { @@ -1795,13 +1853,13 @@ void draw_border(int s, int c) { SDL_SetRenderDrawColor(g_renderer, r, g, b, SDL_ALPHA_OPAQUE); - tb.x = lb.x = bb.x = 0; - tb.y = lb.y = rb.y = 0; - rb.x = g_viewport_width - s; - bb.y = g_viewport_height - s; - tb.w = bb.w = g_viewport_width; + tb.x = lb.x = bb.x = g_scaling_rect.x; + tb.y = lb.y = rb.y = g_scaling_rect.y; + rb.x = (g_scaling_rect.w + g_scaling_rect.x) - s; + bb.y = (g_scaling_rect.h - s) + g_scaling_rect.y; + tb.w = bb.w = g_scaling_rect.w; tb.h = bb.h = lb.w = rb.w = s; - lb.h = rb.h = g_viewport_height; + lb.h = rb.h = g_scaling_rect.h; SDL_RenderFillRect(g_renderer, &tb); SDL_RenderFillRect(g_renderer, &lb); @@ -1809,27 +1867,6 @@ void draw_border(int s, int c) { SDL_RenderFillRect(g_renderer, &bb); SDL_SetRenderDrawColor(g_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE); - - if (s < 0x0f) { - - unsigned char i = 0x01; - if (s <= 0x02) i = 0x04; - else if (s <= 0x08) i = 0x02; - - SDL_Rect tib, lib, rib, bib; - tib.x = lib.x = bib.x = s; - tib.y = lib.y = rib.y = s; - rib.x = ((g_viewport_width - s) - i); - bib.y = ((g_viewport_height - s) - i); - tib.h = bib.h = lib.w = rib.w = i; - tib.w = bib.w = g_viewport_width - (s<<1); - lib.h = rib.h = g_viewport_height - (s<<1); - - SDL_RenderFillRect(g_renderer, &tib); - SDL_RenderFillRect(g_renderer, &lib); - SDL_RenderFillRect(g_renderer, &rib); - SDL_RenderFillRect(g_renderer, &bib); - } } } diff --git a/src/video/video.h b/src/video/video.h index 70fcfd56..8ee14b03 100644 --- a/src/video/video.h +++ b/src/video/video.h @@ -86,6 +86,7 @@ enum { B_ACE_OFF, B_CAPTAIN_OFF, B_CADET_OFF, + B_SHOOT, B_EMPTY }; // bitmaps @@ -140,13 +141,13 @@ SDL_Texture *get_yuv_screen(); SDL_Surface *get_screen_blitter(); SDL_Surface *get_screen_leds(); FC_Font *get_font(); +bool use_old_font(); bool get_opengl(); bool get_vulkan(); -bool get_fullscreen(); -bool get_use_old_osd(); bool get_singe_blend_sprite(); -bool get_video_timer_blank(); +bool get_video_blank(); bool get_video_resized(); +bool get_rotated_state(); void set_opengl(bool value); void set_vulkan(bool value); int get_textureaccess(); @@ -156,14 +157,14 @@ void set_vsync(bool value); void set_yuv_blue(bool value); void set_fullscreen(bool value); void set_fakefullscreen(bool value); -void set_fullscreen_scale_nearest(bool value); +void set_scale_linear(bool value); void set_force_aspect_ratio(bool bEnabled); void set_ignore_aspect_ratio(bool bEnabled); void set_scanlines(bool value); void set_shunt(int value); void set_alpha(int value); void set_yuv_video_blank(bool value); -void set_video_timer_blank(bool value); +void set_video_blank(bool value); int get_scalefactor(); // by RDG2010 void set_scalefactor(int value); // by RDG2010 void set_rotate_degrees(float fDegrees); @@ -172,9 +173,10 @@ Uint16 get_video_width(); void set_video_width(Uint16); Uint16 get_video_height(); void set_video_height(Uint16); -void draw_scanlines(int, int, int); +void draw_scanlines(int); void draw_border(int, int); void draw_string(const char *, int, int, SDL_Surface *); +void draw_shoot(int, int, SDL_Surface *); void draw_subtitle(char *, bool ins); void draw_LDP1450_overlay(); void vid_toggle_fullscreen(); @@ -183,7 +185,6 @@ void vid_scoreboard_switch(); void set_aspect_ratio(int fRatio); void set_detected_height(int pHeight); void set_detected_width(int pWidth); -void set_subtitle_enabled(bool bEnabled); void set_subtitle_display(char *); void set_LDP1450_enabled(bool bEnabled); void set_singe_blend_sprite(bool bEnabled); @@ -196,6 +197,7 @@ void set_score_bezel_alpha(int8_t value); void set_score_bezel_scale(int value); void set_ace_annun_scale(int value); void set_tq_keyboard(bool bEnabled); +void set_annun_lamponly(bool bEnabled); void set_annun_bezel(bool bEnabled); void set_ded_annun_bezel(bool bEnabled); void set_annun_bezel_alpha(int8_t value); @@ -203,6 +205,10 @@ void set_scale_h_shift(int value); void set_scale_v_shift(int value); void set_score_screen(int value); +void set_vertical_orientation(bool); +void format_fullscreen_render(); +void format_window_render(); + bool draw_ranks(); bool draw_annunciator(int which); bool draw_annunciator1(int which); @@ -211,14 +217,15 @@ bool draw_annunciator2(int which); void take_screenshot(); void set_queue_screenshot(bool bEnabled); -unsigned int get_draw_width(); -unsigned int get_draw_height(); +unsigned int get_logical_width(); +unsigned int get_logical_height(); +void set_overlay_offset(int offset); int get_yuv_overlay_width(); int get_yuv_overlay_height(); void reset_yuv_overlay(); -void notify_stats(int width, int height); +void notify_stats(int width, int height, const char*); bool get_yuv_overlay_ready(); diff --git a/win32/README.md b/win32/README.md index 0935b279..e1a01614 100644 --- a/win32/README.md +++ b/win32/README.md @@ -9,7 +9,7 @@ Latest build is: (_32bit_ and _64bit_ versions are available.) hypseus.exe -v - [version] Hypseus Singe: v2.10.4 + [version] Hypseus Singe: v2.11.1 [console] Windows 10 [console] SDL(CC): 2.0.14 [console] SDL(LD): 2.0.16