1990 Commits
Author SHA1 Message Date
Flyinghead 8108e63907 rcheevos: race condition in event handlers and async tasks
The data passed to event handlers (achievements in particular) must be
copied if used by an async task. It might be deleted before the async
task runs.
Fixes MINIDUMP-3ZR MINIDUMP-4XJ MINIDUMP-4TB MINIDUMP-4CA MINIDUMP-38H
2024-10-21 16:13:00 +02:00
Flyinghead b0403ed103 imgui: ignore invalid fonts when merging
Avoid crashing in release mode if a merged font is invalid or FontNo
can't be found. The font is simply ignored and the glyph range isn't
loaded.
Fixes MINIDUMP-4TD
2024-10-21 16:03:28 +02:00
Flyinghead c86ed291cf picotcp: use dns.flyca.st as default dns
Use dns.flyca.st as default dns.
Resolve name when pico network starts.
2024-10-19 17:59:24 +02:00
Flyinghead d981c48a75 libretro: fix translations 2024-10-19 12:47:26 +02:00
github-actions[bot] 82925c4e81 Fetch translations & Recreate libretro_core_options_intl.h 2024-10-18 22:20:39 +00:00
Flyinghead 54e8589f63 android: disable import/export home when SAF is disabled. Code clean up
Disable import/export home folder buttons when not using SAF file
picker.
Get rid of unused home migration feature when onboarding.
Android TV screenshots and banner.
2024-10-18 19:23:03 +02:00
Flyinghead 4750ddb646 android: new option to use legacy file picker instead of new SAF one
Android 9 and earlier can use the legacy file browser. This fixes issues
with broken SAF file picker on Android TV 9.
Catch exception when no file picker is installed on the device (Android
TV 12) and instruct the user to install one.
Issue #1657
2024-10-17 16:21:06 +02:00
Flyinghead 894ac54b80 imgui: fix dpad navigation issue on shield tv
Pressing dpad up or down moves the selection 2 lines up or down resp.
Regression due to ca613db70d.
Happens on 1920x1080 screen with 213 dpi.
Relax vertically touching items test.
2024-10-17 16:04:27 +02:00
Flyinghead d4a223656f enable RTT Copy to VRAM for Silent Scope
Fixes VMU display
Issue #1703
2024-10-17 16:00:46 +02:00
Flyinghead b698cc3d10 dx11: reset device context state to fix libretro shaders
Reset device context before each render. Rebind palette and fog textures
every frame.
Fixes corruption with libretro shaders.
Issue #1612
2024-10-15 17:28:54 +02:00
Flyinghead 75af269bb8 rend: ignore inside clipping if rect is default value
Fixes invisible race start countdown in f355 (arcade).
Issue #1698
2024-10-15 15:55:34 +02:00
Flyinghead fd475bdd8e vk: some pipelines don't need the provoking vertex extension
ModVol and OIT Final and Clear pipelines don't need it.
2024-10-14 17:19:41 +02:00
Flyinghead f71dd6d4d8 cdi: better detection of invalid CDI media 2024-10-14 16:45:22 +02:00
Flyinghead 5aec6d05b0 vk: (lr) use one vk::DeviceQueueCreateInfo when possible
Using 2 with the same queue index causes a validation error and crash.
2024-10-14 16:39:33 +02:00
Flyinghead b4937ef271 f355: pass full BIOS path to slaves
if the bios file is located relative to the rom location, slaves won't
be able to find it. Pass the full bios path to avoid the issue.
2024-10-14 16:31:23 +02:00
Flyinghead a50164a91b vk: missing some changes to use VK_FORMAT_R8G8B8A8_UNORM
Fixes Naomi 2 games and android on-screen gamepad.
2024-10-13 14:22:50 +02:00
Wunkolo 595842f606 vk: Remove naomi2 vertex attributes when not needed
Disables the naomi2 vertex input attribute when emitting non-naomi2 pipelines.
This addresses some validation messages involving unused vertex inputs and optimizes the bandwidth of the input assembler a little bit for non-naomi2 games.
2024-10-13 13:26:42 +02:00
Wunkolo 8f74f7883a vk: Use VK_FORMAT_R8G8B8A8_UNORM for vertex colors
Rather than using `VK_FORMAT_R8G8B8A8_UINT` for these vertex attributes and then dividing by `255.0` in each of the shaders, the `VK_FORMAT_R8G8B8A8_UNORM` format will automatically remap byte components into the `0.0-1.0` range and removes the need to do the extra divisions or castings within the shader.
2024-10-13 13:25:40 +02:00
scribam 71dc4c3e39 ci: disable android signing on pull requests 2024-10-13 13:25:02 +02:00
scribam 6edad8eaba android: update gradle and agp 2024-10-13 13:25:02 +02:00
Wunkolo ea1cd9d31b vk: Fix undefined push-constant data
The full push-constant region is 24 bytes(6 floats), but some of these push-constant writes only wrote 20 bytes of data(5 floats).
Causing 4 bytes at the end to be left undefined.
Resolved by pushing an extra zero.
2024-10-13 13:24:27 +02:00
Flyinghead bb7ad07701 extra depth scale for sturmwind
Issue #1691
2024-10-12 17:35:59 +02:00
Flyinghead 9793e54646 avoid deadlock when sh4 cpu is restarted while emu is being stopped
The sh4 cpu is stopped/restarted during a soft reset, and dynarec code
reset (arm64, arm, x86). If the emulator is stopped concurrently, the
call may hang. Use a mutex-protected method to restart the cpu only if
the emu is still running.
2024-10-12 17:31:58 +02:00
Flyinghead 6d2ed417be lr: fix core options to work around translation issue
Adjacent string literals aren't supported.
Fix syntax errors in libretro_core_options_intl.h
Issue #1688
2024-10-12 11:49:12 +02:00
github-actions[bot] d3916f13d7 Fetch translations & Recreate libretro_core_options_intl.h 2024-10-11 22:20:30 +00:00
Flyinghead b2c6159b10 Merge remote-tracking branch 'origin/dev' 2024-10-11 15:28:19 +02:00
Wunk 4d73cc8e13 vk: Add VK_EXT_provoking_vertex optimization (#1681)
* vk: Add `VK_EXT_provoking_vertex` optimization

The dreamcast uses the last vertex as the provoking vertex, while vulkan uses the first vertex.
This requires an additional call to `setFirstProvokingVertex` to reorder the vertices for all incoming geometry.
With `VK_EXT_provoking_vertex`, the pipeline can designate that the provoking vertex is to be the last vertex, which removes the need to re-order incoming geometry on the CPU.

* vk: Propagate physical device API version to VMA

Allows VMA to make assumptions such as using the `*KHR` or non-`KHR` versions of certain function names.

* vk: Refactor libretro device initialization for `VK_EXT_provoking_vertex`

* vk: Top out at vulkan API version to VMA to 1.1

Despite the physical device possibly being 1.2 or 1.3, we only want up to 1.1. Otherwise we will be responsible for other API functions being resolved and loaded when passing to VMA.

* vk: Enable `VK_EXT_provoking_vertex` usage for ModVol and Final(OIT) pipeline

* vk: Enable `VK_EXT_provoking_vertex` for ModVol(OIT) pipeline

Pretty much anything handling dreamcast-geometry should use this extension when available

* vk: Additional `VK_EXT_provoking_vertex` pipeline fixes
2024-10-11 10:23:48 +02:00
Wunkolo 5b343562b9 vk: Add CommandBufferDebugScope utility-type
Adds a new RAII-based utility type for adding diagnostic information to command buffers.
Enabled only when `VK_DEBUG` is set to `1`.
2024-10-09 19:47:14 +02:00
Wunkandflyinghead b20db6a8bb vk: Disable LOD clamping in samplers (#1674)
This addresses the `BestPractices-Arm-vkCreateSampler-lod-clamping` message from ARM:
https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/65b79bac615ec1c47ab61a02d55a3bba871b56b9/layers/best_practices/bp_descriptor.cpp#L103-L110

Rather than clamping the LOD in the samplers, instead rely on the Image-View's `vk::ImageSubresourceRange` to limit the number of sampled LODs.

Currently, only game-textures actually have MipMaps, so this does not introduce any additional mip-map sampling or filtering anywhere. If any code want's to actually limit the number of LODs sampled, then they would allocate an additional ImageView for the range of MipMaps to be sampled.

Co-authored-by: flyinghead <[email protected]>
2024-10-09 19:46:36 +02:00
Wunkolo a8bc1c12f4 vk: Optimize redundant QuadBuffer uploads
Hashes the contents of the `QuadBuffer` vertex-data such that data is only uploaded when the vertices actually change rather than every frame.
2024-10-09 19:40:59 +02:00
Wunkolo b94acb70a6 vk: Use matching u/v/w sampler address-mode when possible
This addresses the `BestPractices-Arm-vkCreateSampler-different-wrapping-modes` message from ARM:
https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/65b79bac615ec1c47ab61a02d55a3bba871b56b9/layers/best_practices/bp_descriptor.cpp#L95-L100

The `W`-axis for these samplers is always unused, it's never the case that these samplers are going to be used for 3D textures.
ARM suggests trying to keep all of the wrapping-modes the same if possible for performance.

`wRepeat` will be set to the same value as `vRepeat` to try and encourage all three wrapping-modes to be the same.
2024-10-09 19:40:20 +02:00
Wunkolo 0c3f5c7a76 vk: Refactor device/instance extension enablement
* Uses a utility-lambda for repeated extension-adding logic
* Uses an `std::set` for the list of available extensions for quick queries
* `VK_EXT_DEBUG_REPORT` and `VK_EXT_DEBUG_UTILS` aren't device extensions and don't need to be here. They are instance extensions
* Each extension that is tested to be added has a corresponding log message for if it was enabled or if it was unavailable

```
00:00:162 rend\vulkan\vulkan_context.cpp:427 N[RENDERER]: Device extension enabled: VK_KHR_swapchain
00:00:162 rend\vulkan\vulkan_context.cpp:427 N[RENDERER]: Device extension enabled: VK_KHR_get_memory_requirements2
00:00:162 rend\vulkan\vulkan_context.cpp:427 N[RENDERER]: Device extension enabled: VK_KHR_dedicated_allocation
00:00:162 rend\vulkan\vulkan_context.cpp:430 N[RENDERER]: Device extension unavailable: VK_KHR_portability_subset
00:00:162 rend\vulkan\vulkan_context.cpp:430 N[RENDERER]: Device extension unavailable: VK_EXT_debug_marker
```
2024-10-09 19:39:49 +02:00
Flyinghead 03d20f9d5a bug report: ask for flycast version instead of github hash 2024-10-09 19:39:04 +02:00
Flyinghead 01e5cd882c pvr: fix default clipping rectangle
Set default clipping rectangle to max (1280x480).
Fixes Irides: Master of blocks bogus clipping to tile 0,0.
2024-10-09 19:37:42 +02:00
Wunk 556e2ead56 vk: Refactor physical device selection (#1671)
Rather than electing the first physical device it finds, and falling back on the first-listed GPU: a series of stable-partitions are done so that the "least compromising" GPU is selected based on a series of criteria.

It will now maximally try to find a GPU that(in order of priority):
* Is a discrete GPU
* Supports `fragmentStoresAndAtomics`
* Supports `R5G5B5`/`R5G6B5A1`/`R4G4B4A4`

In the case that a system has two dGPUs and one of them supports optimal-formats, the optimal-format one is selected

In the case that a system has an iGPU and the dGPU and they both support optimal formats, the dGPU is selected.

In the case that a system has an iGPU and the dGPU and the dGPU doesn't support optimal formats, the dGPU is still selected.
2024-10-08 17:07:09 +02:00
Wunkolo ff6a3119b0 vk: Determine object type enum when setting object name
Uses compile-time type-information provided by vulkan-hpp to automatically determine a vulkan-object's `objectType` when calling `setObjectName`.
2024-10-08 17:05:32 +02:00
Wunkolo 86657c0c12 Fix {Push,Pop}StyleVar assert
When entering an error or contentpath warning popup, there are two `ImguiStyleVar` on the stack.
Within the pop-up frame, an additional `ImguiStyleVar` is added.
When the popup ends, there is technically one more ImguiStyleVar on the internal stack than when we entered the popup, causing an assert to hit:

```
Program: G:\flycast\out\build\x64-Debug\flycast.exe
File: G:\flycast\core\deps\imgui\imgui.cpp
Line: 10104

Expression: SizeOfStyleVarStack >= g.StyleVarStack.Size && "PushStyleVar/PopStyleVar Mismatch!"
```

These nested imgui RAII objects need to be scoped such that the stack is preserved both upon entry and exit of these popups to avoid these asserts.
2024-10-08 17:05:03 +02:00
Flyinghead d7c168f406 naomi: copy cart dma data in chunks
Copy cart dma data in 1K chunks to avoid transferring all in one shot.
Fixes Soul Surfer and Beach Spiker audio glitches when playing a sample
before it's completely transferred.
Issue #1513
2024-10-08 17:03:00 +02:00
Flyinghead f37e43b26f vk: don't set scissoring in final OIT subpass
If scissoring is enabled, previous framebuffer background isn't drawn
outside of scissor region.
Fixes blinking in Soul Calibur battle loading screen.
Issue #1668
2024-10-08 11:49:34 +02:00
Flyinghead e427c4d5c4 lr: don't set IntOption if overridden
Fixes OIT Max Layers overrides being ignored.
Issue #1610
2024-10-08 11:39:49 +02:00
Wunkolo 56fe3b9c9d Fix arm64_unwind.h include-order
`sh4_core.h` has defines for symbols like `r` and `pr` which conflict with the variable names in `arm64_unwind.h` and cause even deeper errors over in `wingdi.h(4954)` and `wincrypt.h(4741)`.

Swapping the include order avoids this collision.
2024-10-07 18:48:26 +02:00
Flyinghead 30bb864b37 vulkan: check image usage flags if image already exists during RTT
Recreate image if usage flags are incorrect.
Fixes vk validation error in Virtua Tennis player list selection screen.
Issue #1664
2024-10-07 18:47:52 +02:00
nbFlyinghead d689c50e21 naomi: increase dma xfer rate except for force five
Revert 54ac9c6361 but make an exception
for force five. Issue #141
Fixes loud music in beach spikers and soul surfers. Issue #1513
Fixes some menu textures not being loaded in F355.
2024-10-05 13:30:36 +02:00
Flyinghead efd71b3a44 Storage::getParentPath can throw 2024-10-04 16:51:08 +02:00
Flyinghead 5450646b5c android: add virtual gamepad transparency setting
Issue #384
2024-10-04 16:45:28 +02:00
Flyinghead 55e0211a57 android: use ASS to select custom adreno driver 2024-10-04 16:36:56 +02:00
Flyinghead 5d719e0b49 rend: unexpected conversion to unsigned for VO_STARTX/Y with msvc
MSVC converts VO_STARTX and VO_STARTY bit-field values to unsigned int,
leading to an overflow when the result is negative.
Issue #1606
2024-10-03 18:03:55 +02:00
Flyinghead e10a9929da Set OIT max layers for more games
Issue #1610
2024-10-03 17:56:30 +02:00
scribam 3d41e4ea3e deps: update sdl to version 2.30.8 2024-10-02 19:50:37 +02:00
Flyinghead 2dd4cbe33d vk oit: draw transparent polys in the first frame after (re)init
Fixes missing background in progress window in Fighting Force 2
Issue #1652
2024-09-29 16:42:38 +02:00
Flyinghead 2653c5ed73 naomi2: fix modifier volumes clipping
Don't clip modifier volumes but tesselate triangles intersecting the
near plane. Then project clipped vertices onto it in the vertex shader.
Issue #1651
2024-09-29 16:42:38 +02:00
github-actions[bot] 343021a8c5 Fetch translations & Recreate libretro_core_options_intl.h 2024-09-27 22:20:38 +00:00
flyinghead 7907100b9c dx11: wrong texture returned to libretro in some cases
If a render to texture happens before presenting the current frame,
another texture will be bound to shader slot #0 and will be returned to
the libretro frontend.
Issue #1616 and #1619
2024-09-25 21:57:15 +02:00
Flyinghead f179c00bdd gl: fix Delay Frame Swapping pacing issue on android
Partial revert of c83b0e325f.
Fix root issue in OpenGLRenderer::DrawOSD.
2024-09-24 14:50:41 +02:00
Flyinghead c83b0e325f android: fix Delay Frame Swapping sync issue. ANR in single-threaded
Framebuffer swap should only be called when a new frame has been
rendered.
ANR when stopping the emulator in single-threaded mode: race condition
causes stopRequested to not be handled, and Pause event is never sent.
2024-09-24 11:54:15 +02:00
Flyinghead 210e8ca6e3 android: get rid of ouya sdk 2024-09-23 20:46:33 +02:00
Flyinghead a46dc71156 android: target android 14 / sdk 34 2024-09-23 18:01:21 +02:00
Flyinghead 4baf529ff7 race condition when stopping emu thread right after start
In threaded rendering, CpuRunning is set after the emu thread is
started. If calling Emulator::stop() before it is set, the call will
hang.
2024-09-23 17:43:23 +02:00
Flyinghead 63ef3aaab4 android: avoid crash when app is run in restricted mode
App may be run in restricted mode, where the Application object is a
generic android.app.Application. Disallow backup to avoid this. If
Application object isn't of the expected type, restart the app.
2024-09-23 17:21:02 +02:00
Flyinghead abe71409b5 android: race condition with render thread. ANR with auto save state
Race condition when starting then stopping the render thread:
mainui_enabled isn't set until after the thread has started. If stopped
during that time, it will hang.
Auto save state in a background thread to avoid ANR.
2024-09-23 17:17:46 +02:00
Flyinghead f8c12d2835 android: fix getFileInfo for document uri. cheats: limit file size
android: Fix AndroidStorage.getFileInfo for document uri (cheat file)
cheats: limit cheat file size to 1MB to avoid parsing garbage forever. Save file path only if valid.
2024-09-23 17:08:57 +02:00
github-actions[bot] 92555c68c6 Fetch translations & Recreate libretro_core_options_intl.h 2024-09-20 22:20:53 +00:00
Flyinghead 915532f946 vk: don't depend on current clamping values when compiling shader
Fog clamping values may change so the shader shouldn't depend on the
current value when compiling.
Fixes Red Dog Superior Firepower glitch.
Issue #1642
2024-09-18 11:34:35 +02:00
Flyinghead 079180faab Force PAL for Snow Surfer. Increase Max Layers for some games.
Force PAL broadcast for Snow Surfer.
Issue #1643
Increase max layers for Soldier of Fortune, BANG! Gunship Elite and MDK
2.
Issue #1610
2024-09-18 11:30:46 +02:00
Flyinghead 38de2868a0 sgdrvsim: axis 0 is master audio volume, not wheel
Use (unused) axis 4 instead. Wheel position is read with the ffb drive
board, not JVS.
Map clutch to left trigger 2.
Issue #1636
2024-09-16 18:26:13 +02:00
Flyinghead 0e97f97bb7 android: virtual gamepad rumble power wasn't set at app startup
Make sure emu.cfg is loaded before setting rumble power.
Issue #1640
2024-09-16 11:28:25 +02:00
Flyinghead 64d7199107 Merge remote-tracking branch 'origin/master' into dev 2024-09-16 11:16:04 +02:00
scribam 0077b8ecec deps: update sdl to version 2.30.7 2024-09-08 16:24:37 +02:00
Flyinghead 5393235c40 aica: skip remaining step functions when channel is disabled
CA is reset to 0 when channel is disabled due to AEG and this value must
not be changed.
Issue #472 and #1180
2024-09-07 14:55:45 +02:00
Flyinghead a81a02f14b maple: save rfid card after decrementing counter
Issue #1626
2024-09-07 14:50:29 +02:00
github-actions[bot] 480f93e50d Fetch translations & Recreate libretro_core_options_intl.h 2024-09-06 22:21:05 +00:00
Flyinghead 7174ef1194 naomi: full rfid chip emulation for mushiking series
Fixes hang after playing 3 games.
Issue #1626
2024-09-04 09:48:34 +02:00
Flyinghead f039a809da naomi: limit max analog values to avoid overflow
Fixes overflow in wild riders when going full right or full accel/brake.
Follow up to Issue #1627
2024-09-02 17:04:17 +02:00
Flyinghead 1223154665 jvs: fix analog axes values encoding
The least significant byte of analog axis values seems to be handled as
signed.
Fixes crazy taxi going right when turning full left.
Issue #1627
2024-09-01 18:41:37 +02:00
Flyinghead 8cb847940b vk oit: attachment 0 must be loaded too
Issue #1614
2024-09-01 18:41:37 +02:00
github-actions[bot] 9691fe9622 Fetch translations & Recreate libretro_core_options_intl.h 2024-08-30 22:20:34 +00:00
Flyinghead c575eac89b naomi: add mushik4t rom 2024-08-30 17:49:07 +02:00
Flyinghead b468c9bdae aica: reset CA to 0 when disabling channel due to AEG
CA was reset to 0 for non-looping sound when ending, but not for looping
ones when they reach full attenuation. This confuses some games.
Disable the channel when it reaches full attenuation and reset CA to 0.
Revert a7702c622a
Issue #1602
Better fix for
Issues #472, #483, #1180, #1249, #1030 (partial)
2024-08-29 13:09:39 +02:00
Flyinghead 368bd17ae0 vk: use swap_chain_size + 1 semaphores
Fixes validation error VUID-vkAcquireNextImageKHR-semaphore-01779
introduced in vulkan sdk 1.3.275
Issue #1620
2024-08-29 13:01:11 +02:00
Flyinghead 757732d0f8 vk oit: load correct attachment. Only reset pipelines when needed
Fixes partial renders: ECCO initial sequence.
Issue #1614
Don't reset pipelines when resizing framebuffer.
2024-08-29 12:57:10 +02:00
Flyinghead 0ff9caf656 ci: make breakpad optional on all platforms
Issue #739
2024-08-29 12:06:29 +02:00
Flyinghead a93bd9e64e Merge remote-tracking branch 'origin/playstore' into dev 2024-08-24 18:08:59 +02:00
Flyinghead 308d9fc1ac Increase max transparent layers for some games
Issue #1604
Add 96 layers option to libretro core.
Issue #1610
2024-08-24 16:49:16 +02:00
Flyinghead 7a27a43ba4 vulkan: Fix multipass RTT in OIT mode
Use correct temp attachment depending on pass count. Keep attachment
index to bind the correct one before final subpass.
Use correct initial layout for OP+PT attachment 1 (was eUndefined) when
creating the RTT render pass.
Fixes Alone in the Dark cutscenes.
Issue #1609

Recreate RTT attachments if switching CopyToVRAM on/off.
2024-08-24 16:37:52 +02:00
Flyinghead 244bb724c9 naomi: add FFB support for Tokyo Bus Guide
Only rumble seems to be used.
Issue #1601

Add info about awave BIOS
2024-08-24 16:29:29 +02:00
github-actions[bot] 349083030d Fetch translations & Recreate libretro_core_options_intl.h 2024-08-23 22:20:21 +00:00
Flyinghead b99b3450c8 sh4: compute fsrra as 1/sqrt(x) instead of sqrt(1/x)
Fixes invisible chaos emerald in Sonic Adventure cutscene after Emerald
Coast.
Partial revert of ec3ad9b.
Issue #1600
2024-08-20 21:12:05 +02:00
Flyinghead 6061d402bd build fix 2024-08-17 18:08:53 +02:00
Flyinghead 4d06743d9a gdrom: don't crash on unsupported sector size
Fixes MINIDUMP-284
2024-08-17 17:56:35 +02:00
Flyinghead af7353225b pvr: rgb888 needs to be correctly aligned when xclip.min != 0
Fixes glitchy combat opening animation in soul calibur (with full
framebuffer emulation). Use slower but correct method instead.
Issue #1591
2024-08-17 17:29:32 +02:00
Flyinghead cb0b667129 maple: don't assert dma interrupt if using hardware dma trigger
Fixes Virtua Cop 2 pause when shooting. Regression due to ecce915
Issue #474
2024-08-17 17:23:34 +02:00
Flyinghead 00f60a3d62 win32: don't compile clock.c with clang
Issue #1588
2024-08-17 17:08:40 +02:00
github-actions[bot] 5565b79b9e Fetch translations & Recreate libretro_core_options_intl.h 2024-08-16 22:20:19 +00:00
Flyinghead 8ea12443d3 android: fix touchscreen coords when view is scaled
Samsung phones/tablets can scale down the emulator view to improve
performance. In this case, getPointerCoords() returns screen, not view
coordinates. Use MotionEvent.getX/Y() instead.
2024-08-16 13:12:27 +02:00
Flyinghead 6679cb2f31 android: show/hide keyboard in main thread to avoid deadlock
Tentative fix for deadlock when main thread is calling
JNIdc.rendinitNative(null), and render thread is blocked on a lock
trying to hide on-screen keyboard.
2024-08-16 10:17:06 +02:00
Flyinghead f1fd8b12e2 android: do all rumble/haptic on background thread
Haptic effects for the virtual gamepad must be done on a background
thread. Not sure about gamepad rumble but it shouldn't hurt.
Reuse haptic duration for haptic power (0-100).
Fix crash when power is zero (createOneShot needs power >= 1)
2024-08-15 17:25:02 +02:00
Flyinghead ecb468a723 msvc build fix 2024-08-15 13:05:02 +02:00
Flyinghead fbe7cc8fe3 input: crash when setting the keyboard to port None
Issue #1593
2024-08-15 12:28:22 +02:00
Flyinghead aafa9f0bf0 android: intent url ignored unless external storage legacy is enabled
Issue #1584

Accept fileDir (internal storage) as home folder in case it was created
without external storage.
2024-08-15 12:09:27 +02:00
Flyinghead dae3676979 android: NPE in NativeGLView when Emulator.currentActivity is null 2024-08-15 11:58:45 +02:00
Flyinghead 09ab139407 android: deadlock when Emulator::checkStatus is called concurrently
If checkStatus(wait = true) is called, any other thread will be blocked
even when calling with wait = false since the mutex is locked. This
happens on Android when JNIdc.rendinitNative(null) is called by the app
main thread.
Use a shared_future instead and unlock the mutex before waiting.
2024-08-15 11:55:07 +02:00
Flyinghead 138adc28d7 android: ANR when loading cheat file 2024-08-13 17:41:40 +02:00
Flyinghead 9fd80b952a Storage::getSubPath can throw if path doesn't exist (android) 2024-08-13 17:38:23 +02:00
Flyinghead a058481e36 oboe: log record stream buffer capacity, not output stream
Fixes MINIDUMP-43E
2024-08-13 17:18:31 +02:00
scribam 45bf218df4 ci: bump actions/setup-python to v5 2024-07-29 16:45:12 +02:00
scribam 6b3e86619e deps: fix libzip compilation error with gcc 14.1 2024-07-28 20:02:34 +02:00
scribam 56b8bb1245 vk: cleanup
* Use constants for extension names
* Prefer VK_USE_PLATFORM_* constants
* Remove IOS_MVK/MACOS_MVK deprecated code
2024-07-28 20:02:34 +02:00
scribam cea80560db deps: update submodules
* discord-rpc: use upstream repository
* googletest: v1.15.0
* libchdr: master
* oboe: v1.9.0
* rcheevos: v11.5.0
2024-07-28 20:02:34 +02:00
scribam 088c1e6b0d unit: build fix for apple platform when ctest is enabled 2024-07-28 20:02:34 +02:00
scribam bb048dea8f ci: use default xcode version
Currently, it is Xcode 15.4
2024-07-28 20:02:34 +02:00
scribam 588dca2bfd cmake: cleanup
* Set min macos deployment version to 10.13. This is the lowest version supported by Xcode 14.3.1 and 15+
* Prefer target_compile_options to add compilation flags
* Simplify macos custom commands with TARGET_FILE and TARGET_FILE_DIR
* Do not install discord-rpc and libzip files
2024-07-28 20:02:34 +02:00
github-actions[bot] 3afa4322f1 Fetch translations & Recreate libretro_core_options_intl.h 2024-07-26 22:20:39 +00:00
Flyinghead 33d1dafdb7 android: revert changesNotSentForReview param change
Probably due to the current weather conditions at google's HQ
2024-07-20 10:58:26 +02:00
Flyinghead 8b2c1bc5dc android: bug fixes
onInputDeviceAdded may be called with an invalid device id. Avoid NPE
onGenericMotionEvent: event may have a null device. Avoid NPE
getExternalFilesDir may return null if no external storage available.
Use getFilesDir in this case.
Catch exceptions in HomeMover and continue.
addStorage: catch SecurityException and alert user. Graceful failure.
2024-07-20 10:30:27 +02:00
Flyinghead 2b83df86cd boxart: don't save database when pausing (android, uwp)
Avoids ANR on android. Unnecessary since database is now saved
regularly.
2024-07-20 10:07:18 +02:00
github-actions[bot] 0b6b8b3753 Fetch translations & Recreate libretro_core_options_intl.h 2024-07-19 22:21:06 +00:00
Flyinghead 53d092c326 naomi: set SB_GDSTARD and SB_GDLEND when starting dma
Fixes toukon4 fmv freeze
Issue #1582
2024-07-17 10:05:58 +02:00
flyinghead bfba850ee7 Google Play install link 2024-07-16 09:49:29 +02:00
scribam db5a4d1247 ci: add lua54 for freebsd and netbsd 2024-07-14 10:32:33 +02:00
scribam 3ad00596a1 ci: use freebsd 14.1 2024-07-14 10:32:33 +02:00
Flyinghead 39e04b07b8 Merge remote-tracking branch 'origin/dev' 2024-07-11 18:27:44 +02:00
Flyinghead b9cbf3e47f lr: get rid of trash 2024-07-11 18:27:31 +02:00
Flyinghead 72d9ad34dc google play: don't send changes for review automatically 2024-07-08 17:15:42 +02:00
Flyinghead e72a867363 ui: only show dreamcast bios entry if bios present 2024-07-08 16:49:20 +02:00
scribam 2a4356e72c deps: update sdl to version 2.30.5 2024-07-06 14:04:24 +02:00
Flyinghead 136ce267dc aica: apply 6dB attenuation after adding channels in mono
Less saturation with sega bass fishing challenge's default audio
settings.
Issue #1564
2024-07-06 14:03:48 +02:00
github-actions[bot] c6f50fad9d Fetch translations & Recreate libretro_core_options_intl.h 2024-07-05 22:20:32 +00:00
Flyinghead 916afeb5ef Fix Cool Boarders Burrrn game id
Issue #1073
Issue #1265
2024-07-04 09:00:30 +02:00
Flyinghead 81842ccc23 Cool Boarders Burrn and Castle Fantasia fixes
Force HLE Bios for Cool Boarders Burrn.
Issue #1073
Force Copy to VRAM for Cool Boarders Burrn and Castle Fantasia.
Issue #1265
2024-07-03 17:38:23 +02:00
Flyinghead 4fdd28fab7 rend: intersect poly clipping with base clipping
Fixes glitch in FluffMatch split-screen (Fur Fighters)
Issue #145
2024-07-03 11:13:51 +02:00
Flyinghead a01edd22c7 Merge remote-tracking branch 'origin/dev' into playstore 2024-06-30 11:24:46 +02:00
Edward Li c1f5f2e8f9 Do the conversion in Oboe to try to get a low latency stream 2024-06-30 10:36:44 +02:00
scribam f6c1503887 deps: update sdl to version 2.30.4 2024-06-25 14:02:58 +02:00
scribam 71982eda7a miniupnp: add support for api version 18 2024-06-25 14:02:31 +02:00
Flyinghead fefdb6c661 Merge remote-tracking branch 'origin/master' into dev 2024-06-23 16:15:13 +02:00
Flyinghead 4dd490034a android: disable home folder migration 2024-06-23 16:13:28 +02:00
Flyinghead 719fd70860 sdl: always open haptic interface. use default rumble except for wheels
Always open joysticks haptic interface if available and create FFB
effects if supported.
Use default joystick rumble except for racing wheels (sine effect)
Revert 4e3d1caf3f
2024-06-23 16:06:50 +02:00
Flyinghead 49ad2b6864 naomi: save printer output as a screenshot
Use hostfs::saveScreenshot()
2024-06-23 16:00:31 +02:00
scribam 7d645541f8 ci: remove brew zstd 2024-06-23 11:15:34 +02:00
Flyinghead f50d6204dd android: tentative fix for touchscreen not working on android 14
Use more generic source test to detect touch events. Also get rid of
Retroid Pocket 2+ specific test.
Issue #1421
2024-06-23 11:05:40 +02:00
Flyinghead e270621a03 f355: fix gearbox and clutch mappings 2024-06-22 21:40:07 +02:00
Flyinghead 07172416c1 android: tentative fix for touchscreen not working on android 14
Use more generic source test to detect touch events. Also get rid of
Retroid Pocket 2+ specific test.
Issue #1421
2024-06-22 15:07:05 +02:00
github-actions[bot] f9dcd08cf3 Fetch translations & Recreate libretro_core_options_intl.h 2024-06-21 22:20:38 +00:00
Flyinghead 83a27b9125 android: import/export home folder
Use "folder" instead of "directory" in UI.
When game list is empty, show button to easily add a new content path.
Improve folder paths display in settings with middle ellipsis.
android: import/export home folder content
2024-06-21 18:37:34 +02:00
Flyinghead 9976fe10fb android: gamepad rumble support (untested)
Use single thread to handle rumble for virtual and physical gamepads.
Use heavy click effect for vgamepad buttons when available (android 10)
Handle rumble inclination param.
2024-06-21 18:32:25 +02:00
Flyinghead af7edadedb Merge remote-tracking branch 'origin/dev' into playstore 2024-06-21 18:20:40 +02:00
Flyinghead d882c48b4f android screenshots 2024-06-20 18:18:01 +02:00
Flyinghead d92790e69f sh4: incorrect div1 implementation if Rn == Rm 2024-06-20 18:12:11 +02:00
Flyinghead 5eef0309bf Merge remote-tracking branch 'origin/master' into dev 2024-06-20 18:02:36 +02:00
Flyinghead 5f88293fbd discord-rpc: disable clang-format 2024-06-19 15:08:09 +02:00
Flyinghead 245b9043c5 gl: GL_READ_FRAMEBUFFER doesn't exist in GLES2
and glBindFramebuffer isn't needed at this point
2024-06-19 15:06:13 +02:00
Flyinghead e3a1440e25 achievements: don't log token 2024-06-19 15:04:49 +02:00
Flyinghead 0a9eaa6cb8 android: storage fixes
storage: add file update date to FileInfo.
Savestates and custom textures can be loaded from content path / ASS.
Cache last savestate update date to improve perf on android.
android: Don't use scoped storage for android < 5. Optimize listContent.
Fix getSubPath
android: instrumented storage test
2024-06-17 09:53:32 +02:00
Flyinghead e4ca99afba android ci: bump versionCode on each run 2024-06-14 15:36:12 +02:00
Flyinghead e5ccf98693 android ci: set track to internal 2024-06-14 14:31:28 +02:00
Flyinghead e832509175 android ci: missing keystore password 2024-06-14 13:16:15 +02:00
Flyinghead 977d6c6f95 android: upload to google play 2024-06-14 12:59:19 +02:00
Flyinghead 2103dd5a7a storage: add exists() method. load bios from content path. android fix
Add Storage::exists() method
Allow dc and arcade bios to be loaded from content path.
Fix android getSubPath when called on a root uri.
2024-06-14 12:39:32 +02:00
Flyinghead 9df12f950b android: target android 13
disable non-android CI jobs
2024-06-13 20:25:12 +02:00
Flyinghead 272f25ceb3 discord-rpc: disable clang-format 2024-06-13 16:49:34 +02:00
Flyinghead 46340e7e77 ui: add title to select file/folder popups. fix frame padding
android: always do write test in new home folder
2024-06-13 16:05:36 +02:00
Flyinghead aed4d21a4f android: prepare transition to sdk 30+. cache last savestate path
Migrate home folder to externalFilesDir
(/sdcard/Android/data/com.flycast.emulator/files) if running on android
10+.
Use externalFilesDir for home by default. No more onboarding on first
install.
Use content uri instead of hacking out real path since the latter won't
work on higher target sdk.
Cache last readable savestate path in hostfs::getSavestatePath(). All
content folders are scanned when not found, which is very slow with ASS
2024-06-13 15:36:29 +02:00
Flyinghead 9b4667cb38 windows: less log when Storage::getFileInfo fails 2024-06-12 11:08:24 +02:00
Flyinghead ec3ad9b328 sh4: use double for fipr and ftrv. divide before sqrt for fsrra. ssa fix
dynarec: use double to implement fipr and ftrv except on arm32
interpreter: always use double for fipr and ftrv
fsrra: perform division before square root
fmac: use std::fma or native fma op
get rid of unused dynarec op shop_swap
ssa: dead register pass must assume interpreter fallback modifies all
registers
ssa: replace reg+0 address by reg in constant propagation pass
decoder: replace address offset 0 by null param for indexed mem access
2024-06-12 10:54:15 +02:00
Flyinghead ca613db70d ui: better pause menu dpad nav. minor ui fixes
Tweak imgui nav algorithm to improve pause menu nav with dpad.
Imgui widgets name conflicts on network settings tab
2024-06-11 17:31:36 +02:00
Flyinghead 9fd48e7de3 wrong id for capcom vs snk millenium fight 2000 PRO (cvsgd) 2024-06-11 16:49:21 +02:00
Flyinghead 1277a8ff13 fix auto savestate
Automatic save state when unloading the game stopped working
Regression introduced by 6f0581032b
2024-06-11 16:44:42 +02:00
Flyinghead 8adec3f20b achievements: crash when unloading a game with active async task
Async tasks may reference the active game and will crash if it's been
unloaded/freed.
Fixes MINIDUMP-38H
2024-06-11 16:38:30 +02:00
scribam 9aa7371d82 deps: update imgui to version 1.90.8 2024-06-09 15:39:10 +02:00
scribam 0bf1877d96 cmake: use fallback git values 2024-06-09 15:38:39 +02:00
Flyinghead 4cd6278104 rend: force palette update when setting dx order. extra depth for cvs
Force palette update when changing directx color order.
Add 10k extra depth scale to Capcom vs SNK 2000 Pro and cvs.zip to fix
winner character portraits not appearing during ending.
Issue #1546
2024-06-08 16:43:52 +02:00
github-actions[bot] 14b8d4e915 Fetch translations & Recreate libretro_core_options_intl.h 2024-06-07 22:20:06 +00:00
sandboxgamedev123 ddb012bbd2 Add a 32-bit AppImage Script for Linux (#1539) 2024-06-05 15:54:41 +02:00
Flyinghead bfe09667f4 disable native depth interp for mortal kombat. force JP for vonot
Revert (again) forcing native depth interp for AMD gpus
Disable native depth interpolation for Mortal Kombat
Issue #1145
Force Japanese bios for vonot
Issue #1542
2024-06-05 15:53:08 +02:00
Flyinghead 4e3d1caf3f input: temporary logging for failed haptic effects 2024-06-04 13:27:26 +02:00
Flyinghead 6777aa39cb ui: disable dx9 selection if a naomi 2 game is running
Issue #1448
2024-06-03 19:25:22 +02:00
Flyinghead 9bdaa6c40b naomi: drop support for gdi. default to first bios region found
Use the first BIOS region found if the requested one can't be located.
2024-06-03 19:08:19 +02:00
Flyinghead 021249c321 update screenshots (flatpak, AltStore) 2024-06-02 17:33:47 +02:00
Flyinghead e7a4e64a6b android: fix imgui crash when editing virtual gamepad layout
Happens with openGL
Fixes MINIDUMP-374
2024-06-02 17:28:55 +02:00
scribam b840a4f477 windows: fix unit tests 2024-06-01 19:05:23 +02:00
Flyinghead bad55204f2 android: rename packages and activities 2024-06-01 19:03:58 +02:00
Edward Li 70fe47dacf Pretty print for Xcode 15 console 2024-06-01 11:13:24 +02:00
Edward Li 24e579ed99 Fix macOS debug build crash by providing a non empty ID (for the root of a window) 2024-06-01 11:13:24 +02:00
Flyinghead 8ddbe9212a Merge remote-tracking branch 'origin/master' into dev 2024-06-01 11:06:45 +02:00
Flyinghead adeba60ba9 input: ffb support for arcade games. rumble support (f355, 18wheeler)
SDL force feedback for racing wheels.
Support for jvs ffb (f355, 18wheeler), atomiswave (maxspeed, ftspeed)
and midi ffb (initd, clubk, kingrt66, sgdrvsim).
Simple haptic rumble for f355 and 18wheeler.
2024-06-01 11:03:14 +02:00
scribam 95de83431b uwp: fix http ContentLength assignment 2024-05-31 17:34:31 +02:00
scribam 112e05ed5d libzip: enable zstd 2024-05-31 17:34:01 +02:00
Blackbird88 90896368b8 Cheats: Sega GT (USA) - Widescreen cheat 2024-05-27 10:03:55 +02:00
Relwi ce46d1a383 Update README.md
Remove an unnecessary backtick
2024-05-27 10:03:24 +02:00
Flyinghead c1abadb6cd achievements: race condition. pause management. imgui fixes
Race condition when promise is deleted before the future is created
(login)
Require username and password before login.
Disallow pause in hardcore mode when needed.
imgui: fix some failing assertions

Issue #761
Fixes MINIDUMP-35Y, MINIDUMP-34A, MINIDUMP-35K, MINIDUMP-34Y
2024-05-27 10:02:43 +02:00
github-actions[bot] e85fa82101 Fetch translations & Recreate libretro_core_options_intl.h 2024-05-24 22:19:56 +00:00
Flyinghead 0a0d30309b achievements: run all http requests on a background thread
Fixes freeze when unlocking cheevos and other events.
Issue #761
2024-05-24 18:00:28 +02:00
Eric Warmenhoven 30e5466d90 libretro build fix on apple 2024-05-24 08:28:44 +02:00
Blackbird88 48dfab7397 Cheats: Faster Than Speed (Atomiswave) - Widescreen cheat 2024-05-24 08:28:11 +02:00
Flyinghead 4747252187 Merge remote-tracking branch 'origin/dev' 2024-05-23 10:40:57 +02:00
scribam a5608f4f22 android: update project
- Upgrade AGP dependency from 8.3.0 to 8.4.1
- Upgrade Gradle version to 8.6
- Use version catalogs
2024-05-22 16:16:07 +02:00
scribam 20652516e7 deps: update sdl to version 2.30.3 2024-05-22 16:15:40 +02:00
scribam f05e5f3582 deps: update libchdr 2024-05-22 16:15:40 +02:00
scribam 72e892a77e deps: update imgui to version 1.90.6 2024-05-22 16:15:40 +02:00
scribam 0fa3e9a37b cmake: better version conversion for uwp 2024-05-21 10:59:10 +02:00
Flyinghead 1256680a99 lr: Delay Frame Swapping should be enabled by default 2024-05-21 10:45:50 +02:00
Flyinghead 81bebdb900 cheats: fix floigan bros (pal) cheat
this cheat shouldn't be used for the ntsc version.
2024-05-21 10:41:21 +02:00
Flyinghead 6cc64c18dd network: add ports for dee dee planet, floigan bros, IGP and tetris 2024-05-21 10:40:01 +02:00
scribam 6b18ad7e3e cmake: better version conversion for uwp 2024-05-18 13:15:12 +02:00
Edward Li 2797cca5ff Always use BSD sed 2024-05-18 12:37:10 +02:00
Flyinghead b7a2e605f9 dx11: use ALLOW_TEARING flag to disable vsync if available 2024-05-18 12:36:29 +02:00
Flyinghead ec82c7b9ed gl: only display crosshairs when needed
regression due to 4f834610b3
2024-05-18 12:11:08 +02:00
github-actions[bot] 88f23958ac Fetch translations & Recreate libretro_core_options_intl.h 2024-05-17 22:19:56 +00:00
Flyinghead 4f834610b3 gl: refactor vmu and xhair drawing. Blit rendered frame only once
Refactor vmu and xhair drawing to use the same code as libretro.
Fix an issue were each rendered frame was blit twice to the backbuffer.
2024-05-17 17:37:32 +02:00
Flyinghead e2e9a54e0e std::swap is undefined for vector<bool> 2024-05-15 14:20:13 +02:00
Flyinghead cc56b0fbae vk: multi render support
Fixes Quake III split screen vs. and MSR rear view mirror.
Issue #1511
2024-05-15 14:01:58 +02:00
Flyinghead 5755c5b3c6 fix compile warning 2024-05-15 12:33:06 +02:00
Flyinghead 34216f77af naomi: fix marstv freeze
Force JP BIOS version D for this game.
Issue #1508
2024-05-15 11:55:06 +02:00
Flyinghead 21c77adc4d os_notify 2024-05-14 22:43:55 +02:00
Flyinghead 35acb7e62c ui: load savestate thumbnails asynchronously. limit thumbnail size
GetLastFrame can take max width or height.
Limit width of savestate screenshot to 640.
Load savestate thumbnail in async task.
2024-05-14 14:23:40 +02:00
Flyinghead b5f49d6c3a ios build fix 2024-05-13 16:27:31 +02:00
Flyinghead de403a6203 switch, uwp, libretro build fixes 2024-05-13 16:12:32 +02:00
Flyinghead 6f0581032b save screenshot. add screenshot to savestates
Retrieve last frame rgb data (gl, vk, dx9, dx11).
Specific save screenshot code for android, iOS and UWP.
Add Save Screenshot emu key (F12 by default)
vk: defer deletion of in-flight textures when texture cache is cleared.
vk: fix issue when updating imgui textures after a render pass has begun
(achievements)
vk: palette texture not updated after a state has been loaded.
gl: Move opengl-specific stuff into opengl imgui driver.
savestate: Add non compressed header, following by screenshot png data,
before actual savestate.

Issue #842
2024-05-13 15:47:34 +02:00
Blackbird88 f13d7ad2dc Cheats: Tokyo Xtreme Racer 1 (USA) - Widescreen cheat 2024-05-11 17:06:31 +02:00
github-actions[bot] 90b06a688b Fetch translations & Recreate libretro_core_options_intl.h 2024-05-10 22:19:57 +00:00
Blackbird 1b6b61d253 Cheats: Tokyo Xtreme Racer 2 fix
Fixes broken cheat
2024-05-10 11:40:58 +02:00
Flyinghead 83493cc14b achievements: fix size of multiple challenge indicators popup
Issue #761
2024-05-09 18:26:28 +02:00
Flyinghead 9bf60dde3c ui: bug fixes. cheats window changes
Fix boxart list navigation with DPad (regression).
Get rid of several bogus PopStyleVar/PopID.
Better navigation of pause menu buttons.
imgui: tweak NavScoreItem to help pause menu nav.
Allow achievement list navigation with DPad.
Open cheats window fullscreen. Open Add Cheat window as a modal popup.
Add game_scanner.cpp
2024-05-09 10:21:56 +02:00
Flyinghead 24954ec599 work around mingw-w64 init crash
commit https://sourceforge.net/p/mingw-w64/mingw-w64/ci/7b33798917a50cf023f1622eee8eba6d7874b796/
introduces a static initialization order fiasco if a static object is
calling clock_gettime() in its constructor.
2024-05-09 10:19:33 +02:00
Flyinghead c53a1c42c6 work around mingw-w64 init crash
commit https://sourceforge.net/p/mingw-w64/mingw-w64/ci/7b33798917a50cf023f1622eee8eba6d7874b796/
introduces a static initialization order fiasco if a static object is
calling clock_gettime() in its constructor.
2024-05-07 22:33:46 +02:00
Flyinghead 13302b87c8 move ui to its own folder 2024-05-07 22:23:51 +02:00
Flyinghead f76d05a3d5 achievements: leaderboard notifications. detailed toast message
Draw achievement notifications using imgui drawlist api
Fixes for insets
Issue #761
2024-05-07 17:50:36 +02:00
Flyinghead 763d9ce06a ui: split display_settings 2024-05-06 22:26:09 +02:00
Flyinghead 6ab43096a2 ui: use uiScaled() 2024-05-06 21:54:55 +02:00
Flyinghead ceec01ac2e ui: use imgui for vmu on pause menu. toast notifications
Allow nearest sampling with imgui textures (vmu, crosshair)
Use raii for styles and colors
2024-05-06 21:31:04 +02:00
Flyinghead 7327e52e71 ui: crash when loading asian fonts on windows
FontNo must be reset to 0 for Font Awesome.
Issue #1503
Fixes MINIDUMP-314
2024-05-06 14:45:28 +02:00
Flyinghead f04e9d4a65 achievements: better game load message when no achievements
Issue #761
2024-05-06 14:35:00 +02:00
Flyinghead c386f64faa macos: bump minimum macOS version to 10.11 to avoid build error 2024-05-05 16:06:57 +02:00
Flyinghead ff33ff2b88 ui: change pause menu layout. add icons here and there
Always display savestate absolute date.
2024-05-05 16:02:37 +02:00
Edward Li 17db07703e Use Xcode 15.3 2024-05-04 20:53:24 +02:00
Flyinghead 75f64efe93 fix buymeacoffee 'username' 2024-05-04 20:35:11 +02:00
Flyinghead ab8b4f0e54 buymeacoffee funding
stricter deserialize verify for broadcast/cable/region
2024-05-04 20:33:37 +02:00
Flyinghead 43ba8953a2 vk: don't delete the ImGui driver when recreating the swap chain
It might be drawing at this point so just reset it.
2024-05-04 19:24:02 +02:00
Flyinghead 6de2f160a1 achievements: hardcore mode 2024-05-04 17:38:42 +02:00
flyinghead ccc9931de8 achievements: fix crash when loading image cache
Fixes MINIDUMP-312, MINIDUMP-313
Issue #761
2024-05-04 13:51:59 +02:00
github-actions[bot] 0517a4600c Fetch translations & Recreate libretro_core_options_intl.h 2024-05-03 22:19:41 +00:00
Flyinghead fe17d459a5 ui: achievements list, new pause menu
Fix threading issue when hashing disk for RA. Protect cacheMap with
mutex.
Achievement current challenges displayed as small icons.
Embed FontAwesome symbols.
New pause menu.
Issue #761
2024-05-03 20:09:31 +02:00
Edward Li 2d4684a462 Use Xcode 15.3 2024-05-01 18:33:17 +02:00
Flyinghead 300cf0d437 better RetroAchievements UI and threading
Pop ups for authentication, game load, game completed, achievements
unlock and progress.
Handle disk changes.
Issue #761
2024-05-01 18:32:39 +02:00
Flyinghead c96e828c63 move http_client to oslib 2024-04-29 16:17:50 +02:00
Flyinghead 4666ea2fdb macos: bump minimum macOS version to 10.11 to avoid build error 2024-04-29 15:31:21 +02:00
Flyinghead 8f5f2caae6 Merge remote-tracking branch 'origin/master' into dev 2024-04-29 15:27:23 +02:00
Flyinghead 8fdd1dde3d RetroAchievements support
MVP
Issue #761
2024-04-29 14:59:47 +02:00
github-actions[bot] 8e96590065 Fetch translations & Recreate libretro_core_options_intl.h 2024-04-26 22:20:05 +00:00
Flyinghead d46b181084 ui: fix cosmetic issues
Limit Filter fields width to what's available. Issue #1488
Avoid bouncing loop when scrollbar appearance and responsive boxart size
work against each other. Issue #1489
2024-04-25 12:57:34 +02:00
scribam e46815d070 ci: update netbsd and openbsd versions 2024-04-20 09:16:36 +02:00
github-actions[bot] 3c38fc1f16 Fetch translations & Recreate libretro_core_options_intl.h 2024-04-19 22:19:34 +00:00
Díaz Urbaneja Víctor Diego Alejandro (Sodomon) 47b6a90bec Update README.md
edited build instructions
2024-04-18 09:10:50 +02:00
Flyinghead de6a43bd21 savestate: drop support for legacy libretro and <v16 savestates 2024-04-16 09:40:55 +02:00
github-actions[bot] 7438094d7c Fetch translations & Recreate libretro_core_options_intl.h 2024-04-12 22:19:05 +00:00
Flyinghead 336706e728 move most os_* funcs to oslib
add os_DestroyWindow and os_UpdateInputState
2024-04-12 17:37:45 +02:00
C.W. Betts 8f486e71cb Update types.h
Use angle brackets for including pthread.h
2024-04-12 09:24:10 +02:00
Flyinghead b378161837 lr: switch build fix 2024-04-11 18:50:49 +02:00
Flyinghead a136583189 drop dispmanx support. move switch main() to its own file
Dispmanx support is provided by SDL
Enable omx audio and set TARGET_VIDEOCORE when building for RPi3
2024-04-11 16:27:28 +02:00
Flyinghead 06a6e26588 get rid of os_GetSeconds()
replace it with std::chrono-based getTimeMs()
2024-04-11 15:25:25 +02:00
Flyinghead 5541d34a9e lr win32 build fix 2024-04-10 18:10:21 +02:00
Flyinghead 108c8a4b5d vk: move macOS video routing code from context to renderer 2024-04-10 17:31:23 +02:00
Flyinghead 9e916ca1c9 minor input and lua fixes
Make macOS keyboard class with haptic code
Call SDL_JoystickSetPlayerIndex using maple port
Add Network event for LUA
Set proper controller unique id on iOS
rumblePower wasn't copied over new mappings.
2024-04-10 17:24:47 +02:00
Flyinghead 42e98e86d0 set thread names
Name all threads to help debugging and improve crash reports (windows
only)
Add ^C handler for clean exit on linux
2024-04-10 17:08:24 +02:00
Flyinghead 010fba15a8 macOS build fix 2024-04-08 21:26:18 +02:00
Flyinghead bf249061cf thegamedb: ignore common disk ids T0000 and T0000M
These are default disk ids and shouldn't be used to identify media
2024-04-08 19:09:14 +02:00
Flyinghead 24db1422b8 ui: rearrange Settings > Video screen
Issue #665
2024-04-08 19:07:44 +02:00
Flyinghead da6c34b2fd android workflow: fetch submodules recursively (for libadrenotools) 2024-04-07 12:34:34 +02:00
Flyinghead a6c4530e22 vulkan: allow custom GPU driver loading with libadrenotools
Issue #1471
2024-04-07 12:27:54 +02:00
Flyinghead e8340bfa5e maple: implement AllStatusReq for controller and VMU 2024-04-07 11:47:42 +02:00
Flyinghead eaa22a49d1 msvc build fix 2024-04-06 19:07:27 +02:00
Flyinghead 4f87a3556e Fix vmu beep frequency 2024-04-06 17:43:19 +02:00
Flyinghead 41d418ed25 bump libchdr to match master 2024-04-06 17:21:27 +02:00
github-actions[bot] 9d6eab74e1 Fetch translations & Recreate libretro_core_options_intl.h 2024-04-05 22:20:01 +00:00
scribam a0c81d2f2a deps: update sdl to version 2.30.2 2024-04-03 10:50:17 +02:00
flyinghead d6efbc513c win: fix dump textures and box art saves when path contains non-ascii
Texture dumping and local boxart scraper were failing on windows if
image path contains non-ascii chars. nonwide::fopen must be used.
2024-04-03 10:49:40 +02:00
github-actions[bot] ed78eb4d50 Fetch translations & Recreate libretro_core_options_intl.h 2024-03-29 22:19:29 +00:00
Flyinghead 236b747db8 gl: fix GLES2 build
Issue #1470
2024-03-28 17:48:39 +01:00
Flyinghead c9fafa0ed1 widescreen cheats for Surf Rocket Racers (US) and Love & Berry 1 and 3
Courtesy of Goddamn Superhero
2024-03-26 18:43:38 +01:00
Flyinghead 4bd8866164 libretro: don't load overridden settings from frontend
Fixes game specific overrides being ignored.
2024-03-26 18:40:48 +01:00
Flyinghead f346bcd68b elf: only load PT_LOAD sections 2024-03-24 10:16:02 +01:00
github-actions[bot] 187991d71f Fetch translations & Recreate libretro_core_options_intl.h 2024-03-22 22:19:19 +00:00
Alexandre Bouvier 40cdef6c1c cmake: allow system glslang library 2024-03-19 14:16:10 +01:00
Bobby Smith 8252a28e48 [Libretro] Check for per-pixel compatibility and hide the option if not supported 2024-03-17 17:55:23 +01:00
Flyinghead c7ee42f0ba ios: don't use glad
Fixes crash at start up on iOS.
Issue #1461
2024-03-17 17:54:37 +01:00
Flyinghead e27b5dc1aa Merge remote-tracking branch 'origin/master' into dev 2024-03-16 19:40:48 +01:00
github-actions[bot] 966ff3767d Fetch translations & Recreate libretro_core_options_intl.h 2024-03-15 22:19:31 +00:00
Flyinghead 056a02357d Cardcaptor Sakura widescreen cheat 2024-03-14 13:22:44 +01:00
Flyinghead 6115a918b2 arm dynarec: apply mask to mem write8 and write16 value operand
Compilers do not cast the operand, which results in u8 handlers being
called with an u32 value.
2024-03-14 13:21:10 +01:00
Flyinghead 3ffb09ec72 gl: fully recreate opengl texture when loading a custom one
Regenerate texID and call glTexStorage2D when loading a custom texture
(GL 4.2+, GLES3).
rend: missing old_vqtexture_hash in move constructor.
2024-03-14 12:56:11 +01:00
Flyinghead de89d8cfed rend: fix Space Harrier arcade in Shenmue
Use the original tex dimensions and make sure they never change between
updates.
2024-03-12 14:56:13 +01:00
Flyinghead c7d6525c51 force PAL for MTV Sports - Skateboarding (EU) 2024-03-12 14:37:38 +01:00
Flyinghead 5ce1f92e5c naomi: allow mapping of left & right trigger 2
Makes rear brake usable in wild riders
Issue #1450
2024-03-12 14:36:38 +01:00
Flyinghead 464defe0d7 don't force Native Depth Interpolation for AMD GPUs
Some AMD GPUs have issues with this option enabled so let the user
decide.
partial revert of 9f9b29b833 and
cab19ad54b.
Issue #1445

Add BSD CI badge to README
2024-03-10 14:17:21 +01:00
github-actions[bot] d323490d1f Fetch translations & Recreate libretro_core_options_intl.h 2024-03-08 22:20:07 +00:00
scribam d8c15de030 deps: update sdl to version 2.30.1 2024-03-07 15:01:59 +01:00
Flyinghead b55054249f ui: file dropping can start multiple games at once
Happens on macOS, linux and likely others.
Fixes MINIDUMP-2N4
2024-03-07 15:01:28 +01:00
Flyinghead 0aa8910742 ui: update gamepad settings for both console and arcade profiles 2024-03-06 16:53:43 +01:00
Flyinghead 43bb7c83f7 hide P3 and P4 light gun crosshairs for arcade games 2024-03-06 16:42:43 +01:00
Flyinghead 391da7023f sh4: fix SCIF serialization
Fixes MINIDUMP-2M0
Add some diag logging to win_vmem
2024-03-04 17:02:42 +01:00
Flyinghead b0a268b89e richer discord presence using boxart from thegamesdb 2024-03-03 16:03:22 +01:00
scribam 960b8134c1 ci: update mathieu-bour/setup-sentry-cli action 2024-03-02 18:37:52 +01:00
scribam 5a51749daa libretro: fix translation 2024-03-02 18:37:20 +01:00
scribam d2dc60ec00 android: update android gradle plugin to version 8.3.0 2024-03-02 18:36:54 +01:00
github-actions[bot] 33bcf4443f Fetch translations & Recreate libretro_core_options_intl.h 2024-03-01 22:19:09 +00:00
Flyinghead 62d00578af fix compile warnings 2024-03-01 12:58:53 +01:00
Flyinghead dac5c008ab Discord Presence support
Issue #1289
2024-03-01 12:34:49 +01:00
Flyinghead 588035d9eb set currently played game name in the window title
Issue #28
2024-03-01 12:00:24 +01:00
Bobby Smith f63a82afc4 Update libchdr 2024-02-29 19:58:39 +01:00
Flyinghead c052822fd4 jojo's bizarre adventure (US) requires NTSC 2024-02-29 16:45:14 +01:00
Flyinghead 2846b3002b rawinput: append device id to device name
Append device id to friendly name to distinguish between generic
HID-compliant devices.
Issue #664
Issue #835
Better UI for device tables using new imgui table API.
2024-02-29 16:43:53 +01:00
Flyinghead 19a240503d minor clean up 2024-02-29 16:26:49 +01:00
Flyinghead c9d3096e41 android: hid barcode scanner support 2024-02-27 17:39:51 +01:00
Flyinghead d6ae47d0f7 fix FreeBSD x64 segfault context
Issue #1401
2024-02-27 17:39:51 +01:00
Flyinghead 40a7c08d14 isofs: fix long directory listing
Directory entries can't cross a sector boundary, so reading must
continue on the next one.
Add list() method
2024-02-27 17:39:51 +01:00
Flyinghead 6f8a588794 bump depth scale for NHL 2K2
Fixes helmet rendering in team selection menu
Issue #1416
2024-02-27 17:39:51 +01:00
Flyinghead 156aafe95b sh4: fix P4 region mapping and on chip ram addressing
P4 region is normally mapped outside of the sq and system registers
areas (E4-EF, F8-FE).
Fixes NHL 2K2 missing helmet and jersey textures. Issue #1416
Fixes invalid geometry in worldkicks series (using interpreter or 4 GB
vmem space)
Fix On Chip RAM addressing: bit 13 or 25 is used to select the bank.
2024-02-27 17:39:51 +01:00
scribam 1017d3eb95 deps: sync imgui_impl_vulkan.cpp with upstream 2024-02-27 17:39:51 +01:00
scribam 3059b43121 deps: update imgui to version 1.90.4 2024-02-27 17:39:51 +01:00
Flyinghead 93789e2a63 sdl: support multiple mice when allowed by the platform 2024-02-27 17:39:51 +01:00
Flyinghead 6639d6b167 naomi: fix shaktam inputs
Issue #1420
2024-02-27 17:39:51 +01:00
scribam daef33cea5 cmake: improved parallelism in msbuild 2024-02-27 17:39:51 +01:00
scribam a7c89701fe ci: use cross-platform-actions/action to build on bsd systems 2024-02-27 17:39:51 +01:00
scribam 9a119e7646 bsd: update segfault context for arm64 2024-02-27 17:39:51 +01:00
scribam c8462e1f78 deps: update imgui to version 1.90.3 2024-02-27 17:39:51 +01:00
scribam 50944772b7 linux: use egl with x11 instead of glx 2024-02-27 17:39:51 +01:00
scribam 952a785bf0 deps: update libchdr 2024-02-27 17:39:51 +01:00
scribam f9eed1ed3f deps: update libzip to version 1.10.1 2024-02-27 17:39:51 +01:00
scribam b7df183c7c ci: use latest devkitpro docker image 2024-02-27 17:39:51 +01:00
Flyinghead 13edf858e3 init drive when running .elf. Skip special settings for BIOS and .elf. 2024-02-27 17:39:51 +01:00
Flyinghead d45de9e8a9 gladLoader: check return code and log. cheats: light refactoring 2024-02-27 17:39:51 +01:00
Flyinghead 81cbf45bdb samsptk: use cheat instead of extra depth scale
Use a cheat to fix the game bug instead of dealing with ginormous depth
values.
2024-02-27 17:39:51 +01:00
Flyinghead d340b620c3 gdrom: delay "no disk" reporting to let the BIOS play the boot animation
Thanks to kihato for the prototype code.
Issue #587
2024-02-27 17:39:51 +01:00
Flyinghead 443d5a2ba6 pvr: apply a negative bias to background plane depth
Fixes skybox in Xtreme Sports. Issue #1381
Fixes background clipping in Blue Stinger (JP) intro. Issue #721
Fixes Windows CE yuv FMV black screen (4x4 EVO, Armada, Carsear's
Palace, Giant Killers, PBA bowling, Starlancer, Tomr Raider, Wild Metal,
Who wants to beat up...)

Get rid of ForceWindowsCE option
Force PAL for Super Runabout (EU)
2024-02-27 17:39:51 +01:00
Flyinghead 894a38fb71 ui: replace Exit by Close Game. Better format for some UI values.
Issue #1383
2024-02-27 17:39:51 +01:00
Flyinghead aea37b3bd8 gdrom: set correct lead-out FAD of single-density area
Use end FAD +1 of track 2 as start of lead-out for single density area.
gdi: set track end FAD based on track size, not start of next track
chd: ignore pad frames when calculating end FAD
cdi: end FAD was one off
Issue #1386
2024-02-27 17:39:51 +01:00
Flyinghead b5eecb79b8 android: hid barcode scanner support 2024-02-26 16:27:18 +01:00
Flyinghead f629c352e1 fix FreeBSD x64 segfault context
Issue #1401
2024-02-26 11:27:03 +01:00
Flyinghead ff91d1101a isofs: fix long directory listing
Directory entries can't cross a sector boundary, so reading must
continue on the next one.
Add list() method
2024-02-25 15:59:22 +01:00
Flyinghead 4f1512d369 bump depth scale for NHL 2K2
Fixes helmet rendering in team selection menu
Issue #1416
2024-02-25 14:40:37 +01:00
Flyinghead 2dde1d5e7b sh4: fix P4 region mapping and on chip ram addressing
P4 region is normally mapped outside of the sq and system registers
areas (E4-EF, F8-FE).
Fixes NHL 2K2 missing helmet and jersey textures. Issue #1416
Fixes invalid geometry in worldkicks series (using interpreter or 4 GB
vmem space)
Fix On Chip RAM addressing: bit 13 or 25 is used to select the bank.
2024-02-25 14:37:27 +01:00
scribam 3c8769cb5c deps: sync imgui_impl_vulkan.cpp with upstream 2024-02-24 22:08:40 +01:00
scribam ba12c01ab8 deps: update imgui to version 1.90.4 2024-02-24 22:08:40 +01:00
Flyinghead 713739bbc7 sdl: support multiple mice when allowed by the platform 2024-02-24 21:33:40 +01:00
Flyinghead 4667d17d78 naomi: fix shaktam inputs
Issue #1420
2024-02-24 19:42:41 +01:00
github-actions[bot] bc51aefa9c Fetch translations & Recreate libretro_core_options_intl.h 2024-02-23 22:19:36 +00:00
Immersion95 67c4e62c51 Adds option to enable/disable "Fix Upscale Bleeding Edge"
Helps with texture bleeding case when upscaling. Disabling it can help if pixels are warping when upscaling in 2D games (MVC2, CVS, KOF, etc.)
2024-02-22 11:30:26 +01:00
scribam b71541f8dd cmake: improved parallelism in msbuild 2024-02-22 09:21:34 +01:00
scribam 56cad843c9 ci: use cross-platform-actions/action to build on bsd systems 2024-02-21 08:46:27 +01:00
scribam 1b0781c680 bsd: update segfault context for arm64 2024-02-21 08:46:27 +01:00
scribam 0c5e79d618 deps: update imgui to version 1.90.3 2024-02-17 17:40:22 +01:00
scribam 5c8d7021f6 linux: use egl with x11 instead of glx 2024-02-17 17:38:39 +01:00
scribam 8d2bcdf35e deps: update libchdr 2024-02-17 17:37:32 +01:00
scribam eb2826f6d3 deps: update libzip to version 1.10.1 2024-02-15 10:00:56 +01:00
scribam 6cb929953c ci: use latest devkitpro docker image 2024-02-10 12:41:51 +01:00
Flyinghead 232924d88a init drive when running .elf. Skip special settings for BIOS and .elf. 2024-02-10 12:41:17 +01:00
Flyinghead 90b13a40ab gladLoader: check return code and log. cheats: light refactoring 2024-02-10 12:06:48 +01:00
Flyinghead a50f5765da Merge remote-tracking branch 'origin/master' into dev 2024-02-10 11:58:39 +01:00
github-actions[bot] 44fa364f36 Fetch translations & Recreate libretro_core_options_intl.h 2024-02-09 22:19:47 +00:00
Flyinghead 7029e1615a systemsp: lovebery needs Copy to VRAM. Allow space in card codes.
Enable Copy to VRAM for lovebery and lovebero.
Allow space characters in card codes.
Issue #1388
Force HLE BIOS for Suika.
Issue #1278
2024-02-09 13:05:38 +01:00
Flyinghead 3469b7fca7 gl: use red for single channel textures instead of alpha on GLES3
Only GLES2 needs to use the alpha channel. glTexStorage2D only supports
red.
Issue #1391
2024-02-09 12:59:50 +01:00
Flyinghead 434083c716 samsptk: use cheat instead of extra depth scale
Use a cheat to fix the game bug instead of dealing with ginormous depth
values.
2024-02-07 19:41:03 +01:00
Flyinghead d9d91381b5 gdrom: delay "no disk" reporting to let the BIOS play the boot animation
Thanks to kihato for the prototype code.
Issue #587
2024-02-07 16:11:25 +01:00
Flyinghead 531c6f94d5 pvr: apply a negative bias to background plane depth
Fixes skybox in Xtreme Sports. Issue #1381
Fixes background clipping in Blue Stinger (JP) intro. Issue #721
Fixes Windows CE yuv FMV black screen (4x4 EVO, Armada, Carsear's
Palace, Giant Killers, PBA bowling, Starlancer, Tomr Raider, Wild Metal,
Who wants to beat up...)

Get rid of ForceWindowsCE option
Force PAL for Super Runabout (EU)
2024-02-07 16:02:55 +01:00
Flyinghead 9aa9b5bebc ui: replace Exit by Close Game. Better format for some UI values.
Issue #1383
2024-02-07 11:05:09 +01:00
Flyinghead e592650afc gdrom: set correct lead-out FAD of single-density area
Use end FAD +1 of track 2 as start of lead-out for single density area.
gdi: set track end FAD based on track size, not start of next track
chd: ignore pad frames when calculating end FAD
cdi: end FAD was one off
Issue #1386
2024-02-06 11:07:20 +01:00
flyinghead c146a92f83 Merge pull request #1379 from flyinghead/dev
merge dev branch
2024-02-03 18:25:15 +01:00
dakrk d4fa3c441e cheats: fix parsing cheat codes on some platforms
using strtol here instead of strtoul when cheat code values are expected to be unsigned and are above 7fffffff breaks on platforms like Windows where long is 32-bit even on 64-bit platforms, capping out at 2147483647 and causing some cheat codes to break.
2024-02-03 18:19:40 +01:00
scribam 47eeab9985 switch: lock devkipro docker image to known good version 2024-02-03 16:28:57 +01:00
scribam be8c559b2f deps: update sdl to version 2.30.0
vcpkg is no longer required to build sdl for uwp
2024-02-03 16:28:57 +01:00
scribam 51d25bb49b android: update android gradle plugin to version 8.2.2 2024-02-03 16:28:57 +01:00
github-actions[bot] 6d69598800 Fetch translations & Recreate libretro_core_options_intl.h 2024-02-02 22:19:10 +00:00
Flyinghead 36684bf82c vk: share shader code between regular and oit renderers 2024-02-01 18:19:03 +01:00
Flyinghead cdaaeb5b27 naomi: printer fixes
Fix create bitmap DC2 sequence: 4 bytes then data.
Record msb mode at time of image definition as it might change before
the image is printed.
ntvmys uses 64-pixel wide custom characters.
Custom chars must use current bitmap msb setting.
Implement rule line dot fill and pattern fill.

Fixes most ntvmys print out issues.
Issue #1378
2024-02-01 18:15:34 +01:00
Flyinghead 4220c0d64f naomi: reset destination ram if dma xfer from invalid rom offset
Reset destination area to 0 if attempting a dma xfer from an invalid rom
offset. Also update SB_GDSTARD and SB_GDLEND in this case.
Fixes texture corruption in ntvmys.
Issue #1378
2024-02-01 17:51:25 +01:00
Flyinghead e286f98f72 naomi: new rom ntvmys 2024-01-31 16:52:34 +01:00
Flyinghead e714e94510 rend: do bilinear filtering of palette textures on the GPU
All renderers updated.
2024-01-31 16:46:25 +01:00
Flyinghead 8715e5a5e9 gl: use glTexStorage/glTexSubImage to update textures when available 2024-01-31 16:03:07 +01:00
Flyinghead 1153238e2c sdl: (linux) fix window position at startup/recreation
Window decorations dimensions aren't taken into account on linux when
creating a window. So reposition it after it's shown.
2024-01-29 17:08:10 +01:00
Flyinghead 617d82f5a2 libretro: rename Purupuru to Vibration Pack 2024-01-29 11:29:52 +01:00
Flyinghead 471e0a7786 sdl: add timeout for barcode scanner to recover from incomplete reads
Reset barcode buffer after 0.5 s. Allows to recover from a failed read
or the user pressing '*'.
2024-01-29 11:25:55 +01:00
Flyinghead 887e616f76 dx9: load d3d9.dll and d3dx9_??.dll dynamically 2024-01-29 11:15:30 +01:00
Flyinghead aa2fa1f611 ui: rename Purupuru to Vibration Pack 2024-01-29 11:08:17 +01:00
Flyinghead 57c88e07c4 gl: even better test to detect the nouveau driver
Issue #1373
2024-01-29 10:51:48 +01:00
Flyinghead 593b3205bd reios: fix GETSCD and GET_DRV_STAT status during disk swapping
GET_DRV_STAT returns BUSY when disk is being recognized.
GETSCD returns asc and ascq in result 1 on error, does not return unit
attention if drive is busy.
Fixes disk swapping for Shenmue II, Dancing Blade II and Kaen Seibo.
Fixes wrong drive visual in Golf Shiyouyo Course Data Syuu

Issue #1046
2024-01-28 16:00:46 +01:00
Flyinghead ecce9157bd maple: raise interrupt on vblank when maple bus is occupied
Raise a maple interrupt at the next vblank when the host occupies the
maple bus to read the lightgun position. Fixes RevolveR single shot
issue since the game is waiting for the interrupt.
Issue #1369
2024-01-28 15:21:40 +01:00
Flyinghead b2d96d77d7 naomi: support hid barcode scanner. sdl: detect keyboard layout
sdl: Support for HID barcode scanners such as unitech MS146.
Automatically detect keyboard layout at start up.
2024-01-27 16:01:57 +01:00
github-actions[bot] e1537ddbda Fetch translations & Recreate libretro_core_options_intl.h 2024-01-26 22:19:34 +00:00
Flyinghead 4c7e57ebd6 gdrom: revert SPI_TEST_UNIT change
Fixes disk swapping for Alone in the Dark and Resident Evil: Code
Veronica (real BIOS)
Issue #1046
2024-01-26 19:49:01 +01:00
Flyinghead 116dc0e1ed gdrom: don't rely on Status in libGDR_GetDiscType
Status is Busy when disk swapping is in progress so libGDR_GetDiscType
always returns NoDisk/Open. Rely on the scheduler instead so that the
correct type is returned when disk swapping is finished.
Issue #1046
Issue #189
2024-01-25 12:36:04 +01:00
Flyinghead 10d3ffdf09 jvs: fix crackin'dj inputs. serialize coin count
crackin'dj: map vertical mouse axis to right turntable. Invert fader.
Simulate turntable motor. Embed eeproms with calibration done.
Fix coin being inserted after loading a savestate.
2024-01-24 19:39:20 +01:00
Flyinghead cbd01fba38 gdrom: fix disk swapping for some games
Add a 1 s delay when inserting a disk before the drive is ready.
Fixes disk swapping for Skies of Arcadia, Shenmue II (except HLE), Alone
in the Dark, Dancing Blade, First Kiss Story II and Kaen Seibo.
Issue #1046
Issue #189
Fixes BIOS menu disk swapping.
2024-01-24 18:35:23 +01:00
Flyinghead 88fd2641d9 pvr: allow blending for opaque polys of list continuations
Fixes Crackin'DJ invisible background animation and Monkey Ball grey map
background.
2024-01-23 19:20:40 +01:00
Flyinghead 70a69cf48d switch: fastmem/vmem implementation
Only map first writable mirror due to switch limitation.
2024-01-22 15:18:49 +01:00
Flyinghead f8d5517b8e Disable overclocking for ggpo and online games. Always release vmem.
Disable over/underclocking when GGPO is enabled and when online
(modem/bba).
Always release the address space, which releases virtmem.
2024-01-22 09:46:51 +01:00
Flyinghead 16b2f59a47 ui: use flattened navigation where possible. fix sdl on-screen keyboard
Use flattened nav on file select, add cheat and controller mapping
windows and list boxes.
Don't show the SDL on-screen keyboard twice.
Use ImGuiChildFlags_Border instead of the legacy border parameter
(BeginChild)
2024-01-22 09:36:17 +01:00
Flyinghead 07d6ca6c84 gl: better test to detect the nouveau driver
GL_VENDOR=nouveau or GL_RENDERER=NVE4 (case insensitive)
Issue #1373
2024-01-22 09:18:17 +01:00
Flyinghead c9c015976a switch: tentative fix 2 of git security issue affecting version number 2024-01-20 19:39:22 +01:00
Flyinghead 2615cc13f1 Revert "switch: tentative fix of git security issue affecting version number"
This reverts commit 393c3dbfd9.
2024-01-20 19:26:16 +01:00
scribam 599dc92d11 ci: use freebsd 14 2024-01-20 19:24:07 +01:00
scribam e26302ef03 deps: update glad 2024-01-20 19:24:07 +01:00
scribam fd3e74e224 ci: remove ninja-build as it is already installed in devkitpro image 2024-01-20 19:24:07 +01:00
scribam 5b5d7b01eb ci: bump actions/cache and ad-m/github-push-action 2024-01-20 19:24:07 +01:00
scribam f6b01aba0c android: update android gradle plugin to version 8.2.1 2024-01-20 19:24:07 +01:00
Flyinghead 19bb4a6e5d switch: implement rumble with native API 2024-01-20 19:23:09 +01:00
Flyinghead bc70d9118d ui: restore drag scrolling on controller mapping popup
regression introduced by 105ab95efa
2024-01-20 16:20:09 +01:00
Flyinghead 393c3dbfd9 switch: tentative fix of git security issue affecting version number 2024-01-20 16:14:18 +01:00
github-actions[bot] 8fd6fefda7 Fetch translations & Recreate libretro_core_options_intl.h 2024-01-19 22:19:50 +00:00
Flyinghead a620a432c9 boxart: save database regularly when scraping
Issue #1117
2024-01-17 17:54:28 +01:00
Flyinghead 9e37d1e726 switch: restore x15 register when returning from the fault handler
Also restore NZCV and FPU registers.
Fixes crash/glitch with YUV converter.
Fixes SoA crash when rendering to a texture.
Issue #1312
2024-01-17 17:52:26 +01:00
Flyinghead c1b087df83 arm64: notify compiler that x10 is used in setHostRoundingMode
Fixes a crash on switch in single-threaded mode in
setDefaultRoundingMode.
2024-01-17 10:08:44 +01:00
Flyinghead 2add951f70 switch build fix 2024-01-16 11:39:51 +01:00
Bobby Smith 070ac717d3 [Libretro] Add options to manage each expansion slot 2024-01-16 11:22:12 +01:00
Flyinghead cfb7ff3054 switch: use latest devkitpro. touchscreen support. cleaner abort
Use latest devkitpro image.
Call diagAbortWithResult on fatal errors instead of freezing/infinite
loop.
Add Exit button on main content screen.
Touchscreen support.
2024-01-16 11:21:32 +01:00
scribam e03c37b013 deps: update imgui to version v1.90.1 2024-01-13 14:58:33 +01:00
Flyinghead 0b0904cdc5 systemsp: hopper and medal game fixes
hopper: Limit coin sensors to 100 ms to avoid coin chute jam errors.
hopper: Use periodic sensor for hopper to avoid hopper jam errors.
Issue #1365
medal: wire inputs and emulator required sensors. Embed medal games
nvmem to disable comm and all errors.
magicpop, unomedal, puyomedal, ochaken and westdmrg now playable.

kingyoch rom parent is kingyo
2024-01-13 14:52:29 +01:00
github-actions[bot] 195f401044 Fetch translations & Recreate libretro_core_options_intl.h 2024-01-12 22:19:21 +00:00
flyinghead 552e5b7d7a dx9,dx11: only draw lightgun crosshair when necessary
missing check for arcade games
Issue #1363
2024-01-11 22:20:21 +01:00
Flyinghead 2a48049216 systemsp: cart network hle. hopper emulation.
WIP emulation of cart network features.
Hopper emulation.
WIP medal emulation.
Playable games: kingyo, manpuku and shateki
2024-01-10 15:56:21 +01:00
Flyinghead c001240797 move audio drivers to their own folder 2024-01-10 11:45:54 +01:00
github-actions[bot] e7d0a5f2f9 Fetch translations & Recreate libretro_core_options_intl.h 2024-01-05 22:19:42 +00:00
Flyinghead 032cc17659 video routing fixes
dx11: terminate video routing in DX11Renderer::Term. Don't use
DX11Context.
dx11: avoid using local static vars
gl: don't send rendered frame when full FB is on
gl: send rendered framebuffer
gl: terminate video routing in termGLCommon. Don't use GLGraphicsContext

gl: avoid crash on quick exit during test automation
2024-01-05 12:46:39 +01:00
Flyinghead c0c6f206bf f355: fix win32 condition variable implementation
A race condition can happen on condition variables due to
unlock/wait/lock not being atomic. This results in the wrong process
being notified, causing a deadlock.
Happens more frequently in twin mode.
Issue #1361
2024-01-05 12:36:20 +01:00
scribam 6aa59c54a5 Minor misc changes (#1360)
* core: cleanup include headers
* dx11: remove unimplemented function
* core: annotate destructors with override
* aica: use range-based for loop
* bm: use const reference/structured bindings with blkmap
2024-01-02 14:38:16 +01:00
Flyinghead 9c964ac955 refactor embedded resource loading. Use for imgui font and android OSD
Generic embedded resource loading function
Zip bios and printer fonts
Add buttons.png and Roboto-Medium.ttf as embedded resources
2024-01-02 14:37:29 +01:00
Flyinghead 5734556440 naomi: crc32 for asndynmt[o]. Use vfnet.flyca.st domain for netdimm 2024-01-01 16:16:55 +01:00
Flyinghead e76b76dcc4 vk: allow any size for buttons.png on android 2024-01-01 16:07:59 +01:00
Flyinghead cab19ad54b libretro: crash at boot when checking for GPU vendor 2024-01-01 16:06:25 +01:00
Flyinghead a7702c622a aica: don't disable channel when reaching full attenuation
Some games rely on the channel still being processed and CA/LP being
updated. Courtesy of @kihato
Issues #472, #483, #1180, #1249, #1030 (partial)
2023-12-31 12:02:42 +01:00
Flyinghead 9f9b29b833 rend: force Native Depth Interpolation for AMD gpus 2023-12-28 17:48:33 +01:00
Flyinghead 06529b63f7 gl: don't invert y when saving a test screenshot 2023-12-28 17:36:50 +01:00
Flyinghead 0d36154618 hle bios: wince games hang after IP.BIN
regression introduced by 41723a831f
2023-12-28 17:17:11 +01:00
Flyinghead c7b6f22e10 naomi: limit rom dma delay to 1 sec
Fixes crash at boot with jambo safari.
Fix for MINIDUMP-293
2023-12-25 19:07:08 +01:00
Bobby Smith d069b45bff [Libretro] Adds some core options description + minor changes 2023-12-23 20:43:19 +01:00
github-actions[bot] 4a0ace5de2 Fetch translations & Recreate libretro_core_options_intl.h 2023-12-22 22:19:29 +00:00
Bobby Smith 57c2dcd961 [Libretro] Fix VMU scaling for dynamic res games 2023-12-21 14:20:34 +01:00
vkedwardli 790f5b1ad2 Video Routing Revamp (#1323)
* Update Spout2 dep
* Remove all `initVideoRouting` call from `GraphicContext`
* Fix MinGW build error
2023-12-21 14:19:57 +01:00
Flyinghead 54ac9c6361 naomi: lower rom dma transfer speed
Decrease from 20 to 7 MB/s. Fixes various freezes with Force Five aw
conversion.
Issue #141

Don't expose atomiswave A0_006 registers to naomi and other arcade
platforms.
2023-12-21 14:18:53 +01:00
Flyinghead 449b871e0c vk: crash when loading custom texture
Regression due to 939e2bc68f
Issue #1351
2023-12-21 10:04:35 +01:00
scribam e057370e97 core: add missing pragma once to header files 2023-12-17 11:12:20 +01:00
scribam c938f7b0df deps: build breakpad on current compatible systems only 2023-12-17 11:11:51 +01:00
Bobby Smith 99dc278ad2 Broadcast override for South Park Rally 2023-12-17 11:11:23 +01:00
scribam bccdc6600a ci: update github actions 2023-12-17 11:10:56 +01:00
Flyinghead ba1a68a69f vk: fix setObjectName on 32-bit platforms 2023-12-17 11:10:19 +01:00
Flyinghead 363c2c4c3f modem: register flags documentation 2023-12-17 11:07:13 +01:00
Flyinghead fe429ec01e move holly interrupts out of types.h 2023-12-16 23:04:39 +01:00
Flyinghead 192838b9c1 maple: lightgun must return 0 for trigger axes
Fixes Death Crimson 2 fast forwarding in story mode when using a
lightgun.
Issue #646
2023-12-16 16:47:48 +01:00
github-actions[bot] 2a19ccf945 Fetch translations & Recreate libretro_core_options_intl.h 2023-12-15 22:19:48 +00:00
scribam 00954f1b60 egl: make sure display is valid before cleanup 2023-12-13 17:32:40 +01:00
scribam bf4346c849 android: update agp and gradle to version 8.2 2023-12-13 17:31:56 +01:00
scribam 32502e7459 cmake: remove hardcoded path to portlibs/switch 2023-12-13 17:31:17 +01:00
scribam 99031e23d3 windows: cleanup non-sdl code paths 2023-12-13 17:30:29 +01:00
github-actions[bot] f4f087a6ea Fetch translations & Recreate libretro_core_options_intl.h 2023-12-08 22:19:57 +00:00
Flyinghead 0433fd824c naomi: fix handling of dma abort
Fixes hang in f355 twin and twin2
2023-12-08 18:30:12 +01:00
Bobby Smith 9137ff998f Add a hotkey to bypass emulated keyboard 2023-12-07 16:48:31 +01:00
Flyinghead 7cc77b10ed naomi: schedule end of cart dma
Set to 20 MB/s to fix meltyb satsuki vs kouma hang when starting fight
Issue #1255
2023-12-07 16:14:10 +01:00
Flyinghead 07f208d2a2 elan: set dma completion delay to fixed min value
Fixes initdexp hang at race start
Issue #1337
2023-12-07 13:43:52 +01:00
Flyinghead 05cd7ee8d3 naomi2: fix initdv3j boot. avoid end of area crash with initdv2/v3jb
Abort processing and set elan error when invalid draw/dma commands are
executed.
Issue #981
Fixes MINIDUMP-K5 MINIDUMP-JS MINIDUMP-S0 MINIDUMP-98 MINIDUMP-125
MINIDUMP-12D MINIDUMP-22Q

Delay completion of elan dma transfers. Fixes initdv3j boot.
Issue #647

gdrom: some data was serialized twice
2023-12-05 18:25:40 +01:00
scribam d8e61520af windows: map arm/arm64 to host_context_t 2023-12-04 12:00:38 +01:00
Flyinghead e9beea484d Merge remote-tracking branch 'origin/master' into dev 2023-12-04 11:58:12 +01:00
Flyinghead 4aecdbbb25 input: new saturation setting for full analog axes. Gamepad settings UI
Saturation reduces or increases the range of analog axes.
Issue #675
Axes values are re-scaled with dead zone to allow small values.
New Gamepad Settings dialog box to set up dead zone, saturation and
rumble/haptic power.
2023-12-04 11:57:49 +01:00
Flyinghead d7c28a4805 aica: recommpile dsp when loading a state
Fixes bad noise when loading a menu state on tetris from in game.
2023-12-03 20:51:09 +01:00
Flyinghead 939e2bc68f vk: better deferred deletion. fix validation layer issues
Use raii-like mechanism to delete resources when not in use.
Fix several issues reported by validation layers (vtennis rtt, main
buffer size resizing, ...)
2023-12-03 19:18:16 +01:00
Flyinghead ce4a3a7147 scif: always schedule timer when updating baud rate
Old savestates don't have any callback set, and read only devices
(barcode readers) won't schedule any either
UI message when r/w card is ejected
2023-12-03 18:22:52 +01:00
Flyinghead 5fde889d7c builtin cheat for f355 network race. enable builtin cheats when online
Increase the datapump timeout from 500 to 1000 to avoid an error when
posting network race results.
Enable built in cheats when online
2023-12-03 16:44:43 +01:00
github-actions[bot] fd2a87fca2 Fetch translations & Recreate libretro_core_options_intl.h 2023-12-01 22:19:52 +00:00
Bobby Smith 153dbb0c56 [Libretro] Input descriptors fixes (#1330)
* Input descriptors fixes
* Refresh input descriptors w/o having to toggle menu
2023-12-01 15:05:30 +01:00
scribam e53433e6f5 cmake: use glad glx/egl/wgl only when sdl2 is not found 2023-12-01 15:04:41 +01:00
scribam db7895cea5 Some ifdefs to improve builds (#1325)
* mmu: hide some jit and fast mmu functions behind ifdef
* linux: move log to the correct place
2023-12-01 15:03:59 +01:00
scribam f3a774ab4e imgui: use fonts upload code from v1.90 2023-12-01 15:02:43 +01:00
Flyinghead bd25c14cfd libretro: fix manic panic touchscreen buttons 2023-11-29 12:31:30 +01:00
Flyinghead 035ea0b0c0 Force HLE bios for stupid invaders. Don't autosave state if networking
Force HLE bios for stupid invaders
Issue #354

Don't autosave state if GPPO or naomi networking is on
2023-11-29 12:30:16 +01:00
Flyinghead d6593b9c6e maple: race controller has only 3 axes
Reporting 5 axes (with the optional pedals unit) breaks some games:
daytona usa, super speed racing, F1 world grand prix, ...
2023-11-29 12:26:04 +01:00
scribam 105ab95efa deps: update imgui and implot 2023-11-25 17:08:01 +01:00
Edward Li 2c711e46fe Batch script for generating Visual Studio project 2023-11-25 17:07:34 +01:00
Edward Li 923be3899d msvc: update zlib includes, set default startup project 2023-11-25 17:07:34 +01:00
Flyinghead cb518b5481 serial: fix RDF and TDFE status bits
RDF and TDFE can't be reset if tx/rx fifo is below/above trigger
Remove rx overrun check
Proper reset of scif state
Fixes maxspeed, vonot and hell gate battle cable.
Tetris connects but still has input responsiveness issues.

sh4 mmr: use unnamed bitfields
2023-11-25 17:06:45 +01:00
Flyinghead a18e3701c6 Merge remote-tracking branch 'origin/master' into dev 2023-11-25 16:58:59 +01:00
Flyinghead 2ed4b4a984 tentative uwp build fix 2023-11-25 15:55:24 +01:00
Flyinghead f11a5981fe dynarec: increase code cache free space limit from 16 to 32 KB
Windows CE games have huge code blocks. (Tomb Raider - Last Revelation)
Fixes MINIDUMP-21R
2023-11-25 15:53:52 +01:00
github-actions[bot] ea83b08f89 Fetch translations & Recreate libretro_core_options_intl.h 2023-11-24 22:19:21 +00:00
scribam b785944560 cmake: use CMAKE_CXX_EXTENSIONS for Nintendo Switch 2023-11-23 16:51:50 +01:00
Flyinghead 8f3124d14e gdrom: increase gdrom ticks by 10%
Fixes Sakura Taisen 3 broken music
Issue #692
2023-11-23 16:49:05 +01:00
Flyinghead 14f3507b86 naomi: initd card reader fix. card reader refactoring
cardInserted was shadowed by initd card reader
use deque and vector instead of array+indexes
2023-11-23 16:44:03 +01:00
Flyinghead 4efacd7d71 Battle cable support
work in progress
f355 and aero dancing seem to work
vonot and tetris don't
maxspeed is broken
2023-11-23 16:40:20 +01:00
Flyinghead a9d5b77053 Merge remote-tracking branch 'origin/master' into dev 2023-11-20 17:13:51 +01:00
Flyinghead bc28c7ccb3 lr: enabke Insert Card button for all card reader games
Hide naomi f355 series and sgdrvsim on non-desktop platforms
2023-11-20 17:11:27 +01:00
scribam f14c29fd04 android: update android gradle plugin to version 8.1.4 2023-11-18 18:21:45 +01:00
scribam 3303ecbbd1 cmake: create folder hierarchy only for Xcode or Visual Studio generators 2023-11-18 18:21:19 +01:00
Flyinghead c4c4c2fde0 naomi: club kart card reader support 2023-11-18 18:20:41 +01:00
Bobby Smith 78a874d20e Add slider to change crosshair size and a core option for the Libretro core (#1304) 2023-11-18 13:44:57 +01:00
Flyinghead ef321d81a4 ui: customizable UI scale factor. rescan content button 2023-11-15 20:48:00 +01:00
Flyinghead df83ca436c input: use 16 bits of precision for analog axes/triggers 2023-11-15 18:24:30 +01:00
Bobby Smith 665ef86cf0 [Libretro] Change VMUs scaling for GL/D3D11 2023-11-15 11:55:25 +01:00
Flyinghead b9601d26e3 disable per-game settings for video routing options
Enabling video routing in a per-game config causes a crash.
Fixes MINIDUMP-22K
2023-11-15 11:54:33 +01:00
Flyinghead 038df0d923 dx9: half-pixel fix for rtt. disable separate alpha/color blend funcs
The dx9 half-pixel translation fix must use the rtt texture pixel size.
Issue #1299

ImGui enables separate alpha and color blending funcs so it needs to be
disabled in the renderer.
Issue #1301
2023-11-15 11:50:45 +01:00
Flyinghead 73cbd7a183 libretro: crosshair/vmu invisible with gl per-triangle/per-strip
libretro needs ofbo.aspectRatio to be set when drawing crosshairs and
vmus
2023-11-15 11:47:34 +01:00
Flyinghead ab25cc73a9 libretro: fix lightgun crosshair blend func and size
Use upscale factor for lightgun crosshair (opengl, dx11)
Fix crosshair blend function (opengl)
2023-11-14 15:46:44 +01:00
Flyinghead a0014bc810 naomi: allow printing for f355/1 screen. Fix print template
f355 vanilla can print even when running with a single screen.
Fix print template by Ciopy Burns
Repeat print template vertically as needed for longer prints
No networking for f355 vanilla
2023-11-14 15:42:20 +01:00
Flyinghead 6de5879cb4 libretro: enable "Insert Card" button for vf4 and barcode games
Still no way to input barcode code however
2023-11-14 15:37:26 +01:00
Flyinghead 32ecb141df libretro: macos build fix
Some OpenGL functions are missing on macOS
2023-11-13 14:39:20 +01:00
Flyinghead 4cd90d8ebb rend: yet another hash fix of vq textures
The calculated size for vq textures was half the correct value, which
affects the texture hash. Calculate the old hash and use it as fallback
for backward-compatibility.
Issue #1291
Make the texture data start address really point to max mipmap data, no
more codebook skipping.
2023-11-13 14:37:38 +01:00
Flyinghead 46eab502e4 libretro: don't link with OpenGL libs on android, windows and linux
Issue #1221
2023-11-12 13:05:13 +01:00
Flyinghead 535fbe29f8 rend: fix hash of vq textures
Do correct hashing of VQ textures to avoid hash conflicts. Keep previous
hash for backward-compatibility.
Issue #1291
2023-11-11 18:57:16 +01:00
Flyinghead 41723a831f use static init when possible. use unnamed bit-fields. refactor vmuBeep
no functional changes
2023-11-11 18:54:10 +01:00
scribam abe1d4fd27 deps: replace glew with glad (#1290) 2023-11-11 18:29:36 +01:00
github-actions[bot] dda04e63fa Fetch translations & Recreate libretro_core_options_intl.h 2023-11-10 22:19:50 +00:00
Flyinghead e60f30b357 naomi: use background template for f355 printing
template courtesy of Ciopy Burns
2023-11-10 17:58:46 +01:00
Flyinghead f0f27558af initd: network config was overriding difficulty level
same for initd, initdv2 and initdv3
disable networking for club kart prize
2023-11-10 17:54:28 +01:00
Flyinghead 0f6a92caad linux: retrieve page size at build time
Fixes RPi 5 16 KB page size. Will not work if cross-compiling however
Issue #1288
2023-11-09 19:29:00 +01:00
Flyinghead 9a60cd7ded kingrt66: network config was overriding other settings
Auto accel, CB Mic and Motor Power settings share the same config byte
in eeprom, so don't change them when configuring network settings.
2023-11-09 19:25:10 +01:00
Flyinghead 926877397c Merge remote-tracking branch 'origin/master' into dev 2023-11-07 16:32:12 +01:00
vkedwardli b92277ac58 macOS: Register file extensions for openFile (Drag ROM to App Icon), update setupWorkingDirectory, rename SDLMain to SDLApplicationDelegate to avoid confusion with the function SDL_main() (#1287)
Register file extensions for openFile, and supports the following actions
    Drag ROM to Application icon to launch the app
    Drag ROM to the running app's dock icon
    Drag ROM to the running app's window (applicable to all SDL platform by SDL_DROPFILE)
Update setupWorkingDirectory
    macOS default cwd is a nonsense "/" for non-terminal application
Rename SDLMain to SDLApplicationDelegate to avoid confusion with the function SDL_main()
some code cleanup
2023-11-07 16:29:08 +01:00
scribam 9a7bf75e4e deps: update sdl to version 2.28.5
Set minimum version required to 2.0.9 because of SDL_JoystickRumble
2023-11-07 16:27:23 +01:00
Flyinghead 1253e1199d tentative sentry build fix 2023-11-05 19:19:22 +01:00
Edward Li 51508dcdc6 macOS: Indicate slave machines by dock badge label 2023-11-05 18:39:37 +01:00
Edward Li f6b3577de5 Save race result image to writable data folder 2023-11-05 18:39:37 +01:00
Edward Li a4ec706c79 Init ThermalPrinter only when cabinet type is Deluxe.
nvmem: Enable printer by default for `f355twin` and `f355twn2`
2023-11-05 18:39:37 +01:00
Flyinghead cb890c7b6f windows: fix run instance with path containing spaces or non ascii 2023-11-05 18:39:04 +01:00
github-actions[bot] dbfead6a15 Fetch translations & Recreate libretro_core_options_intl.h 2023-11-03 22:19:52 +00:00
Flyinghead fd3f207e45 maple: move arcade input settings into maple init
Get rid of settings.input.JammaSetup
2023-11-02 19:00:29 +01:00
Flyinghead 594b403997 naomi: add some (mostly not working) roms
mazanj
dygolfp
shors2k2m
shors2k2s
shors2k2l
shors2k2
wccf116
wccf1dup
wccf212e
wccf234j
wccf310j
wccf331e
wccf322e
wccf331j
wccf341j
wccf400j
wccf420e
galilfac (systemsp)

Fix hotd2p, virnbap, huhimage
2023-11-02 18:44:52 +01:00
Flyinghead bafe07de85 aica: better sounding LPF
Use 4 bits of exponent instead of 5 for the cut off frequency
Force sample to 0 if cut off freq is 0
Improve BIOS menu sounds
Issue #108
2023-11-02 18:33:14 +01:00
Bobby Smith 3e047a6e03 Create expansion device for "Racing Controller" 2023-11-01 15:43:08 +01:00
Flyinghead 29c0dca0ce naomi: enable printer for all f355 editions
only usable in deluxe mode (f355twin, f355twn2)
2023-11-01 15:41:41 +01:00
flyinghead 5cfd3f0ba3 Merge pull request #1274 from bslenul/lr-invalid-values
[Libretro] Remove some "Invalid value" errors
2023-10-31 13:55:23 +01:00
flyinghead 923dcf10a7 Merge pull request #1271 from notcbw/enable_deadzone
Minor GUI change to add an option that sets the deadzone for analog sticks
2023-10-31 13:55:12 +01:00
Flyinghead 7b71bd319c Android and iOS support. Change dead zone to integer % value in UI
UI: dead zone changes from 0 to 100%. Add % for Rumble too.
Support Android and iOS gamepads.
Assume legacy gamepads have an analog stick (evdev, xinput)
2023-10-30 18:28:29 +01:00
Flyinghead 51089c5e0a aica: always avoid race condition when sh4 interrupt is raised
... even if an SH4 interrupt is already asserted.
Regression introduced by c7d214e55a
Fixes audio freeze in Test Drive Le Mans
Issue #1267
2023-10-30 17:47:19 +01:00
Flyinghead 24944e00a7 force Full Framebuffer Emulation for some games
Eisei Meijin III
Marionette Company
World Neverland Plus
Issue #1266
2023-10-30 17:43:33 +01:00
Bobby Smith 66faf0d330 [Libretro] Remove some "Invalid value" errors 2023-10-30 16:21:26 +01:00
Bowen Cui c0de126b2b Add option to set deadzone for analog sticks 2023-10-30 05:21:36 -04:00
github-actions[bot] c1f0a5a15f Fetch translations & Recreate libretro_core_options_intl.h 2023-10-27 22:19:54 +00:00
Flyinghead f640b32cc9 enable Copy to VRAM for a bunch of games
Worms World Party (US)
Hundred Swords
Musapey's Choco Marker (dreamcast)
Choco Marker (naomi)
Sister Princess Premium Edition
Sentimental Graffiti 1 & 2
Kanon
Aikagi
AIR
Issue #1265
2023-10-27 14:56:28 +02:00
Flyinghead 93e47dd410 aica: don't change LEA for non-looping sounds
Non-looping sounds with LSA=0 and LEA=0 shouldn't be played at all.
Regression introduced by dac5b991e0.
Fixes white noise in Sonic Adventure Emerald Coast action stage.
Issue #1264
2023-10-27 14:52:07 +02:00
Flyinghead 8fb3def2d5 gl oit: fix several issues
Disable blending when rendering a-buffers. Fixes ECW Anarchy Rulz black
title screen and Demolition Racer glitchy end of race screen.

Use palette in the depth pass for punch-through polygons using palette
texture. Fixes shadow issue in Alone in the Dark.

Copy ouput fbo to geom_fbo before drawing. Fixes missing transparent
polygons in subsequent partial renders. Fixes Test Drive Le Mans missing
labels in loading screen.

Issue #1262
2023-10-25 16:59:01 +02:00
Flyinghead 98a0f2b821 gl: frame upside down with GLES 2.0 if video shift is on
drawQuad ignores the swapY param if vertices are provided so swap Y
coords of vertices.
2023-10-25 16:53:25 +02:00
Flyinghead 4fafa91506 gl: disable dithering with GLES 2.0
GLES 2.0 doesn't allow initialization of const arrays.
Fixes MINIDUMP-1YP MINIDUMP-1YQ
2023-10-25 16:51:44 +02:00
Flyinghead 09a1fea40f arm32: fix host rounding mode on android
It looks like setting host rounding stopped working on armv7 android a
while ago (v1.0 already has the issue). Directly setting the host FPSCR
register doesn't work so use the C99 standard functions fegetenv and
fesetenv instead.
Fixes flickering yoshimitsu legs in Soul Calibur.
Fixes rotating objects in Sword of the Berserk.
Issue #556
Issue #1259
2023-10-25 16:48:58 +02:00
Flyinghead e55d70c0e6 dx9,dx11: depth surface and temp render target resize issue with RTT
dx9: resize depth surface to max width and height when RTT
dx11 oit: resize all depth and temp render targets when RTT but keep
current framebuffer.
Fixes Flag to Flag not updating the screen when RTT'ing rear view
mirrors.
Issue #1257
2023-10-23 10:36:41 +02:00
Flyinghead ca45ff3834 default to Vulkan renderer if OpenGL not compiled in
Issue #1258
2023-10-23 10:10:49 +02:00
Flyinghead 35c71ebcfd rend: add hcount and vcount used by meltyb for video shift calc
meltyb (and possibly others) uses hcount=850 (instead of 851) and
vcount=528 (instead of 529)
2023-10-22 12:08:19 +02:00
Flyinghead 33edcca348 texture: expand color data of planar textures
Partial revert of f4835a89d3
Fixes color differences between planar and !planar textures in Sakura
Taisen 2.
Issue #1256
2023-10-22 10:17:01 +02:00
Flyinghead dac5b991e0 aica: ignore LEA if <= LSA
Fixes Legacy of Kain Ash Village music
Issue #1104
2023-10-22 10:12:30 +02:00
Flyinghead 8ba5e05421 android scoped storage: default to hack the uri manually in getParentUri
If DocumentsContract.Path.getPath() fails, try to hack the uri manually
instead of returning null/empty (android 10)
2023-10-21 21:40:13 +02:00
github-actions[bot] 35b7be3905 Fetch translations & Recreate libretro_core_options_intl.h 2023-10-20 22:19:13 +00:00
Flyinghead b7d923e02b maple: clear mapleDmaOut on reset. Other reset issues
mapleDmaOut wasn't reset, causing crashes or freezes in subsequent runs
Issue #1253

reset YUV state, pvr tile clip, MMU sq_remap, sh4 sq_buffer and more
2023-10-20 16:15:42 +02:00
Flyinghead eaf2c0064c enable copy to vram for sakura taisen 1
Issue #1252
2023-10-19 19:58:05 +02:00
Flyinghead a65cd9e5f9 savestate: fix retroarch savestate compatibility
A new RA header must be skipped in standalone
2023-10-19 19:56:43 +02:00
Flyinghead e94b26f1df gdrom: return blank sector if FAD miss
Fixes NBA Hoopz (US) voice samples
Issue #1247
2023-10-17 14:29:05 +02:00
Flyinghead e96b38ff5c rend: support vscalefactor > 1 for RTT
SCALER_CTL.vscalefactor also applies to RTT and values > 1 will increase
the texture height.
dx11: initialize abufferPointers to avoid issues with first frame
rendered.
Fixes pause menu/battle animation with Skies of Arcadia (PAL)
Issue #1127
2023-10-16 14:51:27 +02:00
Flyinghead e894d4df5c sh4: limit penalty cycles to first 3 mem ops
Fixes choppy video in Dynamite Cop! and Resident Evil 2 intros.
Fixes desync between character and background in UFC championship intro.
Fixes Dino Crisis (JP) desync between video and subtitles.
Fixes South Park Rally boot freeze with one controller and 2 vmus.
Add cheats for Dave Mirra BMX to fix main loop timing.
Issue #1034
2023-10-16 14:39:15 +02:00
Flyinghead c58ae4daac vulkan: terminate context if init fails
Avoids crash on exit
2023-10-16 14:19:47 +02:00
github-actions[bot] cb9af7d742 Fetch translations & Recreate libretro_core_options_intl.h 2023-10-13 22:19:51 +00:00
Flyinghead 2a364dee67 dynarec: check null codeBuffer in rewrite() if called before init
Fixes MINIDUMP-1VN, MINIDUMP-1X1, MINIDUMP-1XD
2023-10-13 11:41:18 +02:00
Flyinghead 56107b3667 dx11 oit: missing depth pass for transparent polys when autosort=0
The depth pass with transparent polys must also be done when autosort=0.
Fixes The Grinch pause menu
Issue #1244
2023-10-13 11:00:19 +02:00
Flyinghead 31aab32d95 dx9: unreleased resources make device reset fail
dcfbSurface and vmu texture were leaked when updated, causing the device
reset to fail when maximizing or restoring the app window.
Issue #1243
2023-10-13 10:55:45 +02:00
Flyinghead 0b66409ed2 naomi: default eeprom for pokasuka ghosts
Fixes coin assignments error at boot
Issue #1237
2023-10-13 10:51:07 +02:00
Flyinghead 8ae288d2ca gdb: revert swapping of words
Partial revert of b0a520fe18
Short and ints shouldn't be swapped.
gdb can handle both little and big endian SH4 (set endian big/little).
2023-10-12 09:49:55 +02:00
Flyinghead 4419ff310a naomi: default eeprom for manic panic
Fixes coin assignments error at boot
Issue #1237
2023-10-12 09:36:09 +02:00
Flyinghead 2f524923da set extra depth scale back to 0.1 for Caesars Palace 2000
Fixes pause menu background transparency in video keno game.
Regression introduced by cc1b45b7cc
Issue #1236
2023-10-11 14:42:35 +02:00
Flyinghead 07d761a880 rec x64: move jit_set_exec out of exception scope in rewrite 2023-10-11 14:28:39 +02:00
Flyinghead f6f6637973 naomi: mushikep compatibility 2023-10-11 14:25:11 +02:00
Flyinghead 2cd3ffb33f Revert "vk oit: add sync event between renderer and vk context on Mali
gpu"

This reverts commit abd9219347.
Issue #1234
2023-10-11 14:13:34 +02:00
Flyinghead abd9219347 vk oit: add sync event between renderer and vk context on Mali gpu
Use vk event to wait for renderer pipeline to finish before rendering
the final frame in vk context. This seems to help Mali gpus.
Issue #1234
2023-10-11 09:35:18 +02:00
Flyinghead 417a42ae10 boxart: image mix up due to broken rand() on windows
srand() wasn't called and rand() returns the same number twice on
windows (RAND_MAX is only 32767).
Use c++11 random instead.
Issue #1231
2023-10-10 11:47:50 +02:00
Flyinghead 0e12153c45 libretro: frame is flipped vertically with GLES 2
drawQuad ignores the swapY parameter if vertices are provided.
Reverse the shiftY direction for pvr2 filter.
Issue #1233
2023-10-10 11:37:00 +02:00
Flyinghead cb33387ed6 gdrom: clear DRQ on ATA_NOP
Fixes Sentimental Graffiti 2 hang when switching disk
Issue #1232
2023-10-09 22:39:54 +02:00
Flyinghead 38d4689b63 gl,vk,dx: use nearest filtering for mipmap with PT polys
Interpolating between LoDs produces unexpected alpha values.
dx,vk: add negative LoD bias
Fixes "Press Start" text in Trizeal title screen

dx11: get rid of bogus nearest wrap hack
Can't reproduce original issue with daytona
Fixes Virtua Tennis title screen
Issue #1230
2023-10-09 21:09:03 +02:00
Flyinghead 23d1db9c75 nvmem: add email address to flash ISP config
Issue #1227
2023-10-09 20:44:15 +02:00
Flyinghead 4e079b5d0b missing override keyword 2023-10-08 19:14:33 +02:00
Flyinghead 3fcbdd3fc5 gl: missing precision qualifier for dithering table
Fixes MINIDUMP-1VR MINIDUMP-1W0 MINIDUMP-1W1 MINIDUMP-1WE MINIDUMP-1WF
2023-10-08 19:13:07 +02:00
Flyinghead 78b44919c5 vk, gl: ignore fb_enable and blank_video during normal render
Fixes some screen missing. Already handled in renderFB. Should be
handled at Present time.
gl4: first frame after renderFB was missing

Issue #1217
2023-10-07 15:46:28 +02:00
github-actions[bot] 13a8d49c90 Fetch translations & Recreate libretro_core_options_intl.h 2023-10-06 22:19:36 +00:00
flyinghead 7308f9a704 sh4: dont change host rounding mode in Sh4_int_Reset()
Don't change host rounding mode in Sh4_int_Reset(), which is typically
called from the UI thread.
Set rounding mode to default before calling renderer (single-thread
mode), restore it before returning.
Fixes issues with dx11 shaders compilation: rounding mode affects
inexact literal float values.
Issue #1224
Issue #1207
2023-10-06 18:17:14 +02:00
Flyinghead 18f9b84af6 elf: memory corruption if .elf file is invalid 2023-10-05 11:45:14 +02:00
Flyinghead 56517b027a naomi: fix gdrom searching in rom parent path
OpenDisc() now throws so exceptions must be caught
Never return null from OpenDisc
2023-10-05 11:43:22 +02:00
flyinghead d4a02e3c2b Merge pull request #1219 from scribam/android
android: update android gradle plugin to version 8.1.2
2023-10-04 17:07:39 +02:00
flyinghead 33131e1395 Merge pull request #1214 from scribam/sdl
deps: update sdl to version 2.28.4
2023-10-04 17:06:58 +02:00
flyinghead 73ac46f421 Merge pull request #1213 from scribam/lua
lua: set minimum version required to 5.2
2023-10-04 17:06:08 +02:00
scribam 7fc70ee1f4 android: update android gradle plugin to version 8.1.2 2023-10-03 22:50:35 +02:00
scribam d9b5f27311 deps: update sdl to version 2.28.4 2023-10-02 21:42:47 +02:00
scribam 252838d896 lua: set minimum version required to 5.2 2023-10-02 19:52:33 +02:00
Flyinghead cb91ad3ae0 reset platform to dreamcast after unloading game
so that Language, Broadcast, Cable, etc. are enabled in the UI
2023-10-01 20:07:59 +02:00
Flyinghead 60f3d718ac arm64 rec: fix crash with some naomi games (regression)
Fixes crash with doa2a and doa2m and some atomiswave conversions.
Regression due to b47f4f56ef
Fixes MINIDUMP-1TY, MINIDUMP-1TD, MINIDUMP-16Q, MINIDUMP-1AC
2023-10-01 19:31:18 +02:00
github-actions[bot] e8e382372a Fetch translations & Recreate libretro_core_options_intl.h 2023-09-29 22:19:16 +00:00
flyinghead 205c365b1b Merge pull request #1208 from flyinghead/dev
merge dev branch
2023-09-27 16:59:19 +02:00
Flyinghead 09857008bd rend: guard against NaN depth if z is negative
Fixes prison white background effect in RayMan 2
Issue #1209
2023-09-27 14:55:31 +02:00
Flyinghead 5eddc26850 dx11: work around some float literal precision issue with the compiler
For some reason the directx compiler doesn't convert float literal in a
deterministic way (!). A difference of one ulp can be seen between
different compilation of the same code.
This causes an issue with the rounding of the alpha value for PT polys.
Issue #1207
2023-09-26 17:05:21 +02:00
Flyinghead 496429d6f4 ci: re-enable fail-fast 2023-09-25 23:10:49 +02:00
Flyinghead a915f185f8 Merge remote-tracking branch 'origin/master' into dev 2023-09-25 22:17:29 +02:00
Flyinghead 0f6e1752e3 rend: clear framebuffer when vram address changes
Fixes top and bottom leftovers from BIOS boot in San Francisco Rush
2049.
Issue #1197
2023-09-25 18:23:26 +02:00
Flyinghead e57ccde532 systemsp: pluggable input manager. fix lr. disable isshoni P1 button 1
Delegate input management to game-specific class
Default, card reader/dispenser and isshoni input managers
isshoni: Use button 1 for touchscreen press
libretro: systemsp input mapping
2023-09-25 17:38:41 +02:00
vkedwardli f75a16f40c Ignore Mouse Capture when Left Ctrl or Left ALT is mapped to a Dreamcast Key (#1203) 2023-09-24 16:02:18 +02:00
Flyinghead a869e183db gl: video shift y needs to be inverted too
follow up to 5ffcdb5f1e
Fix crash in pvr2 post processor when rendering the dc framebuffer
2023-09-24 13:09:00 +02:00
Flyinghead c60edb0090 gl: get rid of async copy to vram
Fix issues when games access texture data directly in vram.
Jet Set Radio custom graffiti copy to vmu. Issue #232
Cardcaptor Sakura best shots. Issue #1089
Grandia II battle start effect.

Force Copy to VRAM for Cardcaptor Sakura, Grandia II, Canvas, Sakura
Taisen 3 and more
2023-09-24 11:29:22 +02:00
Flyinghead 84d82f360b dx11: black screen with full fb emu when scaling. dx9: fb render fix
dx11: black screen when full framebuffer emulation is enabled if scaling
is on (480 -> 240p)
Fixes Mr.Driller. Issue #1067
dx9: wrong stretching when rendering the dc framebuffer if aspect ratio
different from 4:3
2023-09-24 11:04:24 +02:00
Flyinghead b002bdff39 ui: color chooser for crosshair was changing on its own
Only change color when needed and use rounding when converting back to
integer.
Issue  #1074
2023-09-24 10:57:50 +02:00
Flyinghead 5ffcdb5f1e gl: flip Y coord when drawing framebuffer to avoid rounding issues
Flip Y again when drawing to final framebuffer
Fixes HUD characters truncated vertically in Test Drive V-Rally
Issue #1088
2023-09-23 14:57:19 +02:00
Flyinghead 79bbd86c2f rend: Fix PT polygons alpha test
Alpha test for PT polys is done after mixing texture and vertex colors
and clamping. Revert db0534d5dd. See
86235bb4a3.
Fixes visible triangle arrows after selecting a character in Langrisser
Millenium.
Issue #1201

vk oit: OP polygons don't support blending
2023-09-23 14:01:26 +02:00
Flyinghead 39a212140a vk: add bumpmap flag to pipeline hash
Fixes disappearing pause menu text and green wooden boxes in Mat
Hoffmann's Pro BMX
Issue #878
2023-09-23 11:13:14 +02:00
github-actions[bot] dddd712f08 Fetch translations & Recreate libretro_core_options_intl.h 2023-09-22 22:19:05 +00:00
Colton Pawielski a7dbbbe578 Add Dreamcast 32MB RAM Mod (#1198) 2023-09-22 11:10:44 +02:00
Flyinghead 2445739c0e arm,arm64 rec: check fault location before attempting to rewrite
Ignore fault if pc isn't in the dynarec code buffer.

Fix for MINIDUMP-1S0, MINIDUMP-1RS
2023-09-20 17:25:09 +02:00
Flyinghead 403f1f635b systemsp: load rom boot id from compact flash volume
Open and decrypt 1STREAD.BIN then the image file to extract the rom boot
id.
Fix boot id for non-encrypted roms (bingogals)
Reset naomi default eeprom when forcing different region and before
reloading the bios.
2023-09-20 17:22:28 +02:00
Flyinghead 879372cb79 rec-x64: use FMA when available
x64 vfmadd is a better implementation of the sh4 FMAC op, so use it if
available. Fall back to mul+add if GGPO is enabled to avoid desyncs
between different cpu models.
Issue #1201
2023-09-20 17:14:50 +02:00
Flyinghead 6b05c0ab01 tex conv: extend alpha channel of planar 4444 textures
The alpha channel needs to be extended for PT polygons to work. Fixes
Langrisser Millenium black title screen and missing textures on
character selection screen.
Issue #1201
2023-09-20 17:06:05 +02:00
Flyinghead 289f264371 systemsp: set correct region for rom games
Override the region when not supported by the game. Only works for rom
games.
2023-09-19 17:59:20 +02:00
Flyinghead 869ddb643d systemsp: initialize media name and default eeprom
Fix failure to load a systemsp rom game after running a compactflash
game.
Fix error 05 if selecting the wrong region then switching to Japan.
2023-09-19 16:13:27 +02:00
Flyinghead c63f1a9997 pvr: background poly vertex order fix
Fix background poly vertices coordinates to form a valid triangle strip

Fixes lovebery bogus background poly on character selection screen.
Issue #1200
2023-09-19 16:08:22 +02:00
Flyinghead 0fc0dc5101 systemsp: rfid management chip emulation
fixes dinoking, dinokior, dinoki25, lovebery, lovebero and loveber3
2023-09-18 11:00:08 +02:00
github-actions[bot] 213bc70e2d Fetch translations & Recreate libretro_core_options_intl.h 2023-09-15 22:19:06 +00:00
Flyinghead c839bc89eb naomi: crash when loading a legacy .bin rom
More fix for MINIDUMP-1DA, MINIDUMP-1D8, MINIDUMP-1EM
2023-09-15 18:50:55 +02:00
Flyinghead 84f2871650 renderer: set render timeout to 20 ms to reduce input lag at 30 FPS
Fixes mouse not responding in 30 fps (Quake 3) or variable fps games
(Unreal)
Issue #949
2023-09-14 15:18:56 +02:00
Flyinghead e1b4d4d703 naomi: crash when loading a legacy .bin rom
Fixes MINIDUMP-1DA, MINIDUMP-1D8, MINIDUMP-1EM
2023-09-14 15:08:56 +02:00
vkedwardli b564b0bf91 Increase L2+ / R2+ trigger sensitivity for digital buttons (#1190) 2023-09-14 09:08:58 +02:00
Flyinghead 7e1dcf9003 maple: move test, coin and trigger buttons into the upper 16-bit range
avoid interfering with regular jvs/maple buttons
2023-09-12 19:13:40 +02:00
Flyinghead 0f4c903fed ios build fix 2023-09-12 19:06:59 +02:00
Flyinghead 0ac483acfc sh4 dynarec refactoring
sh4 code buffer class
dynarec interface and implementations
2023-09-12 16:52:25 +02:00
Flyinghead f4835a89d3 implement dithering in full FB mode
gl, vk, dx11, dx9: implement ordered dithering in GLSL/HLSL
refactor framebuffer and texture writes to vram
don't expand color data when reading planar textures
2023-09-10 16:25:19 +02:00
Nejsplitter 139f248572 libretro: Allow up to 300 MHz overclock (#1193) 2023-09-09 17:00:00 +02:00
flyinghead b23d37f76f lr dx11: set all shaders in Quad to avoid conflicts with RA
RA uses geometry and/or compute shaders, which must be disabled when the
core is drawing.
Issue #1192
2023-09-09 16:22:50 +02:00
flyinghead 56358be542 lr: opengl OIT renderer not enabled at startup
default renderer on windows is now dx11, which confuses the lr opengl
graphics context creation.
Issue #1191
2023-09-09 16:09:59 +02:00
Edward Li 1377e61d03 DX11: Use high performance GPU on Windows 10 (1803 or later) 2023-09-07 09:51:45 +02:00
Flyinghead ce694ba8b5 apple: vulkan sdk 1.3.261.1 2023-09-02 20:36:08 +02:00
Flyinghead 8eae6b97fc ui: keyboard input was ignored when resuming game if no render
When resuming a game, keyboard is ignored until the next frame is
rendered. This is due to ImGUI not updating its WantCaptureKeyboard flag
until the next frame, which is an issue if the game isn't actively
rendering frames (Zombie Revenge pause screen, Giant Killers)
2023-09-02 20:00:07 +02:00
Flyinghead d29645cc49 naomi: derbyoc JP card reader support. security pic for doa, tduno
Derby owner's club (JP) uses a Sanwa CRP-1231LR card reader. World
edition uses a Sanwa CRP-1231BR.
Set x76f100 security pic content for doa2, doa2a, doa2m, tduno
2023-08-27 17:20:43 +02:00
github-actions[bot] f870ccc23c Fetch translations & Recreate libretro_core_options_intl.h 2023-08-25 22:19:13 +00:00
Flyinghead 3aa2f922e7 fix test 2023-08-25 17:13:45 +02:00
Flyinghead 129fff1c2a naomi: x76f100 and at93cxx implementation. naomi2 elan fix
proper emulation of x76f100 security eeprom and at93cxx serial eeprom
elan: don't reset projection matrix at end of frame. Issue #1177
2023-08-25 17:01:40 +02:00
scribam 10b13dfe9c deps: update to match Vulkan SDK 1.3.261.0 2023-08-24 17:33:47 +02:00
scribam d506cc40a2 deps: update CMakeRC.cmake 2023-08-24 17:33:47 +02:00
scribam 358a54152b deps: update imgui to version 1.89.8 and implot 2023-08-24 17:33:47 +02:00
scribam 06e2c455e8 deps: update sdl to version 2.28.2 2023-08-24 17:33:47 +02:00
scribam a1838eee30 deps: update libchdr 2023-08-24 17:33:47 +02:00
scribam 56b082def7 uwp: add support for arm 2023-08-02 09:32:55 +02:00
Shingo INADA 92a10ba0f0 [input] fix LT2/RT2 mapping save 2023-07-31 16:12:13 +02:00
Flyinghead c637ae8281 Merge remote-tracking branch 'origin/master' into dev 2023-07-30 18:05:38 +02:00
scribam 40953b17c4 uwp: add support for arm64 2023-07-30 18:03:32 +02:00
scribam a473154250 sentry: use new syntax for uploading files 2023-07-30 18:02:56 +02:00
scribam 13f3c3e228 android: update cmake and ndk 2023-07-30 18:02:43 +02:00
scribam 817cc87c8c android: update android gradle plugin to version 8.1.0 2023-07-30 18:02:43 +02:00
GABO1423 ab09efa762 (README) Modify Xbox Section 2023-07-28 10:03:31 +02:00
Flyinghead 7061c043d9 naomi: derbyocw card support. serial pipes refactoring. systemsp fixes
common interface for most serial pipes
jvs: MIE RS422 port support
card reader: allow reading/writing of individual tracks
systemsp:  fix interrupt handling. refactor serial ports. isshoni wanwan
puppy touchscreen support
2023-07-26 21:34:03 +02:00
Flyinghead 92a19e9250 hopper fixes. fix kick4cash input
kick4cash encoders are rotated 45° and polling is done twice per frame.
add bet button to shootout pool and club kart (prize)
hopper: load/save config. fix pay out and bet values. proper defaults
based on selected currency.
2023-07-23 17:16:08 +02:00
scribam 4f5fd31d81 archive: replace zip_get_num_files (deprecated) by zip_get_num_entries 2023-07-22 19:04:52 +02:00
scribam 1b565f9879 clang-tidy: run modernize-concat-nested-namespaces 2023-07-22 19:04:52 +02:00
scribam d2b475ae41 boxart: remove redundant call to c_str() 2023-07-22 19:04:52 +02:00
Lucas Azevedo 9c61006941 Fix GUI SDL mouse buttons
Clicks were swapped in GUI as SDL uses 2 for middle and 3 for right and
the GUI expects the opposite (minus 1).
2023-07-18 11:00:58 +02:00
scribam 4db26bc092 spg: fix warning 'vblk_cnt' defined but not used 2023-07-16 19:57:51 +02:00
Flyinghead 8c0f543bc8 naomi: hopper support for kick'4'cash, shootout pool and club kart prize
high level emulation of 837-14438 and naomi SWP hopper boards
2023-07-16 19:57:16 +02:00
Flyinghead 8e3a48eb6f naomi: fix shootout pool inputs
Use button 1 to switch between cue aim and cue roller rotary encoders.
Remap start/mode to start
2023-07-16 19:10:39 +02:00
Flyinghead 7a22318b0f sdl: don't send button up events based on mouse button state
as doing so cancels other inputs bound to the same target
2023-07-16 19:03:07 +02:00
github-actions[bot] a0bf24f7cc Fetch translations & Recreate libretro_core_options_intl.h 2023-07-14 22:20:09 +00:00
Flyinghead 3c6eaa4d34 aica arm: use scratch reg for call/jump if offset if too big (armv7)
Issue #1148
2023-07-14 21:32:49 +02:00
Flyinghead 3bf817aea1 vk: reset semaphore index to 0 when recreating the swap chain
When frame dupe is enabled and switching to fast forward, the current
semaphore index might end up pointing past the end of the semaphore
array, causing a crash.
Issue #1138
2023-07-10 12:41:13 +02:00
scribam a3ebe02f85 vk: modernize device properties retrieval 2023-07-09 18:51:44 +02:00
scribam 4eda9ebffc cmake: exclude nowide tests from unit tests 2023-07-09 18:50:47 +02:00
Edward Li 278f26aadd macOS: Enable clipboard functions and corresponding menu items 2023-07-06 18:42:31 +02:00
Flyinghead 17b82ab5d3 ci: disable fail fast on c-cpp job because of MacOS failures 2023-07-05 10:59:12 +02:00
Flyinghead 30e66d1c17 reios: ignore high order bits for FAD
Mask FAD with ffffff. Apparently the regular BIOS does the same. Fixes
bogus FAD issued by Guilty Gear X when playing CD audio.
Issue  #1124
2023-07-05 10:23:54 +02:00
Edward Li 2089015221 Fix Spout2 MinGW error 2023-07-03 11:38:35 +02:00
Edward Li e19a62aa07 Ignore brew update failure 2023-07-03 11:38:35 +02:00
scribam 42d003597e deps: update sdl to version 2.28.1 2023-07-03 11:38:06 +02:00
scribam f9da57d87f deps: reapply patches to vixl 2023-07-03 11:37:42 +02:00
scribam daf8230cca deps: update vixl 2023-07-03 11:37:42 +02:00
Flyinghead f02265b662 systemsp: fix sram addressing
translate dinoki4 rom name
2023-07-03 11:36:59 +02:00
Flyinghead 5eb893a995 Sega SystemSP support
add naomi roms: anpanman2, anpanman2a, drbyocwt and clubkpzbp
2023-07-01 16:24:51 +02:00
Flyinghead dfd517706a Merge remote-tracking branch 'origin/master' into dev 2023-07-01 16:03:10 +02:00
Flyinghead b47f4f56ef user-defined literals: _KB, _MB, _GB 2023-07-01 14:31:25 +02:00
Edward Li a870fb7f6c deps: update vulkan to 1.3.250.1, fix 404 on macOS 2023-06-30 18:12:53 +02:00
vkedwardli 7cd308fcae Realtime Video Routing (#1126)
* Syphon video routing with OpenGL and Vulkan (MacOS)
* Spout video routing with DX11 and OpenGL (Windows)
* Fix Xcode detection
2023-06-26 11:56:56 +02:00
scribam 6e6f75386b deps: update sdl to version 2.28.0 2023-06-26 11:53:22 +02:00
Flyinghead aad4921e09 picotcp: fix kos ppp nego. modem,bba: fix kos detection
picotcp: ignore conf ack received when lcp layer is up (kos ppp)
picotcp: ignore icmp ping seq and id #
scheduler: add void * arg to callback function. Get rid of static instances when possible
bba: use scheduler to delay link changes (fixes kos bba detection)
modem: fix soft reset. don't reset TDBE during reset (fixes kos modem detection)
2023-06-23 11:40:22 +02:00
Flyinghead 8b8113b482 Merge remote-tracking branch 'origin/master' into dev 2023-06-23 10:12:32 +02:00
Ricardo Mendonça Ferreira 98acd1178d Libretro: support for more controllers, code cleanup
Added support for new controllers in the Libretro interface: 
- Maracas (RETRO_DEVICE_MARACAS)
- Fishing Controller (RETRO_DEVICE_FISHING)
- Pop'n Music (RETRO_DEVICE_POPNMUSIC)
- Race Controller (RETRO_DEVICE_RACING)
- Densha de Go! (RETRO_DEVICE_DENSHA)

Also did a bit of refactoring, mostly for readability, but also moving repeated code into functions.
2023-06-22 22:28:25 +02:00
Flyinghead 0070f9abad network: fix known UDP ports bind regression
introduced by b4e5af6346
Add driving strikers netdemo known port
Issue #1112
2023-06-21 16:31:01 +02:00
Flyinghead dca048981f network: process both inbound and outbound packets for 2k games
DreamPi processes inbound packets on tcp port 5011 (dc2k2) so let's do
both.
Issue #1112
2023-06-18 11:20:40 +02:00
Eric Warmenhoven 74b98d85ed libretro: another apple platforms build fix 2023-06-16 17:27:14 +02:00
Flyinghead 67a7637b9f network: tentative fix for 2k sport games
Fix port 5011 outbound packets instead of incoming ones for original hw
interop.
Issue #1112
2023-06-16 17:26:39 +02:00
Eric Warmenhoven 2511a19d2d libretro: apple platforms build fix 2023-06-15 16:05:36 +02:00
deviato f04ddad94f Update README.md 2023-06-15 16:05:08 +02:00
Flyinghead b4e5af6346 picotcp: bind native udp socket to the same local port as the pico one
The Toy Racer server ignores the source udp port so it must match the
dreamcast one. Will not work if the port is in use or well-known, or if
NAT gets in the way.
Issue #1112
2023-06-15 16:04:32 +02:00
Murad "Gness Erquint" Beybalaev f679fd9ba9 Typo in GUI.
"Covert art" → "cover art".
2023-06-13 14:56:33 +02:00
Flyinghead b6930a2a9e rend: force texture scanorder to 0 if vq and mipmap are set
Fixes crash and corrupted texture in Star Wars Demolition
Issue #1108
2023-06-13 14:55:47 +02:00
scribam 4db7137dbf deps: update miniupnpc to version 2.2.5 2023-06-12 16:07:41 +02:00
scribam bee534922b android: update android gradle plugin to version 8.0.2 2023-06-12 16:06:20 +02:00
Flyinghead d6fe46649c sdl: also use F11 to toggle fullscreen
in addtion to alt+enter
2023-06-12 16:05:34 +02:00
Flyinghead 236539c881 lr: add missing libs object files (elf, resource) for switch
Issue #1098
2023-06-05 17:17:51 +02:00
Flyinghead 2644c2ef47 pvr: more std::vector::operator[] UB
Issue #1100
2023-06-05 17:13:40 +02:00
scribam f590766421 deps: update nowide 2023-06-04 12:49:55 +02:00
Flyinghead fa1c62d11a naomi: fix spawn eeprom network settings 2023-06-04 12:49:35 +02:00
Flyinghead ffc0a42c18 std::vector::operator[index] with index >= size is UB 2023-06-04 12:48:50 +02:00
github-actions[bot] bc3c1ab628 Fetch translations & Recreate libretro_core_options_intl.h 2023-06-02 22:19:35 +00:00
vkedwardli 6c249ee4d2 Set header() and OptionArrowButtons() alpha to 1.0f (#1096)
* Set `header()` alpha to 1.0f

* Do not grey out `OptionArrowButtons()` also
2023-06-02 14:26:04 +02:00
Edward Li 3330f01267 Different config folder for multiple instances 2023-06-02 14:25:20 +02:00
scribam bd946bfbea deps: update imgui to version v1.89.6 2023-06-02 14:24:32 +02:00
Flyinghead bb92e9f7a4 add rfid cheat for mushik2k 2023-06-02 14:23:46 +02:00
Flyinghead 63686eeee1 naomi: add fallback bios files. Proper region names
ui: use proper region names for arcade (export, korea)
naomi: add previous version of BIOS files and fall back if latest ver
not found
fall back to use multiregion bios hack for korea
add CRC for all bios files
2023-06-02 14:23:14 +02:00
scribam c0a286532a deps: update Vulkan-Headers and VulkanMemoryAllocator 2023-05-31 17:03:20 +02:00
Eric Warmenhoven ce0354f294 Fix libretro build on apple platforms 2023-05-31 17:02:49 +02:00
Flyinghead 231a1b624f maple: fishing controller vibration pack, analog to dpad
refactoring to avoid duplicate code
2023-05-31 17:01:54 +02:00
Flyinghead 9b8fd39d12 libelf: make static lib
gentoo builds shared libs by default
2023-05-31 16:54:48 +02:00
Flyinghead 90c4e42c11 naomi: add mushikk, mushikc and mushik2k
cheats for mushikk and mushikc rfid check
mushik2k needs rev.H korean bios and won't boot
2023-05-31 16:53:49 +02:00
flyinghead ee806bc035 Merge pull request #1090 from flyinghead/dev
Merge dev branch: f355 multiboard, manic panic, touch de uno, vf4 netdimm, ...
2023-05-30 15:51:35 +02:00
Flyinghead d76611730e scraper: check for null disc after opening
Fixes MINIDUMP-11H
2023-05-29 17:34:29 +02:00
Flyinghead bdd677d66a ui: disable non-functional Dreameye maple device
Fix for MINIDUMP-127
2023-05-29 17:31:55 +02:00
Flyinghead 2299c9fade gl: detach and delete shaders after linking program
Fix attempt for MINIDUMP-RA, MINIDUMP-RM, MINIDUMP-Y7
2023-05-29 17:28:28 +02:00
885714e883 Support for Maracas & Pop'n Music controllers, WIP for others (#1035)
Racing controller, fishing controller and Densha de Go controller

Co-authored-by: Ricardo <[email protected]>
Co-authored-by: Flyinghead <[email protected]>
2023-05-29 12:45:34 +02:00
Flyinghead f95c7212bf gcc13 build fix 2023-05-28 11:43:58 +02:00
Flyinghead bb0da9488f bump glslang to 12.2.0
Fix gcc13 compile error
2023-05-28 10:56:14 +02:00
Flyinghead 1aeacb0297 android: storage::getSubPath can throw 2023-05-28 10:52:16 +02:00
github-actions[bot] b92b7a3ece Fetch translations & Recreate libretro_core_options_intl.h 2023-05-26 22:19:12 +00:00
Flyinghead 0a1fe0135f lr: default language=EN, region=USA. TrickStyle fix
libretro: set default language to English and default region to USA.
Same as standalone.

Force language to English for TrickStyle (US)
Issue #1082
2023-05-25 13:18:42 +02:00
Flyinghead 4391058563 aica: dma cycles schedule tweak
Increase lower limit to schedule dma callback from 224 to 513
Fixes freeze/crash in Nomad Soul
Issue #1080
2023-05-25 13:02:14 +02:00
Flyinghead ea9bdd03e4 Merge remote-tracking branch 'origin/master' into dev 2023-05-24 10:44:14 +02:00
Flyinghead ed99c96232 mmu: slow mmu build fix 2023-05-24 10:43:20 +02:00
Flyinghead 755e17dc97 rend: fix clipping edge case
Fixes some transitions in Bokomu no Tatsujin
Issue #1072
2023-05-24 10:31:55 +02:00
Edward Li 76af42ae6e Latest Vulkan SDK has a new volume name VulkanSDK 2023-05-23 10:21:40 +02:00
A-w-x e94babe57e update breakpad submodule 2023-05-22 20:37:57 +02:00
Flyinghead 416e4c5366 appimage: AppImageKit-checkrt -> linuxdeploy-plugin-checkrt 2023-05-22 15:55:57 +02:00
Flyinghead 6b9840268f vf4: fix networking on windows (vanilla, evo). Add eeprom and nvmem
connect returns EWOULDBLOCK instead of EINPROGRESS on windows
add eeproms for vf4, vf4evo and vf4tuned (2-player cabinet)
add nvmems for vf4, vf4evob and vf4tuned (network & card readers
enabled, all day card schedule, stage select, ...)
2023-05-20 11:19:26 +02:00
github-actions[bot] 415d8c2ea3 Fetch translations & Recreate libretro_core_options_intl.h 2023-05-19 22:19:19 +00:00
Flyinghead 3f456c6738 vf4: insert card now ejects the card if already inserted
support vf4 card renewal
2023-05-19 17:45:18 +02:00
Flyinghead 59480ea5a6 gdrom: force ADR to 1 for all tracks in TOC. Set lead-out as data
Fixes gdrom check in Eldorado Gate 4 to 7
Issue #1043
2023-05-17 16:30:24 +02:00
Flyinghead 920666bc70 rent a hero 1: hle bios fix
Issue #1070
2023-05-17 16:20:46 +02:00
Flyinghead eebcb322cf vk: imgui crash during start up
font tex id must be nulled when destroying vk objects
2023-05-16 16:36:56 +02:00
scribam 04b0489ff3 deps: update imgui_impl_vulkan.* 2023-05-16 14:51:03 +02:00
scribam dd5f44ff91 deps: update imgui_impl_dx* 2023-05-16 14:51:03 +02:00
Flyinghead a7b89ba06a android: don't get null array region in jni_util
Fixes MINIDUMP-YY
2023-05-16 14:45:31 +02:00
Flyinghead e5344d37d0 gdrom: fix cdda restart. revert previous change. fix hle pause/release
Revert changes from Issue #690
Fixes cdda restart in Mr.Driller, Bust-a-move 4, Wetrix+ and Reel
fishing. Issue #1019
hle: returning current cdda information fixes the pause/release issue
2023-05-16 14:33:33 +02:00
Flyinghead c07f862ef2 ggpo: exchange vf4 cards when starting the session 2023-05-16 09:43:21 +02:00
Flyinghead 8b0add47a2 revolt(jp): scale down depth to avoid menu glitch
This game uses large depth values in the menus (2000000)
Issue #1065
2023-05-14 17:34:30 +02:00
Flyinghead fe9ce46ab1 pvr: don't crash when hblank int mode is invalid or unsupported
Fixes MINIDUMP-ZE
2023-05-14 16:42:14 +02:00
Flyinghead 01c5c98396 pvr: check current ta context index when deserializing
Fixes MINIDUMP-YS
2023-05-14 16:40:36 +02:00
Flyinghead d00f07acb8 naomi: check cart malloc
Fixes MINIDUMP-QW
2023-05-14 16:36:14 +02:00
Flyinghead 83bfa9158d aica: don't crash if AFSEL=1
Fixes MINIDUMP-XW
2023-05-14 16:22:10 +02:00
Flyinghead ac2637286b Merge remote-tracking branch 'origin/master' into dev 2023-05-13 15:55:47 +02:00
flyinghead 541544292a dx11 oit: resize to null width and height when rendering to texture
Regression introduced by d2e8c9465b
Issue #974
2023-05-13 15:09:27 +02:00
github-actions[bot] 97bd3fc082 Fetch translations & Recreate libretro_core_options_intl.h 2023-05-12 22:19:18 +00:00
scribam 71ce2a2415 cmake: use c++17 globally 2023-05-12 10:46:48 +02:00
Flyinghead 4b0d377e66 pvr: don't clip negative depth vertices
Fixes baserunner cams depth in World Series Baseball 2K1
Issue #1027
2023-05-12 10:20:46 +02:00
Flyinghead ae2bc8182f pvr: FB_W_CTRL.fb_alpha_threshold comparison is greater or equal
Fixes black tile under player feet in Izumo.
Force CopyToVRAM.
Issue #1040
2023-05-12 10:13:48 +02:00
Flyinghead d9ec14e048 rend: rtt can also use SCALER_CTL.hscale
Issue #1025
2023-05-09 21:28:22 +02:00
Flyinghead c0f0a758df pvr: treat nan intensity as max. avoid nullptr crash in appendSpriteVtx
Fixes Gaiamaster Kessen! black texture. Issue #1021

Fix for MINIDUMP-RC
2023-05-09 21:07:40 +02:00
Eric Warmenhoven 06270e66c8 Build tvOS libretro core 2023-05-08 20:36:40 +02:00
Flyinghead 75fe707de3 bios font kanji row 66 was incorrect
Issue #1059
2023-05-07 21:58:54 +02:00
Flyinghead 1a5a2f64d4 naomi: insert card button compatibility with ggpo
handle insert card button like standard naomi buttons so it can be used
with ggpo
load card data when it's inserted, not before
2023-05-06 20:54:45 +02:00
scribam 220fd51b27 deps: gather backends under imgui/backends directory
stay consistent with upstream
2023-05-04 09:26:01 +02:00
scribam 29cdc77817 deps: update implot 2023-05-04 09:26:01 +02:00
scribam 483c59f2e4 deps: update imgui to version v1.89.5 2023-05-04 09:26:01 +02:00
scribam 1fdab613fd deps: update glslang and Vulkan-Headers to sdk-1.3.243.0 2023-05-04 09:25:24 +02:00
scribam 539b9e7746 cmake: improve target architecture detection 2023-05-04 09:24:48 +02:00
scribam 045f693eef ci: use freebsd 13.2
remove unused png package
2023-05-02 09:46:28 +02:00
scribam 3192f84576 remove unused iconv.h include 2023-05-02 09:45:54 +02:00
Flyinghead 27038d4cf9 fix test 2023-04-29 18:02:26 +02:00
scribam 4acb670b88 netbsd build fix 2023-04-29 17:51:25 +02:00
Flyinghead 79b9b49218 naomi: netdimm net client and rfid card reader emulation
high-level emulation of netdimm v3.17 net client lib
vf4/mushiking rfid card reader emulation
2023-04-29 17:50:56 +02:00
Eric Warmenhoven 5f161df06b libretro: Don't use Xcode cmake generator for iOS 2023-04-28 19:59:43 +02:00
Eric Warmenhoven fc3b9046d8 Build fix: iOS libretro core using Xcode 12.2 2023-04-27 18:37:44 +02:00
Flyinghead 754d2a53a0 add mazan nvmem with sword calibrated and free play enabled 2023-04-26 20:20:40 +02:00
Flyinghead e913bae9e3 alienfnt: handle +++ modem escape sequences
Allow modem to start when returning from test mode
2023-04-26 20:17:19 +02:00
Flyinghead 22d228c1b0 imgui: don't send X button events to avoid the nav window popping up
Issue #1034
2023-04-26 20:14:18 +02:00
Eric Warmenhoven d3a3cab425 Build iOS libretro core 2023-04-26 14:39:04 +02:00
Eric Warmenhoven 1fe7352ed0 libretro: avoid exporting symbols on osx
On Mac when running a debug build of flycast and retroarch in the
debugger, it gets confused about which glsl to pick. The easiest way
to fix this is to build the flycast core in a way where it's only
exporting symbols that are going to be called by retroarch directly.
2023-04-26 14:39:04 +02:00
Flyinghead 9d1a5cf0d3 ui: allow horizontal screen stretching up to 250%
Issue #1012
Issue #609
2023-04-24 17:41:42 +02:00
Flyinghead c8a45d95a7 dynarec: fix mov64 edge case when registers must be swapped
Handle case where mov64 must swap its operands depending on register
allocation.
Fix canonical call for FSCA when return operands are register-allocated.

Issue #1020
2023-04-24 17:38:49 +02:00
Flyinghead 92a1c1891b alienfnt: support for serial modem and worldwide ranking server
Emulate modem on sh4 serial port.
Use picotcp stack to handle ppp protocol.
Include nvmem with network settings (server at alienfront.duckdns.org,
disabled by default).
2023-04-16 15:41:54 +02:00
Flyinghead 858174791f disable multiboard on openbsd and netbsd
for lack of interprocess mutexes
2023-04-15 15:45:11 +02:00
Flyinghead fb4e653269 lr: crosshair not transparent with vk. Mazan can be played with gamepad
Use transparent quad pipeline to draw crosshairs and vmus
Allow mazan and touchscreen games (manic panic, tduno, ...) to be played
with a gamepad.
2023-04-15 15:45:11 +02:00
scribam 210100a108 naomi: netbsd/openbsd pthread fixes
These systems do not have pthread_condattr_setpshared/pthread_mutexattr_setpshared
2023-04-13 18:10:19 +02:00
Flyinghead edd1487378 gl: powervr2 filter has some uninitialized vecs
Issue #1005
2023-04-13 18:07:17 +02:00
Flyinghead 68f4ce1ec5 naomi: fix multiboard slave not starting
regression due to 87fdd203b5
2023-04-13 18:03:41 +02:00
Flyinghead c3c355a8c5 android: use jni helper. better support for arrays and global refs. 2023-04-12 10:22:38 +02:00
Flyinghead 70d3e221a9 mushiking series support
Emulate barcode reader. UI to input card id.
scif: SCFSR2.DR should also trigger an interrupt. Fixes the partial read
issue with manic panic ghosts touchscreen.
Add default implementations in SerialPipe for read-only and write-only
devices.
Fix card jammed error in mushiking with custom input code.
Add mushi2k61 and mushi2k62 to naomi rom list.
Cheats to skip rfid check.
2023-04-12 10:09:21 +02:00
Flyinghead b556617e1d sh4: only reset serial pipe on hard reset
See d3690b12c6
2023-04-09 20:56:14 +02:00
Flyinghead e327172fd0 sh4: check access length when getting a ram pointer with GetMemPtr
Check access length and return nullptr if overflowing ram.
Fix ch2-dma code accordingly.

Fixes MINIDUMP-GX
2023-04-09 20:47:12 +02:00
Flyinghead c5f82483e6 naomi: fix multiboard windows position
Position slave windows over master.
Support any window width.
2023-04-09 20:28:10 +02:00
Flyinghead a418b05272 ui: make cheat list touch-scrollable 2023-04-09 20:20:07 +02:00
Flyinghead 5c3f66fe05 ui: ignore inaccessible content path when scanning for games 2023-04-09 20:18:56 +02:00
Flyinghead 81ce3f7d10 msvc32 build fix 2023-04-08 19:11:21 +02:00
scribam 64cfba735e deps: update sdl to version 2.26.5 2023-04-08 18:38:35 +02:00
scribam 8828b4fe52 deps: update implot to fix IMGUI_DEFINE_MATH_OPERATORS requirements 2023-04-08 18:38:26 +02:00
Flyinghead 87fdd203b5 android scoped storage (ASS) support
introduce Storage abstraction interfaces
use Storage i/f to load zip and 7z archives, cdi/cue/gdi/chd media,
cheats and to find custom textures.
Use android file picker to add storage. Request persisted access perms.
jni helper classes.

Issue #813
2023-04-08 18:37:50 +02:00
Flyinghead 187674ddac uTip is no more 2023-04-04 22:37:06 +02:00
Flyinghead f94a08f12f mmu: avoid crash due to approximative fast mmu matching
Fixes MINIDUMP-EA (Sonic Shuffle)
2023-04-02 22:06:22 +02:00
Flyinghead 252ad711f1 vk: throw if vmaMapMemory fails
MINIDUMP-PX
2023-04-02 22:02:53 +02:00
github-actions[bot] 9d6bfd4786 Fetch translations & Recreate libretro_core_options_intl.h 2023-03-31 22:19:08 +00:00
Flyinghead d3690b12c6 net: don't reset naomi network on soft reset (maxspeed)
Resetting makes maxspeed crash as the serial pipe isn't reset and
becomes invalid.
Fixes MINIDUMP-PJ
2023-03-31 20:09:33 +02:00
Flyinghead 32e08ca165 modem: don't crash on unexpected register writes
Just log and ignore.
Fixes MINIDUMP-62
2023-03-31 20:03:16 +02:00
Flyinghead bc4f8fbe60 dx11: enable depth writing in oit pass
Make sure both depth attachments are identical at the end of each pass.
Issue #996
2023-03-31 20:01:12 +02:00
scribam fd3deeb318 ci: bump aws-actions/configure-aws-credentials 2023-03-30 17:32:01 +02:00
Flyinghead 7108358ebd Merge remote-tracking branch 'origin/master' into dev 2023-03-30 17:31:22 +02:00
Flyinghead 98daea0e97 bios font: fix row E0 and F0 of the katakana half-width code page 2023-03-30 17:26:28 +02:00
Flyinghead 48acb03b81 underclock/overclock SH4 option
Increase/reduce the dynarec cycle count for each block.
Issue #210
2023-03-30 17:22:24 +02:00
Flyinghead 08ac485eac ui: fix drag scrolling and imgui gl renderer. use imgui events
Missing call to KeepAliveID was preventing drag scrolling in empty
areas. Also check for HoveredIdDisabled to allow scrolling by dragging
disabled items and enable HoveredIdAllowOverlap.
imgui gl renderer: use ImDrawCmd::IdxOffset instead of counting
manually. Use correct alpha blending function.
Use imgui events for all input. Simplify keyboard input by getting rid
of modifiers.
Enable flat navigation in content window.
Add format string to OptionSlider.
2023-03-30 16:54:54 +02:00
Flyinghead c033a81eca get rid of KeyboardDeviceTemplate 2023-03-29 16:48:46 +02:00
Flyinghead 5df9127add vk: enable depth writing in oit pass so
Make sure both depth attachments are the same at the end of each pass.
Get rid of unneeded depth dependency/transition.
Issue #996
2023-03-28 21:20:37 +02:00
Flyinghead b9e9cc534c lr: build fix when USE_OPENGL=OFF
Issue #997
2023-03-28 21:07:50 +02:00
Flyinghead 79be464326 aica: proper write mask on aica dma address registers
Fixes MINIDUMP-P3
2023-03-28 21:05:18 +02:00
Flyinghead f67aad0b2d pvr: don't wait if Present msg is already in the queue
Only Render* msgs are an issue when piling up on slow platforms.
Fixes frame skipping only working when delay frame swap is on
Issue #975
2023-03-28 21:01:56 +02:00
Flyinghead 55b36fe719 dx11: revert 47a33f97f9
Issue #865
2023-03-28 20:55:56 +02:00
scribam 7cce77cccd android: update android gradle plugin to version 7.4.2 2023-03-27 16:59:35 +02:00
scribam 170f794c3a deps: remove imgui obsolete keyio functions
Fix compilation with #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
2023-03-27 16:59:06 +02:00
scribam ae4bd79ca1 deps: remove imgui obsolete functions
Fix compilation with #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
2023-03-27 16:59:06 +02:00
Flyinghead d76982bbeb naomi,aw: embed default flash for some games
Needed to configure network on first run.
2023-03-27 16:57:48 +02:00
Flyinghead fb4229c4ae support for daytona usa networking 2023-03-27 16:45:25 +02:00
Flyinghead caec338d25 dx9, dx11: video shift support
Shift the framebuffer according to VO_STARTX and VO_STARTY.
Issue #594
lr: draw overlay and manage shifting in dx11 context
2023-03-27 16:41:59 +02:00
Flyinghead b94200233d vk: video shift support. refactor lr vk context
Shift the framebuffer according to VO_STARTX and VO_STARTY.
Issue #594
lr: draw overlay and manage shifting in vk context
2023-03-27 16:38:15 +02:00
Flyinghead eb3ebe24e8 gl,gl4: video shift support, fix powervr filter, refactor lr osd
Shift the framebuffer according to VO_STARTX and VO_STARTY.
Issue #594
GlVertexArray class to handle vertex arrays (or lack thereof)
lr: Fix PowerVR2 filter including in full fb emu mode. Use quad to draw
vmus and lightgun xhairs.
2023-03-27 16:31:57 +02:00
Flyinghead 4514a4bfcc libretro: lightgun with gamepad fixes. Lightgun with touchscreen support
Lightgun with gamepad: fix reload, fix trigger and buttons on AW
Issue #881

Support for lr pointer device for lightgun with touchscreen.
Issue #604
2023-03-25 11:52:18 +01:00
Flyinghead 5e4e48fffe mmu: don't crash when table full, just ignore
Fixes MINIDUMP-NF
2023-03-25 11:45:03 +01:00
Flyinghead 47a33f97f9 dx11: disable texture support check on uwp/xbox
Tentative fix for Issue #865
2023-03-25 11:43:17 +01:00
Flyinghead b36ef9da1e libretro: use gamepad left analog stick for lightgun coordinates
Issue #881
2023-03-24 11:59:46 +01:00
Flyinghead 068861d0cc pvr: mask low address bits according to 32-bit vram access size
Avoid crash when accessing the very last vram byte with short or int.
Correct behavior should be to raise an sh4 address exception.
Fixes MINIDUMP-N2
2023-03-24 11:53:38 +01:00
Flyinghead f2f8f3ccd2 bump libchdr to latest
commit 8e09bf2b
Fixes MINIDUMP-HD, MINIDUMP-M8
2023-03-24 11:48:52 +01:00
Flyinghead 2d7a1ce71a atomiswave: fix failure to identify the game
regression by 78f80eb7dc
2023-03-23 09:45:25 +01:00
Flyinghead 74d72eb257 imgui: fix gamepad navigation
Issue #986
2023-03-23 09:39:25 +01:00
Flyinghead 9512ee657a Allox f355 deluxe to run with only one screen 2023-03-22 19:01:34 +01:00
Flyinghead 78f80eb7dc naomi: printer support for f355 and tduno[2]. Fix some bios font glyphs
Thermal printer support for f355 (G2 ext bus) and tduno[2] (maple JVS)
Change game id for sgdrvsim and dragntr3 to distinguish them.
Fix cyrillic page in BIOS font.
2023-03-22 19:00:50 +01:00
Flyinghead fa525b4488 Fix hotd2p inputs
Issue #731
2023-03-22 15:36:10 +01:00
Flyinghead ee3e83e09c Fix loading of Sega Yonin Uchi Mahjong MJ (mj1)
gd cart: load first .bin if the specified one isn't found. Fix loading
of main directory for mj1. Don't update progress too often when
decrypting.
chd: allow loading of 1-track CD-ROMs
Use 2 jvs boards for mj1

Issue  #985
2023-03-22 13:00:59 +01:00
Flyinghead ea4354ba2e Shin Nihon Pro Wrestling 4 crashes with RGB component
Force TV Composite instead
2023-03-21 11:36:47 +01:00
Flyinghead 5c5c872afc aica: small dma transfer must be correctly scheduled
Previously transfer taking less than 4096 cycles would be instantly
executed.
Fixes Sports Jam announcer broken audio.
Issue #980
2023-03-21 11:32:21 +01:00
Flyinghead 9f2ffd102c oit: Can't discard pixel in pixel shader when using 2ndary accumulator
When using the secondary accumulator as source or destination, pixel
must not be discarded even if blending results in a nop. Doing so
cancels the transfer to/from the accumulator.
Issue #979

dx11 oit: use FAILED to detect pixel shader creation error. Log error
codes when Buffers::init fails.
2023-03-21 11:22:04 +01:00
scribam 34f8941868 deps: apply drag scrolling custom code to imgui 2023-03-20 16:52:51 +01:00
scribam 07b217d9f8 deps: update imgui to version 1.89.4 2023-03-20 16:52:51 +01:00
Flyinghead cb83d319b9 naomi: 4-player and eeprom fixes
Add 4-player support to Dirty Pigskin Football, WFF Royal Rumble, World
kicks PCB and Beach Spikers.
Fix several bugs in initEeprom and force 4-player cab when needed.
Get rid of pstone, pstone2 and ringout default eeproms.
2023-03-20 12:35:36 +01:00
scribam 23daa3efdf deps: use latest stable release for oboe (1.7.0) 2023-03-18 16:11:41 +01:00
scribam 3a1ffceb58 deps: update glslang and Vulkan-Headers to sdk-1.3.239.0 2023-03-18 16:11:41 +01:00
scribam f3431bd95d deps: update sdl to version 2.26.2 2023-03-18 16:11:41 +01:00
Flyinghead 01c7250be2 hle bios: add latin-1, jis x0201 and jis x0208 glyphs to bios font
Use CMakeRC to embed font binary file
2023-03-18 16:11:03 +01:00
github-actions[bot] e6bc36e110 Fetch translations & Recreate libretro_core_options_intl.h 2023-03-17 22:20:03 +00:00
Flyinghead afc1f5f4e1 Merge remote-tracking branch 'origin/master' into dev 2023-03-15 21:09:47 +01:00
Flyinghead 4a2ad8b145 pvr: SortedTriangle has unsafe pointer to PolyParam
std::vector elements can be reallocated. Use index instead of pointer.
2023-03-15 20:58:12 +01:00
Flyinghead 17ab0aba26 dx11,dx9: Force ignoreTexAlpha if texture doesn't have an alpha channel
The supporting texture might have one if converted but it shouldn't be
used.
Fixes cinematic scenes in Alone in the Dark.
Issue #974
2023-03-13 21:12:39 +01:00
Flyinghead cc1b45b7cc texture corruption after load state regression. wince depth scale change
Texture weren't updated after loading a state. Regression introduced by
942224c685.
Change Windows CE depth scale from 0.1 to 0.01 to fix black screen FMV
on AMD and Intel GPUs. Issue #973
2023-03-13 21:03:16 +01:00
Flyinghead 4d990947de sgdrvsim: display or network broadcast speedometer and tachometer
Display speedometer value, or network broadcast speedo and tacho on port
8002 (slave 2) if option is set
2023-03-13 17:45:12 +01:00
Flyinghead 5542d6db21 picotcp: full deinit when terminating
New pico_stack_deinit() function to fully deinit picotcp. Need to call
pico_stack_init when restarting.
Get rid of dns client

Tentative fix for MINIDUMP-G6, MINIDUMP-J0, MINIDUMP-HY, MINIDUMP-G5,
MINIDUMP-J0, MINIDUMP-HY, MINIDUMP-FP, MINIDUMP-F7, MINIDUMP-9H,
MINIDUMP-CB, MINIDUMP-CE; MINIDUMP-B3, MINIDUMP-1Y, MINIDUMP-A7,
MINIDUMP-9M
2023-03-13 17:36:32 +01:00
Flyinghead 8ca89ead0e Enable RTT Copy to VRAM for Shenmue
Fixes Space Harrier mini arcade game.
Issue #967
2023-03-12 16:06:05 +01:00
Flyinghead ebf5f24487 ui: reduce boxart image size. Avoid crash with invalid option values
Reduce boxart image size from 200 to 150.
Avoid under/overflowing label tables with invalid option values when
using combo boxes.

Fixes MINIDUMP-GK
2023-03-12 16:04:05 +01:00
Flyinghead 90269d5204 vk oit: reset all pipelines on init/reset
Avoid validation errors when switching to/from RTT Copy to VRAM
2023-03-12 16:00:49 +01:00
Flyinghead e4332f6275 tex: ignore stride if 0. renderer: ignore invalid textures
Ignore StrideSel if 0 during texture update and use width instead.
Return false from BaseTextureCacheData::Update() if texture is invalid.
Make sure valid textures have non-null height and size.
gl,vk,dx9,dx11: ignore invalid textures

Fixes MINIDUMP-GP
2023-03-12 15:58:56 +01:00
Flyinghead cd7168772d reios: crash when CDDA play with no disk
Fixes MINIDUMP-HW
2023-03-12 15:51:05 +01:00
Flyinghead 77ded80450 cdi: check each track sector size when opening
Fixes MINIDUMP-J4
2023-03-12 15:48:13 +01:00
github-actions[bot] fbc69b6ae1 Fetch translations & Recreate libretro_core_options_intl.h 2023-03-10 22:20:01 +00:00
Flyinghead ea7dd699b9 only launch sgdrvsim slaves on desktop platforms 2023-03-10 18:10:57 +01:00
Flyinghead 018a852995 network: naomi net was closing stdin. Slaves don't broadcast outputs
naomi network: Initialize socket to -1. Only close if valid.
Multiboard or sgdrvsim slaves don't broadcast digital outputs
Don't save slave windows position
2023-03-10 18:01:49 +01:00
Flyinghead 8a28ddbfe6 jvs: allow p2 buttons to be always on. sgdrvsim improvements
jvs: allow button mapped to jvs P2 to be always on. Don't overflow
button descriptors table
midiffb: invert axis if needed
Launch sgdrvsim network instances automatically. Remap some buttons and
make some always on.
2023-03-10 17:57:27 +01:00
Flyinghead f186046c98 partial support for sega driving simulator 2023-03-09 17:54:57 +01:00
Flyinghead 5644e834fa x86 dynarec: use UpdateSystem_INTC like other recs
get rid of unused rdv_DoInterrupts and rdv_DoInterrupts_pc
2023-03-09 09:37:48 +01:00
Flyinghead 0b1f69bfd2 dynarec: more accurate cycle counting. limit code duplication
arm, arm64, x86: only account for current block cycles if block is
executed. Test cycle_counter before updating it.
arm, arm64: use function for mmu block check (vaddr and FPU ops) to
reduce host code size per block.
2023-03-08 19:24:49 +01:00
Flyinghead 4eb5cd928e nuke rec-cpp 2023-03-08 18:56:26 +01:00
Flyinghead b8d47fe0a8 sh4 dmac: more accurate implementation. Fixes sh4_dmac_demo.elf 2023-03-07 18:38:41 +01:00
Flyinghead abcd9d77d4 set some global to static 2023-03-07 18:36:26 +01:00
Flyinghead 095e5ede81 sh4: more accurate cycle counting
get rid of float ops hack for dead or alive 2
get rid of idle skip option and code block hashing
count cycles for high-level wince functions and handlers (GetTickCount,
QueryPerformanceCounter and TLB_MISS handler)

Fixes Dave Mirra Freestyle BMX time counter running too fast.
More FPS for many wince games. Better wince perf on slow devices.
2023-03-07 18:35:01 +01:00
flyinghead 52754cbbbb win32 lr build fix 2023-03-07 14:26:04 +01:00
Flyinghead ea9d048bc9 appimage: don't run checkrt on SteamOS
when checkrt calls dlmopen("libstdc++.so.6") for the second time, the
call gets stuck in an error loop and never returns.

Issue #929
2023-03-07 13:48:30 +01:00
Flyinghead 942224c685 in single threaded, only defer emu stop on android
on other platforms, render() won't be called => audio not terminated,
rom files not saved, pause event missed

unprotect memory and reset memwatch before loading a state
2023-03-07 13:43:22 +01:00
Flyinghead 670a25b039 dx11: dynamically load d3dcompiler_47/46.dll to avoid old versions
Fixes MINIDUMP-8H, MINIDUMP-CD
2023-03-07 13:35:15 +01:00
Flyinghead cab02c86bc android: only restart if game is running
Fixes MINIDUMP-G1, MINIDUMP-FV, MINIDUMP-FY, MINIDUMP-FD, MINIDUMP-F2,
MINIDUMP-EN
2023-03-06 17:02:01 +01:00
Flyinghead b4a67460e0 cmake switch and bsd fix 2023-03-06 16:23:51 +01:00
Gabriel Morazán b56750df30 (UWP) AppxManifest Tweaks 2023-03-06 10:31:09 +01:00
Flyinghead aa5fd64777 dx11: use FAILED() macro instead of != S_OK
Tentative fix for MINIDUMP-FG
2023-03-06 10:30:33 +01:00
Flyinghead 5a13b4df28 cmake: add option to force use of host sdl library
Issue #928
2023-03-06 10:28:39 +01:00
Flyinghead 67bba95dd1 dmac: set DMAOR.AE and raised interrupt if ch2 address error
Fixes crackin'dj 1 & 2 freeze at boot
Regression introduced by 66eb08f2d1
2023-03-06 10:26:52 +01:00
Flyinghead cd6152b193 per-game vmu A1 option
When enabled, each game has its own A1 vmu file.
Issue #555
2023-03-05 15:32:47 +01:00
Flyinghead 67c070c20f naomi: display crosshair for touchscreen games 2023-03-05 15:13:18 +01:00
Flyinghead 2355bb8bb5 pvr: drop more vertices with large x and y
Fixes Manic Panic Ghosts bogus transparent rectangles in first stage
2023-03-05 15:08:17 +01:00
Flyinghead c4d24254db naomi2: FFB support for Club Kart and King of Route 66 2023-03-04 17:45:53 +01:00
namtsui 27b6bafd0f vendor newest libelf (#955)
* vendor newest libelf

source:
https://github.com/seL4/util_libs/tree/2d5b59c99a93507266c10efe50760f25b7d73728/libelf

* use exec_elf.h from openbsd to define structs

* libelf: build fixes

- do not link against muslc.
- windows and apple use bundled exec_elf.h.
- casts added like the old elf32.h, elf64.h and elf.c so pointer
  arithmetic works. otherwise some compilers complain about void*.
- remove unused bits of exec_elf.h and added typedefs.

* adapt CMakeLists.txt to use libelf's CMakeLists.txt

* adapt reios_loadElf() to new libelf API
2023-03-03 16:05:12 +01:00
Eric Warmenhoven 9cbdcc6260 Only compile x86_64 for osx-x86_64, rather than universal 2023-03-02 08:04:01 +01:00
Flyinghead 192bbb715e input: use gamepad left stick for abs/lightgun coordinates
Issue #881
2023-03-01 21:48:51 +01:00
Flyinghead 014da3a225 naomi: network output FFB for 18 wheeler and f355 2023-02-28 20:23:58 +01:00
Flyinghead 803f4cd298 controller bindings for load and save state
Issue #615
2023-02-28 20:21:29 +01:00
Flyinghead 885a0508c0 Merge remote-tracking branch 'origin/master' into dev
# Conflicts:
#	core/hw/aica/sgc_if.cpp
#	core/hw/naomi/naomi.cpp
#	core/hw/sh4/dyna/driver.cpp
2023-02-28 20:02:23 +01:00
namtsui a1472fb190 OpenBSD 7.2 patches (#953)
* OpenBSD: BSS is immutable so mark it as mutable so that mprotect RWX works

see: mimmutable(1)
https://github.com/google/syzkaller/commit/bc009f82ea71c399f19eef28f115ff5cda7be4ba

* OpenBSD does not have mcontext_t

<signal.h> provides `typedef struct sigcontext ucontext_t;'.
take register names from <machine/signal.h>, which provides struct
sigcontext.

see:
https://github.com/RPCS3/rpcs3/commit/1a13d3ae4e28fc46baef52086c64189f84cf2b9f

* OpenBSD uses major.minor for shared libs, so properly dlopen libGL.so

* OpenBSD remove redefinition of swap16

* OpenBSD: SDL2 controller detection

Use sdl_open_joystick() to open controllers on startup instead of
SDL_JOYDEVICEADDED event, which never gets detected.

* OpenBSD does not have mcontext_t but linux does
2023-02-28 18:22:45 +01:00
Flyinghead b86df7217c sdl: don't add a joystick if its name can't be retrieved
Otherwise it crashes later on during SDL_JoystickClose

Fixes MINIDUMP-9K, MINIDUMP-B4
2023-02-27 17:59:48 +01:00
Flyinghead 26815d042a arcade ouput: send game name before any output
Send the game id before any output to inform clients of the current
running game.
2023-02-27 17:46:00 +01:00
Flyinghead 026f21eddf naomi: report error if rom is invalid instead of crashing
Fixes MINIDUMP-CS
2023-02-27 17:43:08 +01:00
Flyinghead 30501aebb1 Race condition when stopping while emu is failing
Emulator::stop now throws if an error occurred on the emu thread.
Fixes MINIDUMP-5B
2023-02-26 22:01:32 +01:00
Flyinghead 4014b1b574 lr: libchdr win32 build fix 2023-02-24 22:11:41 +01:00
Flyinghead 8d54382b10 aica: apply RAM mask to sample address (SA)
Fixes MINIDUMP-B9
2023-02-24 21:24:56 +01:00
Flyinghead 47dd8241b6 dx11: log error code 2023-02-24 21:14:01 +01:00
Flyinghead 195da2adcc oboe: device lost detection might be triggered while stopping
Fixes MINIDUMP-BD
2023-02-24 21:11:47 +01:00
Flyinghead 2b430eec6f gui: stop game scanner when exiting 2023-02-24 18:44:45 +01:00
Flyinghead d51e36998b bump libchdr to latest. add switch build fix
Issue #895
Fixes MINIDUMP-5C, MINIDUMP-4C, MINIDUMP-3G, MINIDUMP-3H, MINIDUMP-8C,
MINIDUMP-AP, MINIDUMP-AN, MINIDUMP-AM, MINIDUMP-AA
2023-02-24 18:44:06 +01:00
scribam a970a1263c ci: update mathieu-bour/setup-sentry-cli 2023-02-22 18:03:37 +01:00
Flyinghead cf9ccea70b texcache: unprotect vram immediately even if actual Delete is delayed
Fixes MINIDUMP-A5, MINIDUMP-AF
2023-02-22 17:57:31 +01:00
Flyinghead f885cbb4ea reios: don't crash if system settngs can't be read from flash
Log a warning and proceed. This can happen if the flashrom is corrupted.
Fixes MINIDUMP-9W
2023-02-22 17:51:25 +01:00
Flyinghead 97dfabc416 pvr: don't reset TA parser during soft reset
Rendering might be in progress in another thread and this leads to
crashes.
Fixes MINIDUMP-AW and MINIDUMP-AY
2023-02-22 17:49:01 +01:00
Flyinghead 8d2b0749a0 gl: vmu and lightgun xhair not rendered if switching renderer 2023-02-22 17:46:14 +01:00
Flyinghead a3acf4a8cc gl: don't use glIsProgram to avoid Adreno 308 random failures
Adreno 308 randomly return false from glIsProgram on valid programs
Fixes MINIDUMP-A1 and MINIDUMP-AX
2023-02-22 17:44:17 +01:00
scribam e505ab6019 safe usage of std::isalnum/std::print 2023-02-20 22:57:24 +01:00
Flyinghead 9b24984b07 crash when switching to full mmu
The MMU now has a state variable, which must be set before the dynarec
is reset.
Regression in afcb3b7ad8

Fixes MINIDUMP-AZ, MINIDUMP-B7, MINIDUMP-B0
2023-02-20 22:56:23 +01:00
Flyinghead 7ce08ea860 Fix Touch de Uno 1 & 2 inputs
Fix touchscreen touch detection
Default eeproms with calibrated touchscreen and disabled printer
2023-02-20 11:14:02 +01:00
Flyinghead a156edbd73 Merge remote-tracking branch 'origin/master' into dev 2023-02-19 14:10:37 +01:00
Flyinghead 9dae5827cc naomi: touchscreen emulation for manic panic ghosts and touch de zunou 2023-02-19 13:51:23 +01:00
Flyinghead 5da799244f rend: fix regression on YUV texture conversion
std::clamp wrong parameters order in d8137a967c
2023-02-18 22:44:44 +01:00
Flyinghead bf79183bd6 mmu: max alignment requirement is 32-bit
a 64-bit access only needs to be 32-bit aligned.
use enum for mmu errors
2023-02-18 13:33:38 +01:00
Flyinghead afcb3b7ad8 mmu: get rid of FullMMU option. Detect wince with string id in ram
ForceWindowsCE now just sets ExtraDepthScale
2023-02-18 13:33:38 +01:00
Flyinghead 5bfbcb210c dynarec: refactor imm mem r/w and store queue handlers. clean up mmu
Eliminate duplicate code for immediate memory read/write in all dynarecs
Simplify PREF to use do_sqw_nommu even for simple SQ remap
Check for address errors before mmu translation
Get rid of unneeded template params in mmu translation funcs
2023-02-18 13:33:38 +01:00
Flyinghead 4f65d45e55 rend: don't access first poly if list is empty. dx11 oit: resize error
fix crash with dx11 and gl4 when tr poly count is 0
quick exit if nothing to do
2023-02-18 13:33:38 +01:00
scribam 3f8ecfedbb sdl: use _WIN32 2023-02-18 13:25:14 +01:00
scribam d8137a967c C++17 (#926)
* cmake: use c++17

* Use std::size

* Use std::make_unique

* Use std::clamp

* Use structured binding

* Use [[fallthrough]]

* Use enable_if_t/is_enum_v/is_integral_v/is_same_v

* Use if constexpr

* Use try_emplace

* Use auto for iterators

* Use inline variables
2023-02-18 13:24:34 +01:00
github-actions[bot] ffec935e2f Fetch translations & Recreate libretro_core_options_intl.h 2023-02-17 22:20:33 +00:00
Flyinghead 253301ba4f UWP build fix. Readme update 2023-02-16 11:14:01 +01:00
Flyinghead a21b79cfbe builtin cheat to help Extreme Hunting 2 boot 2023-02-15 18:59:44 +01:00
Flyinghead 3f4c24d350 gl4: don't reference two-volumes attributes if not used
The naomi2 vertex shader doesn't set 2-volume attributes (vtx_base1,
vtx_offs1 and vtx_uv1) if they aren't used. But the pixel shader always
references them even though they aren't actually used. This breaks some
gl drivers: "The shader uses varying vtx_uv1, but previous shader does
not write to it."

Fixes MINIDUMP-93
2023-02-15 18:56:12 +01:00
Flyinghead 645f413523 sentry: get the build version from the log file if available
avoid discrepancy between uploading and minidump versions
2023-02-13 20:02:14 +01:00
Flyinghead 08478aa757 bsd build fix 2023-02-12 15:05:02 +01:00
Flyinghead 4aef8667b7 fix AppImage shared libraries list 2023-02-12 15:05:02 +01:00
Flyinghead 9d08da1fc9 build AppImage for linux
Issue #638
2023-02-12 15:05:02 +01:00
Flyinghead 4408aa7dbe force SDL build on linux to include libdecor for wayland 2023-02-12 15:05:02 +01:00
Flyinghead d2e8c9465b dx11 oit: render target and depth texs must have the same dimensions
Fixes missing depth/stencil when changing resolution or
enabling/disabling full framebuffer emulation.
2023-02-12 15:05:02 +01:00
Flyinghead 04df0da7cb pvr: increase index size for wild riders
Index overrun with wild riders
Fixes MINIDUMP-7A
2023-02-12 15:05:02 +01:00
Flyinghead 5eeddecb40 maple: set bus speed back to 2Mbps. Worms Pinball needs FFBE
Power Drift crashes with 1Mbps
partial revert of 2332884d8b
Force Slave Zero to use real bios (still has issues)

Worms Pinball prototype needs full framebuffer emulation
2023-02-12 15:05:02 +01:00
scribam 71aea45811 vulkan: lower shader version requirement 2023-02-11 14:41:41 +01:00
scribam cf690fbb61 cmake: improve compile options for VulkanMemoryAllocator 2023-02-11 14:41:07 +01:00
Flyinghead 85b286ec47 oboe: don't attempt to recover the audio stream suring init
Apparently oboe can call the error callback function during the initial
openStream. Let it fail in this case.
Fixes MINIDUMP-8K
2023-02-11 14:25:41 +01:00
Flyinghead 07d0cf6839 cdi: don't crash if file re-open fails
Not sure how this can happen but it does. Could be a device removed or
corrupted CDI with many tracks.
Fixes MINIDUMP-8F, MINIDUMP-8Q
2023-02-11 14:09:22 +01:00
github-actions[bot] 5e43b603ac Fetch translations & Recreate libretro_core_options_intl.h 2023-02-10 22:20:39 +00:00
Flyinghead 69d2cfd56d read disk MCN and tracks ISRC from .cue files 2023-02-10 15:07:25 +01:00
Flyinghead 0f90293252 dynarec: handle illegal instructions 2023-02-10 14:53:54 +01:00
Flyinghead 0d166e1403 msvc build fix 2023-02-10 14:17:45 +01:00
Flyinghead b5879e6e1d unintended change and merge issue
log: revert change that wasn't supposed to be committed
emulator: fix incorrect merge
2023-02-10 12:56:57 +01:00
Flyinghead 5b169b7f9d naomi: use master pid to make unique multiboard shared mem file on unix 2023-02-10 12:54:20 +01:00
Flyinghead 099a758c94 hw: new hardware register implementation
used for sh4 mm registers and holly
ignore incorrect size reads and writes
separate data and read/write handlers
2023-02-10 12:51:36 +01:00
Flyinghead 638e5d233a gl: fix naomi2 lights regression
regression introduced by e18a4afcbb
2023-02-10 10:15:09 +01:00
Flyinghead a23362cee0 ios: fix virtual gamepad X button in arcade mode
Issue #911
2023-02-08 12:11:41 +01:00
Flyinghead 040db856f8 limit millenium racer widescreen cheat to the correct game
Tentative fix for MINIDUMP-87
2023-02-08 12:08:11 +01:00
Flyinghead 8d0654c323 vk: revert to glslang 11.11.0 (sdk 1.3.224.1)
partial revert of 1c8e558e25
Issue #908
2023-02-08 11:59:37 +01:00
Flyinghead cacfdbad90 Revert "deps: update glslang and vulkan"
This reverts commit 1c8e558e25.
2023-02-07 11:31:58 +01:00
Flyinghead 811bf6f449 Revert "vk oit: tentative workaround for AMD crash"
This reverts commit 084066bde7.
2023-02-07 11:28:14 +01:00
Flyinghead 43f8f3e4ad bsd build fix 2023-02-07 11:27:51 +01:00
Flyinghead a045c52146 sdl: handle joystick and gamepad api errors to avoid crashes
Fixes MINIDUMP-7K
2023-02-06 15:20:21 +01:00
Flyinghead 98531e07ea hle bios: fix SF rush, jeremy mc grath and the grinch
protection checksum and game bugs
2023-02-06 15:15:44 +01:00
Flyinghead 5020a267af pvr: fix unsorted pass triangle count. tr count should accumulate
partial revert of 927db7f189
Fix missing walls in Bust a Move 4 (vs)
2023-02-06 15:09:18 +01:00
Flyinghead debe21de7b Merge remote-tracking branch 'origin/master' into dev 2023-02-05 22:20:28 +01:00
Flyinghead 084066bde7 vk oit: tentative workaround for AMD crash
Issue #908
2023-02-05 21:56:08 +01:00
Flyinghead 46d7dfc750 fix AppImage shared libraries list 2023-02-05 18:37:32 +01:00
Flyinghead 37c17e4300 pvr: re-use TA contexts if not used for 60 frames 2023-02-05 18:32:35 +01:00
Flyinghead 3a21f545d8 cfg: allow non per-game option to be overriden. Remove per-game for some
Allow non per-game options to be overridden with command line args.
Fixes MINIDUMP-7G

Save state slot, box art settings, UploadCrashLogs, UseRawInput and lua
filename shouldn't be settable per-game.
2023-02-05 11:38:21 +01:00
Flyinghead f35167a0de egl: better constants 2023-02-05 11:31:22 +01:00
Flyinghead 0b6c09da02 sdl: don't rely on event to get window size when processing resize event
window size may be different from drawable size if high-dpi is enabled.
Fixes wayland resize with scale factor > 100%.
2023-02-05 11:30:23 +01:00
Flyinghead d9c08bd081 gl: save current framebuffer in RenderLastFrame. get rid of verify (OSD)
Current framebuffer must be saved in gl.ofbo.origFbo when entering
RenderLastFrame and restored on exit.
Tentative fix for MINIDUMP-74

glIsProgram(OSD_SHADER) is strangely failing on Adreno 308 so let's get
rid of it (and pray).
Fix for MINIDUMP-7D, MINIDUMP-7C, MINIDUMP-7B, MINIDUMP-79, MINIDUMP-6J
2023-02-05 11:26:50 +01:00
Flyinghead 927db7f189 pvr: sorted triangle count incorrect with multiple render passes
causes crash in setProvokingVertex

Fix for MINIDUMP-7A, MINIDUMP-7H, MINIDUMP-7J
2023-02-05 11:18:18 +01:00
github-actions[bot] badf36899e Fetch translations & Recreate libretro_core_options_intl.h 2023-02-03 22:20:20 +00:00
Flyinghead d3aed076a6 build AppImage for linux
Issue #638
2023-02-03 18:36:27 +01:00
scribam 962b0bb65c android: update android gradle plugin to version 7.4.1 2023-02-03 11:47:11 +01:00
Flyinghead 6e940e4d08 ggpo: move endOfFrame() call back to start render
Naomi2 TA context geometry for the current frame is lost when
rollbacking during vblank in because it hasn't been queued for render
yet.
Fixes black screen after GGPO rollback for Naomi 2 games
2023-02-03 11:34:58 +01:00
Flyinghead 90e9f70a1a vk: fix resizing on wayland. validation errors with framebuffer render
wayland doesn't return the current surface dimensions in
getSurfaceCapabilities so we defaulted to 640x480. Instead use the
current display dimension as set by SDL.
Issue #648
Issue #898 (partial fix)

Vulkan validation errors when doing direct framebuffer rendering if fb
slots are skipped, since the corresponding fence isn't waited on.
Instead use an independent index to use them in sequential order.
2023-02-03 11:19:41 +01:00
Flyinghead bfdab4db20 pvr: add dummy sorted triangle to signal that per triangle is in use
Avoids crash when sorted triangle list is empty and renderer uses wrong
index values
2023-02-03 11:07:21 +01:00
Flyinghead f0e4574132 aica arm: stop the cpu if setting an illegal mode instead of crashing
Fixes MINIDUMP-70
2023-02-03 11:03:08 +01:00
Flyinghead c461624a67 move khronos to deps. get rid of old controller mappings and pandora 2023-02-03 10:42:43 +01:00
Flyinghead e6060aff6b force SDL build on linux to include libdecor for wayland 2023-02-02 21:16:16 +01:00
Flyinghead d1e6ee9cd7 pvr: add a dummy sorted triangle if list is empty
this signals that sorted triangles are being used otherwise wrong
indexes values lead to a crash
2023-02-02 20:19:52 +01:00
Flyinghead 6480a6e4e5 more fpu tests 2023-02-02 20:15:52 +01:00
Flyinghead 6cfbdf6586 ui: imguiDriver may be null if renderer/context fails to reinit
Force a reinit in this case
Fixes MINIDUMP-6R
2023-02-01 18:05:37 +01:00
Flyinghead 6b2063b06f GGPO fixes
Memwatchers weren't properly reset after a ggpo session.

Race condition when stopping if GGPO restarts the cpu for a new frame.

The emu thread might still run some rollback frames before stopping, so
the emu state must be updated only after ggpo is stopped.
Fixes MINIDUMP-6P

Don't autosavestate when GGPO is on

Really disable renderer during GGPO advance frame

Don't stop the sh4 after render (single threaded) when GGPO is on

android: Don't restart when unpaused if online
2023-02-01 18:04:26 +01:00
Flyinghead 301a7c5dcd savestate: write-only regs value must be deserialized (SB_?DAPRO) 2023-02-01 13:58:29 +01:00
Flyinghead e70a0dcf3d sh4_fpu clean up. tests 2023-02-01 13:53:32 +01:00
Flyinghead d1ab3461a6 savestates: dropping support for old formats
savestates older than 3 years aren't supported anymore
2023-01-31 17:57:54 +01:00
Flyinghead b81a6762bc switch build fix 2023-01-31 17:39:57 +01:00
Flyinghead 5875eda4d0 game id of console games wasn't trimmed
regression introduced by ee84567c17
2023-01-31 12:58:43 +01:00
Flyinghead 04c418d02a serialize: move code out of serialize.cpp and into modules 2023-01-31 10:13:03 +01:00
scribam 02a002d55b sdl: use target SDL2main 2023-01-30 13:54:31 +01:00
Flyinghead 0305904873 force NTSC for some games 2023-01-30 13:40:35 +01:00
Flyinghead ee84567c17 naomi: use gameId instead of naomi_game_id to get current game name
naomi_game_id isn't reset if a console game is loaded.
settings.content.gameId should be used instead.

Issue #901
Fixes MINIDUMP-6G
2023-01-30 13:34:06 +01:00
Flyinghead 528235ce9d jvs: fix kingrt66 instant win with accelerator 2023-01-30 13:28:14 +01:00
Flyinghead 27ea6ca092 aica: rename mem and reg accessors 2023-01-30 13:21:43 +01:00
Flyinghead cb94354099 switch build fix 2023-01-30 12:18:19 +01:00
Flyinghead 53dab29ddb iOS and Switch build fixes 2023-01-30 11:10:14 +01:00
Flyinghead b1479e6e34 aica: use namespaces, simplify api, handle serialization
Rename VArray2 to RamRegion. Add alloc(), free(), setRegion() and
de/serialize()
2023-01-30 10:40:07 +01:00
Flyinghead ea3262f7b0 log: alpha order for categories. update some category names 2023-01-29 21:24:44 +01:00
Flyinghead 143073b61d rename _vmem to addrspace and move platform vmem stuff to virtmem ns
use namespaces
simplify names
no functional changes
2023-01-29 18:48:33 +01:00
Flyinghead c472d60f80 __fastcall goes after return type too 2023-01-29 15:47:47 +01:00
Flyinghead 0c01075ba8 __fastcall goes after return type 2023-01-29 14:07:37 +01:00
Flyinghead 1149d499a8 x86: windows ce support in dynarec
clean up some unused methods and return values
2023-01-28 19:22:36 +01:00
scribam 85a941d6c6 openbsd fixes 2023-01-28 18:25:10 +01:00
Flyinghead 0a27b63584 aica: remove useless verify on reg access sizes
Fixes MINIDUMP-6C
2023-01-28 18:22:39 +01:00
Flyinghead 6f5f91245b windows: use directx 11 by default 2023-01-28 18:21:18 +01:00
github-actions[bot] 234955ac01 Fetch translations & Recreate libretro_core_options_intl.h 2023-01-27 22:20:02 +00:00
Flyinghead 99d5266aa0 Merge remote-tracking branch 'origin/master' into dev
# Conflicts:
#	core/hw/holly/sb_mem.cpp
#	core/hw/naomi/naomi.cpp
#	core/hw/naomi/naomi_flashrom.cpp
#	core/hw/pvr/ta_ctx.h
#	core/rend/gui.cpp
2023-01-27 15:41:45 +01:00
Flyinghead a5967a283f bump breakpad to fix win32 build error 2023-01-27 14:09:35 +01:00
Flyinghead 21a4935ec4 sentry: set release when uploading 2023-01-27 13:12:31 +01:00
Flyinghead 610e3cf968 naomi: avoid crash with M4 carts if M4 key is missing
Fix shorsepr crash at boot
Fixes MINIDUMP-5Z
2023-01-27 13:03:52 +01:00
Flyinghead 45c9d6185b gcc warning on windows 2023-01-27 11:16:54 +01:00
Flyinghead e18a4afcbb vk and pvr fixes. Renderer::Process returns void. N2 light 0 is no-light
pvr: Heap use after free due to PolyParam vector reallocation
vk: fix wrong buffer size calculation
Renderer::Process now returns void since it can't fail anymore
naomi2: light model at index 0 is "no light"
dx9, gles: throw if naomi 2 not supported
2023-01-27 11:16:25 +01:00
Flyinghead 499f86b065 pvr: use std::vector instead of List<> in render context
Remove overrun-related code.
Replace N2 matrix and light model pointers with indices.
2023-01-26 14:13:28 +01:00
scribam 80cf4406a7 cleanup include headers 2023-01-26 10:06:51 +01:00
Flyinghead cc4e3875f3 libretro: expose BBA and UPnP network options 2023-01-26 10:05:58 +01:00
Flyinghead 1c4871acb3 naomi: fix derbyocw rom list
was using drbyocwa roms
2023-01-25 17:16:52 +01:00
Flyinghead 3b683648fa switch build fix 2023-01-24 22:49:46 +01:00
Flyinghead 3923f10277 build fix 2023-01-24 21:44:35 +01:00
Flyinghead 1a681746b5 mmu: fix rte delay slot fetch address error with slow mmu
slow mmu clean up
P4 isn't executable
mmu test
mmu_TranslateSQW: throw exception but don't return status
2023-01-24 21:17:48 +01:00
Flyinghead 5703ef26cf os_DebugBreak is [[noreturn]] 2023-01-24 19:24:26 +01:00
Flyinghead 5096d50d37 move rom/flash stuff to hw/flashrom. nvmem api 2023-01-24 19:17:48 +01:00
Flyinghead f7e227a4aa dx9: don't crash if creating a boxart texture fails. log and skip tex
Fix for MINIDUMP-5Q
2023-01-24 14:52:55 +01:00
Flyinghead bbff377ceb maple: less log on dma error
Fixes GameShark CDX log spam
See MINIDUMP-5R
2023-01-24 14:30:09 +01:00
Flyinghead f8372c51a7 Revert "wip headers"
This reverts commit e3e2c3a0d2.
2023-01-24 14:26:14 +01:00
Flyinghead 31debefbe1 release dynarec mem allocs when terminating, including arm and dsp
Issue #453
2023-01-24 09:21:46 +01:00
Flyinghead c7d214e55a aica: update pending ints when enable mask is changed
Updating interrupts masks SCIEB and MCIEB can enable new interrupts so
check for that.
Only avoid race condition when needed.
2023-01-23 20:04:18 +01:00
scribam e3e2c3a0d2 wip headers 2023-01-23 18:29:04 +01:00
Flyinghead f96ce85365 dx11: attempt to recover if context reinit fails. More checks and logs 2023-01-23 12:20:10 +01:00
Flyinghead aa79196d38 vk: only destroy surface if instance and surface aren't null
Don't request Arm debug layer VK_LAYER_ARM_AGA
Fix for MINIDUMP-5G
2023-01-23 12:11:43 +01:00
Flyinghead 2b14c3e605 Try dx11 if dx9 and opengl both fail
Fix for MINIDUMP-5F
2023-01-23 12:06:26 +01:00
Flyinghead 41ba110ef4 enable RTTI for MSVC builds 2023-01-23 12:04:10 +01:00
Flyinghead ad42a32260 switch build fix 2023-01-22 18:21:55 +01:00
Flyinghead cc408f9688 aica arm7: fallback to interpreter for invalid LDR/STR
Fixes MINIDUMP-4X
2023-01-22 18:11:03 +01:00
Flyinghead 520e96a039 egl: call eglTerminate when closing context 2023-01-22 17:22:47 +01:00
Flyinghead db9fbbaebf custom texture loader must be stopped before the tex cache is cleared
Fix for MINIDUMP-53
2023-01-22 17:22:04 +01:00
Flyinghead 88384ad7d1 dynarec: crash in rdv_BlockCheckFail when current block can't be found
Only when MMU is on and used to compute blockcheck_failures so can be
ignored.
Tentative fix for MINIDUMP-59
2023-01-22 17:13:34 +01:00
Flyinghead 464b459073 modem: don't die when reg11 is written
Fix for MINIDUMP-5A
2023-01-22 17:10:12 +01:00
Flyinghead aea228c3df force real BIOS for Fushigi no Dungeon 2023-01-22 17:07:16 +01:00
scribam 8cdd171ab7 gl,gl4: simplify gl_create_resources calls 2023-01-21 12:12:21 +01:00
Flyinghead 9473c235f2 sh4: Fix CCN_MMUCR register definition
Some reserved bits were missing, which was breaking the (slow) MMU since
the write mask is correct.
2023-01-21 12:11:42 +01:00
Flyinghead b443467770 naomi: relax some eeprom checks based on BOOTID specs 2023-01-21 12:01:22 +01:00
Flyinghead a6bf9dd39c Option to disable VMU sounds. VMU sounds use better waveform. 2023-01-21 11:54:34 +01:00
Flyinghead 8fdcea2e20 maple: delay raising overrun interrupt when dest isn't in RAM
Only raise error when copying data back to RAM.
Fixes Cheats 'N Codes Volume 1
2023-01-21 11:38:58 +01:00
Flyinghead 31bd943d67 gl,vk: don't use linear mipmap filter with nearest
Fixes glitches in Railroad Tycoon II
Partially revert 15b21fff2b and
a9cabdc342
2023-01-21 11:32:28 +01:00
github-actions[bot] ba78a3aa5b Fetch translations & Recreate libretro_core_options_intl.h 2023-01-20 22:19:43 +00:00
warmenhoven 1948c66c11 Reload and vmem fixes for libretro on Mac (#885)
* Try to properly set up vmem on OSX
* Add Mac OSX arm64 libretro buildbot
* Don't term libretro on macOS
* Unload game when loading fails
2023-01-20 20:37:56 +01:00
Flyinghead 3cf7cf0a7f network: Emulate BBA should not be changed once a game is started
Change UI to disable BBA toggle when game is started.
Refactor UI to use DisabledScope helper.
Make sure the network stack deletes the same device it initialized.

Tentative fix for MINIDUMP-4N
2023-01-20 14:52:27 +01:00
Flyinghead a593cddf52 pvr: mvsc2 needs yet more rendering cycles
Fixes texture corruption in the character line up during intro.
Follow up to 976fb99aa3
2023-01-20 14:41:36 +01:00
Flyinghead cecf16e65e dump textures: don't crash if malloc fails
Tentative fix for MINIDUMP-4P
2023-01-20 14:38:23 +01:00
scribam 458b233e16 android: add vibrate compatibility with newer versions 2023-01-18 20:37:10 +01:00
Julien Reichardt cca7ed6bf7 Cleanup metainfo file 2023-01-18 20:36:30 +01:00
Flyinghead f63cf7406a logging changes 2023-01-18 14:03:02 +01:00
Flyinghead e21d666328 reios: allow loading CDIs with ip_meta.wince = 1
For some reason Neo XYX has this flag set. I haven't found any wince CDI
that has this flag set but it shouldn't hurt.
Fix for MINIDUMP-47
2023-01-18 10:12:24 +01:00
Flyinghead ab3f5dbc4c sdl: fix crash in getNativeHwnd() when recreating window
fixes rawinput crash
Fix for MINIDUMP-4B, MINIDUMP-4G, MINIDUMP-4F, MINIDUMP-4E
2023-01-18 09:45:01 +01:00
Flyinghead 528f15f117 win32 build fix 2023-01-17 22:39:22 +01:00
Flyinghead 7c72aa8a80 unintended new files in CMakeLists.txt 2023-01-17 22:10:54 +01:00
Flyinghead 2420c05930 android: implement unwind info for arm32 2023-01-17 22:06:22 +01:00
Flyinghead 3a312f3814 add llvm's libunwind 2023-01-17 21:56:30 +01:00
Flyinghead bac67bd91a missing submodule oboe 2023-01-17 21:29:34 +01:00
Flyinghead 36e67203a4 Merge remote-tracking branch 'origin/master' into dev
# Conflicts:
#	core/deps/oboe
#	core/emulator.cpp
#	core/hw/maple/maple_jvs.cpp
#	core/rend/gui.cpp
2023-01-17 21:20:14 +01:00
Flyinghead a52d1c97ec UWP build fix 2023-01-17 20:55:59 +01:00
Flyinghead 9d3125c546 fix tony hawk's 1 & 2 PAL disk ids 2023-01-17 11:41:50 +01:00
Flyinghead 86a6d7a4f5 widescreen cheat for Biohazard: Code Veronica: Kanzenban (JP)
same cheat as Resident Evil: Code Veronica X Kanzenban (Eng.
translation)
Issue #880
2023-01-17 11:40:35 +01:00
Flyinghead 0f214b1441 reios: fix crash if disc is null at boot
Don't overflow Disc::sessions

Fix for MINIDUMP-41
2023-01-17 11:39:00 +01:00
Flyinghead a0b50cd41d pvr: don't crash on invalid poly list types. log and ignore
Fix for MINIDUMP-3Z
2023-01-17 11:36:00 +01:00
Flyinghead 1d1754dc98 pvr: don't crash on YUV converter error. log and continue
Fix for MINIDUMP-44
2023-01-17 11:25:08 +01:00
Flyinghead b8464ef6c5 widescreen cheat for Resident Evil - Code Veronica X Kanzeban
Courtesy of keefged4
Issue #880
2023-01-16 18:16:05 +01:00
Flyinghead 692ca52182 pvr: fix background poly texture coordinates
V tex coordinates were inverted for Donald Duck Goin Quackers
2023-01-16 17:56:37 +01:00
Flyinghead b4ecaecd45 dynarec: raise sh4 address error if trying to compile unaligned address
Error was only raised when mmu is enabled.
tentative fix for MINIDUMP-3Q
2023-01-16 17:53:01 +01:00
Flyinghead 9954768636 dx11: simplify RenderFramebuffer for libretro and fix black frames
RA uses some shaders that need to be disabled (as in Render()).
Also the framebuffer texture can be returned directly.

might help Issue #865
2023-01-16 17:50:23 +01:00
scribam cbffc5cade android: misc changes (#876)
* android: add appCategory attribute

* android: remove unnecessary @TargetApi

* android: replace 'for' loop with enhanced 'for'

* android: use java-style array declaration
2023-01-15 20:44:47 +01:00
Flyinghead 4bbf5c562e ssa: infinite loop in skipSingleBranchTarget
Fixes Mat Hoffman's Pro BMX freeze when exiting a session.
Issue #878
2023-01-15 20:04:05 +01:00
Flyinghead 329e5ed467 android: allow starting games with intent while a game is running
stops and unload the current game then starts the new one
2023-01-15 20:02:03 +01:00
Flyinghead 19a160695c android: since ndk23 exceptions traversing dynarec blocks cause a crash
NDK 23 switched to clang's unwinder instead of gcc so __register_frame()
takes a single FDE as argument (as in macOS).
Fix for MINIDUMP-3M and MINIDUMP-3N
2023-01-15 19:31:44 +01:00
Flyinghead 1e195b7237 sdl audio: fix crash when decrasing audio buffer size. fix deadlock
sample_count wasn't reset to 0 on init, so it could point past the end
of the audio buffer if buffer size is decreased, leading to a crash.
Fix for MINIDUMP-29

Deadlock if audio buffer size is too small (< 1024 samples)
2023-01-15 12:07:26 +01:00
Flyinghead 2b37a5dc08 sdl audio: use SDL to convert from 44.1 to 48 kHz
Fix crash introduced by 7205068809
Use SDL_ConvertAudio to convert audio when needed.

Fix for MINIDUMP-3K
2023-01-15 11:21:42 +01:00
Flyinghead 8aadf5b097 cheats: don't update the cheat list when adding one fails
The operation should fail or succeed completely.
Issue #871
2023-01-15 11:16:40 +01:00
Flyinghead 13428ba696 allow screen stretching to be overridden when using widescreen cheat
Issue #870
2023-01-15 11:14:21 +01:00
Flyinghead 52f2ca7ff6 windows: convert command line arguments to UTF8
Issue #875
2023-01-15 11:13:07 +01:00
scribam 174ce8786b android: add oboe as a submodule 2023-01-14 13:02:34 +01:00
scribam fc118f295d android: remove oboe 2023-01-14 13:02:34 +01:00
scribam 18cfe2f92f android: update project for Android Studio Eel 2023-01-14 13:02:34 +01:00
scribam 0d4a7dbac9 android: use getDefaultDisplay with android api level < 17 2023-01-14 13:02:04 +01:00
Flyinghead a370851494 dynarec: check stale blocks in rdv_DoInterrupt if block not found
tentative fix for MINIDUMP-36
2023-01-14 12:54:05 +01:00
Flyinghead 7b49cc73ee gl,gl4: use correct framebuffer size for matrix when rtt'ing 2023-01-14 12:52:10 +01:00
Flyinghead a8c5af8425 dx: don't resize main framebuffer when rendering to texture
dx9 and dx11 renderers were wrongly resizing main framebuffer to 0,0
when rendering to a texture.

Fix for MINIDUMP-1W
2023-01-14 12:48:56 +01:00
Flyinghead 3441a9ccf0 pvr: calculate framebuffer size when TA context is dequeued
Config can change after the TA context has been queued (upscaling, full
framebuffer emu, etc.) which can make the calculated framebuffer size
wrong during render, leading to crashes in renderers.
Fix for MINIDUMP-35
2023-01-14 12:39:38 +01:00
Flyinghead 659d21680b android: race condition on Emulator::threadResult
The emu thread can be stopped/started by the app main java thread while
the render thread is running. This can lead to a race condition on the
threadResult future between checkStatus() and start(). So protect
relevant sections with a mutex.

Fix for MINIDUMP-1G, MINIDUMP-1H, MINIDUMP-2G and MINIDUMP-33
2023-01-14 10:52:27 +01:00
Flyinghead 2da833883b pvr: skip triangles with NaN/Inf coordinates when sorting them
Issue #867
2023-01-14 10:46:21 +01:00
Flyinghead c301bf0827 pvr: ignore invalid TA types instead of crashing
Fix for MINIDUMP-32
2023-01-14 10:42:26 +01:00
Flyinghead 1c4303b76d arm dynarec: verify is no longer true
Fix for MINIDUMP-37
2023-01-14 10:29:44 +01:00
github-actions[bot] 170a6ac36e Fetch translations & Recreate libretro_core_options_intl.h 2023-01-13 22:20:05 +00:00
Flyinghead 92fa4c041d gdrom: log invalid size register access but don't crash
Fix for MINIDUMP-1T
2023-01-13 11:34:40 +01:00
Flyinghead f34a9f6eac jvs: serialize drive board output value and more
Issue #864
2023-01-13 11:25:04 +01:00
Flyinghead 9fb69af355 dx9: more error handling. more logging
Handle case where dx context init fails when switching to/from fast
forward.
Log errors.
2023-01-13 11:15:32 +01:00
Flyinghead 59606d8935 naomi: more robust error handling when loading invalid roms
Fix for MINIDUMP-2S
2023-01-13 10:49:52 +01:00
Flyinghead bd7f5ec4c1 disable non-working ikaruga ws cheat
Issue #866
2023-01-13 10:46:51 +01:00
Flyinghead d082993a7a ui: race condition when network times out while pressing start
Fix for MINIDUMP-2Y
2023-01-13 10:06:36 +01:00
Flyinghead 640d4162b6 holly: log invalid pvr register access size but don't crash
Fix for MINIDUMP-2V
2023-01-13 09:52:17 +01:00
Flyinghead 66eb08f2d1 sh4: check that dma-ch2 source address is in ram
Force real BIOS for Force Five dc conversion
Fix for MINIDUMP-2W
2023-01-13 09:28:45 +01:00
Flyinghead 93fbd67a85 dx9: recover after screen lock. reset render state cache on entry
Device is lost for a long time when the screen is locked. Need to
continue calling present() to recover.
Reset render state cache on in RenderFramebuffer and RenderLastFrame
entry points.
More logging in renderer resizing.
2023-01-12 16:09:01 +01:00
Flyinghead cf031717dd chd: skip invalid media with 0 track 2023-01-12 16:05:07 +01:00
Flyinghead 075ec1cf98 log: increase in-memory log to 20 lines 2023-01-12 16:02:15 +01:00
Flyinghead 8f3b6a2371 lr: call set_system_av_info even for dx11
call was disabled due to a crash that doesn't happen anymore
Issue #863
2023-01-12 14:37:05 +01:00
Flyinghead ac24d9be5b preserve savestate compat with sh4 exception changes 2023-01-11 23:01:37 +01:00
Flyinghead a0e800f102 build fix 2023-01-11 22:39:20 +01:00
Flyinghead 7e4572a86a naomi: f355 multiboard support WIP 2023-01-11 22:31:36 +01:00
Flyinghead 4f0d3a958d ui: debug tab with logging and profiling options 2023-01-11 21:15:45 +01:00
Flyinghead 06c5ba7f0e sh4: simplify exceptions 2023-01-11 20:42:33 +01:00
Flyinghead 673fb26d6e android: threading fix. stop vibrator thread. allow screen saver
If the android activity is destroyed and the game unloaded, the gui's
game state wasn't updated, leading to a crash if resuming. Same for the
android game state if pausing, destroying then resuming.
tentative fix for MINIDUMP-27, MINIDUMP-25, MINIDUMP-23
Wait until emu is stopped in single-threaded.
Stop vibrator thread when view is detached
Allow the screen saver when a game isn't running.
2023-01-11 11:44:28 +01:00
Flyinghead 5fa98da17e dx9: stricter device reset failure check. More logging
tentative fix for MINIDUMP-1P
2023-01-11 09:44:00 +01:00
Flyinghead 9b2f33f7bd jvs: fix wrungp CAUTION message regression
due to 53ed006a54
Issue #861
2023-01-11 09:05:47 +01:00
Flyinghead 2b70c73f80 gl: compilation and runtime fixes for GLES 2.0
Fix libretro compile errors with GLES2
Fix black screen at runtime with gles 2.0

Issue #859
2023-01-11 09:02:24 +01:00
Flyinghead 1aec64cbae android: don't close the oboe stream twice on device lost
tentative fix for MINIDUMP-26
2023-01-11 08:58:55 +01:00
Flyinghead 611946559c macos build: fix brew python link error 2023-01-10 12:40:48 +01:00
Flyinghead 2997c6396f downgrade libchdr to before zlib 1.2.12 upgrade 2023-01-10 12:38:17 +01:00
Flyinghead 859d5df056 revert libchdr to before lzma-22 upgrade 2023-01-10 11:56:43 +01:00
Flyinghead 8a1902e5a8 GDI's and gdrom CHD's must have at least 3 tracks 2023-01-10 11:28:42 +01:00
Flyinghead 285655f52d vk: check if vkEnumerateInstanceVersion is null before calling it
vkEnumerateInstanceVersion is only available in vk 1.1 so it might be
null after dynamic loading of entry points.

tentative fix for MINIDUMP-1Z, MINIDUMP-20 and MINIDUMP-21
2023-01-10 09:58:56 +01:00
Flyinghead fceb170a2a picotcp: enable multithreading. protect bba input queue with mutex.
tentative fix for MINIDUMP-1Y
2023-01-10 09:46:28 +01:00
Flyinghead 4376e89149 Bump libchdr to latest 2023-01-09 18:33:44 +01:00
scribam cbd1d3134e deps: update sdl to version 2.26.2 2023-01-09 18:02:30 +01:00
Flyinghead fc479dbcc0 dx9: better handling of device lost. Fix fb not rendered if 1st
Handle case where device reset fails and continue attempting a reset.
tentative fix for MINIDUMP-12 and MINIDUMP-1Q

RenderFramebuffer wasn't working when first render after init
2023-01-09 18:01:44 +01:00
Flyinghead ae47ac19b8 dx11: check supported texture formats. Fix fb render not working if 1st
Check supported texture formats including mipmap and mipmap autogen.
Fall back to 8888 format.
tentative fix for MINIDUMP-17, MINIDUMP-1R and MINIDUMP-1M

RenderFramebuffer wasn't working if first render after init.
2023-01-09 17:50:46 +01:00
Flyinghead 84f6bd3fef libretro build fixes 2023-01-09 17:44:40 +01:00
Flyinghead d3b2da8e3b gui: &ll game scanner game_list updates must be guarded by mutex
arcade_game_list doesn't need to however
tentative fix for MINIDUMP-1S
2023-01-09 09:14:03 +01:00
Flyinghead 493ccc27d1 widescreen cheat for Fire ProWrestling. courtesy of Espirral 2023-01-08 11:35:24 +01:00
Flyinghead b37e6dc28d Merge remote-tracking branch 'origin/master' into dev 2023-01-08 11:19:48 +01:00
Flyinghead 8cd6a94e26 arm dynarec: avoid SIGBUS errors due to unaligned memory access
VSTR and VLDR require a 32-bit alignment in armv7. SH4 alignment
requirement is identical but ignored (no SH4 address error is raised).
So instead of crashing, just align the memory address.

Fix for MINIDUMP-1J
2023-01-08 11:13:01 +01:00
Flyinghead 13df32ba3f vk: check vkGetInstanceProcAddr value before use and report error
Tentative fix for MINIDUMP-1F
2023-01-08 11:06:47 +01:00
Flyinghead 262a39cafb android: avoid UI race condition when stopping or resuming game
Gamepad events aren't delivered to the UI thread in Android. This can
lead to race conditions between the UI thread (calling gui_display_ui())
and the event thread (calling gui_open_settings()).

Issue #852
Fix for MINIDUMP-1D, MINIDUMP-1E, MINIDUMP-1K
2023-01-08 10:59:36 +01:00
Flyinghead 480f2e31b0 widescreen cheats for 102 Dalmatians. courtesy of Espirral 2023-01-07 12:02:35 +01:00
Flyinghead d0bb0aea97 android: defer stopping audio until after current frame is rendered
In android, stop requests are not run in the UI thread so in
single-threaded mode, they must be deferred until after the current
frame is rendered to avoid deadlocking on audio.
2023-01-07 11:51:32 +01:00
Flyinghead bf3f927a99 reios: don't crash on unknown trap vector. log error and ignore 2023-01-07 11:46:59 +01:00
github-actions[bot] 19818e717f Fetch translations & Recreate libretro_core_options_intl.h 2023-01-06 22:20:08 +00:00
Flyinghead b6491a3842 android: REICAST_HOME -> FLYCAST_HOME 2023-01-05 20:21:15 +01:00
Flyinghead c04c696ba6 arm64 dynarec: pad link section with nop to allow full mmu relink
fix literal pool being overwritten
Fix for MINIDUMP-18
2023-01-05 14:36:23 +01:00
Flyinghead 17474bf005 android: log abort message to normal log so it's stored in the minidump 2023-01-05 13:01:49 +01:00
Flyinghead 756ec0e672 arm build fix 2023-01-04 12:27:04 +01:00
Flyinghead 3dfdb60139 arm dynarec: handle immediate operand to fsca 2023-01-04 12:12:24 +01:00
Flyinghead 5a409dbe2c boxart: [] operator with non-existing key on const json is UB
Use json::at() instead.
Don't return pointer to GameBoxart to UI since it can be
replaced/deleted by the scraper thread.
Tentative fix for MINIDUMP-16
2023-01-04 12:09:09 +01:00
Flyinghead 9ef37d9776 arm[64] dynarec: xtrct can have immediate operands
Fixes MINIDUMP-15
Sakura Taisen 2 crash
2023-01-03 15:15:13 +01:00
Flyinghead ba0a357d48 missing change for 12bba31270 2023-01-03 11:32:00 +01:00
Flyinghead 659ffa4406 vk: catch vulkan dyn loader exception when driver can't be loaded
Fixes MINIDUMP-R
2023-01-03 11:08:28 +01:00
Flyinghead 12bba31270 lr: fix incorrect DC framebuffer size 2023-01-03 11:03:31 +01:00
flyinghead dd66e44871 compile warnings 2023-01-02 16:39:34 +01:00
flyinghead c5c87522ca x64 dynarec: wrong op in GenReadMemImmediate
Fixes MINIDUMP-14
2023-01-02 16:06:58 +01:00
flyinghead 5ef80f0a17 dx11: disable scissor test when rendering framebuffer
Issue #847
2023-01-02 16:04:17 +01:00
Flyinghead 7372df3aff android: check if activity is null before using it to show/hide keyboard
tentative fix for MINIDUMP-Z
2022-12-31 16:53:08 +01:00
Flyinghead cf514b0d6b pvr: skip remaining vertices if incomplete after inf vertex
in makePrimRestartIndex
Issue #846
2022-12-31 16:51:35 +01:00
github-actions[bot] b232a10167 Fetch translations & Recreate libretro_core_options_intl.h 2022-12-30 22:19:43 +00:00
Flyinghead 2a465d2f03 ios: check if jit is enabled. attempt to enable it by debugging self
JIT detection and enabling taken from ppsspp
Re-check JIT and restart AltServer discovery every 10 secs until JIT is
enabled.
Attempt to enable JIT by forking a process to debug the parent process.
(jailbroken devices)
2022-12-30 16:22:38 +01:00
Flyinghead 802f70fedd pvr: recover from renderer init failure
issue MINIDUMP-V
fix some warnings
2022-12-29 19:18:19 +01:00
scribam 5acfa7d3d6 vulkan: return an error if no physical devices found 2022-12-29 19:12:53 +01:00
Flyinghead 85188bf137 naomi: fix button labels for hmgeo
Issue #841
2022-12-25 22:09:34 +01:00
Flyinghead bfc44f2b4e scraper: skip invalid textures. invalid CUE crash. memory leak
Sanity check of PVR texture params before converting it to avoid crash
(MINIDUMP-K).
.cue gdrom needs at least 3 tracks.
Delete disc if invalid.
2022-12-25 11:27:48 +01:00
Flyinghead 96aaa8b14a elan: don't map RAM with vmem if not naomi2 game
Issue #839
2022-12-24 13:33:16 +01:00
Flyinghead 53ed006a54 naomi: 18wheeler, soulsurfer and wldrider input improvements
18wheeler: limit wheel range. Issue #693
18wheeler: Implement gear tristate lever with 2 buttons. Fake motor drive board to avoid error messages in deluxe version.
soulsurfer: floormat button/contact is always on
wldriders: unmap rear brake so it doesn't have to be released
2022-12-24 10:48:17 +01:00
github-actions[bot] 171c41df12 Fetch translations & Recreate libretro_core_options_intl.h 2022-12-23 22:20:01 +00:00
Matt Phillips 4b53edb3bd Basic CPU graphs using ImPlot (#838) 2022-12-23 16:07:35 +01:00
Flyinghead 62085539a7 dynarec: reg alloc 64-bit regs. avoid some interpreter fallbacks
Option to reg alloc 64-bit regs in two host regs. Used when FPSCR.SZ ==
1 (64-bit reg and memory transfers.) Enabled for arm, arm64 and x64
(windows only) dynarecs.
Don't fallback to interpreter when FPSCR.PR==1 (double precision) for
FMOV, FLDS and FLTS.
2022-12-23 16:06:54 +01:00
scribam 1c8e558e25 deps: update glslang and vulkan 2022-12-23 10:14:31 +01:00
scribam 568145c247 metainfo: fix wrong category name 2022-12-23 10:14:02 +01:00
Flyinghead 5703bc7df2 ui: arcade games appear twice if the game list is updated 2022-12-23 10:13:26 +01:00
Flyinghead 95a00a165a sentry: upload crashes after reading emu.cfg to comply with user choice
android: get rid of Send Logs button
2022-12-23 10:06:24 +01:00
Flyinghead 599bc8a823 arm64 dynarec: need up to 5 ops for mem accesses
Issue #837
2022-12-22 14:55:42 +01:00
Flyinghead 9578841480 pvr: fix texture bleeding before making indexes
fix crash with sorted triangles.
Issue #836
2022-12-22 13:15:32 +01:00
Flyinghead 5387a6b534 android: minify makes httpclient fail
fixes sentry.io upload
2022-12-22 13:13:23 +01:00
Flyinghead bf09e96e04 android: more logging 2022-12-21 18:02:30 +01:00
Flyinghead b5d8cecd91 android: delay sentry upload to avoid broken pipe. Log more stuff
tentative fix for the broken pipe error when uploading to sentry on
android.
init log and sleep for 5 secs before upload
log git version, gpu name and version, renderer type and game id
2022-12-21 16:49:08 +01:00
Matt Phillips 6d913f42c8 Host-side profiler - initial commit (#834)
* Host-side (Flycast) profiler - initial commit

* Profiler - configurable frame warning time

* Compile fix for !DC_PROFILER
2022-12-21 11:24:11 +01:00
Flyinghead 1e0a875fa3 sentry: various fixes. Upload last log lines with the minidump 2022-12-21 11:23:15 +01:00
Flyinghead 4d77ce5a66 unused function 2022-12-20 22:24:15 +01:00
Flyinghead f3a6fb7d8b sentry.io integration 2022-12-20 21:52:46 +01:00
Flyinghead b6f73d96ca vk,dx: provoking vtx with sorted triangles. No depth write in per-strip
Provoking vertex wasn't set with sorted triangles (dx9, dx11, vulkan)
vk,dx9: No depth write in per-strip as in opengl and dx11.
2022-12-20 21:47:19 +01:00
Matt Phillips 13f3c8281f Fixed single stepping, added support for vCont packets and ranged stepping (faster), initial work to support other breakpoint types 2022-12-18 16:27:38 +01:00
Flyinghead 0107435a73 iOS build fix 2022-12-17 11:25:58 +01:00
Flyinghead ce674a872a dyna: implement missing ops: ldc/stc sr/fpscr, tas, div1
add dynarec implementations for missing ldc and stc ops with sr and
fpscr
add dynarec implementation for tas.b
canonical implementation for div1
delete unused reg_old_sr_status and reg_sr
2022-12-17 11:09:51 +01:00
Flyinghead 51758b965e ggpo: disable full framebuffer emulation. memwatch perf fix
Disable full framebuffer emulation with ggpo if threaded rendering is
enabled. Would require thread synchronization on VRAM page map.
memwatch: do single lookup on page map in hit()
2022-12-17 10:54:01 +01:00
Flyinghead 7fec511463 maple: don't recreate devs on rollback. Raise error if dest is invalid
maple: raise error is maple dest dma address isn't on RAM
maple: don't recreate maple devices when loading a rollback savestate
2022-12-17 10:51:12 +01:00
github-actions[bot] 1dd006d846 Fetch translations & Recreate libretro_core_options_intl.h 2022-12-16 22:19:48 +00:00
Flyinghead 2800927fa1 arm64 dynarec: can't rely on faultAddress with 512 MB vmem
Use x0 instead
2022-12-16 20:40:23 +01:00
Flyinghead f133e3cccb verify() must not call a function with side-effect 2022-12-16 20:40:23 +01:00
Matt Phillips b0a520fe18 Various GDB fixes and improvements (#832)
* Enabled GDB server, compile fix for MSVC, added GDB option to config

* GDB - 'vMustReplyEmpty' should not be explicitly handled, it is a test for how the target responds to unknown vpackets (which was incorrect)

* GDB wait for debugger option to allow debugging from bootstrap, and Event::Resume moved after renderer init so agent.interrupt() can pause the renderer

* Draw "Waiting for debugger", and fixed UI not rendering last frame before a state change

* Fixed GDB regs/mem endianness
2022-12-16 20:34:30 +01:00
Matt Phillips 3f30dd01ad Support for multi-processor compilation with MSVC (/MP option) (#830) 2022-12-15 22:50:38 +01:00
Matt Phillips 0c081a9597 Support for comma separated "-config section:key=value,section:key=value,..." command line syntax
(cherry picked from commit 451997d01e)
2022-12-15 22:49:55 +01:00
Matt Phillips 7176460de3 External windows serial console (#828)
* Open external console for serial output on Windows

(cherry picked from commit e41a1410b9)

* Compile fix for _UNICODE

(cherry picked from commit 4e6927bd27)
2022-12-15 22:49:20 +01:00
Matt Phillips 733a1fa73d Added USE_DX9 and USE_DX11 as configurable options in CMake 2022-12-15 22:48:38 +01:00
Flyinghead e3809ba058 gl: macOS build fix 2022-12-14 23:43:36 +01:00
Flyinghead 4d3de39c64 gl: no GL_PRIMITIVE_RESTART and glPrimitiveRestartIndex in GLES 2022-12-13 23:42:11 +01:00
Flyinghead 1765e50703 lr: missing symbols and functions 2022-12-13 23:33:24 +01:00
Flyinghead f9feaa313b pvr: sort triangles during parse. Use primitive restart
Sort triangles during ta_parse. Use the same index as other polys. Store
results in rend_context.
Use primitive restart if available to avoid too many degenerate
triangles.
Update renderers.
2022-12-13 22:57:57 +01:00
Flyinghead 9781d8971a gl: use static buffers for quad vertices 2022-12-13 20:56:19 +01:00
Flyinghead a0a9b5bbc5 holly: crash when reading a write-only register 2022-12-12 22:15:12 +01:00
Flyinghead c684faf423 naomi widescreen cheats: initd, initdv2, gunsur2, spawn, cspike, jambo
Widescreen cheats for initd, initdv2, gunsur2, spawn, cspike, jambo,
soulsurf.
Courtesy of Goddamn Superhero
Disable ws chear for House of the Dead 2 (wrong gun coordinates)
2022-12-11 16:33:30 +01:00
Flyinghead cdca559d99 ggpo: optimize memwatch, save/load state. endOfFrame on vblank in
ggpo: Optimize memwatch and load/save state. Unprotect memory before restoring a state. Smaller timesync wait. Missing error handling.
pvr: call ggpo::endOfFrame() on vblank in only
ssa: fix warning
2022-12-10 17:19:34 +01:00
Flyinghead d76dff8594 ggpo: don't call exit on assert. clean up logging
Don't call exit when an assertion fails, throw an exception instead. Log
ggpo API errors.
Deleted most ggpo logging methods and use flycast logging.
2022-12-10 13:06:31 +01:00
github-actions[bot] 223504a206 Fetch translations & Recreate libretro_core_options_intl.h 2022-12-09 22:20:25 +00:00
Flyinghead 1ab4eb00c0 tex cache: minor key mask fix. egl: no need for depth/stencil surface
Part of PalSelect was used as cache key for palette textures
PrintTexture fix
egl,wgl,xgl: No need for depth/stencil surface
gl: non-functional refactoring
2022-12-09 17:49:32 +01:00
Flyinghead 32e3e7d9c5 vmem: no more 4GB vmem mode. only map elan RAM in naomi2 mode
Do not attempt to reserve 4GM of virtual space on 64-bit hosts. Use
512MB everywhere.
Don't map elan RAM if not needed and dont protect/unprotect it in
memwatch.
2022-12-09 17:37:49 +01:00
Flyinghead 98123b9215 vk: don't sort triangles in per-strip mode
useless and now crashes since vertices aren't in ascending order anymore
2022-12-08 21:35:51 +01:00
Flyinghead 9069a49145 pvr: take jitter into account in spg sheduler. fix scheduler edge case
Take jitter into account when calculating current scanline
Scheduler would miss the next int if it's on the next scanline
Support for Hblank interrupt mode 2 (every scanline)
2022-12-06 22:04:37 +01:00
Flyinghead d417237e64 Merge remote-tracking branch 'origin/master' into dev
# Conflicts:
#	core/emulator.cpp
2022-12-06 21:47:50 +01:00
Flyinghead 648f33473f test fix 2022-12-06 21:12:41 +01:00
Flyinghead 446619ce85 atomiswave only has 2 MB of aica ram
new savestate version
build.h clean up
2022-12-06 20:51:45 +01:00
Flyinghead f5fa1f6210 holly, sh4: reg access handlers don't need size. SB_FFST constant 0 2022-12-06 20:42:00 +01:00
Flyinghead 976fb99aa3 pvr: naomi mvsc2 needs more rendering cycles
Regression introduced by 0b0e64304e
2022-12-06 19:50:34 +01:00
Flyinghead a0529d1cfc drop support for legacy .reicast config dir (linux, macOS) 2022-12-06 18:09:43 +01:00
Flyinghead 8001af9743 sh4: proper write masks for memory-mapped registers 2022-12-06 17:58:30 +01:00
Flyinghead e48b72a859 race condition causing emu thread exceptions to be ignored
in multithreaded mode, checkStatus() *must* be called to report
exceptions thrown by the emu thread
2022-12-05 21:24:27 +01:00
Flyinghead 71ba018782 widescreen cheatcode for vf3tb US
courtesy of goddamn superhero
2022-12-05 18:36:49 +01:00
Flyinghead 59ff44132b aica: get rid of audio samples batching
Some audio issues are reported because of this option and the now
correctly clocked aica cpu.
2022-12-05 18:34:52 +01:00
scribam 8a0323ec08 deps: update sdl to version 2.26.1 2022-12-04 16:32:08 +01:00
Flyinghead 4c7df6c7f4 pvr: don't merge polys in per-triangle. merge polys in per-strip
Merging polygons in per-triangle can produces a large number of
degenerate triangles (up to x3), which must then be sorted, resulting in
a performance hit. This is useless since the sorted triangles are merged
after being sorted. (Regression introduced by
20d25059bf)
Issue #818

In per-strip mode, polygons are now sorted before creating the index and
merging. So it doesn't have to be done in the renderer anymore.
2022-12-04 16:31:39 +01:00
github-actions[bot] 676cd3104b Fetch translations & Recreate libretro_core_options_intl.h 2022-12-02 22:20:30 +00:00
Flyinghead a40210c55c no aica batching for Tony Hawk's 1 & 2 2022-11-29 17:27:31 +01:00
Flyinghead 034f90c1e0 ggpo: zero-init unused but sent inputs
avoids lots of useless rollbacks
2022-11-29 17:12:15 +01:00
DisasterMo 64223927b8 Fix Crowdin config & workflow
Also add new languages and update translation scripts
2022-11-28 15:00:25 +01:00
tunip3 e2c03255bb make Xbox display scale scale with res instead of just switching between 2 presets for 1080p and 4k 2022-11-25 19:21:10 +01:00
scribam 63495d3a6a deps: update sdl to version 2.26.0 2022-11-22 17:23:32 +01:00
scribam 88466ec352 vulkan: add missing simplification (follow-up from 8426bcad) 2022-11-19 12:53:28 +01:00
Edward Li 1995eb935b Build OpenMP.xcframework 2022-11-19 12:52:58 +01:00
scribam f6532ca27a fix some warnings 2022-11-19 12:52:26 +01:00
Flyinghead 75dd5305c4 Revert "ci: use devkitpro/devkita64:latest (#672)" due to regression
Several games are freezing at start up
Issue #783
This reverts commit 3d00ac338b.
2022-11-15 17:52:12 +01:00
Flyinghead 76cf989455 disable free play for radirgy noa
Issue #527
2022-11-14 16:00:11 +01:00
Flyinghead 5b8e932509 move steam deck hack to sdl/sdl.cpp 2022-11-14 15:59:19 +01:00
scribam 993b705d8b vulkan: use dynamic dispatch loader 2022-11-09 17:20:05 +01:00
Flyinghead 19204882c4 pvr: reschedule spg when SPG_HBLANK_INT is updated
Fixes Triggerheart Exelica input lag
Issue #691
2022-11-04 18:34:43 +01:00
vkedwardli 605dc59f8d Fix Steam Deck's Game Mode also 2022-11-04 16:01:06 +01:00
Flyinghead 2332884d8b maple: lower xfer rate to 1 Mbps. More accurate payload size calculation
Maple bus max xfer rate is 2 Mbps but actual speed is 1 Mbps.
Fixes Slave Zero (PAL) freeze with HLE.
Some improvements on payload size calc. Clean up.
2022-11-04 11:22:50 +01:00
Flyinghead 94f3d80a75 Merge remote-tracking branch 'origin/master' into dev
# Conflicts:
#	CMakeLists.txt
#	core/hw/pvr/Renderer_if.cpp
#	core/oslib/audiobackend_alsa.cpp
#	core/rend/vulkan/desc_set.h
#	core/rend/vulkan/oit/oit_drawer.cpp
2022-11-02 20:12:34 +01:00
Flyinghead 0b0e64304e pvr: adaptive end-of-render interrupt delay
EoR interrupt delay now depends on the TA context size.
Issue #634
Fixes issues with FMV in some WinCE games (Resident Evil 2, Next Tetris,
Nightmare Creatures 2)
2022-11-01 18:29:44 +01:00
Flyinghead 5a1a766bd4 pvr: emu unresponsive if no render. Present when FB_R_SOF = FB_W_SOF
Fix no input polling while waiting for present.
Present frame immediately if FB_R_SOF = FB_W_SOF.
2022-11-01 18:23:54 +01:00
Flyinghead c15f446ffc hle bios: fix pal detection for some pal wince games
Caesar's Palace 2K, The Next Tetris, KISS
2022-10-31 11:31:21 +01:00
Flyinghead c88cdde9ec test fix 2022-10-30 12:47:39 +01:00
Flyinghead 40dbf53792 pvr: use render pass # to read the right tile when marking blocks
Fixes Unreal Tournament flashing/black screen.
gl: mark vram area in rtt to avoid overwriting data (Worms World Party)
Force Worms World Party to use CopyToVRam (regression due to
6a5db32d5d)
Don't calculate precise aspect ratio and use 4/3 instead (or more if
widescreen or stretch).
Fix clipping issue when using SCALER_CTL.vscalefactor. Avoir crash when
clip values are >= width or height.
vulkan: RenderFramebuffer wasn't working at all if !EmulateFramebuffer
2022-10-30 12:10:24 +01:00
vkedwardli 0cbf6f6601 Fixing Steam Deck's wrong dpi caused by incorrect 60mm * 60mm EDID (#796) 2022-10-27 22:00:22 +02:00
bslenul c8fc873cf9 [Game List] Separate DC and arcade games 2022-10-26 15:37:17 +02:00
Flyinghead b935bef906 gl: missing init of width and height in GlFramebuffer
gl,vk,dx9,dx11: always use the TA context copy for TA_GLOB_TILE_CLIP and
SCALER_CTL
2022-10-25 17:50:41 +02:00
Flyinghead c1f0dd81d2 pvr: copy pvr regs at start_render time to avoid concurrent update
copy TA_GLOB_TILE_CLIP and SCALER_CTL to rend context when starting
render. Use rend context copy to calculate framebuffer size.
Fixes framebuffer size glitches in vf4 water stages.
lr: pass aspect ratio when resizing.

dx11: Wrong sizing of rotated games.

gl: test automation fixes.
2022-10-25 15:00:04 +02:00
Flyinghead 5722dc90f0 Full framebuffer emulation. Renderer interface changes
Helps for:
Densha de Go! 2, Issue #171
Vigilante 8, Issue #275
Xtreme Sports
Sonic Shuffle
The Ring of the Nibelungen
2022-10-23 16:32:42 +02:00
Flyinghead e3c260f4ca pvr: don't use op list to mark block if tile pointer is null
Naomi Doom sets the opaque list block to null in the tile, but op size
in TA_ALLOC_CTRL is non-zero. So use the TR list in this case.

Issue #682
2022-10-23 15:49:23 +02:00
Flyinghead d1e48c657e missing overrides 2022-10-23 15:44:12 +02:00
Flyinghead decf70c87c get rid of INLINE, NOINLINE, __forceinline 2022-10-22 22:14:19 +02:00
scribam 4de9076b49 macos: fix cmake post build command with ninja 2022-10-22 14:09:13 +02:00
Flyinghead 922df88cdd msvc build fix 2022-10-22 13:05:11 +02:00
Flyinghead f25aeee756 audio: don't crash if audio init fails. Fall back to auto
Don't crash if an audio backend fails to initialize.
Fall back to auto or run without sound.
Better audio backend framework
2022-10-22 12:08:05 +02:00
Edward Li 2b36953fdc Always fills the window with responsive size 2022-10-21 10:55:34 +02:00
Edward Li 1dcf302665 Add Aspect Fit & Aspect Fill description for Widescreen and Super Widescreen 2022-10-21 10:54:59 +02:00
Flyinghead 1fd95c2886 Roadsters (US) doesn't support RGB cable
Issue #791
Compile warnings
2022-10-21 10:54:26 +02:00
Edward Li 93e1d7fcee rend_resize_renderer_if_needed check for window size changes also 2022-10-20 09:51:04 +02:00
Flyinghead b2b860bb8e gl: vmu not showing and memory corruption
Fix vmu not displayed
Memory corruption when restarting gl driver (android)
2022-10-20 09:49:53 +02:00
Flyinghead 0bd88fc9d9 gui: div by zero crash if window is too small 2022-10-19 10:07:48 +02:00
Flyinghead 20f9450218 ignore start() if emulator already started
can happen on android
2022-10-19 10:06:53 +02:00
flyinghead 401c402afc Revert "cmake: use more system libs (#775)" (#785)
This reverts commit c5c941e928.
2022-10-19 10:04:21 +02:00
Flyinghead 77a105d888 set USE_DX9 in CMakeLists.txt instead of build.h 2022-10-18 10:12:27 +02:00
Flyinghead 257c6b729f rzip: allow multiple writes 2022-10-18 10:08:02 +02:00
Alexandre Bouvier c5c941e928 cmake: use more system libs (#775) 2022-10-18 10:04:15 +02:00
Edward Li 092006fbbe Mark Flycast as a game for Launchpad 2022-10-15 21:33:22 +02:00
Edward Li 6add19fb04 unprotect elan memory during dc_reset hard 2022-10-15 21:32:49 +02:00
Flyinghead 02d4b821d7 naomi: allow eeprom-based settings to be overridden (rotate, region) 2022-10-12 22:59:46 +02:00
scribam 3d00ac338b ci: use devkitpro/devkita64:latest (#672) 2022-10-09 19:08:54 +02:00
scribam 387b9778f3 cmake: remove "-static-openmp" for apple (#773)
Fix warning "clang: warning: argument unused during compilation: '-static-openmp' [-Wunused-command-line-argument]"
2022-10-08 19:18:50 +02:00
scribam 582876b99e libomp.rb: update and set min macosx version to 10.9 2022-10-08 18:34:00 +02:00
scribam 3b3391c0d1 deps: update sdl to version 2.24.1 2022-10-08 18:33:11 +02:00
Alexandre Bouvier df61b1046a cmake: normalize whitespaces 2022-10-08 18:32:36 +02:00
scribam 8426bcad27 vulkan: simplify function calls 2022-10-08 18:32:01 +02:00
GABO1423 d22fa54f7b (Libretro) Enable Per-Pixel Options on DX11 builds 2022-10-05 10:46:10 +02:00
Piotr Jagiełło 2d56dddf7a cmake: execute git commands in the source directory 2022-10-05 10:45:18 +02:00
Flyinghead 7da0549b8c operator [0] on empty vector crashes
Issue #763
2022-10-04 18:21:10 +02:00
Flyinghead b821ece052 alsa: default to 'auto' device if configured one can't be opened
Issue #762
2022-10-02 17:09:13 +02:00
Flyinghead b240da41e0 lr: use VK_API_VERSION_MAJOR/MINOR/PATCH 2022-09-26 11:19:15 +02:00
Flyinghead d85baba1d3 Merge remote-tracking branch 'origin/dev' 2022-09-26 11:07:33 +02:00
Edward Li 8a44b909a4 [Apple] Proper version handling for Info.plist 2022-09-26 11:06:31 +02:00
GABO1423 5362264b18 (UWP) Remove expandedResources 2022-09-26 11:05:54 +02:00
Flyinghead 1858cf3b33 Merge remote-tracking branch 'origin/master' into dev 2022-09-24 19:28:38 +02:00
Flyinghead 1f876cde39 lr: use default button name if naomi inputs name is empty 2022-09-23 16:40:18 +02:00
Flyinghead 7288c7b541 win32: build win app, not console 2022-09-23 16:38:49 +02:00
Edward Li 2b8f5a7b9d Print correct version info for Vulkan and MoltenVK 2022-09-21 14:43:28 +02:00
Edward Li c2e1425209 Stop Apple fanboys from asking where is Metal 2022-09-21 14:43:28 +02:00
scribam c9c1218234 vulkan: add deps as submodules and sync with Vulkan 1.3.224.1 2022-09-18 16:56:56 +02:00
scribam 11d776aea1 vulkan: remove external files 2022-09-18 16:56:56 +02:00
scribam 1386744fe0 .cirrus.yml: update freebsd image to version 13.1 2022-09-17 12:49:42 +02:00
Edward Li da0d012328 Handle Dock menu's Quit action 2022-09-16 16:03:25 +02:00
Flyinghead f88abf9987 extra depth scaling for south park rally
fixes car depth on character selection screen
2022-09-14 17:52:35 +02:00
Flyinghead 4a4fa7792f vk oit: limit drawer swap chain to 2, same as non-oit
Fixes flashing during partial redraws (south park rally)
2022-09-14 17:48:57 +02:00
Flyinghead 73adbc660b win32: build win app, not console 2022-09-14 17:46:14 +02:00
Flyinghead aa97a6d64f pvr: last naomi2 poly was ignored in some cases
Fix the disappearing moustache in wild riders
Fix other potential edge cases in pvr parsing
2022-08-25 19:34:23 +02:00
Flyinghead e0d87eb093 Merge remote-tracking branch 'origin/master' into dev
# Conflicts:
#	core/rend/gui.cpp
2022-08-22 13:09:56 +02:00
Flyinghead 85b8c599c4 pvr: object list is sometimes shared between op and tr modvols
Region tile object list pointers can be identical for op and tr modvols,
in which case tr modvols should be drawn using op modvols geometry.
Used by crazy taxi 1/2, alien front online, daytona usa and probably
many others.
Issue #717
2022-08-22 12:38:04 +02:00
scribam 72136c2bfc deps: update sdl to version 2.24.0 2022-08-22 12:29:34 +02:00
Flyinghead 71e9420929 macOS: std::exception handler not catching FlycastException
Catch std::runtime_error instead
vk: Clear boxart texture cache before shutting down imgui driver
2022-08-14 18:39:09 +02:00
scribam 7457db8bba android: update android gradle plugin to version 7.2.2 2022-08-06 17:30:10 +02:00
GABO1423 69125b490e (UWP) Build Tweaks (#709)
* (UWP) Disable Vulkan Build Flag

* (CI) Remove UWP Build Flag
2022-08-04 17:37:06 +02:00
vkedwardli 3c94cd3194 Fix macOS accent menu (#708)
* `SDL_StartTextInput` only when textfield is focused

* [macOS] "Reveal in Finder" button for Home Directory

* only enable for `USE_SDL`
2022-08-04 17:35:40 +02:00
Flyinghead a6ac753c64 boxart: ignore disks with invalid ip_meta. sanitize disk id chars 2022-07-29 10:48:39 +02:00
Flyinghead 55600c40a9 sdl: use exp scale for rumble power
Better sensitivity for low power values.
Issue #707
2022-07-28 10:47:42 +02:00
Flyinghead 9070c246d4 move iso9660.h 2022-07-28 10:43:44 +02:00
bslenul 75ff5409f4 Switch broadcast region for San Francisco Rush 2049 and Sega Smash Pack - Volume 1 2022-07-25 11:26:12 +02:00
Flyinghead 642fad9a6e cfg: per-game settings must be deleted when changed back to standard
When a per-game setting is the same as the standard one, it is ignored
and not saved to emu.cfg. However the previously saved per-game setting
wasn't deleted, making it impossible to revert.

Issue #653
2022-07-25 11:25:42 +02:00
GABO1423 5ae7ac3eca (UWP) Add Additional Rescap Capabilities 2022-07-22 18:13:11 +02:00
Edward Li 885862a45e Get writable log path for macOS also 2022-07-22 18:12:43 +02:00
Edward Li 9b751fced8 NSLog with UTF-8, better color handling 2022-07-22 18:12:43 +02:00
Flyinghead 19ccc6a38d uwp build fix 2022-07-21 14:51:20 +02:00
Flyinghead ad8b41adb0 boxart: extract 0GDTEX.PVR. Offline scraping
extract iso9660 file system utility out of reios
.pvr limited parser
2022-07-21 10:43:45 +02:00
Flyinghead 807b8dea91 lr: Framebuffer size and aspect ratio. Fix vmu size and position (GL)
gl4: fix lightgun xhair size and position
2022-07-19 20:26:37 +02:00
Flyinghead 8e8935b9c4 pvr: xform matrix 240p support. screen stretching changes
Use FB_R_CTRL.vclk_div to detect progressive mode.
transform_matrix: Support non-4:3 aspect ratio such as 640x240. Don't
expect 480 height. Issue #690
Add black bars at top and bottom if screen aspect ratio is too low.
Issue #584.
Framebuffer size doesn't depend on screen stretching. Stretching is done
when blitting to screen.
lr: correct subsequent stretching when drawing vmus and xhair
2022-07-18 18:21:09 +02:00
Flyinghead 76bf574668 gl,gl4: disable anisotropic filtering if not linear
Issue #695
2022-07-15 20:36:29 +02:00
Flyinghead 9d17fc15a3 gdrom, hle: don't restart cdda if paused or playing
Fix regression due to ab791d1b9c
(unpausing restarts the current track)
Issue #690
2022-07-14 16:49:56 +02:00
Flyinghead 1cadd4e923 gdrom: set sub-q channel flag on audio tracks in TOC (ADDR)
Fixes V-Rally 2 CDDA tracks not playing. Issue #534
2022-07-14 16:43:41 +02:00
Flyinghead ab791d1b9c gdrom: ignore CD_PLAY when already playing, not when paused
Issue #690
2022-07-13 12:52:29 +02:00
Flyinghead 4f206d2773 pvr: set correct framebuffer size in 240p/pixel_double
Some games use 240p and pixel_double resulting in a 320x240 framebuffer.
Renderer should be resized accordingly.
Fixes linear filtering artifact in KoF dream match 1999 (Issue #690)
2022-07-12 15:55:49 +02:00
Flyinghead 7f9d9b81aa gdrom: don't reset current cdda sector on cd_play if already playing
Issue #690
2022-07-12 15:33:11 +02:00
Edward Li c77c3ab015 DRY 2022-07-09 11:46:27 +02:00
Edward Li 8acd81cc43 Add MacPorts as alternative link 2022-07-09 11:46:27 +02:00
Enrique Santos c0e52b9a1a load game: destroy old maple devices before create call 2022-07-08 20:38:16 +02:00
Flyinghead 0840da1bd5 sdl: fix inverted axis detection 2022-07-08 20:36:20 +02:00
vkedwardli 852df89f93 [macOS] Handle Quit menu item properly (#684)
* [macOS] Handle Quit menu item properly

* cleanup
2022-07-05 14:37:28 +02:00
vkedwardli b5eb8694f6 macOS Breakpad (#683)
* Breakpad.framework and dump_syms

* Use ExceptionHandler manually instead of using public methods from the framework

* Change macOS buildType to RelWithDebInfo and enable building Breakpad framework

* Enable symbol upload on GitHub runner

* Compile Breakpad directly instead of embedding the Breakpad.framework

* Print minidump location also

* Ignore `EXC_MASK_BAD_ACCESS` again
2022-07-05 14:36:21 +02:00
Flyinghead f4986008fe jvs: fix 86-request decoding
Fixes kingrt66 inputs when networked
Issue #673
2022-07-05 14:34:57 +02:00
Flyinghead d6644c4935 lr: terminate emu during deinit on android
Issue #566 is for linux only, not android
2022-07-03 18:38:59 +02:00
Flyinghead 19112aecb2 Merge remote-tracking branch 'origin/master' into dev
# Conflicts:
#	core/hw/naomi/naomi_cart.cpp
2022-07-01 12:42:37 +02:00
Flyinghead 5bb8c86903 uwp: force windows sdk version to one compatible with current xbox fw
Fixes error at install: The package requires OS version 10.0.22621.0 or
higher on the Windows.Universal device family. The device is currently
running OS version 10.0.22000.4970.
2022-07-01 12:16:30 +02:00
vkedwardli a659b57e63 Install Vulkan SDK in generate_xcode_project.command (#678) 2022-06-30 14:11:26 +02:00
vkedwardli 44e96c544b Use source_group to create folder hierarchy for Xcode project (#679) 2022-06-30 14:10:15 +02:00
scribam 0a5b8891a8 android: update gradle 2022-06-30 14:09:20 +02:00
Flyinghead 6a5db32d5d don't protect RTT textures vram
Fixes Spikers Battle RTT texture spurious update before use
(transitions)
2022-06-27 13:37:22 +02:00
Flyinghead b0f3e065be ui: wrong scaling after imgui driver reset
ImGuiStyle::ScaleAllSizes() is cumulative so reset style before calling
it
Issue #676
2022-06-27 13:32:30 +02:00
Flyinghead b5b0875203 android keyboard support 2022-06-26 22:04:36 +02:00
Flyinghead 9a557978c4 gamesdb: fix exception when boxart is missing 2022-06-26 21:55:00 +02:00
Flyinghead fe895211c1 ui: reset imgui driver before creating new one
Possible fix for Issue #676
2022-06-26 15:23:30 +02:00
Flyinghead 907131b7f5 allow ForceWindowsCE option to be used in per-game config
Issue #252
2022-06-24 13:27:21 +02:00
Flyinghead 76508146ae cheats: only apply widescreen cheat if current value is expected
Issue  #180
2022-06-24 11:47:24 +02:00
Flyinghead 7f28b767e4 gl: boxart clamp to edge if border not supported 2022-06-24 10:57:48 +02:00
Flyinghead 5f5a748031 boxart: batch uid searches. Bios image. More arcade rom name changes 2022-06-23 22:06:50 +02:00
vkedwardli 867b519a2b [macOS] Fix imagemagick not found on GitHub runners (#674)
disable dep check for brew reinstall
2022-06-21 09:50:05 +02:00
Flyinghead 74852520dc maxspeed: allow use of per-game network settings
Issue #671
2022-06-20 20:56:53 +02:00
Flyinghead faec4d8e50 gl: always use int arithmetic in palette index glsl calculation 2022-06-20 20:52:15 +02:00
Flyinghead d2aca1d621 savestate: overflow crash when serializing 2022-06-20 20:49:09 +02:00
Flyinghead 7bcd8c819a arcade rom names update. non square boxart
Correct handling of non square images
Improve search for arcade game names
Retrieve other images if no boxart (titlescreen, screenshot)
Changed some arcade rom names to more friendly ones
2022-06-20 18:07:06 +02:00
Flyinghead 7209a61583 boxart: race conditions. revert dash in disk id hack
Filter BIOS by name like regular games.
2022-06-18 17:49:37 +02:00
Flyinghead 1523fafce0 vk: fix crash when resizing window in boxart mode 2022-06-17 16:17:58 +02:00
Flyinghead 3915c55251 boxart: skip invalid disks. fix disk id dash issue. save found status 2022-06-17 16:13:58 +02:00
Flyinghead 5259aa20e6 boxart: delete trailing [.*] in game names. Remove extension first 2022-06-16 17:03:14 +02:00
Flyinghead 11ecb473b6 new option to broadcast digital outputs over the network
Similar to MAME's "-output network" option. Should be compatible with
MAME Hooker and the like.

Limit boxart images loaded per frame to 10.
2022-06-16 16:50:26 +02:00
Flyinghead 7982fdac1c switch needs curl 2022-06-15 23:13:01 +02:00
Flyinghead 54d92a11e8 build fixes 2022-06-15 22:38:05 +02:00
Flyinghead 5eb302898f box art fetch and display
Issue #22
2022-06-15 21:22:12 +02:00
Flyinghead 5b3a414987 Merge remote-tracking branch 'origin/master' into dev 2022-06-15 19:25:41 +02:00
Flyinghead 05961ac883 android build fix 2022-06-11 13:41:44 +02:00
flyinghead afd07c25ba pvr: store tex address in render context. texture cache refactoring
Store FT_W_SOF1 and FT_W_CTRL in render context since they can be
modified before render end. New tentative fix for vf4 water reflection
flashing black during netplay.
Refactor texture cache to use constructors. RTT code moved from
renderers.
Partial revert of ddcd3861d3
2022-06-11 13:24:22 +02:00
flyinghead 7ab92d88b1 msvc x86 build fix 2022-06-10 17:57:53 +02:00
flyinghead 3780299803 win32 raw api: user-friendly names for devices
Issue #664
2022-06-10 17:20:29 +02:00
flyinghead d78bb9ed3f don't list hidden folders and files on windows. Better parent dir prompt
Issue #666
2022-06-10 15:29:28 +02:00
Flyinghead b5f1552ed8 elan: don't crash on invalid texture xfer size
Issue #647: fixes initdv3jb area conquered crash
2022-06-06 15:54:25 +02:00
Gabriel Morazán 917cc7f27c Readme Updates. (#659)
* Update Reicast Link
2022-06-05 17:32:59 +02:00
Gabriel Morazán 2327e73ee7 (README) Update Xbox Section 2022-06-02 18:11:49 +02:00
Gabriel Morazán 397ddef68c (Libretro) Actually allow DX11 only cores.
Simple build fix.
2022-06-02 18:11:49 +02:00
Gabriel Morazán 3ec7f293ee (Libretro) Allow a DX11 only core to be built. (#657)
Main use case is Xbox systems.
2022-06-01 22:27:51 +02:00
flyinghead 26c8e8dab8 dx11 oit: naomi2 regression. Tr modvols shader needs divPosZ too 2022-06-01 19:26:56 +02:00
Flyinghead fdcea88519 gl4: wrong depth for transparent polys with native depth interp
Issue #630
2022-06-01 19:26:56 +02:00
flyinghead bf6c73060b native depth interpolation option to help AMD gpus
When enabled, set 1/z in pos.w and use native interpolation for colors,
UV and depth.
Get rid of manual modvol clipping in dx11.
2022-06-01 19:26:56 +02:00
Flyinghead ddcd3861d3 ggpo: don't protect rtt texture vram if ggpo is enabled
tentative fix for flashing water reflection texture in vf4 during
netplay
2022-05-31 17:42:42 +02:00
Flyinghead 971d47eb42 sdl: SDL_QuitSubSystem() on exit
Tentative fix for issue #654
2022-05-31 17:42:42 +02:00
Enrique Santos 13bd42bdab chat: disable window timeout after you respond to message 2022-05-30 16:15:44 +02:00
Flyinghead 71ac212dc7 elan: disable texture for vertices without UV coordinates
Fixes initial D white transparent quad at start of race
2022-05-30 16:15:15 +02:00
Flyinghead 2319a00c4f vk: bump moltenvk to 1.3.211.0 2022-05-29 13:35:22 +02:00
Flyinghead 1268077f6b cheat: missing cheat value in constructor
Fixes vf4tuned dimm check cheat writing random value (SH4 exception,
boot loop)
2022-05-29 13:30:06 +02:00
vkedwardli 5c579de459 Enable Texture Upscaling on macOS (#645)
* Compile a universal libomp
* static linking OpenMP
2022-05-28 13:00:20 +02:00
Flyinghead 167faff1f3 vk: invalid lightgun crosshair if maple device A isn't a lightgun 2022-05-28 12:58:53 +02:00
Flyinghead 22ad95cbfe ios: diagonal DPad buttons. Pan between buttons. Help tip for menu
Add diagonal DPad buttons
Allow switching virtual button without lifting finger.
Display help tip on first startup about pausing/opening menu.
2022-05-27 18:32:55 +02:00
Flyinghead db8508cefc ios: update AltKit 2022-05-27 18:20:16 +02:00
Flyinghead 5ac0772a2a vk oit: out of pool memory with moltenvk during render to texture 2022-05-26 18:06:30 +02:00
Flyinghead e2c2d6606d Fix Dead or Alive 2: Limited Edition (JP) widescreen cheat
Issue #625
2022-05-26 17:54:45 +02:00
Flyinghead 48361f58b6 vk oit: wrong temporary framebuffer dimensions 2022-05-25 16:44:24 +02:00
Enrique Santos dcb439f74a add ggpo chat window timeout 2022-05-23 11:42:11 +02:00
flyinghead 739a27be63 dx11 oit: render target and depth/stencil must have same dimensions
Fixes glitches during doa2 attract mode (depth/stencil missing).
2022-05-23 11:41:37 +02:00
Flyinghead e84cdce398 reios: flashrom read returns 0 on success. system id/timezone flash fix
flashrom read returns 0 on success, not size read.
Fixes Slave Zero (PAL) crash
2022-05-21 15:46:22 +02:00
Flyinghead af2fe242f9 flash: console id is checksummed 2022-05-18 14:58:21 +02:00
Flyinghead 0fb177bf85 reios: fix regression on many games due to 77a2bbbb
Jeremy McGrath
Skies of Arcadia
Speed Devils Online
Sydney 2000
Tech Romancer
Time Stalkers
Virtua Athlete 2000
Quake 3 (EU)
Climax Landers (JP)
Frame Gride
Pop'n'Music 1 & 2
Simple2000 2 & 3
2022-05-18 14:56:14 +02:00
Edward Li baab70c509 Rumble using MacBook's Taptic Engine (take 2) 2022-05-17 16:37:37 +02:00
scribam bc1c70bd1a ci: remove brew install libomp 2022-05-17 16:36:57 +02:00
scribam 12929c4571 openmp: use _OPENMP preprocessor, search openmp pkg unconditionally if enabled 2022-05-17 16:36:57 +02:00
Flyinghead 62522e4eb3 vk: naomi2 crash when lightModel is null
fixes crash at end of tutorial in kingrt66
2022-05-17 16:36:34 +02:00
Flyinghead 221060cc70 widescreen cheat for Dynamite Deka2 (JP), Zombie Revenge (naomi)
Better Dynamite Deka ex (naomi) widescreen cheat.
Courtesy of Goddamn Superhero
2022-05-16 13:06:38 +02:00
Flyinghead 58d1f7cee1 pvr: reset nextContext in Reset(). Use tactx_Alloc for direct fb render
Fix crash with multipass renders
Issue #634
2022-05-16 13:04:38 +02:00
Flyinghead 430256266f pvr: lightModels TA overrun on beach spikers
Better sizing of TA_context lists
2022-05-15 13:41:03 +02:00
Flyinghead f9e38b11d9 pvr: restore TA_context pool
fixes performance regression on android
2022-05-15 13:37:58 +02:00
Flyinghead 78e075546a libretro android build fix 2022-05-15 13:35:23 +02:00
flyinghead 658e111e3c dx11 oit: naomi2 regression. Tr modvols shader needs divPosZ too 2022-05-14 12:01:50 +02:00
jdgleaver 0e23b0bedd (libretro) Add option to detect and notifiy frontend of internal frame rate changes (60 <-> 30 <-> 20 fps, etc.)
Improves frame pacing in games with locked 30 fps and 20 fps frame rates
2022-05-13 17:13:25 +02:00
Flyinghead 903c768f7f vk oit: First frame after init wasn't displayed 2022-05-13 17:12:31 +02:00
Flyinghead d08f0e6599 gl4: wrong depth for transparent polys with native depth interp
Issue #630
2022-05-13 13:03:02 +02:00
Flyinghead cd22ba1a2b android: use WifiManager.MulticastLock to receive broadcast packets
In many cases, broadcast UDP packets can't be received on android unless
a MulticastLock is held.
2022-05-12 17:39:49 +02:00
flyinghead 77a11d2a2e native depth interpolation option to help AMD gpus
When enabled, set 1/z in pos.w and use native interpolation for colors,
UV and depth.
Get rid of manual modvol clipping in dx11.
2022-05-12 13:43:43 +02:00
flyinghead cce8cb8528 dx11 oit: missing TextureFiltering support
Issue #628
2022-05-11 19:16:31 +02:00
jdgleaver 6c6b447ea1 (libretro) Limit maximum number of audio samples that can be uploaded per call of retro_run() 2022-05-05 18:02:40 +02:00
Flyinghead 4554450d1d oit: add max layers and pixel buffer size options 2022-05-05 18:01:05 +02:00
Flyinghead a0d1dbf833 dx11: don't create the device in debug mode 2022-05-04 19:38:43 +02:00
Flyinghead a1a89df17f change vf4ft dimm check cheat. Don't apply cheat if not needed.
Fixes the SH4 exception seen with the previous cheat on some platforms.
Don't write memory if value is unchanged to avoid unnecessary protection
faults.
2022-05-04 10:30:35 +02:00
Flyinghead cf36384481 use nearest/point sampling to draw framebuffer if nearest is forced 2022-05-03 17:55:02 +02:00
flyinghead 9103371362 vk: increase descSet pool size for storage buffers and input attachments
Fixes out of host memory error on macOS
Issue #619
2022-05-03 17:49:46 +02:00
flyinghead 1b5ad34c8e dx11: (oit) use temporary render target for multipass
Render to temporary render target at end of pass and swap with regular
RT.
Fixes Tony Hawk 2 missing transparent geometry and character shadow.
Issue #618
2022-05-03 17:47:43 +02:00
Flyinghead c57e88850c lr: avoid crash when rewind is on
Issue #471
2022-05-01 19:22:22 +02:00
scribam 101a831534 cmake/macos: remove multitouch library 2022-05-01 12:34:43 +02:00
Flyinghead 3cc991fa4f oit: poly number/vertex id overflow
Use 17 bits for vertex id but substract first vtx index
Use 13 bits for poly number instead of 12
Panzer Front uses more than 4095 tr polys.
Issue #616
2022-05-01 12:33:53 +02:00
Flyinghead c348f4ccad allow a core without open gl to be built
Issue #515
2022-04-30 18:05:12 +02:00
Flyinghead 0181685d2f cheats: use software name as additional condition for widescreen
don't enable widescreen cheat for code veronica X
Issue #229
2022-04-30 12:08:36 +02:00
Flyinghead 39bb94dd55 jvs: don't scale ninja assault lightgun coordinates
Fixes reload issues (Issue #610)
2022-04-30 11:50:56 +02:00
Flyinghead 77a2bbbb8d reios: cancel gd dma int in g1_end_dma. drv_stat returns busy when busy
Cancel G1 DMA interrupt in G1_DMA_END (fixes MSR, Psychic Force, Pro
Pinball, Sega Swirl)
GET_DRV_STAT must return busy when drive is busy (fixes Hell Gate, Zero
Gunner)
Better named constants
2022-04-29 15:18:41 +02:00
Flyinghead afb0a80de1 pvr: autosort needs empty passes to be accounted for
Issue #612
2022-04-29 11:37:17 +02:00
Flyinghead 49932e02a6 gdrom: generate raw subcode 2022-04-27 14:32:53 +02:00
Flyinghead 990a4ad583 vk: ignore pipeline cache if loading fails 2022-04-27 14:30:03 +02:00
Flyinghead fc9e1e401b naomi: emulate midi ffb drive board response
needed for driving simulator
2022-04-27 14:28:58 +02:00
scribam 15ca7e82bd ci: fix java-version for actions/setup-java 2022-04-26 10:14:58 +02:00
Flyinghead 3b81bbcae5 naomi2: gmp diffuse/specular flags select vertex or model colors only
These flags shouldn't be used to disable diffuse/specular shading
Fixes road surface glitches in initdv3e (Usui map)
2022-04-21 13:55:09 +02:00
Flyinghead 902fc2cbe8 naomi: override Region settings if current region BIOS isn't found 2022-04-20 14:16:15 +02:00
Flyinghead 50f5dabf4a naomi2: use diffuse/specular color before light routing
fixes lion's jacket color and shun's face glitch (vf4)
2022-04-20 14:13:42 +02:00
scribam aa6c9e2106 msvc: fix linking issues in debug build 2022-04-17 13:24:37 +02:00
scribam 919fdb3594 ci: add distribution input to actions/setup-java@v3 2022-04-17 13:24:11 +02:00
Flyinghead c625cc68bf lr: increase vk descSet pool size. Insert card binding
vk: Use same descriptor set pool sizes for standalone and core
lr: bind "Insert Card" to L button (Naomi button 6)
lr: reset input descriptors when loading a new game
lr: don't reset maple devices in arcade mode: reloading eeprom cancels game settings
2022-04-17 13:23:16 +02:00
flyinghead d732140bf9 Merge pull request #595 from flyinghead/dev
Naomi 2 support
2022-04-16 14:24:49 +02:00
Flyinghead db525bd5db android: fix touchscreen on Retroid Pocket 2+
Unexpected event source for touchscreen events
2022-04-15 18:06:15 +02:00
Flyinghead 039c666247 more types.h clean up. better aica handler templates 2022-04-15 17:03:49 +02:00
Flyinghead ed5c24c281 arm64 build fix 2022-04-15 11:17:22 +02:00
Flyinghead f2f4010203 clean up types.h, refactoring 2022-04-14 11:34:45 +02:00
Flyinghead a9e261d280 simplify TA parsing 2022-04-13 20:36:52 +02:00
Flyinghead a710674cd4 gui: init once. reset ui driver when needed. android 120+ Hz support
ImGui is now initialized once at startup and shutdown before
terminating. graphics initialization is independent.
Move more imgui stuff into imgui drivers.
switch: set scaling on external screen to 1.4, same as xbox
UI scaling refactoring.
2022-04-13 18:06:19 +02:00
Flyinghead ddfc00ed9f Merge remote-tracking branch 'origin/master' into dev 2022-04-13 16:29:41 +02:00
Flyinghead ac71970561 don't save built-in cheats (vf4 dimm check) 2022-04-13 13:10:56 +02:00
Flyinghead fd50529d86 gl: (lr) black screen when vmu display is on
need to call glBindVertexArray(0) to avoid VAO being modified by the
frontend
2022-04-12 18:23:09 +02:00
Flyinghead 52d95e537c lr ci: disable switch build 2022-04-11 15:56:43 +02:00
Flyinghead 15b21fff2b vk: don't use anisotropic with nearest. Use linear mipmap filter
Issue #580
2022-04-11 13:35:48 +02:00
scribam f46bccfecd cmake: reunified dx9 files 2022-04-10 11:28:09 +02:00
Flyinghead 1f55973f72 libretro ci: add switch build 2022-04-10 11:27:37 +02:00
scribam 3d5fd61285 macos: fix size for image icons 2022-04-09 12:06:17 +02:00
scribam 069b501ca3 android: update android gradle plugin to version 7.1.3 2022-04-09 12:05:22 +02:00
flyinghead d035af7ff0 xbox: low resolution (640x480) with recent firmware
Device ids for xbox series s/x returned from
GetGamingDeviceModelInformation() have changed
2022-04-09 12:04:51 +02:00
scribam 20302cd378 cmake: add XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER 2022-04-07 23:09:08 +02:00
scribam 959685e260 ci: use xcode for macos 2022-04-06 14:54:28 +02:00
Flyinghead e0058c17ff lr: don't terminate emu on deinit. gl4: buffer wasn't released on term()
shared libraries containing gnuc unique symbols are never unloaded on
linux, and possibly other platforms. So don't terminate the emulator on
deinit and init it only once.
Issue #566

gl4: buffer not released on term() was causing crashes or black screen when restarted.
2022-04-05 14:53:47 +02:00
Flyinghead bf61f5cfe8 Merge remote-tracking branch 'origin/master' into dev 2022-04-04 12:11:10 +02:00
Flyinghead 8dcc25e1a9 ta: default base/offset color is white, not black
fixes black players in NHL 2K
2022-04-04 11:47:11 +02:00
Flyinghead a428167dc6 naomi network: alienfnt startup crash if not connected 2022-04-04 11:43:54 +02:00
Flyinghead e46d819c46 aws needs bash shell 2022-04-04 11:41:28 +02:00
Flyinghead 48e3a3eb68 aica: double arm clock speed
actual aica arm clock seems to be 22.5792 MHz, which means 512 cycles
per sample at 44.1 KHz (from 256)
fixes vf4 audio hiccup in character selection screen
2022-04-03 20:53:44 +02:00
Flyinghead a635fb3f77 test automation build fix, better exit 2022-04-03 20:46:50 +02:00
scribam 274f2fe10d ci: add ninja, update actions and ccache support 2022-04-03 15:38:49 +02:00
Flyinghead 320f679038 win32 build fix 2022-04-02 16:59:57 +02:00
Flyinghead 94c20ba29f elan: reset TA parser before loading state 2022-04-02 16:43:15 +02:00
Flyinghead 8baebcfb5b maxspeed networking. Store aw force feedback value 2022-04-02 16:41:52 +02:00
flyinghead 2c96d49cf2 dx9, dx11: support for forced point/linear tex sampling and anisotropy 2022-04-02 11:18:48 +02:00
Hugo Locurcio a9cabdc342 Add texture filter override setting, expose anisotropic filtering
The new texture filter option can be set to:

- Default (keeps the game's intended filter mode).
- Force Nearest-Neighbor (crisper appearance).
- Force Linear (smoother appearance).

Additionally, mipmapping can now be enabled on nearest neighbor-filtered
textures (which is used if nearest-neighbor filtering is enabled, including
with anisotropic filtering).

Anisotropic filtering was already implemented in both OpenGL and Vulkan,
but it was not exposed in the GUI.
2022-04-01 16:00:41 +02:00
Hugo Locurcio 90a95b4688 Add 6×, 7×, 8× and 9× options for internal resolution
This can be used to get a smoother image (supersampling) on
1440p and 4K displays. The 9× setting is also suited for native
resolution rendering on 8K displays.
2022-04-01 16:00:28 +02:00
flyinghead 7fcce4a59b naomi network: ignore WSAECONNRESET. Longer timeout for client 2022-03-30 15:48:23 +02:00
Flyinghead 554ffcd08f naomi: use platform-independent network error codes (win32) 2022-03-30 14:13:02 +02:00
scribam 0c46ea13c7 ci: use windows-latest 2022-03-27 18:14:38 +02:00
Flyinghead af0574c04e build fixes for msvc, ios and android 2022-03-27 15:57:01 +02:00
Flyinghead 6c38295d62 new naomi network protocol. vblank event. initd rumble support
new vblank event, used by cheats, lua and naomi net
new udp net protocol for naomi. rx/tx on vblank on emu thread.
input: rumble power configurable (Issue #158)
ui: rumble intensity slider, enable/disable upnp
aica: hook to consume midi out
decode midi out to simulate rumble for initd
upnp can now be disabled
2022-03-27 15:23:21 +02:00
Flyinghead 1e01dbb151 wrong line padding value when copying RTT to vram due to previous commit 2022-03-26 20:51:07 +01:00
Flyinghead be270259ee crash with RTT and copy to VRAM if width > linestride
RTT texture width must not exceed FB_W_LINESTRIDE
fixes Flag to flag crash
2022-03-25 15:41:16 +01:00
Nikos Chantziaras 03f9955f8b libretro: present frames before audio upload
retro_audio_sample_batch_t can block for a long time if the frontend
performs audio sync. This unnecessarily delays frame presentation.
2022-03-23 21:30:03 +01:00
Flyinghead 55e613fae5 widescreen cheats for gun spike, initdv3e, alpilotj, monkey ball
Courtesy of Esppiral
2022-03-21 17:51:31 +01:00
Flyinghead a5bad2b9b7 more naomi widescreen cheats. Fix vathlete 4-player mode
widescreen cheats for asndynmt, doa2m, slashout, spikers battle,
18wheeler, beach spikers. Courtesy of Esppiral
vathlete needs 2 I/O boards for 4-player mode
2022-03-20 17:49:50 +01:00
Flyinghead ebb251d8cf widescreen cheat for vf4tuned
Courtesy of Esppiral
2022-03-19 11:30:45 +01:00
Flyinghead 56768f2d3d naomi2: use TA parser. Use N2light directly with vk, dx11
Use TA parser to handle list type and clipping for Naomi 2 polys.
Pass all pass-throuch TA data to TA parser but stop on naomi2 command.
Set default projection matrix instead of identity (fixes Area conquered
screen invisible in initd).
Change N2Light and N2LightModel so they are usable in GLSL (vulkan) and
HLSL (dx11).
TA parser throws exception for unhandled param.
ta_vtx.cpp refactoring.
Support for subtractive lights (diffuse+specular). Used in some clubk
circuits.
Fix vulkan crash when direct FB render.
2022-03-16 17:28:45 +01:00
Flyinghead 5b3d36e081 naomi2: network support for clubk and initd
clubk: don't reverse handle by default
hotd2 doesn't have a proper game id or standard eeprom
2022-03-15 19:44:24 +01:00
Flyinghead ad08590197 vulkan: cache per-poly desc sets in map
avoid desc set pool exhaustion in per-triangle
2022-03-13 11:39:30 +01:00
Flyinghead 53b5588bda Merge remote-tracking branch 'origin/master' into dev 2022-03-13 11:01:27 +01:00
Flyinghead 1015a8c098 naomi2: vulkan support
oit: use #define instead of functions in GLSL
2022-03-12 17:56:46 +01:00
Flyinghead 27ddc215cc naomi2: boost lights by constant factor. simplify shaders 2022-03-08 17:38:29 +01:00
Flyinghead c11a6cd432 naomi2: partial gles2 compatibility
Issue #553
2022-03-07 20:32:08 +01:00
Flyinghead 514eedbc63 maple: do not raise maple_dma interrupt for light gun
Issue #474 (Virtua Cop 2 momentarily freezes when shot fired)
2022-03-07 19:16:49 +01:00
Flyinghead 1f61f80c92 input: fix naomi rotary encoders
Games with multiple JVS input boards poll inputs more than once,
ignoring some relative mouse movements.

Issue #557
2022-03-06 17:57:16 +01:00
scribam 830ffd0559 deps/picotcp: pico_ipv6_source_dev_find requires PICO_SUPPORT_IPV6
Backport https://github.com/virtualsquare/picotcp/commit/529074aab4f53a87426673548d6793ced666b6ed
2022-02-28 07:24:50 +01:00
scribam ed066df469 deps: update miniupnpc 2022-02-28 07:24:36 +01:00
scribam e6676c7d09 android: update gradle 2022-02-27 08:33:44 +01:00
scribam 33115a39a3 android: use latest cmake from android studio 2022-02-27 08:33:44 +01:00
Flyinghead 6538360fe1 switch: use devkita64:20220128 instead of latest
fixes peformance issue
2022-02-26 08:14:10 +01:00
Flyinghead 3a62e432da switch: revert a92c2899c8
back to .obj instead of .o
2022-02-25 18:35:58 +01:00
Flyinghead 9c3f60c26c CI: windows-2019 for windows. devkita64:20220128 for switch 2022-02-25 18:30:28 +01:00
Flyinghead ed0e5b8c5a remaining references to windows-latest -> windows-2019 2022-02-25 17:47:47 +01:00
Flyinghead c75d94bd90 use windows-2019 for windows builds 2022-02-25 17:36:13 +01:00
Depal1 a8d6374d76 Add installation on MacOS via Homebrew 2022-02-25 17:18:35 +01:00
cmitu 4b10402c5b Disable stencil usage on low end VC4 devices (Pi3)
Make the libretro core boot again when using the legacy VC4 GLES drivers.
Based on https://github.com/libretro/flycast/commit/ee9cd16f

Fixes: https://github.com/flyinghead/flycast/issues/539
2022-02-24 07:17:48 +01:00
Flyinghead e5863920c4 naomi2: fix beach spiker crash
VUR vertices can also have environment mapping
2022-02-22 08:48:51 +01:00
Flyinghead 7f61b44d42 imgui: better drag scrolling code 2022-02-21 19:48:52 +01:00
Flyinghead a5660fa2b4 missing changes from previous commit 2022-02-18 17:40:00 +01:00
Flyinghead ecc03e3ebc naomi: use boot rom id to configure eeprom
Make eeprom from scratch if it doesn't exist based on boot id info.
Override eeprom settings to make game happy
Change region to supported one
Get rid of per-rom region info in rom list
New option to configure Naomi games in free play
2022-02-18 17:35:20 +01:00
Flyinghead a92c2899c8 switch build: cmake is now producing .o instead of .obj 2022-02-18 16:42:05 +01:00
Flyinghead af4638e83f naomi2: fix another initdv2 end of race crash 2022-02-18 16:40:26 +01:00
Flyinghead cecf1a5497 naomi2: fix initdv2 end of race crash 2022-02-17 18:31:20 +01:00
Flyinghead f2374982b8 pvr: don't merge polys with != palette. 2nd pass sometimes ignored
polys with different palette index shouldn't be merged.
If a pass isn't using any opaque, it can't be found. Fall back to using
the transparent or punch-through list in this case.
2022-02-17 18:30:29 +01:00
Flyinghead d736dd027d naomi2: initd card support. lua: fix multi-threading crash
initial d card reader support. insert card button.
lua: use mutex to enforce thread-safety
2022-02-16 19:02:04 +01:00
Flyinghead 214db9e0b1 gl4: depth pass need texture and UV for punch-through polys 2022-02-15 17:18:32 +01:00
Flyinghead 3bbc89afc9 dx11: fix crash with modvols 2022-02-15 17:16:45 +01:00
Flyinghead e35ccbbb18 naomi2: force region for some roms. elan clean up 2022-02-15 17:15:44 +01:00
Flyinghead 20571c5aa1 chd: MIL-CD support
Issue #529
2022-02-15 11:34:11 +01:00
Flyinghead 3872a6b475 libretro: support VMU and lightgun crosshair with dx11 OIT renderer
OIT support was missing
Issue #525
2022-02-15 11:06:51 +01:00
Flyinghead 083a1c85a8 gl: shader compile error on shield tablet
Don't use GL_NV_shader_noperspective_interpolation since it's not really
needed (and wasn't enabled)

Issue #510
2022-02-14 18:54:27 +01:00
Flyinghead 943e0285ac libretro: support VMU and lightgun crosshair with dx11 renderer
Issue #525
2022-02-14 18:47:23 +01:00
Flyinghead d7abfc688c dx11: oit depth pass needs the palette for PT polygons
Punch-through polys may use a palette, which is needed for alpha testing
Issue #467
2022-02-14 18:41:38 +01:00
Flyinghead 8f01ef90cf gl,dx9,dx11: only render frame when Renderer::present() has been called
Issue #511
2022-02-14 18:38:58 +01:00
flyinghead 8d071bf4ea naomi2: dx11 support. fix ambient color. no depth write in per-strip
dx11: naomi2 support
n2: ambient color was swapping red and blue
gl, dx11: don't write depth in per-strip to avoid missing geometry,
prefer wrong depth order/blending for now
optimize naomi2 per-triangle sorting
2022-02-13 21:01:45 +01:00
github-actions[bot] 3929fe64a3 Fetch translations & Recreate libretro_core_options_intl.h 2022-02-11 22:20:12 +00:00
Flyinghead a14086d484 naomi2: shader error in gles. Invert clubkart wheel axis 2022-02-11 19:06:58 +01:00
Flyinghead 20d25059bf naomi2: remove geom shader. Merge transparent polys. bump mapping fix.
elan: Get rid of geometry shader and do geometry clipping manually.
pvr: Aggressively merge transparent polys in per-triangl and OIT mode, duplicating the last vertex to merge opposite cull mode strips.
gl4: reset OIT pointers in final shader. No need for clear pass.
gl4: alternate between 2 buffers for verts.index/tr poly params.
gl4: use gl_VertexID + poly number for poly index.
gl: new GlBuffer class.
2022-02-11 15:54:18 +01:00
Flyinghead ccee7162bc naomi2: soulsurfer inputs, 2-volume UV, wrong TA parser selected
TAParserDX was used for pass-through TA data. Fixes health bar color in
vf4 and dust color in kingrt66.
2-volume missing u1/v1. Fixes clubk shadows.
2022-02-08 10:32:56 +01:00
Flyinghead 4fe8e40569 libretro: fix texupscale and max upscaled texture size settings value 2022-02-06 20:42:41 +01:00
Flyinghead b91b3d5da6 libretro: use correct #ifdef for omp support
enables xBRZ upscaling
2022-02-06 17:52:30 +01:00
Flyinghead debbae6ab1 naomi2: elan v10 emulation. texture dma xfers. 2-volume support
emulate elan v10 (fixes modvol in vf4, initd, beachspiker, wldrider)
wrong color order for model and vtx color
model param override xor support
improved light direction precision. Angle attenuation algo change
get rid of alpha light and modifier volume hacks
texture dma xfer from main and elan ram
gl4: use geometry only vtx and geom shaders for depth pass
2-volume support
2022-02-05 14:50:12 +01:00
Flyinghead 2c6f01ae38 naomi2: kingrt66 wiper button. initd gear up/down
kingrt66: map wiper button, remap shift H and R
initd: map gear up and down
wldrider: remap push and pull
2022-02-05 14:29:01 +01:00
github-actions[bot] 92f81fa054 Fetch translations & Recreate libretro_core_options_intl.h 2022-02-04 22:19:01 +00:00
Flyinghead 0362fd1079 naomi2: disable elan when net rollbacking, optimizations. ggpo: RTT fix
n2: do not process elan commands during ggpo rollbacks.
n2: Cache model colors to avoid unpacking for each vtx
pvr: merge equivalent polys with different culling by duping a vtx
pvr: fix crash during direct FB render
pvr: use correct color ordering for naomi2. Use identify matrix for null matrix pointers
ggpo: do not signal end of frame on a render to texture
2022-02-01 17:37:54 +01:00
Flyinghead 38765dc89a pvr: fix multipass. naomi2: constant color shading.
pvr: link multipass TA contexts. Each pass has its own.
pvr: get rid of context pool
naomi2: constant color shading. Use model diffuse and specular
selection. Don't use vtx color for offset color.
naomi2: pseudo-parallel lights fix
naomi2: pass-through TA data needs forced list type. Terminate with
end-of-list
enable RTT copy to vram for Beach Spikers
2022-01-31 20:40:09 +01:00
Flyinghead 78306b3c12 ggpo: memory leak in free_buffer 2022-01-30 12:39:00 +01:00
Flyinghead e51a291195 ggpo: wrong elan ram offset calculation 2022-01-30 12:39:00 +01:00
flyinghead d551848a9b dummy commit 2022-01-29 19:39:08 +01:00
Flyinghead fe6247dded cheats: iOS build fix 2022-01-29 18:40:19 +01:00
Flyinghead 5fb8b458bb pvr: use TA_OL_BASE instead of PARAM_BASE/TA_ISP_BASE to id TA context
Writes current TA_OL_BASE to all tiles OPB block. Read from region array
at render time to identify context.
Fixes vf4 water reflections RTT
get rid of dump_frame/read_frame
2022-01-29 18:39:38 +01:00
Flyinghead 4e21391f8c ggpo: memory leak in free_buffer 2022-01-29 16:58:28 +01:00
github-actions[bot] 9ab4bb963f Fetch translations & Recreate libretro_core_options_intl.h 2022-01-28 22:20:29 +00:00
Flyinghead 340c55c570 build fix 2022-01-28 22:30:07 +01:00
Flyinghead de1322b928 naomi2: Fix T&L matrix. vmem elan ram support.
Fix T&L matrix (wild riders)
Open GL support for normal/light matrix
handle elan RAM in vmem
2022-01-28 21:24:30 +01:00
Flyinghead 010d257b69 naomi2: vf4tuned cheat/hack to skip DIMM fw version check 2022-01-28 20:02:07 +01:00
Flyinghead 58f05f74cf jvs: set received jvs message trail to zero
fixes sh4 crash during naomi boot
2022-01-28 11:31:30 +01:00
Flyinghead e5d517dad2 use platform.isConsole(), platform.isNaomi(), ... 2022-01-27 17:52:19 +01:00
Flyinghead 965dea5fe6 test fix 2022-01-27 16:44:37 +01:00
Flyinghead 1ffcc75031 naomi2: implement SB_ISTNRM for clxb. serialize elan state 2022-01-27 16:40:12 +01:00
Flyinghead e084cc9a3a jvs: set received jvs message trail to zero
fixes sh4 crash during naomi boot
2022-01-27 15:50:44 +01:00
Flyinghead 6ed78d1202 another GL_CLIP_DISTANCE0 build fix 2022-01-26 22:37:38 +01:00
Flyinghead 270eaa1452 GL_CLIP_DISTANCE1 undefined 2022-01-26 22:19:53 +01:00
Flyinghead e1038ea632 naomi2: fix regressions. 2-volume and bump mapping support WIP
optimize open gl uniforms
2022-01-26 22:15:10 +01:00
Flyinghead 8947100701 libretro: missing new param to gl4GetProgram 2022-01-25 15:43:30 +01:00
Flyinghead cb99e7d920 naomi2: do T&L on the gpu. bypass TA format. env mapping.
fix model/instance/matrix parsing
handle culling reversed model flag
geometry shader for near plane clipping
2022-01-25 15:37:04 +01:00
DisasterMo a4b0a69c45 Enable Indonesian, Swedish and Ukrainian localisations 2022-01-22 19:18:41 +01:00
github-actions[bot] 2a364910c0 Fetch translations & Recreate libretro_core_options_intl.h 2022-01-21 22:20:49 +00:00
Flyinghead 45ba648622 dx11: VersionHelpers.h -> versionhelpers.h
the mingw version is all lowercase
2022-01-19 14:37:49 +01:00
Flyinghead dcd48f4264 ios: on-screen keyboard support 2022-01-19 13:48:16 +01:00
Flyinghead b048921c11 naomi2: fix clipping, parallel light direction, reset state on loadstate 2022-01-18 18:25:40 +01:00
Edward Li 8ee9f1b1d9 Cleanup macOS screen DPI calculation (included in SDL 2.0.20 now) 2022-01-18 11:58:57 +01:00
Edward Li f2c39e4004 Update SDL to 2.0.20 2022-01-18 11:58:57 +01:00
Flyinghead 4335aa563f naomi2 WIP 2022-01-16 22:41:42 +01:00
Flyinghead 62ec3546d6 dx11: uwp doesn't need texture conversions 2022-01-16 10:37:55 +01:00
Flyinghead 8bb0bd05f9 ui: limit scaling further on small low-resolution screens (retroid) 2022-01-16 09:58:33 +01:00
Flyinghead e538242962 dx11: convert 16-bit textures to 32 bits on windows7
1555, 4444 and 565 aren't supported on win7
Issue: https://github.com/libretro/flycast/issues/1123
2022-01-16 09:54:39 +01:00
github-actions[bot] d70d2ad405 Fetch translations & Recreate libretro_core_options_intl.h 2022-01-14 22:21:28 +00:00
Julien Reichardt 4f638f6d77 Use service button instead of coin
The service button can also be used to add coins.
2022-01-11 14:09:54 +01:00
Julien Reichardt 80d78705b0 Add default coin mapping 2022-01-10 12:13:14 +01:00
github-actions[bot] 140cec7c59 Fetch translations & Recreate libretro_core_options_intl.h 2022-01-07 22:20:58 +00:00
scribam 746b3c5a54 sdl: fix joystick rumble 2022-01-06 08:59:39 +01:00
Flyinghead a4788b5b24 zero-init sh4 context when no vmem is available
Issue #439
2022-01-03 18:44:47 +01:00
cmitu 8dcf0f58b5 postprocess: fix GLES2-only build
Added a missing `ifndef` guard for `glBindVertexArray`, useful for GLES2-only builds.
2022-01-02 10:51:03 +01:00
Julien Reichardt a8080c5db3 Fix missing libSDL2.a static library on Linux 2022-01-01 18:29:46 +01:00
github-actions[bot] a52977d1cf Fetch translations & Recreate libretro_core_options_intl.h 2021-12-31 22:20:45 +00:00
Edward Li 0bb6fed822 Remove junk folder when packaging macOS app 2021-12-26 23:20:58 +01:00
Flyinghead d86305a7c3 android: on-screen gamepad not editable in Open GL
Swap wasn't called during editing
Issue #464
2021-12-26 16:03:19 +01:00
Edward Li 5aeef17d09 macOS: Enable "New Instance" in File and Dock menu for SDL 2021-12-25 21:46:19 +01:00
Flyinghead 2d41d993e3 macOS: patch SDL to compile in metal and vulkan
https://github.com/libsdl-org/SDL/issues/5010
2021-12-25 21:45:13 +01:00
github-actions[bot] 503cc7ea97 Fetch translations & Recreate libretro_core_options_intl.h 2021-12-24 22:21:05 +00:00
Flyinghead 7f41847c5c android: bigger on-screen gamepad analog handle. Update project README 2021-12-24 19:46:09 +01:00
scribam fde683a82e ci: cmake install for switch builds 2021-12-23 22:31:39 +01:00
scribam 4feff7d917 ci: add ccache for switch builds 2021-12-23 22:31:39 +01:00
asdf288 e61951a319 Fix typo in GLES2 library name 2021-12-23 22:31:25 +01:00
Flyinghead da81274eb9 lr: gl stencil param isn't obsolete but required
Issue #454
2021-12-23 22:30:44 +01:00
flyinghead 8740141a93 Merge pull request #451 from flyinghead/net-rollback
Merge net-rollback branch
2021-12-23 11:21:29 +01:00
Flyinghead 9223a2b530 readme: link to gamr13's xbox page 2021-12-22 21:41:01 +01:00
Flyinghead 300c74e3fc Merge remote-tracking branch 'origin/master' into net-rollback
# Conflicts:
#	CMakeLists.txt
#	shell/libretro/libretro.cpp
#	shell/libretro/libretro_core_options.h
2021-12-22 21:31:17 +01:00
Flyinghead 3f82c7fb6f iOS: use play and record audio session only when necessary
Change audio session to play and record when a microphone is connected.
Use a play only session otherwise. Issue #360

Hide VSync-related gui option.
2021-12-21 21:36:12 +01:00
Flyinghead 2cb7a1d96c android CI: upload to S3 after dumping symbols 2021-12-21 21:26:31 +01:00
Flyinghead 00562455e0 android CI: choose the openssl flavor of curl 2021-12-20 16:11:54 +01:00
Flyinghead bb88dcfe66 android CI: install libcurl for breakpad. Disable breakpad on macOS 2021-12-20 16:08:22 +01:00
Flyinghead 970e594009 Build with breakpad submodule. Use gcc 11 on windows. 2021-12-20 15:45:46 +01:00
Flyinghead cd5a784277 add breakpad as submodule 2021-12-20 15:23:28 +01:00
Flyinghead 771f653174 delete breakpad 2021-12-20 15:20:26 +01:00
scribam 109cb81ab7 ci: add cmake install and refactor artifact generation 2021-12-20 14:36:48 +01:00
Flyinghead bf87f7ba84 Compilation error on armv7 with gcc 9 2021-12-20 14:27:19 +01:00
scribam 92b8eae2dc ci: cleanup cmake build type 2021-12-19 15:02:05 +01:00
scribam 776f86c7f2 README.md: add badge for Windows UWP CI 2021-12-19 13:29:41 +01:00
cmitu c10c3a1cfe cmake: amend 2b827e43, fix the typo for GLES3_LIBRARIES 2021-12-19 13:28:47 +01:00
scribam 94fccc5112 ci: fix ccache cache key 2021-12-19 11:18:32 +01:00
scribam 73fa0e3efc cmake/deps: update sdl to version 2.0.18 2021-12-19 11:18:24 +01:00
cmitu 2b827e43d7 cmake: add more GLES3 library names
Some systems provide the GLES3 implementation in the same GLESv2 library file, most notably Mesa.
Added the alternative library name when GLES3 is requested.

This makes the build work on the Pi4 - I've only tested it with the libretro core and the GLES 3.1 context is succesfully used.
2021-12-19 10:56:32 +01:00
cmitu e706368225 cmake: add support for legacy RPI GLES2 libs
Raspberry Pi 3 can use the legacy Broadcom GLES2 libraries from /opt/vc/lib.
They are the default GLESv2 libraries on Raspberry PI OS 10 (Buster) and older.
2021-12-19 10:56:32 +01:00
flyinghead 2f5271ab83 yabf4 2021-12-18 13:33:42 +01:00
flyinghead 4e448b23a8 yabf3 2021-12-18 13:25:41 +01:00
flyinghead 38002d4907 yabf2 2021-12-18 13:14:04 +01:00
flyinghead fd81f9b1b4 yabf 2021-12-18 13:11:17 +01:00
flyinghead 77900f5745 ci: env var not replaced 2021-12-18 12:25:02 +01:00
flyinghead 8684aac4f2 yaml parse error 2021-12-18 12:19:09 +01:00
flyinghead b1e0bc90ba uwp: remove angle, upload to S3. windows: don't build SDL 2021-12-18 11:50:03 +01:00
scribam 8e305bfd0f android/vmem: use constant ASHMEM_NAME_DEF 2021-12-18 11:46:04 +01:00
scribam 32716e1480 android: update com.android.tools.build:gradle to version 7.0.4 2021-12-18 11:46:04 +01:00
jdgleaver 833eccb6c4 (libretro) Sanitise core options 2021-12-18 10:16:37 +01:00
github-actions[bot] f64b3618f2 Fetch translations & Recreate libretro_core_options_intl.h 2021-12-17 22:20:56 +00:00
Flyinghead 325cd9a066 DSP crash on apple M1
Issue #415
2021-12-17 13:43:45 +01:00
Flyinghead 544c711fd7 savestate: compatibility between nvmem and !nvmem savestates 2021-12-17 13:41:46 +01:00
Flyinghead e02afb34d1 dx11: wrong shadow scale factor. vk: object leak. Code duplication
dx11: shadow scale factor inverted in per-pixel
vulkan: clear deleted overlay images when terminating
Use color struct for FOG_COL_VERT, FOG_COL_RAM, FOG_CLAMP_MIN,
FOG_CLAMP_MAX and VO_BORDER_COL. Avoid code duplication in renderers.
2021-12-17 13:40:42 +01:00
Flyinghead dc5acd24b2 Merge remote-tracking branch 'origin/master' into net-rollback 2021-12-17 12:40:37 +01:00
Flyinghead 7555263e38 wrungpo had wrong decryption key
Issue https://github.com/libretro/flycast/issues/1108
2021-12-17 11:55:17 +01:00
Flyinghead 71d016722e vulkan: fix various validation errors
oit: skip to new frame even if previous frame was never presented
libretro: quad pipeline used for overlay must use subpass 2 in per-pixel
overlay: delay destruction of VMUs images
libretro: WaitIdle on queue instead of wait_sync_index
2021-12-16 21:26:55 +01:00
jdgleaver 96560e4914 (libretro) Move audio batch callback onto main thread + improve audio sample pacing 2021-12-16 18:21:08 +01:00
Flyinghead 04be40767b android: fallback to /dev/ashmem if ASharedMemory fails. More logs
Issue #439
2021-12-15 23:09:59 +01:00
Flyinghead 5a6197cfc6 libretro: never request a GLES3 context
RA doesn't give us the opportunity to retry if GLES3 isn't supported.
Issue #405
2021-12-15 21:23:35 +01:00
flyinghead 5fca12af49 msvc compilation warnings 2021-12-15 17:58:58 +01:00
flyinghead 853830a446 log errno when failing to open a disk or folder. Better win32 errors
Log errno when failing to open a disk or folder (game scanner)
Better win32 error codes with GetLastError() for opendir, stat, access
2021-12-15 17:55:42 +01:00
flyinghead 2f47f72957 dx11: recreate texture if dimensions or format change. Clear rtt depth
Fixes a crash when switching Copy to VRam on as the RTT texture is no
longer upscaled when updated.
Clear RTT depth/stencil before render.
2021-12-15 11:32:04 +01:00
flyinghead de35cf9840 dx11: fix fullscreen toggling
Prevent DXGI from monitoring Alt+Enter and let SDL handle it
2021-12-15 10:37:52 +01:00
flyinghead 18d8107992 dx11: no color interpolation for flat shading
Fixes Evolution WoSD
refactor setFirstProvokingVertex (dx9, dx11, vk)
Set .1 depth scale for V-Rallye to fix missing background image in menus
(dx11, dx9)
2021-12-15 09:37:58 +01:00
flyinghead 2478b72a3e lr dx11: fix exit crash. Save shader cache where vk cache is 2021-12-14 16:48:23 +01:00
flyinghead 4d60150345 libretro: dx11 crash in single-threaded. Use compiler and feature level
libretro: Null first frame erroneously set as valid causing a crash with dx11 (single-threaded rendering)
libretro: pass dx11 compiler pointer to shaders
dx11: use feature level to check if per-pixel is supported
2021-12-14 10:41:04 +01:00
flyinghead 6a3a8d5578 libretro: dx11 support. dx11 shader cache. dx9 clipping planes
dx11: use 32-bit float depth texture to avoid loss of precision (SA2 into logo)
dx11: cache shader blobs to disk if not provided by OS
dx11: swap interval depends on screen refresh rate (1 for 60 Hz, 2 for 120 Hz, ...)
dx9: use clipping planes to avoid interpolation errors in rasterizer (daytona, mermaid lake)
directsound: use comptr
gui: fix navigation issue with OptionArrowButtons due to missing id
2021-12-13 21:02:44 +01:00
scribam 08828991e7 dx11: msvc x86 build fix 2021-12-12 18:43:36 +01:00
flyinghead 4c14a96888 vk, gl4: out of bound array index when sorting pixels 2021-12-12 18:42:50 +01:00
flyinghead 0478ec9696 dx11: per-pixel renderer 2021-12-11 18:53:35 +01:00
flyinghead 46044c068b cheats: don't rely on cheat count on load. Fix compile warnings 2021-12-11 18:33:28 +01:00
github-actions[bot] c6fe6b83ac Fetch translations & Recreate libretro_core_options_intl.h 2021-12-10 22:20:46 +00:00
flyinghead cc39d4dd7d vmem: close shared mem file descriptor when terminating
Tentative fix for Issue #439
2021-12-10 14:04:45 +01:00
flyinghead b79c049bd4 dx11: wrong shader hash calculation 2021-12-09 09:26:36 +01:00
flyinghead 4cbf19c97e libretro: nvmem not saved when rom path mixes slash and backslash
Issue https://github.com/libretro/flycast/issues/1114
2021-12-07 17:15:35 +01:00
flyinghead 27041cbf59 dx11: better clipping algo. modvol cull mode. win: exception code
dx11: use faster clipping algorithm for modifier volumes
dx11: modifier volumes need cull mode. Fixes Daytona shadows.
win: the fault handler was treating some software exceptions as fatal (msvc)
uwp: remove async hacks and disable MS task wait exception. Fixes error reporting when loading a game.
2021-12-06 17:43:22 +01:00
IlDucci 8e2c72ed1b [Core options text] Typo fixes and minor style changes
- Changes the main category sublabels to match RetroArch's style.
 - Adds a missing period, as reported in Crowdin.
 - Adds an extra minor description to the Language setting.
2021-12-05 12:23:35 +01:00
flyinghead 7820c9bc44 dx9/11: fix rtt2vram crash. dx11: modvol fix and more
dx11: clip modvol triangles before sending them to the gpu
dx9,11: wrong source pointer for rtt to vram
dx11: handle source RowPitch when copy rtt to vram
dx11: crash at reinit
dx11: wrong scissor with direct fb rendering
dx11: blend ops are different for the alpha channel

Fix mingw CI build
2021-12-04 19:16:11 +01:00
github-actions[bot] 92fff9acf5 Fetch translations & Recreate libretro_core_options_intl.h 2021-12-03 22:21:13 +00:00
flyinghead 91da49dc52 mingw: downgrade cmake 2021-12-03 23:08:59 +01:00
flyinghead b5a45417d9 mingw: downgrade gcc to 10.3 2021-12-03 22:29:41 +01:00
Edward Li 3db4993077 Xcode project file (debug friendly) generator with predefined LLDB Init File to bypass SIGBUS error 2021-12-03 15:49:47 +01:00
Edward Li bc1a5fdd8d Make LLDB ignore EXC_BAD_ACCESS for debugging 2021-12-03 15:49:47 +01:00
flyinghead 191f1c38df dx11: scissoring fix. 4K UI scaling
Clearing of side columns in 4:3 uses the quad drawer so it needs to be
called early. Border color was wrong. Fixes GTA2.
Scale UI x2 in 4K mode.
2021-12-03 15:48:42 +01:00
flyinghead adb61259c1 mingw ci: enable dump_syms ouput 2021-12-02 17:20:56 +01:00
DisasterMo ddc2e84e45 Add automatic Crowdin synchronization 2021-12-01 21:28:51 +01:00
flyinghead a050a61f2e ci: install dx9 sdk for mingw 2021-12-01 21:28:21 +01:00
flyinghead 99195c3f4c dx11: set clip planes on X and Y. rend: Force palette update at init
dx11: Set clip planes at X -1/1 and Y -1/1 to avoid rasterizer errors.
Fixes Daytona Mermaid lake depth issues
dx11: fix texture wrap around at UV 1 with nearest filtering
dx9: inside clipping
all renderers: force full palette update at init
2021-12-01 14:54:03 +01:00
flyinghead 280c159078 uwp: fix dirent. Implement access() and stat()
Use UWP version of FindFirstFileEx
Implement basic access() and stat()
Add home dir to list of drives
Allow external storage folders to be added and scanned for games
2021-12-01 14:40:17 +01:00
flyinghead 6a8f1b941e dx11: overlay support. inside clipping. 4K support on xbox. log fix
dx11: support for vmu and lightgun crosshair overlays
dx11: implement inside clipping (fixes 18 wheeler rear view mirror)
dx11: tentative 4K support on xbox
iOS,uwp: save log file in home (iOS)/data(uwp) directory
uwp: don't sign app on pull requests
2021-11-29 18:22:25 +01:00
scribam 8a6ce19e1e input: cleanup virtual function specifier 2021-11-29 18:19:22 +01:00
flyinghead d071adea9a dx11: fix modifier volumes, rotation. sdl: on-screen keyboard support
dx11: Back face stencil ops need to be set
dx11: Rotate CCW instead of CW
dx11: Present with NO_WAIT when fast forwarding
sdl: support for on-screen keyboard. Delay keys up by one frame to allow quick key presses.
ui: better fix to wait for future on UWP
2021-11-28 16:19:03 +01:00
flyinghead 3d7455316f linux build fix 2021-11-27 14:39:28 +01:00
scribam 3f50baa318 picotcp: fix alloca on freebsd 2021-11-27 14:32:04 +01:00
scribam 8164c96379 deps: update libchdr and remove patch 2021-11-27 14:31:22 +01:00
flyinghead 4ab3f01867 uwp: external storage support. enable picotcp 2021-11-27 14:30:36 +01:00
flyinghead dbb277f749 Potential crash when starting game with non-default renderer
Renderer is switched to default and back to the selected one during
reset on the emu thread. The render thread may pick up this change.
2021-11-27 14:13:24 +01:00
flyinghead 0579f2ede6 7z: use fopen on all platforms 2021-11-27 14:08:07 +01:00
orbea ef3af9aad3 cmake: Add an install target (#421)
Don't install glslang or xbyak
2021-11-27 10:42:09 +01:00
flyinghead d5694036fa libretro: don't crash if frontend doesn't implement
RETRO_ENVIRONMENT_GET_CLEAR_ALL_THREAD_WAITS_CB

Issue #418
2021-11-27 10:41:11 +01:00
flyinghead f91847dad0 DX11 renderer WIP 2021-11-26 18:08:41 +01:00
flyinghead c4eaa973f0 picotcp: use strcasecmp 2021-11-24 14:17:00 +01:00
flyinghead 42fa77c81f uwp: the back button (B) shouldn't close the app 2021-11-24 13:42:25 +01:00
flyinghead e4bfeb9e44 picotcp: MSVC support 2021-11-24 13:41:04 +01:00
cglmrfreeman 67f2162fb3 Fix linux breakpad issues when glibc-2.34 is installed
As outlined by [Samuli Piippo in the qtwebengine chromium patch](https://codereview.qt-project.org/c/yocto/meta-qt6/+/378728/2/recipes-qt/qt6/qtwebengine/chromium/0004-breakpad-fix-build-with-glibc-2.34.patch), SIGSTCKZ is no longer being compile time constant in glibc-2.34. The proposed fix compiles on my end and I have not tested on a linux distro with an earlier version of glibc.
2021-11-23 20:23:28 +01:00
flyinghead 465499f6c3 libretro: don't set preferred GLES version when initializing context
Issue #405
2021-11-22 15:28:18 +01:00
flyinghead ea75311a34 uwp: yml typo 2021-11-21 15:34:01 +01:00
flyinghead 33fd8a9ec7 uwp: sign appx package 2021-11-21 15:18:55 +01:00
BornPosthumous 417ffc09f8 Allows override of flycast.lua file (#411) 2021-11-21 15:16:11 +01:00
flyinghead 1057f50f86 uwp CI fix 2021-11-20 19:13:55 +01:00
flyinghead 5b933cde61 uwp: use ccache for CI. gui_util.h typo 2021-11-20 18:24:21 +01:00
flyinghead 47442d1bc9 fix libchdr patch 2021-11-20 17:32:12 +01:00
flyinghead f25c83e006 uwp CI fix 2021-11-20 16:21:27 +01:00
flyinghead bc34024e32 uwp: fix crash when opening menu/canceling load. CI job 2021-11-20 16:18:27 +01:00
flyinghead 628bef9094 libretro: don't set minimum GLES version when initializing context
Issue #405
2021-11-20 14:14:19 +01:00
flyinghead 63598019e1 naomi: rename deathcox to deathcoxj, new deathcox parent rom
MAMESET 0.227 changes
Issue #409
2021-11-20 14:06:19 +01:00
flyinghead 501244ed25 x64 rec: incorrect stack alignment of memory handlers on windows 2021-11-20 12:29:07 +01:00
flyinghead e12912450c missing changes 2021-11-19 23:29:35 +01:00
flyinghead 8262c9ece7 UWP support - WIP 2021-11-19 23:18:45 +01:00
Flyinghead cc208ce451 libretro: arm32 android build must use arm mode, not thumb
Issue #405
2021-11-16 16:46:28 +01:00
scribam c6374a899c win32: build fix when sdl2 is not enabled 2021-11-14 22:56:43 +01:00
Flyinghead 8f80bcb159 New serialize framework. Delay maple dma xfer
New serialize framework. Refactor serialization into modules.
Maple dma xfer must not be executed immediately. Delay until interrupt
is raised.
Fixes Geist Force freeze at start.
2021-11-13 15:56:42 +01:00
Flyinghead e56ecfec40 vk,dx9: black screen/crash in single-threaded on direct fb access
When rendering happens after the render timeout (initial sega copyright
screen and more), the frame is never swapped and never displayed. Causes
a crash in vk since the acquired swapchain image is never
presented/released.
2021-11-11 11:17:39 +01:00
Flyinghead 80cf422a5e dynarec: fix CLRS and SETS ops
Destination reg was missing
Fix crash in OpenTyrian/SDL_DREAMHAL
Issue #403
2021-11-11 10:44:22 +01:00
Flyinghead d788c310ee apple build fix 2021-11-10 21:21:25 +01:00
Flyinghead 7583db3bef vk: option to duplicate frames to simulate swap interval > 1
Issue #293
2021-11-10 20:55:22 +01:00
Flyinghead ac5abd96bb ui: imgui driver, GraphicsContext interface, dx9 swap interval
Refactor imgui backend code into imgui drivers for gl, vk, dx9
Generic GraphicsContext interface for gl/vk/dx9 contexts
Simplify graphics api switching code
dx9, gl(sdl): set swap interval based on monitor refresh rate.
2021-11-10 20:35:30 +01:00
Flyinghead aa944ac5e8 vk: fix vmu transparency in lr core 2021-11-10 18:42:11 +01:00
Flyinghead 35e1fb9ae5 cmake: change default libretro target 2021-11-10 10:17:40 +01:00
twinaphex a15863ae35 (Libretro) CI integration - and necessary fix for compiling Windows
core cross-compiled on Linux
2021-11-09 18:48:55 +01:00
Flyinghead a04fd06e38 gl: iOS doesn't like smooth. More precision needed for vertex colors 2021-11-09 10:38:41 +01:00
scribam f6cc2c7b91 ci: use msys2 only for mingw builds 2021-11-09 10:37:43 +01:00
Flyinghead 99ee526ac5 gles3 doesn't support noperspective. vk needs higher prec for color/uv/z
noperspective not supported in gles 3. Use smooth instead
Vulkan now needs higher precision for colors, UV and z (adreno 630)
2021-11-08 16:53:47 +01:00
scribam d100067e02 cmake: use AltKit default include directory for AltKit-Swift.h 2021-11-08 11:58:42 +01:00
scribam f777c62a66 android: update com.android.tools.build:gradle to version 7.0.3 2021-11-08 11:58:42 +01:00
Flyinghead 06ef0e5fdc vk,gl: use w=1 in shaders. Fix translucent modvols
Use w=1 to avoid multiply/divide of xy as in dx9
Disable rendering when video output disabled
Use original w value in pixel struct to avoid precision loss (samsptk)
vk oit: missing memory barrier was producing Tr modvol glitches (JSR)
gl oit: Tr modvol needs full vertex shader
2021-11-07 18:21:44 +01:00
Flyinghead 5209623064 cue: ignore unrecognized REM entries. parse one line at a time 2021-11-05 19:14:08 +01:00
Flyinghead 7c53413bc5 vk oit: fix depth-only Tr pass
Cosmic smash
2021-11-05 18:36:09 +01:00
Flyinghead 42f92b8dc1 ggpo lib: compile warnings, remove legacy chat 2021-11-05 18:34:23 +01:00
Flyinghead 986baccf83 lr build fix 2021-11-04 13:11:18 +01:00
Flyinghead 32d31e7644 vk: implement TranslucentPolygonDepthMask
Fixes Cosmic Smash
vma: instance is needed at init
Partial vk support for iOS
2021-11-04 09:13:47 +01:00
Flyinghead 03161446b9 can't launch BIOS after playing a game 2021-11-04 08:57:15 +01:00
Flyinghead 17bbb7f145 vk: disable small tex optimization on macOS. Fix libMoltenVK embedding
small textures linear optimization leads to texture corruption with
moltenvk.
Copy libMoltenVk to correct runtime output dir.
2021-11-02 09:44:24 +01:00
Flyinghead 71c4ec34d5 iOS build fix 2021-11-01 13:30:36 +01:00
Flyinghead da3ed74c4e vulkan: moltenvk support on macOS - WIP
sdl: save/restore window position in config
2021-11-01 13:05:22 +01:00
Flyinghead 46ae8f92cc input: per game input mapping 2021-11-01 12:39:50 +01:00
Flyinghead 9b3dec5f70 imgui: fix crash when closing chat with gamepad DPad button down
backport https://github.com/ocornut/imgui/commit/25679a411ee33272d4d047192b30af03e3a384fc
2021-10-27 12:28:31 +02:00
Flyinghead 146bfb28d1 ggpo: always use P1 input in netplay even if playing as P2
fix imgui assert
2021-10-27 12:26:17 +02:00
Flyinghead 46fb331275 look for BIOS files in Content Path folders if not found in data folder 2021-10-27 12:24:30 +02:00
Flyinghead ff39b8b252 macOS: use ~/Library/Application Support/Flycast as home directory
still use ~/.flycast or ~/.reicast if found for backward-compatibility
Issue #336
2021-10-27 12:22:24 +02:00
LaercioMBR 004250ed23 InputDescriptors for radirgyn and mamonoro 2021-10-24 14:07:40 +02:00
Flyinghead 037339f3be ggpo: savestate md5 wasn't computed 2021-10-21 12:03:04 +02:00
Flyinghead e0437ab447 msvc fix 2021-10-20 15:28:34 +02:00
Flyinghead 808a161d39 ggpo: make chat thread-safe. Deadlock on early rollback
Make ggpo_send_message() thread-safe
Deadlock UI/emu threads if rollback happens before first render
Disable rollback wait in single-thread mode
2021-10-20 14:41:18 +02:00
LaercioMBR 6d8e1794a0 Fix Metal Slug 6 inputs (#393) 2021-10-20 14:36:02 +02:00
Flyinghead 89338c0b4b win32 build fix 2021-10-19 17:24:17 +02:00
Flyinghead 7f7cbd5666 missing change 2021-10-19 17:05:00 +02:00
LaercioMBR 846ed76808 InputDescriptors for Dolphin Blue, Demolish Fist and ggx15 2021-10-19 17:02:01 +02:00
Flyinghead ab45b5ec8a ggpo: keyboard/mouse games support. Fix chat when keyboard disabled
ggpo: support for arcade games using keyboard (totd, luptype) and
mouse/rotary encoders (waiwai drive)
Chat and UI now usable when the keyboard is not set to a maple port.
2021-10-19 16:56:46 +02:00
Flyinghead db93a4c4a7 ggpo: in-game chat
use menu key to open/close chat window
disable keyboard/mouse controllers when using chat
disabled controllers can now use emu keys (menu, escape, ff)
2021-10-18 16:40:17 +02:00
Flyinghead 59566eb363 ggpo: support application messages 2021-10-18 16:26:24 +02:00
LaercioMBR 7fb85e5b25 Standardizing InputDescriptors names, added kov7sprt_inputs (#389) 2021-10-18 11:24:38 +02:00
Flyinghead c061912574 android: fix hang when mount returns too much data
Issue #387
2021-10-16 18:16:17 +02:00
Flyinghead 3eeb7e7cae build fix 2021-10-16 18:15:11 +02:00
Flyinghead cf653640b3 ggpo: verify md5 of bios, game and savestate
Verify md5 of flash, eeprom, vmus if no savestate used
Use chd header SHA1 as digest
Load .state.net state file at start

Force real BIOS for some games
2021-10-16 17:56:21 +02:00
Flyinghead 5cfd897298 android: more activity init logs 2021-10-15 13:14:42 +02:00
Flyinghead 7ecb6a6d96 ggpo: Fix udp packet size. Fix verif mismatch due to uninit'ed var 2021-10-15 13:07:21 +02:00
Flyinghead c08f177d3b libretro build fix 2021-10-14 11:51:39 +02:00
Flyinghead 1c6e722961 android: add app external & internal files dir. Race condition at start
Fix crash at startup due to race condition with game scanner
Don't allow selection of non-writable folder during onboarding
Add private internal and external Files folders to list of storage
locations to choose from
Assign first external android gamepad to port A instead of B

ui: Fix layout of controller mapping dialog when port=All
2021-10-14 11:39:27 +02:00
Flyinghead 0d49817f00 fix crash when [config]pvr.rend is invalid for the current platform 2021-10-14 10:52:35 +02:00
Flyinghead 85c21df5e7 Use allocAligned/freeAligned for all aligned allocs 2021-10-14 10:46:44 +02:00
Flyinghead f9d5b8eb74 ui: limit max scaling on small low-res screens (<= 640x480) 2021-10-12 17:34:42 +02:00
Flyinghead bcc3337c58 cheats: support for bit-level RA codes
log start of address space, RAM, VRAM, audio RAM at boot
fix add cheat dialog layout
don't crash on wrong gdrom unlock code
2021-10-12 17:28:01 +02:00
Flyinghead 163888f329 GameShark cheat codes support 2021-10-10 17:24:17 +02:00
Flyinghead 8b986dfab3 vmu beep support 2021-10-10 16:33:37 +02:00
Flyinghead 19bd6d0bca test automation clean up
less #ifdef
force mute audio
don't force vsync
2021-10-10 16:26:36 +02:00
Flyinghead c2caef4ad5 ui: use SDL clipboard functions for imgui
allow cut & paste on linux
2021-10-07 19:14:29 +02:00
Flyinghead 1d9ac4918c pvr: fix SPG_VBLANK_INT reset value 2021-10-07 16:24:00 +02:00
Flyinghead bc3be1029c fix sh4 scheduler. use common cycle counter in sh4 context
scheduler reset and unregister
schedule requests during reset(), not init()
preserve cntx.sh4_sched_next on sh4 reset
Use cntx.cycle_counter in dynarecs and interpreter
Fixes Confidential Mission hang at boot with HLE
2021-10-07 16:18:32 +02:00
Flyinghead bc238de5ce switch: open 4 controllers. android: java7 compatibility 2021-10-06 18:55:04 +02:00
Flyinghead 1072235b1a lua: ui bindings 2021-10-04 19:42:45 +02:00
Flyinghead 3c2c7b379d ggpo: pair with first received sync request if remote IP not specified 2021-10-04 19:38:33 +02:00
Flyinghead 4af194035c win: fix binary s3 upload 2021-10-04 19:21:18 +02:00
Flyinghead 3171cfd381 win: fix binary s3 upload 2021-10-03 21:46:37 +02:00
Flyinghead 8183bf7f95 linux build fix 2021-10-03 20:42:25 +02:00
flyinghead 82bec1e324 lua: build fix for linux and win. dx9: crash on exit 2021-10-03 20:22:52 +02:00
Flyinghead 897cc01f93 some lua bindings 2021-10-03 18:34:27 +02:00
Flyinghead 5bcfa35737 Better background game loader
Pass LoadProgress object to report load progress and cancel
Better UI
Cancel with exception
Fix issues when stopping/exiting in !threaded
dx9: call gui_term on shutdown
2021-10-02 11:30:40 +02:00
Flyinghead c1bcf91dd6 pvr: render timeout when using ggpo or !threaded
will cause ggpo desyncs with previous versions
2021-10-01 16:48:01 +02:00
Flyinghead 621e4d196e crash when enabling bba per-game 2021-10-01 16:14:27 +02:00
Flyinghead 45ebc2239f ggpo: exchange verification data during sync 2021-10-01 16:07:32 +02:00
Flyinghead a6248905a0 ggpo: report UDP bind error. Better error reporting for net init
fix ggpo lib warnings
2021-09-30 17:24:51 +02:00
Flyinghead 699dcdaf5b Merge remote-tracking branch 'origin/master' into net-rollback
# Conflicts:
#	core/hw/maple/maple_if.cpp
#	core/rend/mainui.cpp
#	shell/libretro/libretro.cpp
2021-09-30 15:03:29 +02:00
Flyinghead 23d1f6b507 imgui: bug when drag scrolling in a combo's popup 2021-09-30 14:36:29 +02:00
Flyinghead f72f4c49fb macos: fix freeze in !threaded. input: fix crash when saving mapping
audiostream: delete legacy [audio]disable option
2021-09-30 14:31:51 +02:00
Flyinghead 2803ee8274 imgread.ImagePath clean up. ggpo: poll input late if !thread 2021-09-30 14:24:17 +02:00
Flyinghead 0d2e6f5e98 remove safe mode/div matching option
mismatched delete/free() in TexCache.cpp
2021-09-29 11:57:51 +02:00
Flyinghead 99bf7f77c4 single-threaded mode. refactoring.
single-threaded mode similar to libretro core
stateful Emulator object
disable memory watcher when !gppo
ggpo: poll input as late as possible in !threaded
2021-09-29 10:22:58 +02:00
Flyinghead 7fe2ab720f refactor screen_width/height 2021-09-27 20:29:23 +02:00
Flyinghead 18cecc8d38 gl,vk: use VO_BORDER_COL for clear color 2021-09-27 13:39:08 +02:00
scribam 5d068fc2d4 Update .gitignore 2021-09-27 11:52:18 +02:00
scribam 84d98763f1 README.md: add Nintendo Switch CI badge 2021-09-27 11:52:18 +02:00
scribam 86356c737c Update man page 2021-09-27 11:52:18 +02:00
scribam 1fa233aae7 Remove makefiles and xcode project files 2021-09-27 11:52:18 +02:00
Flyinghead 1dc01314a1 input: don't poll input on emu thread
fixes device reset errors with dx9 on Alt+Enter and other renderer
crashes
2021-09-27 11:51:39 +02:00
Flyinghead fb40bb22df vk: CommandPool size must be 2. Fix lightgun xhair validation error 2021-09-27 11:19:50 +02:00
Flyinghead 1dc22ec76c sdl: null init sdl_controller 2021-09-26 22:02:21 +02:00
Flyinghead 41ac140076 ggpo: lightgun support for arcade games
ui: display button names in arcade mode only
2021-09-26 21:28:31 +02:00
scribam 4e019cc233 Update issue templates 2021-09-25 16:04:23 +02:00
scribam 36007ceb68 android: update com.android.tools.build:gradle to version 7.0.2 2021-09-25 16:04:15 +02:00
scribam 25fdeac697 cmake: iOS minor fixes 2021-09-25 16:04:05 +02:00
Cameron Bates 07d27edb76 Add more keys, gui hotkey 2021-09-22 20:16:11 +02:00
Flyinghead 39fabf39ae naomi: free play eeprom for many games
inputs for ggx, doa2, toyfight, ausfache
don't label common buttons (coin, test, service, start)
2021-09-22 14:26:13 +02:00
Flyinghead 945a483e9b ggpo: less log 2021-09-22 14:20:55 +02:00
Flyinghead 1725dbfa98 input: fix arcade mode for on-screen gamepads.
Use same layout as gamepad arcade for on-screen gamepads (ABXYRL)
map RT and LT to buttons 5 and 6 in arcade
android: Fix non-working fast-forward button
Use maple port in lastAxisValue state
naomi: use default alienfnt buttons: 1-4
2021-09-21 15:56:01 +02:00
Cameron Bates 67790abf0e [iOS] Update AltKit (#366) 2021-09-21 10:12:19 +02:00
scribam 3ec08f6ae1 ci: simplify C/C++ CI workflow 2021-09-21 10:11:56 +02:00
Flyinghead c419654a11 input: don't register multiple button presses when holding axis
keyboard: map left stick and coin button by default
2021-09-20 14:07:42 +02:00
flyinghead 51ad6094e8 input: fix axis bound to emu buttons 2021-09-20 10:05:13 +02:00
flyinghead 5b7d189058 sdl: fix hat button names 2021-09-19 22:35:23 +02:00
Flyinghead 7d57d55414 iOS build fix 2021-09-19 18:55:09 +02:00
Flyinghead 65956dbc8d input: merge buttons and axes
Default mappings for arcade and console
Default mappings for arcade stick/hitbox
Proper handling of inverted axes
ggpo: automatic analog setting for arcade games
2021-09-19 18:27:21 +02:00
Flyinghead d75072362a vk oit: work around adreno 600 driver regression
Android 11 adreno 600 driver v502: PixelBuffer.pixels.length() is
returning 0 in some cases.

Issue #361
2021-09-18 18:08:52 +02:00
Joshua L 22947af854 Sdl gamecontrollerdb.txt fix (#356)
sdl: load gamecontrollerdb.txt before calling SDL_InitSubSystem
2021-09-18 18:07:07 +02:00
Flyinghead 50a67dbd3e build fix 2021-09-16 20:27:57 +02:00
Flyinghead 7fd954e10d rend: apply vscalefactor to scissor in 240p/480p
fixes SF3 3rd strike half-screen in 240p mode
2021-09-16 19:27:59 +02:00
Flyinghead 4c53fcecfa ggpo: detect input size mismatch and abort gracefully 2021-09-16 19:24:49 +02:00
bslenul 17348dae8a [Libretro] Middle mouse fix 2021-09-15 17:26:01 +02:00
Flyinghead 05d495b282 dx9: Fix RenderLastFrame
Fixes black blackground when opening the menu during a game
2021-09-15 17:24:55 +02:00
Flyinghead 3b7a940e9b android: use list of axes for default mapping and axis handling
Issue #338
2021-09-15 14:44:56 +02:00
Cameron Bates 501c6f260a Remove mouse invert option and invert gcmouse by default 2021-09-14 23:43:16 +02:00
Cameron Bates e1fa2b9831 [iOS] GCMouse support (#353) 2021-09-14 11:51:44 +02:00
Edward Li 043175ae4d Rumble using MacBook's Taptic Engine 2021-09-14 11:44:37 +02:00
Flyinghead 8b266b1327 ggpo: force aica.nobatch 2021-09-13 13:01:52 +02:00
flyinghead f7abe3bb34 Merge pull request #351 from flyinghead/libretro
Merge Libretro branch
2021-09-13 10:03:53 +02:00
Flyinghead 480e85f615 ggpo: UI for analog axes settings. Display stats option 2021-09-12 17:42:58 +02:00
Cameron Bates 0182d1ca09 Add dummy value for ALTDeviceID 2021-09-12 15:59:25 +02:00
Flyinghead 99a0dce8cd arm build fix 2021-09-11 19:17:36 +02:00
Flyinghead badcace987 ggpo: analog axes support. Fix right trigger. use miniupnp.
Analog stick X/Y support
Right trigger was ignored
Forward UDP port 19713 with miniupnp before starting ggpo session
Use recursive_mutex for ggpo
2021-09-11 18:50:11 +02:00
Flyinghead e8b73e22b7 Merge remote-tracking branch 'origin/libretro' into net-rollback 2021-09-11 18:11:36 +02:00
Cameron Bates 45f68d59ff iOS Keyboard Support (#347)
PR adds in support for iOS keyboards using GCKeyboard
2021-09-11 13:08:35 +02:00
Flyinghead 1762987aae reios: reset gdrom state at reset
Fixes "Reboot to BIOS" exception when loading another game
2021-09-11 11:22:58 +02:00
Flyinghead ad2e142b01 ui: Show mouse cursor when emu throws an exception. lr: fix vulkan init 2021-09-10 15:32:13 +02:00
Flyinghead 88fa5d5c41 arm64 dsp: don't JitWriteProtect twice. ios: Hide VSync. pvr: fix mutex 2021-09-10 15:26:18 +02:00
Flyinghead e45ec4324f Merge remote-tracking branch 'origin/master' into libretro 2021-09-10 12:19:29 +02:00
Flyinghead d9a8e29a94 missing change 2021-09-09 18:31:08 +02:00
Flyinghead 3ced57a263 network: use interface for startup. avoid deadlock on exit
Use common interface for naomi and ggpo
Simpler ggpo interface
Fix deadlocks on exit with ggpo
2021-09-09 18:17:05 +02:00
Flyinghead 458868a634 ggpo: always save delta ram. Disable ff,cheats,savestates when online
ggpo: always save delta ram on save_game_state as frames may be rerun
and resaved
Global network online status (ggpo, naomi, modem, bba)
Disable fast forward, cheats and savestates when online.
2021-09-08 17:18:01 +02:00
Flyinghead 7ecc0543f4 ggpo: fix common assert() sync.cpp:238 2021-09-08 16:21:54 +02:00
Flyinghead 6d6f3d38d4 libretro build fix 2021-09-07 17:18:56 +02:00
Flyinghead a4e715fa71 serialize modem, aw coin, pvr direct fb state, TA cur context 2021-09-07 16:43:50 +02:00
Flyinghead 8594d11693 maple: refactor usage of rt/lt. zero out joystick values if ggpo active
Fix mouse cursor being invisible when emu throws an exception
2021-09-07 16:30:56 +02:00
Flyinghead a4c14ebef7 Merge remote-tracking branch 'origin/libretro' into net-rollback 2021-09-07 15:02:39 +02:00
Flyinghead 599874c9c1 dx9: VSync option support 2021-09-07 14:16:05 +02:00
Flyinghead 5121b0df93 maple: mutually exclusive btns per controller. better D2A axes
Handle mutually exclusive buttons (U/D, L/R) in each controller.
Track digital X/Y axes state to allow for proper handling of U+D and
L+R. Issue #334
SDL: Ignore key repeat events
2021-09-07 10:54:00 +02:00
Flyinghead e3a2f1cfbe ggpo: transmit RT and LT as digital inputs 2021-09-06 17:16:41 +02:00
Flyinghead 414fb9dba2 ramwatch: protect all ram, not just the bottom half 2021-09-06 16:14:38 +02:00
Flyinghead a402c69c55 ggpo: detect frame rate and use it to pause when ahead 2021-09-05 20:47:37 +02:00
Flyinghead c007165a0f input: naomi btns 5/6 and 7/8 shouldn't be mutually exclusive 2021-09-05 20:12:40 +02:00
Flyinghead a3d50fc197 Merge remote-tracking branch 'origin/libretro' into net-rollback 2021-09-05 20:07:37 +02:00
flyinghead baa0ac44ca paypalme link 2021-09-05 17:30:26 +02:00
Flyinghead 6768901446 allow semicolon in content paths 2021-09-05 10:30:19 +02:00
Flyinghead 35e77976a6 ui: use input from all keyboards
Issue #339
2021-09-05 10:29:12 +02:00
Enrique Santos dba805e8c4 ggpo: static rtc when ggpo is enabled 2021-09-04 18:47:34 +02:00
Enrique Santos e3aca85efd ggpo: add frame delay to settings (#343) 2021-09-04 18:47:21 +02:00
Flyinghead f35a18bb63 ggpo: use bargraphs for net stats 2021-09-04 12:03:29 +02:00
flyinghead a6ad0208db uTip link 2021-09-03 23:54:40 +02:00
Flyinghead e02ccbf32a gl: update fog and texture palette in Process() 2021-09-03 11:12:47 +02:00
Flyinghead b362a55c04 ggpo: rollback glitches. win32 init. switch build. stats
Block net rollbacks until the current frame has been processed to avoid
glitched textures.
Call WSAStartup at init on windows
Display net stats when in game
Switch build fix
2021-09-03 11:11:46 +02:00
Flyinghead 69d0801121 net rollback with ggpo 2021-09-02 17:51:23 +02:00
flyinghead f85bca06d7 dsp: rec crash on windows 2021-09-02 12:34:38 +02:00
scribam 3589e94121 android: update com.android.tools.build:gradle to version 7.0.1 2021-08-31 17:52:51 +02:00
Flyinghead 2baf2cfed6 ci: always install dx2010 2021-08-30 12:13:52 +02:00
Flyinghead 4d5c93adfa ios: add entitlements and sign IPA with ldid 2021-08-29 11:58:05 +02:00
Flyinghead 93eff7fac6 sh4: fix TMU regression
introduced by 05d51cc35c
fixes SA2 running too fast
2021-08-29 11:55:42 +02:00
scribam ce68a9c708 ci: update switch workflow
Checkout submodules non-recursively
Add ninja to speed up compilation
Simplify some steps
2021-08-29 10:45:47 +02:00
scribam 280dad1c07 ci: update android workflow
Checkout submodules non-recursively
Add ccache to speed up compilation
Use ninja and specify target to build only dump_syms
Use official aws-actions/configure-aws-credentials action and awscli to upload artifacts to s3 bucket
2021-08-29 10:45:47 +02:00
Flyinghead c3d954263b gdrom: fix soft reset. ignore slave requests. Unknown ATA cmds handling
Retain currently inserted disk during soft reset
Correct DriveSelect value. Ignore slave drive commands and return 0
status.
Properly handle unknown ATA commands.
Fixes DreamShell boot and CDI boot from BIOS
2021-08-27 18:29:41 +02:00
Flyinghead e058ba5d3b sh4: always perform hard-reset of sh4 and its registers
Fixes infinite loop after reboot
2021-08-27 18:20:40 +02:00
Flyinghead 05d51cc35c sh4: timer underflow lost if TCOR is 0 or very small
Fixes DreamShell boot
2021-08-27 17:55:50 +02:00
vkedwardli a51f310e96 Add volume slider in audio settings (#329)
Use logarithmic volume scale
2021-08-26 13:30:23 +02:00
Flyinghead 89ccdf2814 rend: better fix to force even width rendering 2021-08-26 13:28:13 +02:00
Flyinghead 52af352fcd input: never load mapping file for !remappable controllers
Fixes android on-screen gamepad not working when a (wrong) mapping file
exists for it.

Issue #325
Issue #330
2021-08-26 13:25:18 +02:00
Flyinghead 088287227e x64 msvc build fix 2021-08-26 11:01:44 +02:00
Flyinghead ad1f9527c1 x86 msvc build fix 2021-08-26 10:34:01 +02:00
Flyinghead ca17717af7 dsp: map TEMP/MEMS/MIXS regs to sh4 and aica address space. Clean up 2021-08-26 10:16:07 +02:00
Flyinghead 2a849ccba5 ui: hide dirs on iOS. Fix home on android. force even width rendering
Hide content and home dirs on iOS
Show home dir and allow change on android
Force even width for rendering resolution
2021-08-26 10:08:50 +02:00
Flyinghead 4bf20846bc iOS: output audio to speakers, not the receiver 2021-08-26 10:02:38 +02:00
Flyinghead ad80184e7f missing cmake change 2021-08-24 20:54:17 +02:00
Flyinghead e5ca63db20 aica: arm32 dsp dynarec. Correct dsp level when dsp disabled 2021-08-24 20:49:53 +02:00
vkedwardli 7a33ae35e0 [macOS] Fix DelayFrameSwapping and optimise Vsync logic (#307)
* Support macOS 10.15 and 11
* Enable VSync option on macOS. Use "swapOnVSync" logic from other wsi
* Limit `mainui_rend_frame()` to 5 iterations max: 4 renders and the final swap
2021-08-24 11:43:19 +02:00
Flyinghead ce58ba3472 pvr: detect swap on FB_R_SOF2 too. Force render res. to even width
Fixes Soul Calibur FPS /2 drop with Delay Frame Swapping on
2021-08-24 11:40:53 +02:00
Flyinghead 43ae2ea5f5 macOS: upgrade SDL to 2.0.16
fixes Xbox series X controller support
2021-08-23 17:56:40 +02:00
Flyinghead 2f03922b43 build fix 2021-08-23 14:25:27 +02:00
Flyinghead 5db2856270 missing changes from previous commit 2021-08-23 14:16:52 +02:00
Flyinghead e3e3229612 iOS: multiple controller/rumble support. GL: fix black screen after RTT
iOS:
* multiple controllers support. Rumble support.
* fix audio recording
* declare CHD/GDI/CUE/CDI content types
* start game when opening file URL
* Use safe area for UI and virtual gamepad
* Better icons
2021-08-23 14:02:12 +02:00
Flyinghead 8b2ed736a6 libretro: fix random shutdown when saving/loading state
Issue #326
2021-08-23 11:29:17 +02:00
Flyinghead 27da5f84c4 cmake: fix miniupnpc name warning
Issue #302
2021-08-23 10:23:04 +02:00
Flyinghead 98d04702ae sdl: set vsync swap interval to 2 for 120 Hz displays
Issue #293
2021-08-23 10:11:04 +02:00
Flyinghead a0664a49d2 ci: install awscli 2021-08-22 21:21:32 +02:00
Flyinghead 55fb0a6efb ci: fix switch s3 upload 2021-08-22 21:00:58 +02:00
Flyinghead 7fb83f4f77 libretro: fix content closing when loading or saving state 2021-08-22 20:41:02 +02:00
scribam 3006cd4f60 .cirrus.yml: update to freebsd-13-0 2021-08-22 11:44:34 +02:00
Flyinghead 970f8c6dcd upload iOS and switch builds to S3 2021-08-20 19:57:20 +02:00
Flyinghead c99de2370f build fix 2021-08-20 08:39:37 +02:00
Flyinghead 8c9ff4a66f iOS: DSP fix 2021-08-20 08:32:29 +02:00
Flyinghead 42eeddcbfb iOS: on-screen gamepad layout fix 2021-08-17 10:13:30 +02:00
Flyinghead 8b0f17fb25 iOS: bundle_version must not be null. Add Document Browser support 2021-08-16 13:09:53 +02:00
Flyinghead a3900495d5 iOS: map menu button to Options, start to Menu. Analog triggers 2021-08-16 11:46:45 +02:00
Flyinghead d7bc1f0f77 apple: disable delay frame swapping, libretro: set base_width/height to 640x480, use gl 3.2 on macOS 2021-08-15 10:50:53 +02:00
scribam 281a04837f switch: simplify standalone build 2021-08-13 08:31:32 +02:00
Flyinghead 3ea688be69 iOS: pause/resume based on focus. autosave state on background. VGamepad fix
Get rid of swipe gesture (fixes touch not being delivered)
Use UP+DOWN or LEFT+RIGHT to open menu.
Arcade shortcuts (RT + A/B/X)
Disable system gestures
Monitor network and restart AltKit as needed.
2021-08-12 11:22:22 +02:00
Flyinghead c27180fb32 android: fix navbar background. Add shortcuts for Coin/Service/Test
Fix black navigation bar background.
Shortcuts for virtual gamepad:
RT + A -> D (Coint)
RT + B -> C (Service)
RT + X -> Z (Test)
Issue #137

Don't deliver mouse clicks if analog triggers or stick are used
2021-08-11 12:58:57 +02:00
Flyinghead 1bea7853ef iOS: CI job, JIT status, touch fixes 2021-08-10 17:04:36 +02:00
Flyinghead 104521517c Build fix 2021-08-10 12:00:05 +02:00
Flyinghead bb217e5c49 iOS: AltKit source 2021-08-10 11:34:11 +02:00
Flyinghead 12f302d356 iOS: uv need high precision in fragment shader. cmake build. virtual joystick. AltKit integration 2021-08-10 11:32:22 +02:00
Edward Li 6f233462c1 Add missing JITWriteProtect to DSP 2021-08-09 09:02:59 +02:00
Flyinghead 77e7c25e9c iOS support. Work in progress 2021-08-06 10:30:30 +02:00
Flyinghead b027a6b9a1 android: add missing oboe lib links 2021-08-05 22:06:32 +02:00
Flyinghead 6bb4575c95 Merge remote-tracking branch 'origin/master' into libretro 2021-08-05 18:17:30 +02:00
Flyinghead 37eace9db4 osx: lockup when emulator aborts. Race condition when starting emu 2021-08-05 17:43:26 +02:00
Flyinghead 0414406471 win32 build fix. disable breakpad on BSD 2021-08-03 11:59:19 +02:00
Flyinghead 8c000f327e missing include 2021-08-03 10:08:13 +02:00
Flyinghead 951e70328f Use exception when load content fails. ui: graceful stop on fatal error
libretro: catch/detect fatal errors and shutdown
2021-08-03 10:05:09 +02:00
Flyinghead 2dd7717128 glGetString(GL_EXTENSIONS) may return null in core contexts
xcode project missing update
2021-08-03 09:49:20 +02:00
Flyinghead 9d6c548730 naomi: close cart on reset. sh4: replace some verify by throw
Close naomi/aw cart on reset. Reset input mapping/button names
Get rid of ngen_GetFeatures()
throw exception instead of failing verify if not internal error
catch sh4 exceptions in dynarecs and throw fatal error
2021-08-03 09:47:13 +02:00
Flyinghead 8a46853dfd lr: deadlock on exit with custom textures (win32)
less log
2021-08-02 12:07:40 +02:00
Flyinghead 789fd21bb7 bsd build fix 2021-08-02 12:05:24 +02:00
Flyinghead 3fa97b5ce7 bsd build fix 2021-08-02 10:20:45 +02:00
Flyinghead c8ebbc657a x86 win32 build fix 2021-08-02 10:09:19 +02:00
Flyinghead b59585437c arm32 dynarec: windows ce support 2021-08-01 17:25:48 +02:00
Flyinghead 6f4e1365b1 x86: stack unwind fixes 2021-08-01 17:07:17 +02:00
scribam fcef404f50 android: update gradle and dependencies 2021-07-30 19:35:07 +02:00
Flyinghead aabb492d01 x86 stack unwinding support (android) 2021-07-30 19:13:52 +02:00
Flyinghead cfa21934bb x64: fix stack unwinding issue. don't save xmm regs on stack 2021-07-30 19:10:34 +02:00
Flyinghead 7561ce753a unwind info for arm64. use static c++ lib for android
include oboe static libs
get rid of old regalloc
2021-07-29 17:46:46 +02:00
Flyinghead 5ac0e58886 android: mouse move events missing when btn down. Mouse wheel support
Issue #304
2021-07-27 10:32:22 +02:00
vkedwardli a14fc35e47 Support Fast Forward in macOS (#303) 2021-07-26 20:36:14 +02:00
Flyinghead 5fd00e3063 specify RelWithDebInfo output dir 2021-07-26 00:13:05 +02:00
Flyinghead a46a012c3c tentative fix against .NET stupidity 2021-07-25 22:42:05 +02:00
Flyinghead 3072105efe github: don't upload symbols for linux 2021-07-25 22:27:17 +02:00
Flyinghead 8f09ac2611 github: don't parameterize shell 2021-07-25 22:22:08 +02:00
Flyinghead e12be7cf29 add breakpad support for android, linux and windown 2021-07-25 21:55:29 +02:00
flyinghead 588d79641a msvc x64 build fix 2021-07-25 11:47:14 +02:00
Flyinghead daac6de533 macos build fix 2021-07-24 23:30:12 +02:00
flyinghead c6d7307efe x86 build fix 2021-07-24 23:17:27 +02:00
Flyinghead 710f379bd3 unwind info for x64 dynarecs
delegate to previous signal handler, proper abort for win32
arm32: use builtin gcc __clear_cache
dyna/driver.cpp: no need for a code buffer in win32, cleanup
2021-07-24 22:24:37 +02:00
vkedwardli e4d9be86b4 Fix cmake macOS ARM not building (#301)
set `CMAKE_OSX_ARCHITECTURES` as Cache Entry
2021-07-24 15:52:56 +02:00
vkedwardli 3c483c61e7 Support Apple Silicon (macOS ARM Universal Binary) (#253)
* Add audio arm64 cpp into Xcode project

* Build universal binary for SDL2 also

* Add vixl aarch64 dependency + build arm64 in cmake

* hardcode pagesize for M1 CPU

* Use `MAP_JIT` and toggle between RX and RW

* add pthread.h for cmake

* Disable audio dynarec temporary

* Enable aica arm dynarec

* Supports `br` with condition

* Dynamic linker flag for libSDL2.a since Homebrew path is different on arm (for xcodeproj)

* Fallback path for Intel

* de-dup for arm64, allow cross compilation on both Intel and Apple Silicon Mac

* Rename WriteProtect() to JITWriteProtect(), Move JITWriteProtect from arm7_rec to arm7_rec_arm64

* Remove CodeCache memset

* Remove keyboard_device.cpp from xcodeproj

* Use hard tab

* Update libchdr to support compiling on M1 (thanks @scribam)
2021-07-23 22:34:12 +02:00
Flyinghead c453d14352 libretro: better error handling. fix reset issue with rotated games
compilation warnings, clean up
2021-07-21 16:19:57 +02:00
Flyinghead de060d66ab don't save flash if no game started. libretro: fix notifications
compilation warnings, non-functional changes
2021-07-20 19:21:11 +02:00
Flyinghead c458a8f5e7 os_[Un]InstallFaultHandler. Uninstall fault handler at shutdown 2021-07-20 13:06:08 +02:00
Flyinghead 4a77f847b4 libretro: fix arcade flash files path. ui: stop spamming dc_stop 2021-07-20 10:06:44 +02:00
Flyinghead edc6474f27 save nvmem/flash files when stopping emu 2021-07-19 18:20:58 +02:00
Flyinghead 117f47e3a2 rend: shader builder utility 2021-07-19 12:49:47 +02:00
Flyinghead 4f11ff76a5 input: don't toggle fastforward when game isn't running
it resets the vulkan swapchain and causes random crashes
2021-07-19 12:10:14 +02:00
Flyinghead 10e97b63be jvs: no default mapping if button is remapped to P1 or P2
fixes jambo down-lever pausing the game
2021-07-19 10:15:24 +02:00
Flyinghead af76a09e03 gl: repeat % operator for printf. remove Switch special case 2021-07-18 18:15:35 +02:00
scribam 147bd8341d android: update compileSdkVersion/targetSdkVersion to version 29 2021-07-17 19:35:14 +02:00
scribam 5c0dd67094 android: cleanup jni files 2021-07-17 19:35:14 +02:00
scribam 49688d6523 android: migrate to androidx 2021-07-17 19:35:14 +02:00
scribam 850f23be82 android: update project files 2021-07-17 19:35:14 +02:00
Flyinghead 9e5769912b gl: workaround nouveau bug (oit). Use float palette coords for switch
Don't switch render type before terminating current one.
2021-07-17 15:53:47 +02:00
Flyinghead ab50bc9936 libretro: VGA cable option shown twice. fix arcade/dc option visibility 2021-07-16 17:41:40 +02:00
Flyinghead a604a3904f win: make sure not to call VirtualAlloc with null during jit alloc 2021-07-16 17:35:29 +02:00
Flyinghead e112f2d8af gl: GLES2 build compatibility 2021-07-15 19:24:56 +02:00
Flyinghead 376d2e1433 libretro: fix keyboard input 2021-07-15 18:44:57 +02:00
Flyinghead ed0caa119a Merge remote-tracking branch 'origin/master' into libretro
# Conflicts:
#	CMakeLists.txt
2021-07-15 18:43:29 +02:00
Flyinghead f768146d8e switch: unneeded init functions. needed exit one 2021-07-15 16:50:54 +02:00
Flyinghead 412083d9ea libretro: blank vmus at unload/reset 2021-07-15 15:43:10 +02:00
Flyinghead 07cdb42ff7 switch: set UI scaling factor depending on docking mode 2021-07-15 14:44:39 +02:00
Flyinghead 1e37e8f333 switch: dsp dynarec fix 2021-07-15 12:24:42 +02:00
Flyinghead 4fa89c4a45 switch: build with miniupnp. set correct window size
organize header
remove unneeded switch-specific code
2021-07-15 12:19:11 +02:00
Flyinghead 0d7a2128b6 libretro: fix 32-bit arm build. delete useless #def in pvr2 filter 2021-07-15 12:06:04 +02:00
scribam 9aa3d8b987 android: do not filter abi, allow x86_64 build 2021-07-15 09:54:41 +02:00
scribam eaf44bc18c android: generate release apk with debug keystore, update ci and gradle 2021-07-15 09:54:41 +02:00
Flyinghead ae33c8de18 sdl: increase audio buffer size. libretro: set PIC option 2021-07-15 00:26:00 +02:00
Flyinghead b12e82c344 libretro: add switch lib as artifact 2021-07-14 22:00:05 +02:00
Flyinghead 8dee648d01 arm64 rec: put ngen_FailedToFindBlock at a fixed address
transitioning to MMU will fail it this function's address changes
happens if vmem is disabled (switch)
2021-07-14 21:03:02 +02:00
Flyinghead 8e6dc54b16 switch: add .. entry to folder chooser. start at / 2021-07-14 20:55:22 +02:00
Flyinghead db9c48b085 switch: typo 2021-07-14 17:48:41 +02:00
Flyinghead c0171f5fd1 switch: open sdl joysticks 0 & 1 at init 2021-07-14 17:22:17 +02:00
Flyinghead 9a5a55d074 switch: use /flycast as config folder 2021-07-14 16:38:12 +02:00
Flyinghead 855836d9aa switch: arm rec EntryPoints need rx. fix arm & dsp cache flush 2021-07-14 14:57:43 +02:00
Flyinghead 8a0a0bcdfc switch: use 256x256 jpeg as app icon 2021-07-14 13:57:40 +02:00
Flyinghead 43c00568c6 switch: standalone build 2021-07-14 13:02:57 +02:00
Flyinghead 31be731de0 input: fix atomiswave keyboard bindings 2021-07-14 09:42:13 +02:00
Flyinghead 113ef66e26 libretro: use HAVE_LIBNX in libretro-common 2021-07-13 21:06:03 +02:00
Flyinghead 4d38e69f63 lr switch: enable aica arm and dsp dynarecs. handle rw/rx offset 2021-07-13 20:51:17 +02:00
Flyinghead 8c02345dfd lr switch: use toolchain ar. really disable lto 2021-07-13 19:18:36 +02:00
Flyinghead a2efde1103 libretro: more switch fixes
combine all static libraries into one
save/restore gl state in !threaded mode
patch libchdr
build fixes
2021-07-13 18:51:40 +02:00
Flyinghead eb81583d9f sh4 dyna: support for !vmem 2021-07-13 17:09:26 +02:00
Flyinghead 44213bf830 lr: fix res change for rotated games. display version. vmem: simplify 2021-07-13 13:45:01 +02:00
scribam f187f77e3d Add basic GitHub Actions for Libretro Nintendo Switch 2021-07-12 22:22:07 +02:00
Flyinghead 63a3f02368 libretro: better switch support 2021-07-12 20:14:21 +02:00
Flyinghead 994e6826b4 libretro: option changes (resolution, widescreen, rotation)
Use RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO or
RETRO_ENVIRONMENT_SET_GEOMETRY to report resolution/aspect ratio
changes.
Handle rotation without restarting.
2021-07-12 09:57:58 +02:00
Flyinghead 97991fd8fc gl: delete libretro vmu and crosshair textures when terminating 2021-07-11 20:43:04 +02:00
Flyinghead 1fdda98d8d libretro: return max savestate size. unprotect ram and vram on reset
fixes random crash when saving state
2021-07-11 17:42:30 +02:00
Flyinghead a73ca94124 savestate: push vmu lcd image when loading 2021-07-11 12:37:21 +02:00
Flyinghead 82d2aa8a47 savestate: fix test 2021-07-10 19:30:13 +02:00
Flyinghead 75af07331a savestate: save gdrom read buffer. other fixes
Issue #294
2021-07-10 19:16:19 +02:00
Flyinghead 4be4ad07f3 libretro: m3u playlists 2021-07-10 18:00:21 +02:00
Flyinghead 57874a9bcb libretro: savestate compatibility. B1/D1 vmus now visible 2021-07-10 17:39:16 +02:00
Flyinghead ec7968b2f4 libretro: Reset. Reso not applied (vk). xhair always displayed (vk).
Fix Content Reset crash
Render resolution not set at startup with vulkan !threaded
vk: Crosshair always displayed (white) even when off
Better handling of multiple render (rend_single_frame returns false)
2021-07-09 18:17:14 +02:00
Flyinghead 81546fe727 libretro: handle ThreadedRendering transition. Fix hang in !threaded 2021-07-09 16:28:28 +02:00
Flyinghead 7948bac6ba libretro: fix per-game VMU A1 option 2021-07-09 16:23:46 +02:00
Flyinghead eceb5ba982 naomi: keyboard needs player number 2021-07-09 14:34:11 +02:00
Flyinghead 345dab9633 libretro: fix nvidia palette issue. request 3.2 to get a core gl ctx 2021-07-09 13:10:30 +02:00
Flyinghead 5c952021b7 libretro: vmu and crosshair display. lightgun fixes 2021-07-08 20:09:09 +02:00
Flyinghead 80a5b44fe9 enable vulkan in lr ci builds 2021-07-08 12:52:00 +02:00
Flyinghead b66e6560ca libretro: vulkan support 2021-07-08 12:47:00 +02:00
Flyinghead 673c2988d6 libretro: backport libnx support. Fix log source paths 2021-07-07 19:01:37 +02:00
Flyinghead 042f2e0224 custom textures: saturate colors when dumping RGBA4444 and RGBA5551 2021-07-07 17:19:13 +02:00
Flyinghead b300bb9f7a libretro: non-threaded rendering 2021-07-07 13:12:16 +02:00
Flyinghead 205f2690d6 gl4: delete fog & palette textures when terminating
fixes fullscreen toggle screen corruption
2021-07-07 10:54:10 +02:00
scribam aeea301ee3 Minor include header changes 2021-07-07 10:37:11 +02:00
Flyinghead 8e6bbed74f libretro: aw coin fix. screen rotation. disable loading notifications 2021-07-07 09:48:10 +02:00
flyinghead ef506d49aa libretro: pvr2 postprocessing filter 2021-07-06 21:37:47 +02:00
flyinghead c205a888a9 options: anisotropic filtering, oit pixel buffer size, fast gdrom load 2021-07-06 16:19:12 +02:00
flyinghead a3b66aec1f libretro: win32 support. build fix. 2021-07-06 13:22:54 +02:00
Flyinghead 68f4c50bd3 missing change 2021-07-05 19:48:49 +02:00
Flyinghead 7dbd79750c WIP libretro core update 2021-07-05 19:44:08 +02:00
Flyinghead fd301186c7 android: avoid duplicates in controllers list 2021-07-05 19:26:57 +02:00
Flyinghead b40328e621 input: don't change mapper if file not found. sdl: fix default bindings 2021-07-05 09:59:46 +02:00
flyinghead 7cd832e914 input: use default mapping if no mapping file is found 2021-07-04 23:27:29 +02:00
flyinghead 44feea4c01 Merge pull request #288 from flyinghead/fh/directx
DirectX9 renderer
2021-07-04 18:35:19 +02:00
flyinghead c5ce475359 Merge remote-tracking branch 'origin/master' into fh/directx
# Conflicts:
#	core/input/gamepad_device.cpp
2021-07-04 17:53:49 +02:00
flyinghead 894a0540b9 sdl: convert keyboard mapping from keycodes to scancode on first load 2021-07-04 17:45:45 +02:00
flyinghead 967f4570ed rawinput: simplify USB device names 2021-07-04 15:51:33 +02:00
Flyinghead 14360beaf7 gdrom: reset registers and state on reset
Issue #281
2021-06-27 12:53:54 +02:00
Enrique Santos 46e3258629 Controller Mapping: System Profiles & Unmap Button (#269)
* add unmap button
* separate controller profiles for dc & arcade games
* loads current system mapping on menu exit
* simplify, use default filename for dc controls
* create blank mapping file for sdl controllers if not found
2021-06-27 12:49:47 +02:00
Flyinghead b3ad0a62c1 gl: fix multiple rendering with GLES 2
fixes split-screen multiplayer for SW1 Racer, Q3, Re-volt
2021-06-19 10:48:32 +02:00
scribam a5edd9c7ff deps: remove crypto folder (unused) 2021-06-19 10:46:22 +02:00
Flyinghead 7f49accc22 Merge remote-tracking branch 'origin/master' into fh/directx 2021-06-07 20:53:31 +02:00
Flyinghead b8c2a695b8 ui: allow drag scrolling anywhere. change some ui elements
allow scrolling by dragging (almost) anywhere
move physical devices before dreamcast ones
hide insets when displaying full screen window
reduce scroll bar size on android
fix controller mapping column sizes
2021-06-07 12:18:05 +02:00
Flyinghead c73bbc85bd savestate: rzip size must be 64-bit on all platforms 2021-06-06 11:18:42 +02:00
scribam d6545b253b Misc cleanup 2021-06-06 11:15:06 +02:00
Flyinghead 293761bdf5 gui: separate auto-load and auto-save options. Fix tool tips on android 2021-06-04 11:11:23 +02:00
scribam d862453956 github actions: authorize aws actions on main repository only 2021-06-04 11:08:30 +02:00
Flyinghead 58974c9305 savestate slots 2021-06-03 13:50:40 +02:00
keita yoshimoto cddb6609f1 Multiple save states (#248) 2021-06-03 13:22:40 +02:00
scribam 4a9c51a6c8 github actions: remove flac installation from macos 2021-05-31 23:24:43 +02:00
scribam 329ae11d2f Remove snap configuration file 2021-05-31 23:24:33 +02:00
Flyinghead c3bc5cfc3b vk oit: use a 2nd depth attachment for subpass 1
subpass 1 needs writable depth buffer (see
9f60c5e854)
2021-05-30 18:20:04 +02:00
scribam 24f9003cd3 cirrus ci: add ccache support 2021-05-29 14:32:06 +02:00
scribam 4c2bf59c46 github actions: extend cache for Android build 2021-05-29 14:32:06 +02:00
scribam 642a89733b ci: remove flac package 2021-05-29 14:13:05 +02:00
scribam 2b3d9427e1 .cirrus.yml: use CIRRUS_CLONE_SUBMODULES to checkout submodules 2021-05-29 14:12:51 +02:00
scribam 6368241b77 cmake: fix compilation on FreeBSD 2021-05-29 14:12:51 +02:00
scribam 57ae9022dd Update Windows resource and version.h.in files 2021-05-28 14:56:04 +02:00
flyinghead 7ed68952ba Merge remote-tracking branch 'origin/master' into fh/directx
# Conflicts:
#	core/deps/patches/SDL.patch
#	core/hw/maple/maple_devs.cpp
#	core/rend/gl4/gles.cpp
#	core/rend/gles/gles.cpp
#	core/rend/gui.cpp
#	core/rend/gui.h
#	shell/apple/emulator-osx/reicast-osx.xcodeproj/project.pbxproj
2021-05-26 22:38:48 +02:00
flyinghead 4696733eb4 dx9: linear filtering for fog texture. swap only when frame rendered 2021-05-26 21:40:43 +02:00
flyinghead 5f5d31730c sdl: hide mouse in fullscreen. fix & refactor mouse devices
support rawinput mouse wheel
simplify mapping load
2021-05-19 18:13:52 +02:00
Flyinghead e07977eea9 mac,x11: propagate win/sdl mouse/keyboard changes 2021-05-10 13:48:12 +02:00
flyinghead 71fb024061 rawinput: proper conversion of abs coordinates
Issue #138
get rid of libPvr_GetRenderTarget() -> getNativeHwnd()
2021-05-04 12:03:09 +02:00
flyinghead 54cfc6e09b build fix for non-windows 2021-04-29 19:15:34 +02:00
Flyinghead 150cfa29e7 Merge remote-tracking branch 'origin/master' into fh/directx 2021-04-29 19:06:38 +02:00
flyinghead b90cdf9588 RawInput driver. Multiple keyboards support
Merge Keyboard and KbGamepad
Always use system mouse for UI
Issue #138

Fix DX9 when not using SDL
2021-04-29 18:58:04 +02:00
flyinghead 6316479930 get rid of unneeded pixel unpacker and use better name 2021-04-29 18:38:58 +02:00
flyinghead f9603dc11a vk: use texture pointers instead of u64 2021-04-17 19:04:00 +02:00
flyinghead 5359e9a09d allow gpu-handled palette textures to be replaced by custom version
Issue #219
Fix incorrect texture size calculation for VQ textures.
Reorder BaseTextureCacheData fields to have hottest on top
2021-04-17 18:40:58 +02:00
flyinghead 28d2c6db73 dx9: rotate 90deg 2021-04-16 21:58:37 +02:00
flyinghead abc8b18b78 dx9: mipmaps. load/dump textures. vmu/crosshair display.
upload all texture mipmaps to gpu
dump textures. load custom textures
vmu and lightgun xhair display
fix dx9 half-pixel offset
fix 565_32 unpacker bug
2021-04-16 18:30:47 +02:00
flyinghead c889bfa6d4 dx9: copy to vram. clipping. fix depth/stencil size. better reset
Coordinate device reset with dxcontext. Keep compiled shaders.
Don't use automatic depth/stencil on backbuffer. Manually handle it.
Implement scissoring/clipping
multipass translucent depth
Render-to-texture copy to vram
2021-04-15 15:17:32 +02:00
flyinghead f2a0098fed build fix 2 2021-04-13 12:22:01 +02:00
flyinghead b549c56b23 build fix. default Delay Frame Swapping to true 2021-04-13 11:20:11 +02:00
flyinghead f107d380b9 WIP directx9 renderer 2021-04-12 22:49:04 +02:00
4668 changed files with 447817 additions and 874189 deletions

No files matched your search

-9
View File
@@ -1,9 +0,0 @@
freebsd_instance:
image_family: freebsd-12-2
task:
install_script: pkg install -y alsa-lib cmake evdev-proto flac git libao libevdev libudev-devd libzip mesa-libs miniupnpc ninja pkgconf png pulseaudio sdl2
script:
- git submodule update --init --recursive
- cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja
- cmake --build build --config Release
+2
View File
@@ -0,0 +1,2 @@
buy_me_a_coffee: hhwtpernwq
custom: ['https://www.paypal.com/paypalme/FlycastEmu']
+41
View File
@@ -0,0 +1,41 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Please Note: This form is the minimum required information for submitting bugs.**
**Removing this form may lead to your issue being closed until it is completed.**
Platform / OS / Hardware:
Flycast version:
Hardware:
**_Description of the Issue_**
Add a short, concise description of the issue here
**_Debugging Steps Tested_**
* Fill in any steps already tried here
* Begin each new line with an asterisk
* If no steps are required, please skip
**_Logs Gathered_**
```
Please paste the contents of the log / logs here
You may leave this field blank if you have none.
```
**_Screenshots_**
(Replace this line with any issue screenshots)
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+88 -31
View File
@@ -8,44 +8,101 @@ jobs:
steps:
- name: Set up build environment
run: echo "y" | sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;20.0.5594570"
run: |
sudo apt-get update
sudo apt-get -y install ccache libcurl4-openssl-dev ninja-build
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- uses: actions/cache@v2
- uses: actions/setup-java@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-
java-version: '17'
distribution: 'temurin'
cache: 'gradle'
- uses: actions/cache@v4
with:
path: ~/.ccache
key: android-ccache-${{ github.sha }}
restore-keys: android-ccache-
- name: Disable release signing
run: sed -i 's/signingConfig signingConfigs.release/signingConfig signingConfigs.debug/g' shell/android-studio/flycast/build.gradle
if: github.repository != 'flyinghead/flycast' || github.event_name != 'push'
- name: Bump version code
uses: chkfung/[email protected]
with:
gradlePath: shell/android-studio/flycast/build.gradle
versionCode: ${{ github.run_number }}
- name: Gradle
working-directory: shell/android-studio
run: ./gradlew assembleDebug --parallel
- uses: actions/upload-artifact@v2
with:
name: flycast-debug.apk
path: shell/android-studio/flycast/build/outputs/apk/debug/flycast-debug.apk
- name: Set up git vars
run: |
echo GIT_BUILD=`git describe --all --always | sed 's/remotes\/origin/heads/'`-$GITHUB_SHA >> $GITHUB_ENV
- name: Clean up
run: rm -f shell/android-studio/flycast/build/outputs/apk/debug/*.json
- uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --follow-symlinks
run: ./gradlew assembleRelease bundleRelease --parallel
env:
AWS_S3_BUCKET: flycast-builds
AWS_ACCESS_KEY_ID: AKIAJOZQS4H2PHQWYFCA
AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_KEY }}
AWS_REGION: 'us-east-2'
SOURCE_DIR: 'shell/android-studio/flycast/build/outputs/apk/debug/'
DEST_DIR: android/${{ env.GIT_BUILD }}
if: ${{ github.event_name == 'push' }}
SENTRY_UPLOAD_URL: ${{ secrets.SENTRY_UPLOAD_URL }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
- uses: actions/upload-artifact@v4
with:
name: flycast-release.apk
path: shell/android-studio/flycast/build/outputs/apk/release/flycast-release.apk
- name: Build dump_syms
working-directory: core/deps/breakpad
run: |
./configure --prefix=$PWD
make -j2
make install
- name: Extract symbols
run: |
DUMP_SYMS=./core/deps/breakpad/bin/dump_syms
SO_DIR=shell/android-studio/flycast/build/intermediates/merged_native_libs/release/mergeReleaseNativeLibs/out/lib
for arch in arm64-v8a armeabi-v7a x86 x86_64 ; do
$DUMP_SYMS $SO_DIR/$arch/libflycast.so > libflycast.so.sym
BUILD_ID=`head -1 libflycast.so.sym | awk '{ print $4 }'`
mkdir -p symbols/libflycast.so/$BUILD_ID
mv libflycast.so.sym symbols/libflycast.so/$BUILD_ID
done
- name: Configure AWS Credentials
id: aws-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
aws-region: us-east-2
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push'
- name: Upload to S3
run: |
cp shell/android-studio/flycast/build/outputs/bundle/release/*.aab shell/android-studio/flycast/build/outputs/apk/release/
aws s3 sync shell/android-studio/flycast/build/outputs/apk/release s3://flycast-builds/android/${GITHUB_REF#refs/}-$GITHUB_SHA --acl public-read --exclude='*.json' --follow-symlinks
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
- name: Setup Sentry CLI
uses: mathieu-bour/setup-sentry-cli@v2
env:
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
with:
url: https://sentry.io
token: ${{ env.SENTRY_TOKEN }}
organization: flycast
project: minidump
version: 2.21.2
if: ${{ env.SENTRY_TOKEN != '' }}
- name: Upload symbols to Sentry
run: |
VERSION=$(git describe --tags --always)
sentry-cli releases new "$VERSION"
sentry-cli releases set-commits "$VERSION" --auto
sentry-cli debug-files upload symbols
shell: bash
env:
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
if: ${{ env.SENTRY_TOKEN != '' }}
+48
View File
@@ -0,0 +1,48 @@
name: BSD CI
on: [push, pull_request]
jobs:
build:
env:
CCACHE_DIR: ${{ github.workspace }}/.ccache
runs-on: ubuntu-latest
strategy:
matrix:
operating_system: [ freebsd, netbsd, openbsd ]
architecture: [ arm64, x86-64 ]
include:
- operating_system: freebsd
version: '14.1'
pkginstall: sudo pkg install -y alsa-lib ccache cmake evdev-proto git libao libevdev libudev-devd libzip lua54 miniupnpc ninja pkgconf pulseaudio sdl2
- operating_system: netbsd
version: '10.0'
pkginstall: sudo pkgin update && sudo pkgin -y install alsa-lib ccache cmake gcc12 git libao libzip lua54 miniupnpc ninja-build pkgconf pulseaudio SDL2 && export PATH=/usr/pkg/gcc12/bin:$PATH
- operating_system: openbsd
version: '7.5'
pkginstall: sudo pkg_add ccache cmake git libao libzip miniupnpc ninja pkgconf pulseaudio sdl2
exclude:
- architecture: arm64
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
- uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-${{ matrix.operating_system }}-${{ matrix.architecture }}-${{ github.sha }}
restore-keys: ccache-${{ matrix.operating_system }}-${{ matrix.architecture }}-
- uses: cross-platform-actions/[email protected]
with:
operating_system: ${{ matrix.operating_system }}
architecture: ${{ matrix.architecture }}
version: ${{ matrix.version }}
environment_variables: CCACHE_DIR
run: |
${{ matrix.pkginstall }}
cmake -B build -DCMAKE_BUILD_TYPE=Release -G Ninja
cmake --build build --config Release
+131 -52
View File
@@ -7,97 +7,176 @@ jobs:
name: ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
defaults:
run:
shell: ${{ matrix.config.shell }}
env:
CCACHE_DIR: ${{ github.workspace }}/.ccache
strategy:
matrix:
config:
- {name: i686-pc-windows-msvc, os: windows-latest, cmakeArgs: -DCMAKE_SYSTEM_VERSION="10.0.18362.0" -G "Visual Studio 16 2019" -A Win32}
- {name: x86_64-apple-darwin, os: macos-latest, cmakeArgs: -G "Xcode", destDir: osx}
- {name: x86_64-pc-linux-gnu, os: ubuntu-latest}
- {name: x86_64-pc-windows-msvc, os: windows-latest, cmakeArgs: -DCMAKE_SYSTEM_VERSION="10.0.18362.0" -G "Visual Studio 16 2019" -A x64}
- {name: x86_64-w64-mingw32, os: windows-latest, cmakeArgs: -G "MinGW Makefiles", destDir: win}
- {name: i686-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x86, cmakeArgs: -G Ninja, buildType: Release}
- {name: apple-darwin, os: macos-latest, shell: sh, cmakeArgs: -G Xcode -DUSE_DISCORD=ON, destDir: osx, buildType: RelWithDebInfo}
- {name: apple-ios, os: macos-latest, shell: sh, cmakeArgs: -DCMAKE_SYSTEM_NAME=iOS -G Xcode, destDir: ios, buildType: Release}
- {name: x86_64-pc-linux-gnu, os: ubuntu-20.04, shell: sh, cmakeArgs: -G Ninja -DUSE_DISCORD=ON, destDir: linux, buildType: RelWithDebInfo}
- {name: x86_64-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x64, cmakeArgs: -G Ninja -DUSE_DISCORD=ON, buildType: Release}
- {name: x86_64-w64-mingw32, os: windows-latest, shell: 'msys2 {0}', cmakeArgs: -G Ninja -DUSE_DISCORD=ON, destDir: win, buildType: RelWithDebInfo}
- {name: libretro-x86_64-pc-linux-gnu, os: ubuntu-latest, shell: sh, cmakeArgs: -DLIBRETRO=ON -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -G Ninja, buildType: Release}
- {name: libretro-x86_64-w64-mingw32, os: windows-latest, shell: 'msys2 {0}', cmakeArgs: -DLIBRETRO=ON -G Ninja, buildType: Release}
steps:
- name: Set up build environment (macos-latest)
- name: Set up build environment (macOS)
run: |
brew install ccache flac libao libomp pulseaudio zlib
echo "/usr/local/opt/ccache/libexec" >> $GITHUB_PATH
echo "CCACHE_DIR=/tmp/ccache" >> $GITHUB_ENV
if: matrix.config.os == 'macos-latest'
# Unlink and re-link to prevent errors when github mac runner images install python outside of brew. See https://github.com/actions/setup-python/issues/577
brew list -1 | grep python | while read formula; do brew unlink $formula; brew link --overwrite $formula; done
brew update || :
brew install libao ldid ninja pulseaudio
brew uninstall --ignore-dependencies zstd
VULKAN_VER=1.3.261.1 && aria2c https://sdk.lunarg.com/sdk/download/$VULKAN_VER/mac/vulkansdk-macos-$VULKAN_VER.dmg
hdiutil attach ./vulkansdk-macos-*.dmg -mountpoint /Volumes/VulkanSDK
sudo /Volumes/VulkanSDK/InstallVulkan.app/Contents/MacOS/InstallVulkan --root $HOME/VulkanSDK --accept-licenses --default-answer --confirm-command install
hdiutil detach /Volumes/VulkanSDK
echo "VULKAN_SDK=$HOME/VulkanSDK/macOS" >> $GITHUB_ENV
if: runner.os == 'macOS'
- name: Set up build environment (ubuntu-latest)
- name: Set up build environment (Linux)
run: |
sudo add-apt-repository ppa:christianrauch/libdecoration
sudo apt-get update
sudo apt-get -y install ccache libao-dev libasound2-dev libevdev-dev libflac-dev libgl1-mesa-dev libpulse-dev libsdl2-dev libudev-dev libzip-dev libminiupnpc-dev
echo "CCACHE_DIR=/tmp/ccache" >> $GITHUB_ENV
if: matrix.config.os == 'ubuntu-latest'
sudo apt-get -y install ccache libao-dev libasound2-dev libevdev-dev libgl1-mesa-dev liblua5.3-dev libminiupnpc-dev libpulse-dev libsdl2-dev libudev-dev libzip-dev ninja-build libcurl4-openssl-dev
sudo apt-get -y install libwayland-dev libdecor-0-dev libaudio-dev libjack-dev libsndio-dev libsamplerate0-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libxkbcommon-dev libdrm-dev libgbm-dev libgles2-mesa-dev libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev
if: runner.os == 'Linux'
- uses: actions/cache@v2
- name: Set up build environment (Windows, MinGW)
uses: msys2/setup-msys2@v2
with:
path: /tmp/ccache
key: ccache-${{ matrix.config.os }}-${{ github.sha }}
restore-keys: ccache-${{ matrix.config.os }}-
if: matrix.config.os != 'windows-latest'
msystem: MINGW64
install: git make mingw-w64-x86_64-ccache mingw-w64-x86_64-cmake mingw-w64-x86_64-lua mingw-w64-x86_64-ninja mingw-w64-x86_64-SDL2 mingw-w64-x86_64-toolchain
if: matrix.config.shell == 'msys2 {0}'
- uses: actions/checkout@v2
- name: Set up build environment (Windows, Visual Studio)
run: |
choco install ccache directx-sdk ninja
echo DXSDK_DIR=C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)>> %GITHUB_ENV%
if: matrix.config.shell == 'cmd'
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: ${{ matrix.config.arch }}
if: matrix.config.shell == 'cmd'
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Create artifact directory
run: mkdir -p build/artifact
- name: Compile a universal OpenMP (macOS)
run: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew reinstall --build-from-source --formula ./shell/apple/libomp.rb
if: matrix.config.name == 'apple-darwin'
- name: Build SDL (macos-latest)
run: |
cd shell/apple
mkdir artifacts
brew install --build-from-source ./sdl2.rb
if: matrix.config.os == 'macos-latest'
- name: Compile OpenMP.xcframework (iOS)
run: ./shell/apple/emulator-ios/OpenMP/build_ios_openmp.sh --disableSimulator
if: matrix.config.name == 'apple-ios'
- uses: actions/cache@v4
with:
path: ${{ env.CCACHE_DIR }}
key: ccache-${{ matrix.config.name }}-${{ github.sha }}
restore-keys: ccache-${{ matrix.config.name }}-
if: runner.os != 'macOS'
- name: CMake
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=artifact ${{ matrix.config.cmakeArgs }}
cmake --build build --config Release --parallel 2
cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.buildType }} -DCMAKE_INSTALL_PREFIX=artifact ${{ matrix.config.cmakeArgs }} -DSENTRY_UPLOAD_URL=${{ env.SENTRY_UPLOAD_URL }}
cmake --build build --config ${{ matrix.config.buildType }} --target install
env:
SENTRY_UPLOAD_URL: ${{ secrets.SENTRY_UPLOAD_URL }}
- name: Unit Tests
run: |
mkdir -p build/tests
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=tests -DENABLE_CTEST=ON ${{ matrix.config.cmakeArgs }}
cmake --build build --config Release --parallel 2
./build/tests/flycast
cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.buildType }} -DCMAKE_INSTALL_PREFIX=artifact -DENABLE_CTEST=ON ${{ matrix.config.cmakeArgs }}
cmake --build build --config ${{ matrix.config.buildType }}
./build/flycast
if: matrix.config.name == 'x86_64-pc-linux-gnu'
- uses: actions/upload-artifact@v2
- name: Dump symbols
run: |
mkdir -p symbols
core/deps/breakpad/bin/dump_syms artifact/bin/flycast.exe > symbols/flycast.sym 2>/dev/null
strip artifact/bin/flycast.exe
if: matrix.config.name == 'x86_64-w64-mingw32'
- name: Build breakpad (linux)
working-directory: core/deps/breakpad
run: |
./configure
make
sudo make install
if: matrix.config.name == 'x86_64-pc-linux-gnu'
- name: Dump symbols and make AppImage (linux)
run: |
mkdir -p symbols
dump_syms artifact/bin/flycast > symbols/flycast.sym 2>/dev/null
strip artifact/bin/flycast
shell/linux/make-appimage.sh . artifact/bin appimage
mv flycast-x86_64.AppImage artifact/bin
rm artifact/bin/flycast
if: matrix.config.name == 'x86_64-pc-linux-gnu'
- uses: actions/upload-artifact@v4
with:
name: flycast-${{ matrix.config.name }}
path: build/artifact
path: artifact/bin
- name: Package app (macos)
run: |
cd build/artifact
rm -rf Flycast.swiftmodule
zip -r flycast.app.zip Flycast.app
rm -rf Flycast.app
if: matrix.config.os == 'macos-latest'
cd artifact/bin
zip -rm flycast.app.zip Flycast.app
if: matrix.config.name == 'apple-darwin'
- name: Package app (windows)
run: |
powershell Compress-Archive build/artifact/flycast.exe build/artifact/flycast.zip
rm build/artifact/flycast.exe
powershell Compress-Archive artifact/bin/flycast.exe artifact/bin/flycast.zip
rm artifact/bin/flycast.exe
if: matrix.config.name == 'x86_64-w64-mingw32'
- name: Set up git vars
run: |
echo GIT_BUILD=`git describe --all --always | sed 's/remotes\/origin/heads/'`-$GITHUB_SHA >> $GITHUB_ENV
shell: bash
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
id: aws-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
aws-region: us-east-2
if: github.event_name == 'push'
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push' && matrix.config.destDir != ''
- name: Upload to S3
run: aws s3 sync build/artifact s3://flycast-builds/${{ matrix.config.destDir }}/${{ env.GIT_BUILD }} --acl public-read --follow-symlinks
if: github.event_name == 'push' && matrix.config.destDir != ''
run: aws s3 sync artifact/bin s3://flycast-builds/${{ matrix.config.destDir }}/${GITHUB_REF#refs/}-$GITHUB_SHA --acl public-read --follow-symlinks
shell: bash
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
- name: Setup Sentry CLI
uses: mathieu-bour/setup-sentry-cli@v2
env:
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
with:
url: https://sentry.io
token: ${{ env.SENTRY_TOKEN }}
organization: flycast
project: minidump
version: 2.21.2
if: ${{ env.SENTRY_TOKEN != '' }}
- name: Upload symbols to Sentry (Windows, macOS, Linux)
run: |
VERSION=$(git describe --tags --always)
sentry-cli releases new "$VERSION"
sentry-cli releases set-commits "$VERSION" --auto
sentry-cli debug-files upload symbols
shell: bash
env:
SENTRY_TOKEN: ${{ secrets.SENTRY_TOKEN }}
if: ${{ env.SENTRY_TOKEN != '' && (matrix.config.name == 'x86_64-w64-mingw32' || matrix.config.name == 'apple-darwin' || matrix.config.name == 'x86_64-pc-linux-gnu') }}
+36
View File
@@ -0,0 +1,36 @@
# Prepare source texts & upload them to Crowdin
name: Crowdin Source Texts Upload
# on change to the English texts
on:
push:
branches:
- master
paths:
- 'shell/libretro/libretro_core_options.h'
jobs:
upload_source_file:
runs-on: ubuntu-latest
steps:
- name: Setup Java JDK
uses: actions/setup-java@v4
with:
java-version: 18
distribution: zulu
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Checkout
uses: actions/checkout@v4
- name: Upload Source
shell: bash
env:
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
run: |
python3 intl/upload_workflow.py $CROWDIN_API_KEY "flyinghead-flycast" "shell/libretro/libretro_core_options.h"
+49
View File
@@ -0,0 +1,49 @@
# Download translations form Crowdin & Recreate libretro_core_options_intl.h
name: Crowdin Translation Integration
on:
schedule:
# please choose a random time & weekday to avoid all repos synching at the same time
- cron: '15 22 * * 5' # Fridays at 10:15 PM, UTC
jobs:
create_intl_file:
runs-on: ubuntu-latest
steps:
- name: Setup Java JDK
uses: actions/setup-java@v4
with:
java-version: 18
distribution: zulu
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Create intl file
shell: bash
env:
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
run: |
python3 intl/download_workflow.py $CROWDIN_API_KEY "flyinghead-flycast" "shell/libretro/libretro_core_options_intl.h"
- name: Commit files
run: |
git config --local user.email "[email protected]"
git config --local user.name "github-actions[bot]"
git add intl/*_workflow.py "shell/libretro/libretro_core_options_intl.h"
git commit -m "Fetch translations & Recreate libretro_core_options_intl.h"
- name: GitHub Push
uses: ad-m/[email protected]
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
+62
View File
@@ -0,0 +1,62 @@
name: Nintendo Switch CI
on: [push, pull_request]
jobs:
build:
name: ${{ matrix.config.name }}
runs-on: ubuntu-latest
container: devkitpro/devkita64:latest
strategy:
matrix:
config:
- {name: standalone, destDir: switch}
- {name: libretro, cmakeArgs: -DLIBRETRO=ON}
steps:
- name: Set up build environment
run: |
sudo apt-get update
sudo apt-get -y install awscli ccache
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
- name: Mark git repository as safe
run: git config --global --add safe.directory $PWD
- uses: actions/cache@v4
with:
path: ~/.ccache
key: ccache-switch-${{ matrix.config.name }}-${{ github.sha }}
restore-keys: ccache-switch-${{ matrix.config.name }}-
- name: CMake
run: |
$DEVKITPRO/portlibs/switch/bin/aarch64-none-elf-cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=artifact -G Ninja ${{ matrix.config.cmakeArgs }}
cmake --build build --config Release --target install
- uses: actions/upload-artifact@v4
with:
name: flycast-switch-${{ matrix.config.name }}
path: artifact/bin
- name: Package app
run: zip -m artifact/bin/flycast.nro.zip artifact/bin/flycast.nro
if: hashFiles('artifact/bin/flycast.nro') != ''
- name: Configure AWS Credentials
id: aws-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
aws-region: us-east-2
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push' && matrix.config.destDir != ''
- name: Upload to S3
run: aws s3 sync artifact/bin s3://flycast-builds/${{ matrix.config.destDir }}/${GITHUB_REF#refs/}-$GITHUB_SHA --acl public-read --follow-symlinks
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
+54
View File
@@ -0,0 +1,54 @@
name: Windows UWP CI
on: [push, pull_request]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
- name: CMake
run: |
cmake -B build -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" -A x64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.22000.0
cmake --build build --config Release -- /m
shell: cmd
- uses: ilammy/msvc-dev-cmd@v1
- name: Package app
run: |
mkdir build\artifact
cd build\AppPackages\flycast\flycast_*_x64_Test
mkdir tmp
ren *.msix flycast.msix
makeappx.exe unpack /p .\flycast.msix /d tmp
copy ..\..\..\Release\*.dll tmp
makeappx pack /d tmp /p ..\..\..\artifact\flycast.appx
- name: Sign app
run: signtool sign /f shell\uwp\sign_cert.pfx /p '${{ secrets.SIGN_CERT_PWD }}' /v /fd SHA256 build\artifact\flycast.appx
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push'
- uses: actions/upload-artifact@v4
with:
name: flycast-uwp
path: build/artifact
- name: Configure AWS Credentials
id: aws-credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: AKIAJOZQS4H2PHQWYFCA
aws-secret-access-key: ${{ secrets.S3_SECRET_KEY }}
aws-region: us-east-2
if: github.repository == 'flyinghead/flycast' && github.event_name == 'push'
- name: Upload to S3
run: aws s3 sync build/artifact s3://flycast-builds/xbox/${GITHUB_REF#refs/}-$GITHUB_SHA --acl public-read --follow-symlinks
shell: bash
if: ${{ steps.aws-credentials.outputs.aws-account-id != '' }}
+11 -58
View File
@@ -1,66 +1,19 @@
.DS_Store
*.class
*.orig
*build_obj
Workdir/data
Workdir/reicast*
Workdir/vmu*
Workdir/webui*
Workdir/emu.cfg
Workdir/lib*ant.properties
build/
artifact/
# iOS General
# macOS
.DS_Store
*/build/*
**/build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
profile
*.moved-aside
DerivedData
*.hmap
emulator.xccheckout
reicast.xccheckout
build/*
*.so
*Karen_angelXwind*
local.properties
ant.properties
*build_obj
*.d
Workdir/data
Workdir/reicast*
Workdir/vmu*
Workdir/webui*
Workdir/emu.cfg
Workdir/lib*ant.properties
reicast-ios.xccheckout
# Linux General
shell/linux/.map
shell/linux/flycast.elf.map
shell/linux/nosym-flycast.elf
shell/linux/flycast.elf
shell/linux/dispframe.elf
shell/apple/emulator-ios/OpenMP/OpenMP.xcframework
# Visual Studio
generated
.vs
# Android Studio
*.iml
shell/android-studio/.gradle/
shell/android-studio/flycast/.cxx/
shell/android-studio/flycast/build/
shell/android-studio/flycast/local.properties
.vs/
.vscode/
out/
# JetBrains IDES
.idea/
cmake-build-*/
# Dependencies from .gitmodules
core/deps/breakpad/
core/deps/glslang/
+171
View File
@@ -0,0 +1,171 @@
# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper)
##############################################################################
################################# BOILERPLATE ################################
##############################################################################
# Core definitions
.core-defs:
variables:
GIT_SUBMODULE_STRATEGY: recursive
CORENAME: flycast
CORE_ARGS: -DLIBRETRO=ON -DCMAKE_BUILD_TYPE=Release
.core-defs-linux:
extends: .core-defs
variables:
CORE_ARGS: -DLIBRETRO=ON -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -DCMAKE_BUILD_TYPE=Release
.core-defs-osx-x64:
extends: .core-defs
variables:
CORE_ARGS: -DLIBRETRO=ON -G Xcode -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64
EXTRA_PATH: Release
.core-defs-osx-arm64:
extends: .core-defs
variables:
CORE_ARGS: -DLIBRETRO=ON -G Xcode -DCMAKE_BUILD_TYPE=Release
EXTRA_PATH: Release
.core-defs-ios-arm64:
extends: .core-defs
variables:
CORE_ARGS: -DLIBRETRO=ON -DCMAKE_BUILD_TYPE=Release
.core-defs-android:
extends: .core-defs
script:
- cmake $CORE_ARGS -DANDROID_PLATFORM=android-$API_LEVEL -DCMAKE_TOOLCHAIN_FILE=$NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_STL=c++_static -DANDROID_ABI=$ANDROID_ABI -DANDROID_ARM_MODE=arm "$CMAKE_SOURCE_ROOT" -B$BUILD_DIR
- cmake --build $BUILD_DIR --target ${CORENAME}_libretro --config Release -- -j $NUMPROC
- mv $BUILD_DIR/${CORENAME}_libretro.so $LIBNAME
- if [ $STRIP_CORE_LIB -eq 1 ]; then $NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip $LIBNAME; fi
variables:
API_LEVEL: 18
# Inclusion templates, required for the build to work
include:
################################## DESKTOPS ################################
# Windows
- project: 'libretro-infrastructure/ci-templates'
file: '/windows-cmake-mingw.yml'
# MacOS
- project: 'libretro-infrastructure/ci-templates'
file: 'osx-cmake-x86.yml'
# MacOS arm64
- project: 'libretro-infrastructure/ci-templates'
file: 'osx-cmake-arm64.yml'
# Linux
- project: 'libretro-infrastructure/ci-templates'
file: '/linux-cmake.yml'
################################## CELLULAR ################################
# Android
- project: 'libretro-infrastructure/ci-templates'
file: '/android-cmake.yml'
# iOS arm64
- project: 'libretro-infrastructure/ci-templates'
file: '/ios-cmake.yml'
################################## CONSOLES ################################
# Nintendo Switch
# - project: 'libretro-infrastructure/ci-templates'
# file: '/libnx-static.yml'
# tvOS arm64
- project: 'libretro-infrastructure/ci-templates'
file: '/tvos-cmake.yml'
# Stages for building
stages:
- build-prepare
- build-shared
# - build-static
##############################################################################
#################################### STAGES ##################################
##############################################################################
#
################################### DESKTOPS #################################
# Windows 64-bit
libretro-build-windows-x64:
extends:
- .libretro-windows-cmake-x86_64
- .core-defs
# Windows 32-bit
libretro-build-windows-i686:
extends:
- .libretro-windows-cmake-x86
- .core-defs
# Linux 64-bit
libretro-build-linux-x64:
extends:
- .libretro-linux-cmake-x86_64
- .core-defs-linux
# Linux 32-bit
libretro-build-linux-i686:
extends:
- .libretro-linux-cmake-x86
- .core-defs-linux
# MacOS 64-bit
libretro-build-osx-x64:
extends:
- .libretro-osx-cmake-x86
- .core-defs-osx-x64
# MacOS arm 64-bit
libretro-build-osx-arm64:
extends:
- .libretro-osx-cmake-arm64
- .core-defs-osx-arm64
################################### CELLULAR #################################
# Android ARMv7a
android-armeabi-v7a:
extends:
- .libretro-android-cmake-armeabi-v7a
- .core-defs-android
# Android ARMv8a
android-arm64-v8a:
extends:
- .libretro-android-cmake-arm64-v8a
- .core-defs-android
# Android 64-bit x86
android-x86_64:
extends:
- .libretro-android-cmake-x86_64
- .core-defs-android
# Android 32-bit x86
android-x86:
extends:
- .libretro-android-cmake-x86
- .core-defs-android
libretro-build-ios-arm64:
extends:
- .libretro-ios-cmake-arm64
- .core-defs-ios-arm64
################################### CONSOLES #################################
# Nintendo Switch
#libretro-build-libnx-aarch64:
# extends:
# - .libretro-libnx-static-retroarch-master
# - .core-defs
# tvOS arm64
libretro-build-tvos-arm64:
extends:
- .libretro-tvos-cmake-arm64
- .core-defs-ios-arm64
+37
View File
@@ -4,3 +4,40 @@
[submodule "core/deps/libchdr"]
path = core/deps/libchdr
url = https://github.com/rtissera/libchdr.git
ignore = dirty
[submodule "core/deps/luabridge"]
path = core/deps/luabridge
url = https://github.com/vinniefalco/LuaBridge.git
[submodule "core/deps/breakpad"]
path = core/deps/breakpad
url = https://github.com/flyinghead/mingw-breakpad
[submodule "core/deps/Vulkan-Headers"]
path = core/deps/Vulkan-Headers
url = https://github.com/KhronosGroup/Vulkan-Headers.git
[submodule "core/deps/VulkanMemoryAllocator"]
path = core/deps/VulkanMemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
[submodule "core/deps/glslang"]
path = core/deps/glslang
url = https://github.com/KhronosGroup/glslang.git
[submodule "core/deps/oboe"]
path = core/deps/oboe
url = https://github.com/google/oboe.git
[submodule "core/deps/Syphon"]
path = core/deps/Syphon
url = https://github.com/vkedwardli/Syphon-Framework.git
[submodule "core/deps/Spout"]
path = core/deps/Spout
url = https://github.com/vkedwardli/Spout2.git
[submodule "core/deps/discord-rpc"]
path = core/deps/discord-rpc
url = https://github.com/harmonytf/discord-rpc
[submodule "core/deps/libadrenotools"]
path = core/deps/libadrenotools
url = https://github.com/bylaws/libadrenotools
[submodule "core/deps/rcheevos"]
path = core/deps/rcheevos
url = https://github.com/RetroAchievements/rcheevos.git
[submodule "core/deps/googletest"]
path = core/deps/googletest
url = https://github.com/google/googletest.git
+1725 -797
View File
File diff suppressed because it is too large. Load diff
+33 -11
View File
@@ -1,11 +1,14 @@
# Flycast
[![C/C++ CI](https://github.com/flyinghead/flycast/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/flyinghead/flycast/actions/workflows/c-cpp.yml)
[![Android CI](https://github.com/flyinghead/flycast/actions/workflows/android.yml/badge.svg)](https://github.com/flyinghead/flycast/actions/workflows/android.yml)
[![C/C++ CI](https://github.com/flyinghead/flycast/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/flyinghead/flycast/actions/workflows/c-cpp.yml)
[![Nintendo Switch CI](https://github.com/flyinghead/flycast/actions/workflows/switch.yml/badge.svg)](https://github.com/flyinghead/flycast/actions/workflows/switch.yml)
[![Windows UWP CI](https://github.com/flyinghead/flycast/actions/workflows/uwp.yml/badge.svg)](https://github.com/flyinghead/flycast/actions/workflows/uwp.yml)
[![BSD CI](https://github.com/flyinghead/flycast/actions/workflows/bsd.yml/badge.svg)](https://github.com/flyinghead/flycast/actions/workflows/bsd.yml)
![flycast logo](https://github.com/flyinghead/flycast/raw/master/shell/linux/flycast.png)
**Flycast** is a multi-platform Sega Dreamcast, Naomi and Atomiswave emulator derived from [**reicast**](https://reicast.com/).
**Flycast** is a multi-platform Sega Dreamcast, Naomi, Naomi 2, and Atomiswave emulator derived from [**reicast**](https://github.com/skmp/reicast-emulator).
Information about configuration and supported features can be found on [**TheArcadeStriker's flycast wiki**](https://github.com/TheArcadeStriker/flycast-wiki/wiki).
@@ -13,24 +16,43 @@ Join us on our [**Discord server**](https://discord.gg/X8YWP8w) for a chat.
## Install
### Flatpak
### Android ![android](https://flyinghead.github.io/flycast-builds/android.jpg)
Install Flycast from [**Google Play**](https://play.google.com/store/apps/details?id=com.flycast.emulator).
### Flatpak (Linux ![ubuntu logo](https://flyinghead.github.io/flycast-builds/ubuntu.png))
1. [Set up Flatpak](https://www.flatpak.org/setup/)
1. [Set up Flatpak](https://www.flatpak.org/setup/).
2. Install Flycast from [Flathub](https://flathub.org/apps/details/org.flycast.Flycast)
2. Install Flycast from [Flathub](https://flathub.org/apps/details/org.flycast.Flycast):
`flatpak install -y org.flycast.Flycast`
3. Run Flycast
3. Run Flycast:
`flatpak run org.flycast.Flycast`
### Binaries
### Homebrew (MacOS ![apple logo](https://flyinghead.github.io/flycast-builds/apple.png))
Get fresh builds for your system [on the builds page](https://flyinghead.github.io/flycast-builds/).
1. [Set up Homebrew](https://brew.sh).
**New:** Now automated test results are available as well.
2. Install Flycast via Homebrew:
## Disclaimer
`brew install --cask flycast`
All code contritbuted to this fork is *not* bound by the Individual Contributor License Agreement of the upstream repository (https://github.com/reicast/reicast-emulator) and shall *not* be considered as a contribution to the upstream repository.
### Xbox One/Series ![xbox logo](https://flyinghead.github.io/flycast-builds/xbox.png)
Grab the latest build from [**the builds page**](https://flyinghead.github.io/flycast-builds/), or the [**GitHub Actions**](https://github.com/flyinghead/flycast/actions/workflows/uwp.yml). Then install it using the **Xbox Device Portal**.
### Binaries ![android](https://flyinghead.github.io/flycast-builds/android.jpg) ![windows](https://flyinghead.github.io/flycast-builds/windows.png) ![linux](https://flyinghead.github.io/flycast-builds/ubuntu.png) ![apple](https://flyinghead.github.io/flycast-builds/apple.png) ![switch](https://flyinghead.github.io/flycast-builds/switch.png) ![xbox](https://flyinghead.github.io/flycast-builds/xbox.png)
Get fresh builds for your system [**on the builds page**](https://flyinghead.github.io/flycast-builds/).
**New:** Now automated test results are available as well.
### Build instructions:
```
$ git clone --recursive https://github.com/flyinghead/flycast.git
$ cd flycast
$ mkdir build && cd build
$ cmake ..
$ make
```
+1 -3
View File
@@ -7,12 +7,10 @@ Here lies the core of our codebase. Everything that's OS inspecific rests here.
### Some rudimentary categories are:
- hw -- DC Hardware Components Implementation
- nullDC.cpp -- Main entry points
- emitter -- x86 code emitter
- khronos -- OpenGL and Vulkan headers
- oslib -- Audio drivers
- cfg -- Configuration backend structure
- reios -- (Our) Implementation of the DreamCast BIOS
- deps -- External dependencies
- imgread -- Content drivers
- rec-* -- Recompilers
- rend -- OpenGL and Vulkan renderers
- rend -- Graphics renderers and UI
File diff suppressed because it is too large. Load diff
+72
View File
@@ -0,0 +1,72 @@
/*
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "types.h"
#include <future>
#include <vector>
namespace achievements
{
#ifdef USE_RACHIEVEMENTS
struct Game
{
std::string image;
std::string title;
u32 unlockedAchievements;
u32 totalAchievements;
u32 points;
u32 totalPoints;
};
struct Achievement
{
Achievement() = default;
Achievement(const std::string& image, const std::string& title, const std::string& description, const std::string& category, const std::string& status)
: image(image), title(title), description(description), category(category), status(status) {}
std::string image;
std::string title;
std::string description;
std::string category;
std::string status;
};
bool init();
void term();
std::future<void> login(const char *username, const char *password);
void logout();
bool isLoggedOn();
bool isActive();
Game getCurrentGame();
std::vector<Achievement> getAchievementList();
bool canPause();
#else
static inline bool isActive() {
return false;
}
static inline bool canPause() {
return true;
}
#endif
void serialize(Serializer& ser);
void deserialize(Deserializer& deser);
}
+5 -15
View File
@@ -23,30 +23,20 @@
#include "deps/lzma/7zCrc.h"
#include "deps/lzma/Alloc.h"
#include <cstring>
#define kInputBufSize ((size_t)1 << 18)
static bool crc_tables_generated;
bool SzArchive::Open(const char* path)
bool SzArchive::Open(FILE *file)
{
SzArEx_Init(&szarchive);
File_Close(&archiveStream.file);
File_Construct(&archiveStream.file);
#ifdef USE_WINDOWS_FILE
nowide::wstackstring wpath;
if (!wpath.convert(path))
return false;
archiveStream.file.handle = CreateFileW(wpath.c_str(),
GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (archiveStream.file.handle == INVALID_HANDLE_VALUE)
return false;
#else
archiveStream.file.file = nowide::fopen(path, "rb");
if (archiveStream.file.file == nullptr)
return false;
#endif
archiveStream.file.file = file;
FileInStream_CreateVTable(&archiveStream);
LookToRead2_CreateVTable(&lookStream, 0);
lookStream.buf = (Byte *)ISzAlloc_Alloc(&g_Alloc, kInputBufSize);
+12 -5
View File
@@ -25,6 +25,7 @@
#include "deps/lzma/7zFile.h"
#include <algorithm>
#include <cstring>
class SzArchive : public Archive
{
@@ -38,9 +39,10 @@ public:
ArchiveFile* OpenFile(const char* name) override;
ArchiveFile *OpenFileByCrc(u32 crc) override;
private:
bool Open(const char* path) override;
protected:
bool Open(FILE *file) override;
private:
CSzArEx szarchive;
UInt32 block_idx; /* it can have any value before first call (if outBuffer = 0) */
Byte *out_buffer; /* it must be 0 before first call for each new archive. */
@@ -53,16 +55,21 @@ private:
class SzArchiveFile : public ArchiveFile
{
public:
SzArchiveFile(u8 *data, u32 offset, u32 length) : data(data), offset(offset), length(length) {}
SzArchiveFile(u8 *data, u32 offset, u32 length)
: data(data), offset(offset), _length(length) {}
u32 Read(void *buffer, u32 length) override
{
length = std::min(length, this->length);
length = std::min(length, this->_length);
memcpy(buffer, data + offset, length);
return length;
}
size_t length() override {
return _length;
}
private:
u8 *data;
u32 offset;
u32 length;
u32 _length;
};
+60 -32
View File
@@ -25,11 +25,8 @@ ZipArchive::~ZipArchive()
zip_close(zip);
}
bool ZipArchive::Open(const char* path)
bool ZipArchive::Open(FILE *file)
{
FILE *file = nowide::fopen(path, "rb");
if (file == nullptr)
return false;
zip_error_t error;
zip_source_t *source = zip_source_filep_create(file, 0, -1, &error);
if (source == nullptr)
@@ -37,7 +34,7 @@ bool ZipArchive::Open(const char* path)
std::fclose(file);
return false;
}
zip = zip_open_from_source(source, 0, NULL);
zip = zip_open_from_source(source, 0, nullptr);
if (zip == nullptr)
zip_source_free(source);
return zip != nullptr;
@@ -45,46 +42,77 @@ bool ZipArchive::Open(const char* path)
ArchiveFile* ZipArchive::OpenFile(const char* name)
{
zip_file *zip_file = zip_fopen(zip, name, 0);
if (zip_file == NULL)
return NULL;
return new ZipArchiveFile(zip_file);
zip_file_t *zip_file = zip_fopen(zip, name, 0);
if (zip_file == nullptr)
return nullptr;
zip_stat_t stat;
zip_stat(zip, name, 0, &stat);
return new ZipArchiveFile(zip_file, stat.size, stat.name);
}
struct zip_file *zip_fopen_by_crc(struct zip *za, u32 crc, int flags)
static zip_file *zip_fopen_by_crc(zip_t *za, u32 crc, int flags, zip_uint64_t& index)
{
int i, n;
struct zip_stat stat;
if (crc == 0)
return nullptr;
if (crc == 0) {
return NULL;
}
zip_int64_t n = zip_get_num_entries(za, 0);
for (index = 0; index < (zip_uint64_t)n; index++)
{
zip_stat_t stat;
if (zip_stat_index(za, index, flags, &stat) < -1)
return nullptr;
if (stat.crc == crc)
return zip_fopen_index(za, index, flags);
}
n = zip_get_num_files(za);
for (i = 0; i < n; i++) {
if (zip_stat_index(za, i, flags, &stat) < -1) {
return NULL;
}
if (stat.crc == crc) {
return zip_fopen_index(za, i, flags);
}
}
return NULL;
return nullptr;
}
ArchiveFile* ZipArchive::OpenFileByCrc(u32 crc)
{
zip_file *zip_file = zip_fopen_by_crc(zip, crc, 0);
if (zip_file == NULL)
return NULL;
zip_uint64_t index;
zip_file_t *zip_file = zip_fopen_by_crc(zip, crc, 0, index);
if (zip_file == nullptr)
return nullptr;
zip_stat_t stat;
zip_stat_index(zip, index, 0, &stat);
return new ZipArchiveFile(zip_file);
return new ZipArchiveFile(zip_file, stat.size, stat.name);
}
u32 ZipArchiveFile::Read(void* buffer, u32 length)
{
return zip_fread(zip_file, buffer, length);
}
bool ZipArchive::Open(const void *data, size_t size)
{
zip_error_t error;
zip_source_t *source = zip_source_buffer_create(data, size, 0, &error);
if (source == nullptr)
return false;
zip = zip_open_from_source(source, 0, nullptr);
if (zip == nullptr)
zip_source_free(source);
return zip != nullptr;
}
ArchiveFile *ZipArchive::OpenFirstFile()
{
zip_file_t *zipFile = zip_fopen_index(zip, 0, 0);
if (zipFile == nullptr)
return nullptr;
zip_stat_t stat;
zip_stat_index(zip, 0, 0, &stat);
return new ZipArchiveFile(zipFile, stat.size, stat.name);
}
ArchiveFile *ZipArchive::OpenFileByIndex(size_t index)
{
zip_file_t *zipFile = zip_fopen_index(zip, index, 0);
if (zipFile == nullptr)
return nullptr;
zip_stat_t stat;
zip_stat_index(zip, index, 0, &stat);
return new ZipArchiveFile(zipFile, stat.size, stat.name);
}
+21 -7
View File
@@ -26,25 +26,39 @@
class ZipArchive : public Archive
{
public:
ZipArchive() : zip(NULL) {}
~ZipArchive() override;
ArchiveFile* OpenFile(const char* name) override;
ArchiveFile* OpenFileByCrc(u32 crc) override;
private:
bool Open(const char* path) override;
bool Open(FILE *file) override;
bool Open(const void *data, size_t size);
struct zip *zip;
ArchiveFile *OpenFirstFile();
ArchiveFile *OpenFileByIndex(size_t index);
private:
zip_t *zip = nullptr;
};
class ZipArchiveFile : public ArchiveFile
{
public:
ZipArchiveFile(struct zip_file *zip_file) : zip_file(zip_file) {}
~ZipArchiveFile() override { zip_fclose(zip_file); }
ZipArchiveFile(zip_file_t *zip_file, size_t length, const char *name)
: zip_file(zip_file), _length(length), name(name) {}
~ZipArchiveFile() override {
zip_fclose(zip_file);
}
u32 Read(void* buffer, u32 length) override;
size_t length() override {
return _length;
}
const char *getName() override {
return name;
}
private:
struct zip_file *zip_file;
zip_file_t *zip_file;
size_t _length;
const char *name;
};
+49 -12
View File
@@ -22,24 +22,61 @@
#include "archive.h"
#include "7zArchive.h"
#include "ZipArchive.h"
#include "oslib/storage.h"
Archive *OpenArchive(const char *path)
Archive *OpenArchive(const std::string& path)
{
std::string base_path(path);
Archive *sz_archive = new SzArchive();
if (sz_archive->Open(base_path.c_str()) || sz_archive->Open((base_path + ".7z").c_str()) || sz_archive->Open((base_path + ".7Z").c_str()))
return sz_archive;
delete sz_archive;
FILE *file = nullptr;
hostfs::FileInfo fileInfo;
try {
fileInfo = hostfs::storage().getFileInfo(path);
if (!fileInfo.isDirectory)
file = hostfs::storage().openFile(path, "rb");
} catch (const hostfs::StorageException& e) {
}
if (file == nullptr)
{
file = hostfs::storage().openFile(path + ".7z", "rb");
if (file == nullptr)
file = hostfs::storage().openFile(path + ".7Z", "rb");
}
if (file != nullptr)
{
Archive *sz_archive = new SzArchive();
if (sz_archive->Open(file))
return sz_archive;
delete sz_archive;
file = nullptr;
}
// Retry as a zip file
try {
if (!fileInfo.isDirectory)
file = hostfs::storage().openFile(path, "rb");
} catch (const hostfs::StorageException& e) {
}
if (file == nullptr)
{
file = hostfs::storage().openFile(path + ".zip", "rb");
if (file == nullptr)
{
file = hostfs::storage().openFile(path + ".ZIP", "rb");
if (file == nullptr)
return nullptr;
}
}
Archive *zip_archive = new ZipArchive();
if (zip_archive->Open(base_path.c_str()) || zip_archive->Open((base_path + ".zip").c_str()) || zip_archive->Open((base_path + ".ZIP").c_str()))
if (zip_archive->Open(file))
return zip_archive;
delete zip_archive;
return NULL;
return nullptr;
}
bool Archive::Open(const char* path)
{
FILE *file = nowide::fopen(path, "rb");
if (file == nullptr)
return false;
return Open(file);
}
+8 -3
View File
@@ -27,6 +27,8 @@ class ArchiveFile
public:
virtual ~ArchiveFile() = default;
virtual u32 Read(void *buffer, u32 length) = 0;
virtual size_t length() = 0;
virtual const char *getName() { return nullptr; }
};
class Archive
@@ -36,10 +38,13 @@ public:
virtual ArchiveFile *OpenFile(const char *name) = 0;
virtual ArchiveFile *OpenFileByCrc(u32 crc) = 0;
friend Archive *OpenArchive(const char *path);
protected:
virtual bool Open(FILE *file) = 0;
private:
virtual bool Open(const char *name) = 0;
bool Open(const char *name);
friend Archive *OpenArchive(const std::string& path);
};
Archive *OpenArchive(const char *path);
Archive *OpenArchive(const std::string& path);
+46 -14
View File
@@ -19,15 +19,15 @@
#include "rzip.h"
#include <zlib.h>
#include <cstring>
const u8 RZipHeader[8] = { '#', 'R', 'Z', 'I', 'P', 'v', 1, '#' };
bool RZipFile::Open(const std::string& path, bool write)
bool RZipFile::Open(FILE *file, bool write)
{
verify(file == nullptr);
file = nowide::fopen(path.c_str(), write ? "wb" : "rb");
if (file == nullptr)
return false;
verify(this->file == nullptr);
verify(file != nullptr);
startOffset = std::ftell(file);
if (!write)
{
u8 header[sizeof(RZipHeader)];
@@ -36,14 +36,44 @@ bool RZipFile::Open(const std::string& path, bool write)
|| std::fread(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|| std::fread(&size, sizeof(size), 1, file) != 1)
{
Close();
std::fseek(file, startOffset, SEEK_SET);
return false;
}
// savestates created on 32-bit platforms used to have a 32-bit size
if (size >> 32 != 0)
{
size &= 0xffffffff;
std::fseek(file, -4, SEEK_CUR);
}
chunk = new u8[maxChunkSize];
chunkIndex = 0;
chunkSize = 0;
}
else
{
maxChunkSize = 1_MB;
if (std::fwrite(RZipHeader, sizeof(RZipHeader), 1, file) != 1
|| std::fwrite(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|| std::fwrite(&size, sizeof(size), 1, file) != 1)
{
std::fseek(file, startOffset, SEEK_SET);
return false;
}
}
this->write = write;
this->file = file;
return true;
}
bool RZipFile::Open(const std::string& path, bool write)
{
FILE *f = nowide::fopen(path.c_str(), write ? "wb" : "rb");
if (f == nullptr)
return false;
if (!Open(f, write)) {
Close();
return false;
}
return true;
}
@@ -51,6 +81,11 @@ void RZipFile::Close()
{
if (file != nullptr)
{
if (write)
{
std::fseek(file, startOffset + sizeof(RZipHeader) + sizeof(maxChunkSize), SEEK_SET);
std::fwrite(&size, sizeof(size), 1, file);
}
std::fclose(file);
file = nullptr;
if (chunk != nullptr)
@@ -64,6 +99,7 @@ void RZipFile::Close()
size_t RZipFile::Read(void *data, size_t length)
{
verify(file != nullptr);
verify(!write);
u8 *p = (u8 *)data;
size_t rv = 0;
@@ -93,7 +129,7 @@ size_t RZipFile::Read(void *data, size_t length)
delete [] zipped;
chunkSize = (u32)tl;
}
u32 l = std::min(chunkSize - chunkIndex, (u32)length);
u32 l = std::min(chunkSize - chunkIndex, (u32)(length - rv));
memcpy(p, chunk + chunkIndex, l);
p += l;
chunkIndex += l;
@@ -106,13 +142,9 @@ size_t RZipFile::Read(void *data, size_t length)
size_t RZipFile::Write(const void *data, size_t length)
{
verify(file != nullptr);
verify(std::ftell(file) == 0);
verify(write);
maxChunkSize = 1024 * 1024;
if (std::fwrite(RZipHeader, sizeof(RZipHeader), 1, file) != 1
|| std::fwrite(&maxChunkSize, sizeof(maxChunkSize), 1, file) != 1
|| std::fwrite(&length, sizeof(length), 1, file) != 1)
return 0;
size += length;
const u8 *p = (const u8 *)data;
// compression output buffer must be 0.1% larger + 12 bytes
uLongf maxZippedSize = maxChunkSize + maxChunkSize / 1000 + 12;
+5 -1
View File
@@ -28,16 +28,20 @@ public:
~RZipFile() { Close(); }
bool Open(const std::string& path, bool write);
bool Open(FILE *file, bool write);
void Close();
size_t Size() const { return size; }
size_t Read(void *data, size_t length);
size_t Write(const void *data, size_t length);
FILE *rawFile() const { return file; }
private:
FILE *file = nullptr;
size_t size = 0;
u64 size = 0;
u32 maxChunkSize = 0;
u8 *chunk = nullptr;
u32 chunkSize = 0;
u32 chunkIndex = 0;
bool write = false;
long startOffset = 0;
};
+358
View File
@@ -0,0 +1,358 @@
#if USE_ALSA
#include "audiostream.h"
#include <alsa/asoundlib.h>
#include "cfg/cfg.h"
#include "cfg/option.h"
class AlsaAudioBackend : public AudioBackend
{
snd_pcm_t *handle = nullptr;
bool pcm_blocking = true;
snd_pcm_uframes_t buffer_size = 0;
snd_pcm_uframes_t period_size = 0;
snd_pcm_t *handle_record = nullptr;
public:
AlsaAudioBackend()
: AudioBackend("alsa", "Advanced Linux Sound Architecture") {}
bool init() override
{
snd_pcm_hw_params_t *params;
std::string device = cfgLoadStr("alsa", "device", "");
int rc = -1;
if (!device.empty() && device != "auto") {
rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0)
WARN_LOG(AUDIO, "ALSA: Cannot open device %s. Trying auto", device.c_str());
}
if (rc < 0)
{
INFO_LOG(AUDIO, "ALSA: trying to determine audio device");
// trying default device
device = "default";
rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
// "default" didn't work, try first device
if (rc < 0)
{
device = "plughw:0,0,0";
rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0)
{
device = "plughw:0,0";
rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
}
}
// first didn't work, try second
if (rc < 0)
{
device = "plughw:1,0";
rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
}
// try pulse audio backend
if (rc < 0)
{
device = "pulse";
rc = snd_pcm_open(&handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0);
}
if (rc < 0)
INFO_LOG(AUDIO, "ALSA: unable to automatically determine audio device.");
}
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: unable to open PCM device %s: %s", device.c_str(), snd_strerror(rc));
return false;
}
INFO_LOG(AUDIO, "ALSA: Successfully initialized \"%s\"", device.c_str());
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(&params);
/* Fill it in with default values. */
rc=snd_pcm_hw_params_any(handle, params);
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_any %s", snd_strerror(rc));
term();
return false;
}
/* Set the desired hardware parameters. */
/* Interleaved mode */
rc=snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_access %s", snd_strerror(rc));
term();
return false;
}
/* Signed 16-bit little-endian format */
rc=snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_format %s", snd_strerror(rc));
term();
return false;
}
/* Two channels (stereo) */
rc=snd_pcm_hw_params_set_channels(handle, params, 2);
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_channels %s", snd_strerror(rc));
term();
return false;
}
// 44100 samples/second
rc = snd_pcm_hw_params_set_rate(handle, params, 44100, 0);
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_rate %s", snd_strerror(rc));
term();
return false;
}
// Period size (512)
period_size = std::min(SAMPLE_COUNT, (u32)config::AudioBufferSize / 4);
rc = snd_pcm_hw_params_set_period_size_near(handle, params, &period_size, nullptr);
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_periods_near %s", snd_strerror(rc));
term();
return false;
}
INFO_LOG(AUDIO, "ALSA: period size set to %zd", (size_t)period_size);
// Sample buffer size
buffer_size = config::AudioBufferSize;
rc = snd_pcm_hw_params_set_buffer_size_near(handle, params, &buffer_size);
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: Error:snd_pcm_hw_params_set_buffer_size_near %s", snd_strerror(rc));
term();
return false;
}
INFO_LOG(AUDIO, "ALSA: buffer size set to %ld", buffer_size);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
if (rc < 0)
{
ERROR_LOG(AUDIO, "ALSA: Unable to set hw parameters: %s", snd_strerror(rc));
term();
return false;
}
return true;
}
bool initRecord(u32 sampling_freq) override
{
int err;
if ((err = snd_pcm_open(&handle_record, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot open default audio capture device: %s", snd_strerror(err));
return false;
}
snd_pcm_hw_params_t *hw_params;
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot allocate hardware parameter structure: %s", snd_strerror(err));
snd_pcm_close(handle_record);
return false;
}
if ((err = snd_pcm_hw_params_any(handle_record, hw_params)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot initialize hardware parameter structure: %s", snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
snd_pcm_close(handle_record);
return false;
}
if ((err = snd_pcm_hw_params_set_access(handle_record, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot set access type: %s\n", snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
snd_pcm_close(handle_record);
return false;
}
if ((err = snd_pcm_hw_params_set_format(handle_record, hw_params, SND_PCM_FORMAT_S16_LE)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot set sample format: %s", snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
snd_pcm_close(handle_record);
return false;
}
if ((err = snd_pcm_hw_params_set_rate(handle_record, hw_params, sampling_freq, 0)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot set sample rate to %d Hz: %s", sampling_freq, snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
snd_pcm_close(handle_record);
return false;
}
if ((err = snd_pcm_hw_params_set_channels(handle_record, hw_params, 1)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot set channel count: %s", snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
snd_pcm_close(handle_record);
return false;
}
if ((err = snd_pcm_hw_params(handle_record, hw_params)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot set parameters: %s", snd_strerror(err));
snd_pcm_hw_params_free(hw_params);
snd_pcm_close(handle_record);
return false;
}
snd_pcm_hw_params_free(hw_params);
snd_pcm_nonblock(handle_record, 1);
if ((err = snd_pcm_prepare(handle_record)) < 0)
{
ERROR_LOG(AUDIO, "ALSA: Cannot prepare device: %s", snd_strerror(err));
snd_pcm_close(handle_record);
return false;
}
INFO_LOG(AUDIO, "ALSA: Successfully initialized capture device");
return true;
}
void termRecord() override
{
snd_pcm_close(handle_record);
}
u32 record(void* frame, u32 samples) override
{
int err = snd_pcm_readi(handle_record, frame, samples);
if (err < (int)samples)
{
if (err < 0)
{
DEBUG_LOG(AUDIO, "ALSA: Recording error: %s", snd_strerror(err));
err = 0;
err = snd_pcm_prepare(handle_record);
}
u8 *buffer = (u8 *)frame + err;
memset(buffer, 0, (samples - err) * 2);
}
return err;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
if (wait != pcm_blocking) {
snd_pcm_nonblock(handle, wait ? 0 : 1);
pcm_blocking = wait;
}
int rc = snd_pcm_writei(handle, frame, samples);
if (rc < 0)
{
snd_pcm_recover(handle, rc, 1);
if (rc == -EPIPE)
{
// EPIPE means underrun
// Write some silence then our samples
const size_t silence_size = buffer_size - samples;
void *silence = alloca(silence_size * 4);
memset(silence, 0, silence_size * 4);
snd_pcm_writei(handle, silence, silence_size);
snd_pcm_writei(handle, frame, samples);
}
}
return 1;
}
void term() override
{
snd_pcm_drop(handle);
snd_pcm_close(handle);
}
std::vector<std::string> getDeviceList()
{
std::vector<std::string> result;
char **hints;
int err = snd_device_name_hint(-1, "pcm", (void***)&hints);
// Error initializing ALSA
if (err != 0)
return result;
// special value to automatically detect on initialization
result.emplace_back("auto");
char** n = hints;
while (*n != NULL)
{
// Get the type (NULL/Input/Output)
char *type = snd_device_name_get_hint(*n, "IOID");
char *name = snd_device_name_get_hint(*n, "NAME");
if (name != NULL)
{
// We only want output or special devices (like "default" or "pulse")
// TODO Only those with type == NULL?
if (type == NULL || strcmp(type, "Output") == 0)
{
// TODO Check if device works (however we need to hash the resulting list then)
/*snd_pcm_t *handle;
int rc = snd_pcm_open(&handle, name, SND_PCM_STREAM_PLAYBACK, 0);
if (rc == 0)
{
result.push_back(name);
snd_pcm_close(handle);
}
*/
result.emplace_back(name);
}
}
if (type != NULL)
free(type);
if (name != NULL)
free(name);
n++;
}
snd_device_name_free_hint((void**)hints);
return result;
}
Option* getOptions(int *count) override
{
*count = 1;
static Option result;
result.name = "device";
result.caption = "Device";
result.type = Option::list;
result.values = getDeviceList();
return &result;
}
};
static AlsaAudioBackend alsaBackend;
#endif
+308
View File
@@ -0,0 +1,308 @@
/*
Simple Core Audio backend for osx (and maybe ios?)
Based off various audio core samples and dolphin's code
This is part of the Reicast project, please consult the
LICENSE file for licensing & related information
This could do with some locking logic to avoid
race conditions, and some variable length buffer
logic to support chunk sizes other than 512 bytes
It does work on my macmini though
*/
#if defined(__APPLE__)
#include "audiostream.h"
#include "cfg/option.h"
#include "stdclass.h"
#include <atomic>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioQueue.h>
class CoreAudioBackend : public AudioBackend
{
AudioUnit audioUnit;
u32 BUFSIZE = 0;
u8 *samples_temp = nullptr;
std::atomic<int> samples_wptr;
std::atomic<int> samples_rptr;
cResetEvent bufferEmpty;
// input buffer and indexes
u8 samples_input[2400];
static constexpr size_t InputBufSize = sizeof(samples_input);
std::atomic<int> input_wptr;
std::atomic<int> input_rptr;
AudioQueueRef recordQueue;
static OSStatus renderCallback(void* ctx, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* ts,
UInt32 bus, UInt32 frames, AudioBufferList* abl)
{
CoreAudioBackend *backend = (CoreAudioBackend *)ctx;
for (int i = 0; i < abl->mNumberBuffers; i++)
{
int size = abl->mBuffers[i].mDataByteSize;
u8 *outBuffer = (u8 *)abl->mBuffers[i].mData;
while (size != 0)
{
int avail = (backend->samples_wptr - backend->samples_rptr + backend->BUFSIZE) % backend->BUFSIZE;
if (avail == 0)
{
//printf("Core Audio: buffer underrun %d bytes (%d)", size, abl->mBuffers[i].mDataByteSize);
memset(outBuffer, '\0', size);
return noErr;
}
avail = std::min(avail, size);
avail = std::min(avail, (int)backend->BUFSIZE - backend->samples_rptr);
memcpy(outBuffer, backend->samples_temp + backend->samples_rptr, avail);
backend->samples_rptr = (backend->samples_rptr + avail) % backend->BUFSIZE;
size -= avail;
outBuffer += avail;
// Set the mutex to allow writing
backend->bufferEmpty.Set();
}
}
return noErr;
}
public:
CoreAudioBackend()
: AudioBackend("coreaudio", "Core Audio") {}
bool init() override
{
OSStatus err;
AURenderCallbackStruct callback_struct;
AudioStreamBasicDescription format;
AudioComponentDescription desc;
AudioComponent component;
desc.componentType = kAudioUnitType_Output;
#if !defined(TARGET_IPHONE)
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
#else
desc.componentSubType = kAudioUnitSubType_RemoteIO;
#endif
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
component = AudioComponentFindNext(nullptr, &desc);
if (component == nullptr) {
ERROR_LOG(AUDIO, "coreaudio: AudioComponentFindNext failed");
return false;
}
err = AudioComponentInstanceNew(component, &audioUnit);
if (err != noErr) {
ERROR_LOG(AUDIO, "coreaudio: AudioComponentInstanceNew failed");
return false;
}
FillOutASBDForLPCM(format, 44100,
2, 16, 16, false, false, false);
err = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input, 0, &format,
sizeof(AudioStreamBasicDescription));
if (err != noErr)
{
ERROR_LOG(AUDIO, "coreaudio: AudioUnitSetProperty(kAudioUnitProperty_StreamFormat) failed");
AudioComponentInstanceDispose(audioUnit);
return false;
}
callback_struct.inputProc = renderCallback;
callback_struct.inputProcRefCon = this;
err = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input, 0, &callback_struct,
sizeof callback_struct);
if (err != noErr)
{
ERROR_LOG(AUDIO, "coreaudio: AudioUnitSetProperty(kAudioUnitProperty_SetRenderCallback) failed");
AudioComponentInstanceDispose(audioUnit);
return false;
}
/*
err = AudioUnitSetParameter(audioUnit,
kHALOutputParam_Volume,
kAudioUnitParameterFlag_Output, 0,
1, 0);
verify(err == noErr);
*/
err = AudioUnitInitialize(audioUnit);
if (err != noErr)
{
ERROR_LOG(AUDIO, "coreaudio: AudioUnitInitialize failed");
AudioComponentInstanceDispose(audioUnit);
return false;
}
BUFSIZE = config::AudioBufferSize * 4;
samples_temp = new u8[BUFSIZE]();
samples_rptr = 0;
samples_wptr = 0;
err = AudioOutputUnitStart(audioUnit);
if (err != noErr)
{
ERROR_LOG(AUDIO, "coreaudio: AudioOutputUnitStart failed");
AudioUnitUninitialize(audioUnit);
AudioComponentInstanceDispose(audioUnit);
return false;
}
bufferEmpty.Set();
return true;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
int size = samples * 4;
while (size != 0)
{
int avail = (samples_rptr - samples_wptr - 4 + BUFSIZE) % BUFSIZE;
if (avail == 0)
{
if (!wait)
break;
bufferEmpty.Wait();
continue;
}
avail = std::min(avail, size);
avail = std::min(avail, (int)BUFSIZE - samples_wptr);
memcpy(&samples_temp[samples_wptr], frame, avail);
samples_wptr = (samples_wptr + avail) % BUFSIZE;
frame = (u8 *)frame + avail;
size -= avail;
}
return 1;
}
void term() override
{
AudioOutputUnitStop(audioUnit);
AudioUnitUninitialize(audioUnit);
AudioComponentInstanceDispose(audioUnit);
bufferEmpty.Set();
delete [] samples_temp;
samples_temp = nullptr;
}
static void recordCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer,
const AudioTimeStamp *inStartTime, UInt32 frameSize, const AudioStreamPacketDescription *dataFormat)
{
//DEBUG_LOG(AUDIO, "AudioQueue callback: wptr %d rptr %d bytes %d", (int)input_wptr, (int)input_rptr, inBuffer->mAudioDataByteSize);
CoreAudioBackend *backend = (CoreAudioBackend *)inUserData;
UInt32 size = inBuffer->mAudioDataByteSize;
UInt32 freeSpace = (backend->input_rptr - backend->input_wptr - 2 + InputBufSize) % InputBufSize;
if (size > freeSpace)
{
DEBUG_LOG(AUDIO, "coreaudio: record overrun %d bytes", size - freeSpace);
size = freeSpace;
}
while (size != 0)
{
UInt32 chunk = std::min(size, (UInt32)(InputBufSize - backend->input_wptr));
memcpy(backend->samples_input + backend->input_wptr, inBuffer->mAudioData, chunk);
backend->input_wptr = (backend->input_wptr + chunk) % InputBufSize;
size -= chunk;
}
AudioQueueEnqueueBuffer(backend->recordQueue, inBuffer, 0, nullptr);
}
void termRecord() override
{
if (recordQueue != nullptr)
{
AudioQueueStop(recordQueue, true);
AudioQueueDispose(recordQueue, true);
recordQueue = nullptr;
}
}
bool initRecord(u32 sampling_freq) override
{
AudioStreamBasicDescription desc{};
desc.mFormatID = kAudioFormatLinearPCM;
desc.mSampleRate = (double)sampling_freq;
desc.mChannelsPerFrame = 1;
desc.mBitsPerChannel = 16;
desc.mBytesPerPacket = desc.mBytesPerFrame = 2;
desc.mFramesPerPacket = 1;
desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
desc.mReserved = 0;
OSStatus err = AudioQueueNewInput(&desc,
recordCallback,
this,
nullptr,
kCFRunLoopCommonModes,
0,
&recordQueue);
if (err != noErr)
{
ERROR_LOG(AUDIO, "AudioQueueNewInput failed: %d", err);
return false;
}
AudioQueueBufferRef buffers[2];
for (UInt32 i = 0; i < std::size(buffers) && err == noErr; i++)
{
err = AudioQueueAllocateBuffer(recordQueue, 480, &buffers[i]);
if (err == noErr)
err = AudioQueueEnqueueBuffer(recordQueue, buffers[i], 0, nullptr);
}
input_wptr = 0;
input_rptr = 0;
if (err == noErr)
err = AudioQueueStart(recordQueue, nullptr);
if (err != noErr)
{
ERROR_LOG(AUDIO, "AudioQueue init failed: %d", err);
termRecord();
return false;
}
INFO_LOG(AUDIO, "AudioQueue initialized - sample rate %f", desc.mSampleRate);
return true;
}
u32 record(void* frame, u32 samples) override
{
// DEBUG_LOG(AUDIO, "coreaudio_record: wptr %d rptr %d", (int)input_wptr, (int)input_rptr);
u32 size = samples * 2;
while (size != 0)
{
u32 avail = (input_wptr - input_rptr + InputBufSize) % InputBufSize;
if (avail == 0)
{
DEBUG_LOG(AUDIO, "coreaudio: record underrun %d bytes", size);
break;
}
avail = std::min(avail, size);
avail = std::min(avail, (u32)(InputBufSize - input_rptr));
memcpy(frame, &samples_input[input_rptr], avail);
frame = (u8 *)frame + avail;
input_rptr = (input_rptr + avail) % InputBufSize;
size -= avail;
}
return samples - size / 2;
}
};
static CoreAudioBackend coreAudioBackend;
#endif
+242
View File
@@ -0,0 +1,242 @@
#include "build.h"
#if defined(_WIN32) && !defined(TARGET_UWP)
#include "audiostream.h"
#include "cfg/option.h"
#include <initguid.h>
#include <dsound.h>
#include <vector>
#include <atomic>
#include <thread>
#include "stdclass.h"
#include "windows/comptr.h"
#include "oslib/oslib.h"
HWND getNativeHwnd();
#define verifyc(x) verify(!FAILED(x))
#ifdef __CRT_UUID_DECL
__CRT_UUID_DECL(IDirectSoundBuffer8, 0x6825A449,0x7524,0x4D82,0x92,0x0F,0x50,0xE3,0x6A,0xB3,0xAB,0x1E);
__CRT_UUID_DECL(IDirectSoundNotify, 0xB0210783,0x89cd,0x11d0,0xAF,0x08,0x00,0xA0,0xC9,0x25,0xCD,0x16);
__CRT_UUID_DECL(IDirectSoundCaptureBuffer8, 0x00990DF4,0x0DBB,0x4872,0x83,0x3E,0x6D,0x30,0x3E,0x80,0xAE,0xB6);
#else
struct __declspec(uuid("{6825A449-7524-4D82-920F-50E36AB3AB1E}")) IDirectSoundBuffer8;
struct __declspec(uuid("{B0210783-89cd-11d0-AF08-00A0C925CD16}")) IDirectSoundNotify;
struct __declspec(uuid("{00990DF4-0DBB-4872-833E-6D303E80AEB6}")) IDirectSoundCaptureBuffer8;
#endif
class DirectSoundBackend : public AudioBackend
{
ComPtr<IDirectSound8> dsound;
ComPtr<IDirectSoundBuffer8> buffer;
std::vector<HANDLE> notificationEvents;
ComPtr<IDirectSoundCapture8> dcapture;
ComPtr<IDirectSoundCaptureBuffer8> capture_buffer;
std::atomic_bool audioThreadRunning;
std::thread audioThread;
cResetEvent pushWait;
static constexpr u32 SAMPLE_BYTES = SAMPLE_COUNT * 4;
RingBuffer ringBuffer;
u32 notificationOffset(int index) {
return index * SAMPLE_BYTES;
}
void audioThreadMain()
{
ThreadName _("FlyDirectSound");
audioThreadRunning = true;
while (true)
{
u32 rv = WaitForMultipleObjects(notificationEvents.size(), &notificationEvents[0], false, 100);
if (!audioThreadRunning)
break;
if (rv == WAIT_TIMEOUT || rv == WAIT_FAILED)
continue;
rv -= WAIT_OBJECT_0;
void *p1, *p2;
DWORD sz1, sz2;
if (SUCCEEDED(buffer->Lock(notificationOffset(rv), SAMPLE_BYTES, &p1, &sz1, &p2, &sz2, 0)))
{
if (!ringBuffer.read((u8*)p1, sz1))
memset(p1, 0, sz1);
if (sz2 != 0)
{
if (!ringBuffer.read((u8*)p2, sz2))
memset(p2, 0, sz2);
}
buffer->Unlock(p1, sz1, p2, sz2);
pushWait.Set();
}
}
}
public:
DirectSoundBackend()
: AudioBackend("directsound", "Microsoft DirectSound") {}
bool init() override
{
if (FAILED(DirectSoundCreate8(NULL, &dsound.get(), NULL))) {
ERROR_LOG(AUDIO, "DirectSound8 initialization failed");
return false;
}
if (FAILED(dsound->SetCooperativeLevel(getNativeHwnd(), DSSCL_PRIORITY))) {
ERROR_LOG(AUDIO, "DirectSound8 SetCooperativeLevel failed");
dsound.reset();
return false;
}
// Set up WAV format structure.
WAVEFORMATEX wfx;
memset(&wfx, 0, sizeof(WAVEFORMATEX));
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 44100;
wfx.nBlockAlign = 4;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.wBitsPerSample = 16;
// Set up DSBUFFERDESC structure.
DSBUFFERDESC desc;
memset(&desc, 0, sizeof(DSBUFFERDESC));
desc.dwSize = sizeof(DSBUFFERDESC);
desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS;
desc.dwBufferBytes = SAMPLE_BYTES * 2;
desc.lpwfxFormat = &wfx;
// Create the buffer
ComPtr<IDirectSoundBuffer> buffer_;
if (FAILED(dsound->CreateSoundBuffer(&desc, &buffer_.get(), 0))
|| FAILED(buffer_.as(buffer)))
{
ERROR_LOG(AUDIO, "DirectSound8 CreateSoundBuffer failed");
dsound.reset();
return false;
}
// Set up notifications
ComPtr<IDirectSoundNotify> bufferNotify;
verifyc(buffer.as(bufferNotify));
notificationEvents.clear();
std::vector<DSBPOSITIONNOTIFY> posNotify;
for (int i = 0; notificationOffset(i) < desc.dwBufferBytes; i++)
{
notificationEvents.push_back(CreateEvent(nullptr, false, false, nullptr));
posNotify.push_back({ notificationOffset(i), notificationEvents.back() });
}
bufferNotify->SetNotificationPositions(posNotify.size(), &posNotify[0]);
// Clear the buffers
void *p1, *p2;
DWORD sz1, sz2;
verifyc(buffer->Lock(0, desc.dwBufferBytes, &p1, &sz1, &p2, &sz2, 0));
verify(p2 == nullptr);
memset(p1, 0, sz1);
verifyc(buffer->Unlock(p1, sz1, p2, sz2));
ringBuffer.setCapacity(config::AudioBufferSize * 4);
// Start the thread
audioThread = std::thread(&DirectSoundBackend::audioThreadMain, this);
// Play the buffer !
if (FAILED(buffer->Play(0, 0, DSBPLAY_LOOPING)))
{
ERROR_LOG(AUDIO, "DirectSound8 Play failed");
term();
return false;
}
INFO_LOG(AUDIO, "DirectSound playback started");
return true;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
while (!ringBuffer.write((const u8 *)frame, samples * 4) && wait)
pushWait.Wait();
return 1;
}
void term() override
{
audioThreadRunning = false;
audioThread.join();
buffer->Stop();
for (HANDLE event : notificationEvents)
CloseHandle(event);
buffer.reset();
dsound.reset();
INFO_LOG(AUDIO, "DirectSound playback stopped");
}
bool initRecord(u32 sampling_freq) override
{
if (FAILED(DirectSoundCaptureCreate8(&DSDEVID_DefaultVoiceCapture, &dcapture.get(), NULL)))
{
ERROR_LOG(AUDIO, "DirectSound capture device creation failed");
return false;
}
HRESULT hr;
WAVEFORMATEX wfx =
{ WAVE_FORMAT_PCM, 1, sampling_freq, sampling_freq * 2, 2, 16, 0 };
// wFormatTag, nChannels, nSamplesPerSec, nAvgBytesPerSec,
// nBlockAlign, wBitsPerSample, cbSize
DSCBUFFERDESC dscbd;
dscbd.dwSize = sizeof(DSCBUFFERDESC);
dscbd.dwFlags = 0;
dscbd.dwBufferBytes = 480 * 2;
dscbd.dwReserved = 0;
dscbd.lpwfxFormat = &wfx;
dscbd.dwFXCount = 0;
dscbd.lpDSCFXDesc = NULL;
ComPtr<IDirectSoundCaptureBuffer> pDSCB;
if (FAILED(hr = dcapture->CreateCaptureBuffer(&dscbd, &pDSCB.get(), NULL)))
{
ERROR_LOG(AUDIO, "DirectSound capture buffer creation failed");
dcapture.reset();
return false;
}
pDSCB.as(capture_buffer);
capture_buffer->Start(DSCBSTART_LOOPING);
INFO_LOG(AUDIO, "DirectSound capture device and buffer created");
return true;
}
u32 record(void *buffer, u32 samples) override
{
DWORD readPos;
capture_buffer->GetCurrentPosition(NULL, &readPos);
void *p1, *p2;
DWORD p1bytes, p2bytes;
capture_buffer->Lock(readPos, samples * 2, &p1, &p1bytes, &p2, &p2bytes, 0);
memcpy(buffer, p1, p1bytes);
if (p2bytes > 0)
memcpy((u8 *)buffer + p1bytes, p2, p2bytes);
capture_buffer->Unlock(p1, p1bytes, p2, p2bytes);
return (p1bytes + p2bytes) / 2;
}
void termRecord() override
{
if (!dcapture)
return;
capture_buffer->Stop();
capture_buffer.reset();
dcapture.reset();
}
};
static DirectSoundBackend directSoundBackend;
#endif
+54
View File
@@ -0,0 +1,54 @@
#ifdef USE_LIBAO
#include "audiostream.h"
#include <ao/ao.h>
class LibAOBackend : public AudioBackend
{
ao_device *aodevice = nullptr;
public:
LibAOBackend()
: AudioBackend("libao", "libao") {}
bool init() override
{
ao_initialize();
ao_sample_format aoformat {};
aoformat.bits = 16;
aoformat.channels = 2;
aoformat.rate = 44100;
aoformat.byte_format = AO_FMT_LITTLE;
aodevice = ao_open_live(ao_default_driver_id(), &aoformat, NULL); // Live output
if (aodevice == nullptr)
aodevice = ao_open_live(ao_driver_id("null"), &aoformat, NULL);
if (aodevice == nullptr) {
ERROR_LOG(AUDIO, "Cannot open libao driver");
ao_shutdown();
}
return aodevice != nullptr;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
if (aodevice != nullptr)
ao_play(aodevice, (char*)frame, samples * 4);
return 1;
}
void term() override
{
if (aodevice != nullptr)
{
ao_close(aodevice);
aodevice = nullptr;
ao_shutdown();
}
}
};
static LibAOBackend libAOBackend;
#endif
+51
View File
@@ -0,0 +1,51 @@
#include "audiostream.h"
#include <chrono>
#include <thread>
class NullAudioBackend : public AudioBackend
{
using the_clock = std::chrono::high_resolution_clock;
public:
NullAudioBackend()
: AudioBackend("null", "No Audio") {}
bool init() override
{
last_time = the_clock::time_point();
return true;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
if (wait)
{
if (last_time.time_since_epoch() != the_clock::duration::zero())
{
auto fduration = std::chrono::nanoseconds(1000000000L * samples / 44100);
auto duration = fduration - (the_clock::now() - last_time);
std::this_thread::sleep_for(duration);
last_time += fduration;
}
else
last_time = the_clock::now();
}
return 1;
}
bool initRecord(u32 sampling_freq) override
{
return true;
}
u32 record(void *buffer, u32 samples) override
{
memset(buffer, 0, samples * 2);
return samples;
}
private:
the_clock::time_point last_time;
};
static NullAudioBackend nullBackend;
+201
View File
@@ -0,0 +1,201 @@
/*
Copyright 2021 flyinghead
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#ifdef USE_OBOE
#include "audiostream.h"
#include "cfg/option.h"
#include <oboe/Oboe.h>
#include <vector>
#include <algorithm>
#include <atomic>
#include <memory>
#include "stdclass.h"
class OboeBackend : AudioBackend
{
RingBuffer ringBuffer;
cResetEvent pushWait;
std::shared_ptr<oboe::AudioStream> stream;
std::shared_ptr<oboe::AudioStream> recordStream;
class AudioCallback : public oboe::AudioStreamDataCallback
{
public:
AudioCallback(OboeBackend *backend) : backend(backend) {}
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) override
{
if (!backend->ringBuffer.read((u8 *)audioData, numFrames * 4))
// underrun
memset(audioData, 0, numFrames * 4);
backend->pushWait.Set();
return oboe::DataCallbackResult::Continue;
}
OboeBackend *backend;
};
AudioCallback audioCallback;
class AudioErrorCallback : public oboe::AudioStreamErrorCallback
{
public:
AudioErrorCallback(OboeBackend *backend) : backend(backend) {}
void onErrorAfterClose(oboe::AudioStream *stream, oboe::Result error) override
{
// Only attempt to recover if init was successful
if (backend->stream != nullptr)
{
WARN_LOG(AUDIO, "Audio device lost. Attempting to reopen the audio stream");
// the oboe stream is already closed so make sure we don't close it twice
backend->stream.reset();
backend->term();
backend->init();
}
}
OboeBackend *backend;
};
AudioErrorCallback errorCallback;
public:
OboeBackend()
: AudioBackend("Oboe", "Automatic AAudio / OpenSL selection"), audioCallback(this), errorCallback(this) {}
bool init() override
{
// Actual capacity is size-1 to avoid overrun so add one buffer
ringBuffer.setCapacity((config::AudioBufferSize + SAMPLE_COUNT) * 4);
oboe::AudioStreamBuilder builder;
oboe::Result result = builder.setDirection(oboe::Direction::Output)
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setSharingMode(oboe::SharingMode::Exclusive)
->setFormat(oboe::AudioFormat::I16)
->setChannelCount(oboe::ChannelCount::Stereo)
->setSampleRate(44100)
->setSampleRateConversionQuality(oboe::SampleRateConversionQuality::High)
->setFramesPerCallback(SAMPLE_COUNT)
->setDataCallback(&audioCallback)
->setErrorCallback(&errorCallback)
->setUsage(oboe::Usage::Game)
->openStream(stream);
if (result != oboe::Result::OK)
{
ERROR_LOG(AUDIO, "Oboe open stream failed: %s", oboe::convertToText(result));
return false;
}
if (stream->getAudioApi() == oboe::AudioApi::AAudio && config::AudioBufferSize < 1764)
{
// Reduce internal buffer for low latency (< 40 ms)
int bufSize = stream->getBufferSizeInFrames();
int burst = stream->getFramesPerBurst();
if (bufSize - burst > SAMPLE_COUNT)
{
while (bufSize - burst > SAMPLE_COUNT)
bufSize -= burst;
stream->setBufferSizeInFrames(bufSize);
}
}
stream->requestStart();
NOTICE_LOG(AUDIO, "Oboe driver started. stream capacity: %d frames, size: %d frames, frames/callback: %d, frames/burst: %d",
stream->getBufferCapacityInFrames(), stream->getBufferSizeInFrames(),
stream->getFramesPerCallback(), stream->getFramesPerBurst());
return true;
}
void term() override
{
NOTICE_LOG(AUDIO, "Oboe driver stopping");
if (stream != nullptr)
{
// Don't let the AudioErrorCallback term/reinit while we are stopping
// This won't prevent shit to hit the fan if it's already in the process
// of doing so but this is a pretty rare event and happens on devices
// that have audio issues already.
auto localStream = stream;
stream.reset();
localStream->stop();
localStream->close();
}
}
u32 push(const void* frame, u32 samples, bool wait) override
{
while (!ringBuffer.write((const u8 *)frame, samples * 4) && wait)
pushWait.Wait();
return 1;
}
void termRecord() override
{
if (recordStream != nullptr)
{
recordStream->stop();
recordStream->close();
recordStream.reset();
}
NOTICE_LOG(AUDIO, "Oboe recorder stopped");
}
bool initRecord(u32 sampling_freq) override
{
oboe::AudioStreamBuilder builder;
oboe::Result result = builder.setDirection(oboe::Direction::Input)
->setPerformanceMode(oboe::PerformanceMode::None)
->setSharingMode(oboe::SharingMode::Exclusive)
->setFormat(oboe::AudioFormat::I16)
->setChannelCount(oboe::ChannelCount::Mono)
->setSampleRate(sampling_freq)
->openStream(recordStream);
if (result != oboe::Result::OK)
{
ERROR_LOG(AUDIO, "Oboe open record stream failed: %s", oboe::convertToText(result));
return false;
}
recordStream->requestStart();
NOTICE_LOG(AUDIO, "Oboe recorder started. stream capacity: %d frames",
recordStream->getBufferCapacityInFrames());
return true;
}
u32 record(void *data, u32 samples) override
{
if (recordStream == nullptr)
return 0;
oboe::ResultWithValue<int32_t> result = recordStream->read(data, samples, 0);
if (result == oboe::Result::ErrorDisconnected)
{
WARN_LOG(AUDIO, "Recording device lost. Attempting to reopen the audio stream");
u32 sampleRate = recordStream->getSampleRate();
termRecord();
initRecord(sampleRate);
}
return std::max(0, result.value());
}
};
static OboeBackend oboeBackend;
#endif
+337
View File
@@ -0,0 +1,337 @@
#if USE_OMX
#include "audiostream.h"
#include "cfg/option.h"
#include <IL/OMX_Broadcom.h>
#include <unistd.h>
#define PORT_INDEX 100
#define OUTPUT_FREQ 44100
class OMXAudioBackend : public AudioBackend
{
OMX_HANDLETYPE omx_handle = nullptr;
OMX_STATETYPE omx_state = OMX_StateInvalid;
size_t audio_buffer_idx = 0;
OMX_BUFFERHEADERTYPE** audio_buffers = nullptr;
u32 latency_max = 0;
u32 buffer_count = 0;
u32 buffer_size = 0;
u32 buffer_length = 0;
pthread_mutex_t audio_lock;
pthread_cond_t omx_state_cond;
static OMX_ERRORTYPE eventHandler(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR pEventData)
{
OMXAudioBackend *backend = (OMXAudioBackend *)pAddData;
pthread_mutex_lock(&backend->audio_lock);
if(eEvent == OMX_EventCmdComplete && nData1 == OMX_CommandStateSet)
{
backend->omx_state = (OMX_STATETYPE)nData2;
pthread_cond_signal(&backend->omx_state_cond);
}
pthread_mutex_unlock(&backend->audio_lock);
return OMX_ErrorNone;
}
static OMX_ERRORTYPE emptyBufferDone(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
{
return OMX_ErrorNone;
}
static OMX_ERRORTYPE fillBufferDone(
OMX_OUT OMX_HANDLETYPE hComponent,
OMX_OUT OMX_PTR pAppData,
OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
{
return OMX_ErrorNone;
}
void waitForState(OMX_STATETYPE state)
{
pthread_mutex_lock(&audio_lock);
while(omx_state != state)
pthread_cond_wait(&omx_state_cond, &audio_lock);
pthread_mutex_unlock(&audio_lock);
}
u32 getLatency()
{
OMX_PARAM_U32TYPE param;
memset(&param, 0, sizeof(OMX_PARAM_U32TYPE));
param.nSize = sizeof(OMX_PARAM_U32TYPE);
param.nVersion.nVersion = OMX_VERSION;
param.nPortIndex = PORT_INDEX;
OMX_ERRORTYPE error = OMX_GetConfig(omx_handle, OMX_IndexConfigAudioRenderingLatency, &param);
if(error != OMX_ErrorNone)
WARN_LOG(AUDIO, "OMX: failed to get OMX configuration (OMX_IndexConfigAudioRenderingLatency). Error 0x%X", error);
return param.nU32 * 1000 / OUTPUT_FREQ;
}
public:
OMXAudioBackend()
: AudioBackend("omx", "OpenMAX IL") {}
bool init() override
{
OMX_ERRORTYPE error;
error = OMX_Init();
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: OMX_Init() failed. Error 0x%X", error);
return false;
}
// Initialize settings
latency_max = config::OmxAudioLatency;
buffer_size = config::AudioBufferSize * 4;
buffer_count = 2 + OUTPUT_FREQ * latency_max / (buffer_size * 1000);
OMX_CALLBACKTYPE callbacks;
callbacks.EventHandler = eventHandler;
callbacks.EmptyBufferDone = emptyBufferDone;
callbacks.FillBufferDone = fillBufferDone;
error = OMX_GetHandle(&omx_handle, (OMX_STRING)"OMX.broadcom.audio_render", this, &callbacks);
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: OMX_GetHandle() failed. Error 0x%X", error);
OMX_Deinit();
return false;
}
OMX_PARAM_PORTDEFINITIONTYPE param;
memset(&param, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
param.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
param.nVersion.nVersion = OMX_VERSION;
param.nPortIndex = PORT_INDEX;
param.nBufferSize = buffer_size;
param.nBufferCountActual = buffer_count;
param.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
error = OMX_SetParameter(omx_handle, OMX_IndexParamPortDefinition, &param);
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: failed to set OMX_IndexParamPortDefinition. Error 0x%X", error);
OMX_Deinit();
return false;
}
OMX_AUDIO_PARAM_PCMMODETYPE pcm;
memset(&pcm, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
pcm.nSize = sizeof(OMX_AUDIO_PARAM_PCMMODETYPE);
pcm.nVersion.nVersion = OMX_VERSION;
pcm.nPortIndex = PORT_INDEX;
pcm.nChannels = 2;
pcm.eNumData = OMX_NumericalDataSigned;
pcm.eEndian = OMX_EndianLittle;
pcm.nSamplingRate = OUTPUT_FREQ;
pcm.bInterleaved = OMX_TRUE;
pcm.nBitPerSample = 16;
pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;
pcm.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
pcm.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
error = OMX_SetParameter(omx_handle, OMX_IndexParamAudioPcm, &pcm);
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: failed to set OMX_IndexParamAudioPcm. Error 0x%X", error);
OMX_Deinit();
return false;
}
// Disable all ports
error = OMX_SendCommand(omx_handle, OMX_CommandPortDisable, PORT_INDEX, NULL);
if (error != OMX_ErrorNone)
WARN_LOG(AUDIO, "OMX: failed to do OMX_CommandPortDisable. Error 0x%X", error);
OMX_PORT_PARAM_TYPE param2;
memset(&param2, 0, sizeof(OMX_PORT_PARAM_TYPE));
param2.nSize = sizeof(OMX_PORT_PARAM_TYPE);
param2.nVersion.nVersion = OMX_VERSION;
error = OMX_GetParameter(omx_handle, OMX_IndexParamOtherInit, &param2);
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: failed to get OMX_IndexParamOtherInit. Error 0x%X", error);
}
else
{
for(u32 i = 0; i < param2.nPorts; i++)
{
u32 port = param2.nStartPortNumber + i;
error = OMX_SendCommand(omx_handle, OMX_CommandPortDisable, port, NULL);
if(error != OMX_ErrorNone)
WARN_LOG(AUDIO, "OMX: failed to do OMX_CommandPortDisable on port %u. Error 0x%X", port, error);
}
}
// Go into idle state
error = OMX_SendCommand(omx_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: failed to set OMX_CommandStateSet. Error 0x%X", error);
OMX_Deinit();
return false;
}
waitForState(OMX_StateIdle);
// Check if we're in a state able to recieve buffers
OMX_STATETYPE state;
error = OMX_GetState(omx_handle, &state);
if (error != OMX_ErrorNone || !(state == OMX_StateIdle || state == OMX_StateExecuting || state == OMX_StatePause))
{
WARN_LOG(AUDIO, "OMX: state is incorrect. State 0x%X; Error 0x%X", state, error);
OMX_Deinit();
return false;
}
// Create audio buffers
INFO_LOG(AUDIO, "OMX: creating %u buffers", buffer_count);
// Enable port
error = OMX_SendCommand(omx_handle, OMX_CommandPortEnable, PORT_INDEX, NULL);
if (error != OMX_ErrorNone)
WARN_LOG(AUDIO, "OMX: failed to do OMX_CommandPortEnable. Error 0x%X", error);
// Free audio buffers if they're allocated
if (audio_buffers != NULL)
delete[] audio_buffers;
// Allocate buffers
audio_buffers = new OMX_BUFFERHEADERTYPE*[buffer_count];
for (size_t i = 0; i < buffer_count; i++)
{
error = OMX_AllocateBuffer(omx_handle, &audio_buffers[i], PORT_INDEX, NULL, buffer_size);
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: failed to allocate buffer[%u]. Error 0x%X", i, error);
OMX_Deinit();
return false;
}
}
// Set state to executing
error = OMX_SendCommand(omx_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: failed to do OMX_CommandStateSet. Error 0x%X", error);
OMX_Deinit();
return false;
}
waitForState(OMX_StateExecuting);
// Empty buffers
for (size_t i = 0; i < buffer_count; i++)
{
memset(audio_buffers[i]->pBuffer, 0, buffer_size);
audio_buffers[i]->nOffset = 0;
audio_buffers[i]->nFilledLen = buffer_size;
error = OMX_EmptyThisBuffer(omx_handle, audio_buffers[i]);
if(error != OMX_ErrorNone)
WARN_LOG(AUDIO, "OMX: failed to empty buffer[%u]. Error 0x%X", i, error);
}
const char* output_device = "local";
if (config::OmxAudioHdmi)
output_device = (const char*)"hdmi";
// Set audio destination
OMX_CONFIG_BRCMAUDIODESTINATIONTYPE ar_dest;
memset(&ar_dest, 0, sizeof(ar_dest));
ar_dest.nSize = sizeof(OMX_CONFIG_BRCMAUDIODESTINATIONTYPE);
ar_dest.nVersion.nVersion = OMX_VERSION;
strcpy((char *)ar_dest.sName, output_device);
error = OMX_SetConfig(omx_handle, OMX_IndexConfigBrcmAudioDestination, &ar_dest);
if (error != OMX_ErrorNone)
{
WARN_LOG(AUDIO, "OMX: failed to set OMX configuration (OMX_IndexConfigBrcmAudioDestination). Error 0x%X", error);
OMX_Deinit();
return false;
}
audio_buffer_idx = 0;
buffer_length = 0;
INFO_LOG(AUDIO, "OMX: audio output to '%s'", ar_dest.sName);
return true;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
if(audio_buffers == NULL)
return 1;
size_t data_size = samples * 4;
while(data_size > 0)
{
size_t copy_size = std::min(buffer_size - buffer_length, data_size);
// Don't have more than maximum audio latency
u32 latency = getLatency();
if(latency > latency_max)
{
usleep((latency - latency_max) * 1000);
}
else if(latency == 0)
{
INFO_LOG(AUDIO, "OMX: underrun occurred");
}
memcpy(audio_buffers[audio_buffer_idx]->pBuffer + buffer_length, frame, copy_size);
buffer_length += copy_size;
frame = (char *)frame + copy_size;
// Flush buffer and swap
if(buffer_length >= buffer_size)
{
audio_buffers[audio_buffer_idx]->nOffset = 0;
audio_buffers[audio_buffer_idx]->nFilledLen = buffer_size;
OMX_ERRORTYPE error = OMX_EmptyThisBuffer(omx_handle, audio_buffers[audio_buffer_idx]);
if(error != OMX_ErrorNone)
INFO_LOG(AUDIO, "OMX: failed to empty buffer[%u]. Error 0x%X", audio_buffer_idx, error);
audio_buffer_idx = (audio_buffer_idx + 1) % buffer_count;
buffer_length = 0;
}
data_size -= copy_size;
}
return 1;
}
void term() override
{
OMX_ERRORTYPE error;
// Is there anything else that needs to be done for omx?
error = OMX_Deinit();
if(error != OMX_ErrorNone)
WARN_LOG(AUDIO, "OMX: OMX_Deinit() failed. Error 0x%X", error);
if(audio_buffers != NULL)
{
delete[] audio_buffers;
audio_buffers = NULL;
}
}
};
static OMXAudioBackend omxAudioBackend;
#endif
+116
View File
@@ -0,0 +1,116 @@
#ifdef USE_OSS
#include "audiostream.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <unistd.h>
class OSSAudioBackend : public AudioBackend
{
int audioFD = -1;
int recordFD = -1;
public:
OSSAudioBackend()
: AudioBackend("oss", "Open Sound System") {}
bool init() override
{
audioFD = open("/dev/dsp", O_WRONLY);
if (audioFD < 0)
{
WARN_LOG(AUDIO, "Couldn't open /dev/dsp.");
return false;
}
INFO_LOG(AUDIO, "sound enabled, dsp opened for write");
int tmp=44100;
int err_ret;
err_ret=ioctl(audioFD,SNDCTL_DSP_SPEED,&tmp);
INFO_LOG(AUDIO, "set Frequency to %i, return %i (rate=%i)", 44100, err_ret, tmp);
int channels=2;
err_ret=ioctl(audioFD, SNDCTL_DSP_CHANNELS, &channels);
INFO_LOG(AUDIO, "set dsp to stereo (%i => %i)", channels, err_ret);
int format=AFMT_S16_LE;
err_ret=ioctl(audioFD, SNDCTL_DSP_SETFMT, &format);
INFO_LOG(AUDIO, "set dsp to %s audio (%i/%i => %i)", "16bits signed", AFMT_S16_LE, format, err_ret);
return true;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
write(audioFD, frame, samples * 4);
return 1;
}
void term() override
{
if (audioFD >= 0)
close(audioFD);
audioFD = -1;
}
// recording untested
bool initRecord(u32 sampling_freq) override
{
recordFD = open("/dev/dsp", O_RDONLY);
if (recordFD < 0)
{
INFO_LOG(AUDIO, "OSS: can't open default audio capture device");
return false;
}
int tmp = AFMT_S16_NE; // Native 16 bits
if (ioctl(recordFD, SNDCTL_DSP_SETFMT, &tmp) == -1 || tmp != AFMT_S16_NE)
{
INFO_LOG(AUDIO, "OSS: can't set sample format");
close(recordFD);
recordFD = -1;
return false;
}
tmp = 1;
if (ioctl(recordFD, SNDCTL_DSP_CHANNELS, &tmp) == -1)
{
INFO_LOG(AUDIO, "OSS: can't set channel count");
close(recordFD);
recordFD = -1;
return false;
}
tmp = sampling_freq;
if (ioctl(recordFD, SNDCTL_DSP_SPEED, &tmp) == -1)
{
INFO_LOG(AUDIO, "OSS: can't set sample rate");
close(recordFD);
recordFD = -1;
return false;
}
return true;
}
void termRecord() override
{
if (recordFD >= 0)
close(recordFD);
recordFD = -1;
}
u32 record(void *buffer, u32 samples) override
{
samples *= 2;
int l = read(recordFD, buffer, samples);
if (l < (int)samples)
{
if (l < 0)
{
INFO_LOG(AUDIO, "OSS: Recording error");
l = 0;
}
memset((u8 *)buffer + l, 0, samples - l);
}
return l / 2;
}
};
static OSSAudioBackend ossAudioBackend;
#endif
+252
View File
@@ -0,0 +1,252 @@
#ifdef USE_PULSEAUDIO
#include "audiostream.h"
#include "cfg/option.h"
#include <pulse/pulseaudio.h>
class PulseAudioBackend : public AudioBackend
{
pa_threaded_mainloop *mainloop = nullptr;
pa_context *context = nullptr;
pa_stream *stream = nullptr;
pa_stream *record_stream = nullptr;
static void context_state_cb(pa_context *c, void *userdata)
{
PulseAudioBackend *backend = (PulseAudioBackend *)userdata;
switch (pa_context_get_state(c))
{
case PA_CONTEXT_READY:
case PA_CONTEXT_TERMINATED:
case PA_CONTEXT_FAILED:
pa_threaded_mainloop_signal(backend->mainloop, 0);
break;
default:
break;
}
}
static void stream_request_cb(pa_stream *s, size_t length, void *userdata)
{
PulseAudioBackend *backend = (PulseAudioBackend *)userdata;
pa_threaded_mainloop_signal(backend->mainloop, 0);
}
public:
PulseAudioBackend()
: AudioBackend("pulse", "PulseAudio") {}
bool init() override
{
mainloop = pa_threaded_mainloop_new();
if (!mainloop)
{
WARN_LOG(AUDIO, "PulseAudio: pa_threaded_mainloop_new failed");
return false;
}
context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), "flycast");
if (!context)
{
WARN_LOG(AUDIO, "PulseAudio: pa_context_new failed");
term();
return false;
}
pa_context_set_state_callback(context, context_state_cb, this);
if (pa_context_connect(context, nullptr, PA_CONTEXT_NOFLAGS, nullptr) < 0)
{
WARN_LOG(AUDIO, "PulseAudio: pa_context_connect failed");
term();
return false;
}
pa_threaded_mainloop_lock(mainloop);
if (pa_threaded_mainloop_start(mainloop) < 0)
{
WARN_LOG(AUDIO, "PulseAudio: pa_threaded_mainloop_start failed");
pa_threaded_mainloop_unlock(mainloop);
term();
return false;
}
pa_threaded_mainloop_wait(mainloop);
if (pa_context_get_state(context) != PA_CONTEXT_READY)
{
WARN_LOG(AUDIO, "PulseAudio: context isn't ready");
pa_threaded_mainloop_unlock(mainloop);
term();
return false;
}
pa_sample_spec spec{ PA_SAMPLE_S16LE, 44100, 2 };
stream = pa_stream_new(context, "audio", &spec, NULL);
if (!stream)
{
WARN_LOG(AUDIO, "PulseAudio: pa_stream_new failed");
pa_threaded_mainloop_unlock(mainloop);
term();
return false;
}
//pa_stream_set_state_callback(stream, stream_state_cb, this);
pa_stream_set_write_callback(stream, stream_request_cb, this);
//pa_stream_set_latency_update_callback(stream, stream_latency_update_cb, this);
//pa_stream_set_underflow_callback(stream, underrun_update_cb, this);
//pa_stream_set_buffer_attr_callback(stream, buffer_attr_cb, this);
pa_buffer_attr buffer_attr;
buffer_attr.maxlength = -1;
buffer_attr.tlength = pa_usec_to_bytes(config::AudioBufferSize * PA_USEC_PER_SEC / 44100, &spec);
buffer_attr.prebuf = -1;
buffer_attr.minreq = -1;
buffer_attr.fragsize = -1;
if (pa_stream_connect_playback(stream, nullptr, &buffer_attr, PA_STREAM_ADJUST_LATENCY, nullptr, nullptr) < 0)
{
WARN_LOG(AUDIO, "PulseAudio: pa_stream_connect_playback failed");
pa_threaded_mainloop_unlock(mainloop);
term();
return false;
}
pa_threaded_mainloop_wait(mainloop);
if (pa_stream_get_state(stream) != PA_STREAM_READY)
{
WARN_LOG(AUDIO, "PulseAudio: stream isn't ready");
pa_threaded_mainloop_unlock(mainloop);
term();
return false;
}
const pa_buffer_attr *server_attr = pa_stream_get_buffer_attr(stream);
if (server_attr)
DEBUG_LOG(AUDIO, "PulseAudio: requested %d samples buffer, got %d", buffer_attr.tlength / 4, server_attr->tlength / 4);
pa_threaded_mainloop_unlock(mainloop);
return true;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
const u8 *buf = (const u8 *)frame;
size_t size = samples * 4;
pa_threaded_mainloop_lock(mainloop);
while (size)
{
size_t writable = std::min(size, pa_stream_writable_size(stream));
if (writable)
{
pa_stream_write(stream, buf, writable, NULL, 0, PA_SEEK_RELATIVE);
buf += writable;
size -= writable;
}
else if (wait)
pa_threaded_mainloop_wait(mainloop);
else
break;
}
pa_threaded_mainloop_unlock(mainloop);
return 0;
}
void term() override
{
if (mainloop)
pa_threaded_mainloop_stop(mainloop);
if (stream)
{
pa_stream_disconnect(stream);
pa_stream_unref(stream);
stream = nullptr;
}
if (context)
{
pa_context_disconnect(context);
pa_context_unref(context);
context = nullptr;
}
if (mainloop)
pa_threaded_mainloop_free(mainloop);
mainloop = nullptr;
}
bool initRecord(u32 sampling_freq) override
{
pa_sample_spec spec{ PA_SAMPLE_S16LE, sampling_freq, 1 };
record_stream = pa_stream_new(context, "record", &spec, NULL);
if (!record_stream)
{
INFO_LOG(AUDIO, "PulseAudio: pa_stream_new failed");
return false;
}
pa_threaded_mainloop_lock(mainloop);
pa_buffer_attr buffer_attr;
buffer_attr.fragsize = 240 * 2;
buffer_attr.maxlength = buffer_attr.fragsize * 2;
if (pa_stream_connect_record(record_stream, nullptr, &buffer_attr, PA_STREAM_NOFLAGS) < 0)
{
INFO_LOG(AUDIO, "PulseAudio: pa_stream_connect_record failed");
pa_stream_unref(record_stream);
record_stream = nullptr;
return false;
}
pa_threaded_mainloop_unlock(mainloop);
INFO_LOG(AUDIO, "PulseAudio: Successfully initialized capture device");
return true;
}
void termRecord() override
{
if (record_stream != nullptr)
{
pa_threaded_mainloop_lock(mainloop);
pa_stream_disconnect(record_stream);
pa_stream_unref(record_stream);
record_stream = nullptr;
pa_threaded_mainloop_unlock(mainloop);
}
}
u32 record(void *buffer, u32 samples) override
{
if (record_stream == nullptr)
return 0;
pa_threaded_mainloop_lock(mainloop);
const void *data;
size_t size;
if (pa_stream_peek(record_stream, &data, &size) < 0)
{
pa_threaded_mainloop_unlock(mainloop);
DEBUG_LOG(AUDIO, "PulseAudio: pa_stream_peek error");
return 0;
}
if (size == 0)
{
pa_threaded_mainloop_unlock(mainloop);
return 0;
}
size = std::min((size_t)samples * 2, size);
if (data != nullptr)
memcpy(buffer, data, size);
else
memset(buffer, 0, size);
pa_stream_drop(record_stream);
pa_threaded_mainloop_unlock(mainloop);
return size / 2;
}
};
static PulseAudioBackend pulseAudioBackend;
#endif
+243
View File
@@ -0,0 +1,243 @@
#if defined(USE_SDL_AUDIO)
#include <SDL.h>
#include "audiostream.h"
#include "cfg/option.h"
#include "stdclass.h"
#include <algorithm>
#include <atomic>
#include <mutex>
class SDLAudioBackend : AudioBackend
{
SDL_AudioDeviceID audiodev {};
bool needs_resampling = false;
cResetEvent read_wait;
std::mutex stream_mutex;
uint32_t *sample_buffer;
unsigned sample_buffer_size = 0;
unsigned sample_count = 0;
SDL_AudioCVT audioCvt;
SDL_AudioDeviceID recorddev {};
u8 recordbuf[480 * 4];
std::atomic<size_t> rec_read;
std::atomic<size_t> rec_write;
static void audioCallback(void* userdata, Uint8* stream, int len)
{
SDLAudioBackend *backend = (SDLAudioBackend *)userdata;
backend->stream_mutex.lock();
// Wait until there's enough samples to feed the kraken
unsigned oslen = len / sizeof(uint32_t);
unsigned islen = backend->needs_resampling ? std::ceil(oslen / backend->audioCvt.len_ratio) : oslen;
if (backend->sample_count < islen)
{
// No data, just output a bit of silence for the underrun
memset(stream, 0, len);
backend->stream_mutex.unlock();
backend->read_wait.Set();
return;
}
if (!backend->needs_resampling) {
// Just copy bytes for this case.
memcpy(stream, &backend->sample_buffer[0], len);
}
else
{
SDL_AudioCVT& cvt = backend->audioCvt;
cvt.len = islen * sizeof(uint32_t);
memcpy(cvt.buf, &backend->sample_buffer[0], cvt.len);
SDL_ConvertAudio(&cvt);
memcpy(stream, cvt.buf, cvt.len_cvt);
}
// Move samples in the buffer and consume them
memmove(&backend->sample_buffer[0], &backend->sample_buffer[islen], (backend->sample_count - islen) * sizeof(uint32_t));
backend->sample_count -= islen;
backend->stream_mutex.unlock();
backend->read_wait.Set();
}
public:
SDLAudioBackend()
: AudioBackend("sdl2", "Simple DirectMedia Layer 2 Audio") {}
bool init() override
{
if (!SDL_WasInit(SDL_INIT_AUDIO))
{
if (SDL_InitSubSystem(SDL_INIT_AUDIO)) {
ERROR_LOG(AUDIO, "SDL2 error initializing audio subsystem: %s", SDL_GetError());
return false;
}
}
sample_buffer_size = std::max<u32>(SAMPLE_COUNT * 2, config::AudioBufferSize);
sample_buffer = new uint32_t[sample_buffer_size]();
sample_count = 0;
// Support 44.1KHz (native) but also upsampling to 48KHz
SDL_AudioSpec wav_spec, out_spec;
memset(&wav_spec, 0, sizeof(wav_spec));
wav_spec.freq = 44100;
wav_spec.format = AUDIO_S16;
wav_spec.channels = 2;
wav_spec.samples = SAMPLE_COUNT * 2; // Must be power of two
wav_spec.callback = audioCallback;
wav_spec.userdata = this;
needs_resampling = false;
// Try 44.1KHz which should be faster since it's native.
audiodev = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &out_spec, 0);
if (audiodev == 0)
{
INFO_LOG(AUDIO, "SDL2: SDL_OpenAudioDevice failed: %s", SDL_GetError());
needs_resampling = true;
wav_spec.freq = 48000;
audiodev = SDL_OpenAudioDevice(NULL, 0, &wav_spec, &out_spec, 0);
if (audiodev == 0)
ERROR_LOG(AUDIO, "SDL2: SDL_OpenAudioDevice failed: %s", SDL_GetError());
else
{
INFO_LOG(AUDIO, "SDL2: Using resampling to 48 KHz");
int ret = SDL_BuildAudioCVT(&audioCvt, AUDIO_S16, 2, 44100, AUDIO_S16, 2, 48000);
if (ret != 1 || audioCvt.needed == 0)
{
ERROR_LOG(AUDIO, "SDL2: can't build audio converter: %s", SDL_GetError());
SDL_CloseAudioDevice(audiodev);
audiodev = 0;
}
else
{
audioCvt.buf = new u8[SAMPLE_COUNT * 2 * sizeof(uint32_t) * audioCvt.len_mult];
}
}
}
return audiodev != 0;
}
u32 push(const void* frame, u32 samples, bool wait) override
{
// Unpause the device shall it be paused.
if (SDL_GetAudioDeviceStatus(audiodev) != SDL_AUDIO_PLAYING)
SDL_PauseAudioDevice(audiodev, 0);
// If wait, then wait for the buffer to be smaller than a certain size.
stream_mutex.lock();
if (wait) {
while (sample_count + samples > sample_buffer_size) {
stream_mutex.unlock();
read_wait.Wait();
stream_mutex.lock();
}
}
// Copy as many samples as possible, drop any remaining (this should not happen usually)
unsigned free_samples = sample_buffer_size - sample_count;
unsigned tocopy = samples < free_samples ? samples : free_samples;
memcpy(&sample_buffer[sample_count], frame, tocopy * sizeof(uint32_t));
sample_count += tocopy;
stream_mutex.unlock();
return 1;
}
void term() override
{
if (audiodev)
{
// Stop audio playback.
SDL_PauseAudioDevice(audiodev, 1);
read_wait.Set();
SDL_CloseAudioDevice(audiodev);
audiodev = SDL_AudioDeviceID();
}
delete [] sample_buffer;
sample_buffer = nullptr;
if (needs_resampling)
{
delete [] audioCvt.buf;
audioCvt.buf = nullptr;
}
}
static void recordCallback(void *userdata, u8 *stream, int len)
{
SDLAudioBackend *backend = (SDLAudioBackend *)userdata;
DEBUG_LOG(AUDIO, "SDL2: sdl2_record_cb len %d write %zd read %zd", len, (size_t)backend->rec_write, (size_t)backend->rec_read);
while (len > 0)
{
size_t plen = std::min((size_t)len, sizeof(backend->recordbuf) - backend->rec_write);
memcpy(&backend->recordbuf[backend->rec_write], stream, plen);
len -= plen;
backend->rec_write = (backend->rec_write + plen) % sizeof(backend->recordbuf);
stream += plen;
}
}
bool initRecord(u32 sampling_freq) override
{
rec_write = 0;
rec_read = 0;
SDL_AudioSpec wav_spec, out_spec;
memset(&wav_spec, 0, sizeof(wav_spec));
wav_spec.freq = sampling_freq;
wav_spec.format = AUDIO_S16;
wav_spec.channels = 1;
wav_spec.samples = 256; // Must be power of two
wav_spec.callback = recordCallback;
wav_spec.userdata = this;
recorddev = SDL_OpenAudioDevice(NULL, 1, &wav_spec, &out_spec, 0);
if (recorddev == 0)
{
ERROR_LOG(AUDIO, "SDL2: Cannot open audio capture device: %s", SDL_GetError());
return false;
}
SDL_PauseAudioDevice(recorddev, 0);
INFO_LOG(AUDIO, "SDL2: opened audio capture device");
return true;
}
void termRecord() override
{
if (recorddev != 0)
{
SDL_PauseAudioDevice(recorddev, 1);
SDL_CloseAudioDevice(recorddev);
recorddev = 0;
}
}
u32 record(void* frame, u32 samples) override
{
u32 count = 0;
samples *= 2;
while (samples > 0)
{
u32 avail = std::min(rec_write - rec_read, sizeof(recordbuf) - rec_read);
if (avail == 0)
break;
avail = std::min(avail, samples);
memcpy((u8 *)frame + count, &recordbuf[rec_read], avail);
rec_read = (rec_read + avail) % sizeof(recordbuf);
samples -= avail;
count += avail;
}
DEBUG_LOG(AUDIO, "SDL2: sdl2_record len %d ret %d write %zd read %zd", samples * 2, count, (size_t)rec_write, (size_t)rec_read);
return count / 2;
}
};
static SDLAudioBackend sdlAudioBackend;
#endif
+140
View File
@@ -0,0 +1,140 @@
#include "audiostream.h"
#include "cfg/option.h"
struct SoundFrame { s16 l; s16 r; };
static SoundFrame Buffer[SAMPLE_COUNT];
static u32 writePtr; // next sample index
static AudioBackend *currentBackend;
std::vector<AudioBackend *> *AudioBackend::backends;
static bool audio_recording_started;
static bool eight_khz;
AudioBackend *AudioBackend::getBackend(const std::string& slug)
{
if (backends == nullptr)
return nullptr;
if (slug == "auto")
{
// Prefer sdl2 if available and avoid the null driver
AudioBackend *sdlBackend = nullptr;
AudioBackend *autoBackend = nullptr;
for (auto backend : *backends)
{
if (backend->slug == "sdl2")
sdlBackend = backend;
if (backend->slug != "null" && autoBackend == nullptr)
autoBackend = backend;
}
if (sdlBackend != nullptr)
autoBackend = sdlBackend;
if (autoBackend == nullptr)
autoBackend = backends->front();
INFO_LOG(AUDIO, "Auto-selected audio backend \"%s\" (%s).", autoBackend->slug.c_str(), autoBackend->name.c_str());
return autoBackend;
}
for (auto backend : *backends)
{
if (backend->slug == slug)
return backend;
}
WARN_LOG(AUDIO, "WARNING: Audio backend \"%s\" not found!", slug.c_str());
return nullptr;
}
void WriteSample(s16 r, s16 l)
{
Buffer[writePtr].r = r * config::AudioVolume.dbPower();
Buffer[writePtr].l = l * config::AudioVolume.dbPower();
if (++writePtr == SAMPLE_COUNT)
{
if (currentBackend != nullptr)
currentBackend->push(Buffer, SAMPLE_COUNT, config::LimitFPS);
writePtr = 0;
}
}
void InitAudio()
{
TermAudio();
std::string slug = config::AudioBackend;
currentBackend = AudioBackend::getBackend(slug);
if (currentBackend == nullptr && slug != "auto")
{
slug = "auto";
currentBackend = AudioBackend::getBackend(slug);
}
if (currentBackend != nullptr)
{
INFO_LOG(AUDIO, "Initializing audio backend \"%s\" (%s)...", currentBackend->slug.c_str(), currentBackend->name.c_str());
if (!currentBackend->init())
{
currentBackend = nullptr;
if (slug != "auto")
{
WARN_LOG(AUDIO, "Audio driver %s failed to initialize. Defaulting to 'auto'", slug.c_str());
slug = "auto";
currentBackend = AudioBackend::getBackend(slug);
if (!currentBackend->init())
currentBackend = nullptr;
}
}
}
if (currentBackend == nullptr)
{
WARN_LOG(AUDIO, "Running without audio!");
return;
}
if (audio_recording_started)
{
// Restart recording
audio_recording_started = false;
StartAudioRecording(eight_khz);
}
}
void TermAudio()
{
if (currentBackend == nullptr)
return;
// Save recording state before stopping
bool rec_started = audio_recording_started;
StopAudioRecording();
audio_recording_started = rec_started;
currentBackend->term();
INFO_LOG(AUDIO, "Terminating audio backend \"%s\" (%s)...", currentBackend->slug.c_str(), currentBackend->name.c_str());
currentBackend = nullptr;
}
void StartAudioRecording(bool eight_khz)
{
::eight_khz = eight_khz;
if (currentBackend != nullptr)
audio_recording_started = currentBackend->initRecord(eight_khz ? 8000 : 11025);
else
// might be called between TermAudio/InitAudio
audio_recording_started = true;
}
u32 RecordAudio(void *buffer, u32 samples)
{
if (!audio_recording_started || currentBackend == nullptr)
return 0;
return currentBackend->record(buffer, samples);
}
void StopAudioRecording()
{
// might be called between TermAudio/InitAudio
if (audio_recording_started && currentBackend != nullptr)
currentBackend->termRecord();
audio_recording_started = false;
}
+131
View File
@@ -0,0 +1,131 @@
#pragma once
#include "types.h"
#include <algorithm>
#include <atomic>
#include <cstring>
#include <string>
#include <vector>
class AudioBackend
{
public:
virtual ~AudioBackend() = default;
virtual bool init() = 0;
virtual u32 push(const void *data, u32 frames, bool wait) = 0;
virtual void term() {}
struct Option {
std::string name;
std::string caption;
enum { integer, checkbox, list } type;
int minValue;
int maxValue;
std::vector<std::string> values;
};
virtual const Option *getOptions(int *count) {
*count = 0;
return nullptr;
}
virtual bool initRecord(u32 sampling_freq) { return false; }
virtual u32 record(void *, u32) { return 0; }
virtual void termRecord() {}
std::string slug;
std::string name;
static size_t getCount() { return backends == nullptr ? 0 : backends->size(); }
static AudioBackend *getBackend(size_t index) { return backends == nullptr ? nullptr : (*backends)[index]; }
static AudioBackend *getBackend(const std::string& slug);
protected:
AudioBackend(const std::string& slug, const std::string& name)
: slug(slug), name(name) {
registerAudioBackend(this);
}
private:
static void registerAudioBackend(AudioBackend *backend)
{
if (backends == nullptr)
backends = new std::vector<AudioBackend *>();
backends->push_back(backend);
std::sort(backends->begin(), backends->end(), [](AudioBackend *b1, AudioBackend *b2) { return b1->slug < b2->slug; });
}
static std::vector<AudioBackend *> *backends;
};
void InitAudio();
void TermAudio();
void WriteSample(s16 right, s16 left);
void StartAudioRecording(bool eight_khz);
u32 RecordAudio(void *buffer, u32 samples);
void StopAudioRecording();
constexpr u32 SAMPLE_COUNT = 512; // AudioBackend::push() is always called with that many frames
class RingBuffer
{
std::vector<u8> buffer;
std::atomic_int readCursor { 0 };
std::atomic_int writeCursor { 0 };
u32 readSize() {
return (u32)((writeCursor - readCursor + buffer.size()) % buffer.size());
}
u32 writeSize() {
return (u32)((readCursor - writeCursor + buffer.size() - 1) % buffer.size());
}
public:
bool write(const u8 *data, u32 size)
{
if (size > writeSize())
return false;
u32 wc = writeCursor;
u32 chunkSize = std::min<u32>(size, (u32)buffer.size() - wc);
memcpy(&buffer[wc], data, chunkSize);
wc = (wc + chunkSize) % buffer.size();
size -= chunkSize;
if (size > 0)
{
data += chunkSize;
memcpy(&buffer[wc], data, size);
wc = (wc + size) % buffer.size();
}
writeCursor = wc;
return true;
}
bool read(u8 *data, u32 size)
{
if (size > readSize())
return false;
u32 rc = readCursor;
u32 chunkSize = std::min<u32>(size, (u32)buffer.size() - rc);
memcpy(data, &buffer[rc], chunkSize);
rc = (rc + chunkSize) % buffer.size();
size -= chunkSize;
if (size > 0)
{
data += chunkSize;
memcpy(data, &buffer[rc], size);
rc = (rc + size) % buffer.size();
}
readCursor = rc;
return true;
}
void setCapacity(size_t size)
{
std::fill(buffer.begin(), buffer.end(), 0);
buffer.resize(size);
readCursor = 0;
writeCursor = 0;
}
};
+35 -167
View File
@@ -1,134 +1,16 @@
/*
reicast build options
Reicast can support a lot of stuff, and this is an attempt
to organize the build time options
Option categories
BUILD_* - BUILD_COMPILER, etc...
definitions about the build machine
HOST_*
definitions about the host machine
FEAT_*
definitions about the features that this build targets
This is higly related to HOST_*, but it's for options that might
or might not be avaiable depending on the target host, or that
features that are irrelevant of the host
Eg, Alsa, Pulse Audio and OSS might sense as HOST dedinitions
but it usually makes more sense to detect them as runtime. In
that context, HOST_ALSA makes no sense because the host might
or might not have alsa installed/ running
MMU makes no sense as a HOST definition at all, so it should
be FEAT_HAS_MMU
TARGET_*
A preconfigured default. Eg TARGET_WIN86.
Naming of options, option values, and how to use them
for options that makes sense to have a list of values
{CATEGORY}_{OPTION}
{OPTION}_{VALUE}
eg.
BUILD_COMPILER == COMPILER_GCC, HOST_CPU != CPU_X64, ...
for options that are boolean
{CATEGORY}_IS_{OPTION} or {CATEGORY}_HAS_{OPTION}
Evaluates to 0 or 1
If an configuration cannot be neatly split into a set of
of orthogonal options, then it makes sense to break things
to "sets" or have a hierarchy of options.
Example
-------
In the beggining it made sense to have an audio backend
per operating system. It made sense to have it depend
on HOST_OS and seleect DirectSound or alsa.
// no option needed
Then, as android was introduced, which also uses OS_LINUX
atm, the audio could have been made an option. It could be
a HOST_* option, or FEAT_* one. I'd prefer FEAT_*.
FEAT_* makes more sense as future wise we might want
to support multiple backends.
FEAT_AUDIO_BACKEND
AUDIO_BACKEND_NONE
AUDIO_BACKEND_DS
AUDIO_BACKEND_ALSA
AUDIO_BACKEND_ANDROID
Used like
#if FEAT_AUDIO_BACKEND == AUDIO_BACKEND_DS ....
At some point, we might have multiple audio backends that
can be compiled in and autodetected/selected at runtime.
In that case, it might make sense to have the options like
FEAT_HAS_ALSA
FEAT_HAS_DIRECTSOUND
FEAT_HAS_ANDROID_AUDIO
or
FEAT_HAS_AUDIO_ALSA
FEAT_HAS_AUDIO_DS
FEAT_HAS_AUDIO_ANDROID
The none option might or might not make sense. In this
case it can be removed, as it should always be avaiable.
Guidelines
----------
General rule of thumb, don't overcomplicate things. Start
with a simple option, and then make it more complicated
as new uses apply (see the example above)
Don't use too long names, don't use too cryptic names.
Most team developers should be able to understand or
figure out most of the acronyms used.
Try to be consistent on the acronyms across all definitions
Code shouldn't depend on build level options whenever possible
Generally, the file should compile even if the option/module is
disabled. This makes makefiles etc much easier to write
TARGET_* options should generally only be used in this file
The current source is *not* good example of these guidelines
We'll try to be smart and figure out some options/defaults on this file
but this shouldn't get too complicated
*/
#pragma once
//#define STRICT_MODE
#ifndef STRICT_MODE
#define FAST_MMU
#define USE_WINCE_HACK
#endif
#define DC_PLATFORM_MASK 7
#define DC_PLATFORM_DREAMCAST 0 /* Works, for the most part */
#define DC_PLATFORM_DEV_UNIT 1 /* This is missing hardware */
#define DC_PLATFORM_NAOMI 2 /* Works, for the most part */
#define DC_PLATFORM_NAOMI2 3 /* Needs to be done, 2xsh4 + 2xpvr + custom TNL */
#define DC_PLATFORM_ATOMISWAVE 4 /* Works, for the most part */
#define DC_PLATFORM_HIKARU 5 /* Needs to be done, 2xsh4, 2x aica , custom vpu */
#define DC_PLATFORM_AURORA 6 /* Needs to be done, Uses newer 300 mhz sh4 + 150 mhz pvr mbx SoC */
#define DC_PLATFORM_DREAMCAST 0
#define DC_PLATFORM_DEV_UNIT 1
#define DC_PLATFORM_NAOMI 2
#define DC_PLATFORM_NAOMI2 3
#define DC_PLATFORM_ATOMISWAVE 4
#define DC_PLATFORM_SYSTEMSP 5
//HOST_CPU
#define CPU_X86 0x20000001
@@ -139,13 +21,10 @@
#define CPU_PPC 0x20000006
#define CPU_PPC64 0x20000007
#define CPU_ARM64 0x20000008
#define CPU_MIPS64 0x20000009
//FEAT_SHREC, FEAT_AREC, FEAT_DSPREC
#define DYNAREC_NONE 0x40000001
#define DYNAREC_JIT 0x40000002
#define DYNAREC_CPP 0x40000003
//automatic
@@ -175,19 +54,17 @@
#define FEAT_DSPREC DYNAREC_NONE
#endif
#if defined(TARGET_NO_JIT)
#define FEAT_SHREC DYNAREC_CPP
#define FEAT_AREC DYNAREC_NONE
#define FEAT_DSPREC DYNAREC_NONE
#ifdef __SWITCH__
#define FEAT_NO_RWX_PAGES
#endif
//defaults
#ifndef FEAT_SHREC
#if HOST_CPU == CPU_MIPS
#define FEAT_SHREC DYNAREC_NONE
#else
#if HOST_CPU == CPU_ARM || HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X86 || HOST_CPU == CPU_X64
#define FEAT_SHREC DYNAREC_JIT
#else
#define FEAT_SHREC DYNAREC_NONE
#endif
#endif
@@ -200,30 +77,13 @@
#endif
#ifndef FEAT_DSPREC
#if HOST_CPU == CPU_X86 || HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X64
#if HOST_CPU == CPU_ARM || HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X86 || HOST_CPU == CPU_X64
#define FEAT_DSPREC DYNAREC_JIT
#else
#define FEAT_DSPREC DYNAREC_NONE
#endif
#endif
#if HOST_CPU == CPU_X64 || HOST_CPU == CPU_ARM64
#define HOST_64BIT_CPU
#endif
#define USE_MINIUPNPC
// Compiler Related
#ifndef _MSC_VER
#define ATTR_USED __attribute__((used))
#define ATTR_UNUSED __attribute__((used))
#else
#define ATTR_USED
#define ATTR_UNUSED
#endif
// Some restrictions on FEAT_NO_RWX_PAGES
#if defined(FEAT_NO_RWX_PAGES) && FEAT_SHREC == DYNAREC_JIT
#if HOST_CPU != CPU_X64 && HOST_CPU != CPU_ARM64
@@ -231,22 +91,30 @@
#endif
#endif
#ifdef _WIN32
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define TARGET_UWP
#endif
#ifdef HAVE_D3D11
#define USE_DX11
#endif
#endif
#if !defined(LIBRETRO) && !defined(TARGET_NO_EXCEPTIONS)
#define USE_GGPO
#endif
#if !defined(__ANDROID__) && !defined(TARGET_IPHONE) && !defined(TARGET_UWP) \
&& !defined(__SWITCH__) && !defined(LIBRETRO) && !defined(__NetBSD__) && !defined(__OpenBSD__)
#define NAOMI_MULTIBOARD
#endif
// TARGET PLATFORM
#define RAM_SIZE_MAX (32*1024*1024)
#define VRAM_SIZE_MAX (16*1024*1024)
#define ARAM_SIZE_MAX (8*1024*1024)
#define GD_CLOCK 33868800 //GDROM XTAL -- 768fs
#define AICA_CORE_CLOCK (GD_CLOCK*4/3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs
#define ADAC_CLOCK (AICA_CORE_CLOCK/4) //[11289600] 44100*256, AICA CORE -> PLL 4:1 -> ADAC -- 256fs
#define AICA_ARM_CLOCK (AICA_CORE_CLOCK/2) //[22579200] AICA CORE -> PLL 2:1 -> ARM
#define AICA_SDRAM_CLOCK (GD_CLOCK*2) //[67737600] GD-> PLL 2 -> SDRAM
#define SH4_MAIN_CLOCK (200*1000*1000) //[200000000] XTal(13.5) -> PLL (33.3) -> PLL 1:6 (200)
#define SH4_RAM_CLOCK (100*1000*1000) //[100000000] XTal(13.5) -> PLL (33.3) -> PLL 1:3 (100) , also suplied to HOLLY chip
#define G2_BUS_CLOCK (25*1000*1000) //[25000000] from Holly, from SH4_RAM_CLOCK w/ 2 2:1 plls
#define GD_CLOCK 33868800 //GDROM XTAL -- 768fs
#define AICA_CORE_CLOCK (GD_CLOCK * 4 / 3) //[45158400] GD->PLL 3:4 -> AICA CORE -- 1024fs
#define AICA_ARM_CLOCK (AICA_CORE_CLOCK / 2) //[22579200] AICA CORE -> PLL 2:1 -> ARM
#define SH4_MAIN_CLOCK (200 * 1000 * 1000) //[200000000] XTal(13.5) -> PLL (33.3) -> PLL 1:6 (200)
#define G2_BUS_CLOCK (25 * 1000 * 1000) //[25000000] from Holly, from SH4_RAM_CLOCK w/ 2 2:1 plls
#if defined(GLES) && !defined(GLES3) && !defined(GLES2)
// Only use GL ES 2.0 API functions
+12
View File
@@ -82,6 +82,13 @@ s32 cfgLoadInt(const std::string& section, const std::string& key, s32 def)
return cfgdb.get_int(section, key, def);
}
int64_t cfgLoadInt64(const std::string& section, const std::string& key, int64_t def) {
return cfgdb.get_int64(section, key, def);
}
void cfgSaveInt64(const std::string& section, const std::string& key, int64_t value) {
cfgdb.set_int64(section, key, value);
}
void cfgSaveBool(const std::string& section, const std::string& key, bool value)
{
cfgSaveStr(section, key, value ? "yes" : "no");
@@ -112,6 +119,11 @@ void cfgDeleteSection(const std::string& section)
cfgdb.delete_section(section);
}
void cfgDeleteEntry(const std::string& section, const std::string& key)
{
cfgdb.delete_entry(section, key);
}
void cfgSetAutoSave(bool autoSave)
{
::autoSave = autoSave;
+4 -1
View File
@@ -5,6 +5,8 @@
bool cfgOpen();
s32 cfgLoadInt(const std::string& section, const std::string& key, s32 def);
void cfgSaveInt(const std::string& section, const std::string& key, s32 value);
int64_t cfgLoadInt64(const std::string& section, const std::string& key, int64_t def);
void cfgSaveInt64(const std::string& section, const std::string& key, int64_t value);
std::string cfgLoadStr(const std::string& section, const std::string& key, const std::string& def);
void cfgSaveStr(const std::string& section, const std::string& key, const std::string& value);
void cfgSaveBool(const std::string& section, const std::string& key, bool value);
@@ -12,8 +14,9 @@ bool cfgLoadBool(const std::string& section, const std::string& key, bool def);
void cfgSetVirtual(const std::string& section, const std::string& key, const std::string& value);
bool cfgIsVirtual(const std::string& section, const std::string& key);
bool ParseCommandLine(int argc, char *argv[]);
void ParseCommandLine(int argc, char *argv[]);
void cfgSetAutoSave(bool autoSave);
bool cfgHasSection(const std::string& section);
void cfgDeleteSection(const std::string& section);
void cfgDeleteEntry(const std::string& section, const std::string& key);
+48 -71
View File
@@ -1,92 +1,66 @@
/*
Command line parsing
~yay~
Nothing too interesting here, really
*/
#include <cstdio>
#include <cctype>
#include <cstring>
#include "cfg/cfg.h"
#include "stdclass.h"
char* trim_ws(char* str)
{
if (str==0 || strlen(str)==0)
return 0;
while(*str)
{
if (!isspace(*str))
break;
str++;
}
size_t l=strlen(str);
if (l==0)
return 0;
while(l>0)
{
if (!isspace(str[l-1]))
break;
str[l-1]=0;
l--;
}
if (l==0)
return 0;
return str;
}
int setconfig(char** arg,int cl)
static int setconfig(char *arg[], int cl)
{
int rv=0;
for(;;)
if (cl < 1)
{
if (cl<1)
WARN_LOG(COMMON, "-config : invalid number of parameters, format is section:key=value,section:key=value,...");
return rv;
}
std::string value(arg[1]);
for(;;)
{
auto seppos = value.find(':');
if (seppos == std::string::npos)
{
WARN_LOG(COMMON, "-config : invalid number of parameters, format is section:key=value");
return rv;
WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value,section:key=value,...", value.c_str());
break;
}
char* sep=strstr(arg[1],":");
if (sep==0)
auto eqpos = value.find('=', seppos);
if (eqpos == std::string::npos)
{
WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value", arg[1]);
return rv;
}
char* value=strstr(sep+1,"=");
if (value==0)
{
WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value", arg[1]);
return rv;
WARN_LOG(COMMON, "-config : invalid parameter %s, format is section:key=value,section:key=value,...", value.c_str());
break;
}
*sep++=0;
*value++=0;
auto commapos = value.find(',', eqpos);
char* sect=trim_ws(arg[1]);
char* key=trim_ws(sep);
value=trim_ws(value);
std::string sect = trim_ws(value.substr(0, seppos));
std::string key = trim_ws(value.substr(seppos + 1, eqpos - seppos - 1));
auto endofcurrent = (commapos == std::string::npos) ? value.size() : commapos;
std::string next = (commapos == std::string::npos) ? "" : trim_ws(value.substr(endofcurrent + 1, value.size() - endofcurrent));
value = trim_ws(value.substr(eqpos + 1, endofcurrent - eqpos - 1));
if (sect==0 || key==0)
if (sect.empty() || key.empty())
{
WARN_LOG(COMMON, "-config : invalid parameter, format is section:key=value");
return rv;
WARN_LOG(COMMON, "-config : invalid parameter, format is section:key=value,section:key=value,...");
break;
}
const char* constval = value;
if (constval==0)
constval="";
INFO_LOG(COMMON, "Virtual cfg %s:%s=%s", sect, key, value);
INFO_LOG(COMMON, "Virtual cfg %s:%s=%s", sect.c_str(), key.c_str(), value.c_str());
cfgSetVirtual(sect,key,value);
rv++;
cfgSetVirtual(sect, key, value);
if (cl>=3 && stricmp(arg[2],",")==0)
if (commapos == std::string::npos)
rv++;
if (commapos != std::string::npos)
{
value = next;
continue;
}
else if (cl>=3 && strcmp(arg[2],",")==0)
{
cl-=2;
arg+=2;
@@ -112,9 +86,9 @@ static int showhelp()
return 0;
}
bool ParseCommandLine(int argc,char* argv[])
void ParseCommandLine(int argc,char* argv[])
{
settings.imgread.ImagePath[0] = '\0';
settings.content.path.clear();
int cl=argc-2;
char** arg=argv+1;
while(cl>=0)
@@ -136,6 +110,10 @@ bool ParseCommandLine(int argc,char* argv[])
cl--;
}
#endif
else if ((*arg)[0] == '-')
{
WARN_LOG(COMMON, "Ignoring unknown command line option '%s'", *arg);
}
else
{
char* extension = strrchr(*arg, '.');
@@ -145,22 +123,21 @@ bool ParseCommandLine(int argc,char* argv[])
|| stricmp(extension, ".gdi") == 0 || stricmp(extension, ".cue") == 0))
{
INFO_LOG(COMMON, "Using '%s' as cd image", *arg);
strcpy(settings.imgread.ImagePath, *arg);
settings.content.path = *arg;
}
else if (extension && stricmp(extension, ".elf") == 0)
{
INFO_LOG(COMMON, "Using '%s' as reios elf file", *arg);
cfgSetVirtual("config", "bios.UseReios", "yes");
strcpy(settings.imgread.ImagePath, *arg);
settings.content.path = *arg;
}
else
{
INFO_LOG(COMMON, "Using '%s' as rom", *arg);
strcpy(settings.imgread.ImagePath, *arg);
settings.content.path = *arg;
}
}
arg++;
cl--;
}
return false;
}
+56 -69
View File
@@ -1,7 +1,7 @@
#include "ini.h"
#include "types.h"
#include <sstream>
char* trim_ws(char* str);
#include "stdclass.h"
namespace emucfg {
@@ -24,6 +24,14 @@ int ConfigEntry::get_int()
}
}
int64_t ConfigEntry::get_int64()
{
int base = 10;
if (strstr(this->value.c_str(), "0x") != nullptr)
base = 16;
return (int64_t)strtoll(this->value.c_str(), nullptr, base);
}
bool ConfigEntry::get_bool()
{
if (stricmp(this->value.c_str(), "yes") == 0 ||
@@ -158,6 +166,19 @@ int ConfigFile::get_int(const std::string& section_name, const std::string& entr
}
}
int64_t ConfigFile::get_int64(const std::string& section_name, const std::string& entry_name, int64_t default_value)
{
ConfigEntry* entry = this->get_entry(section_name, entry_name);
if (entry == NULL)
{
return default_value;
}
else
{
return entry->get_int64();
}
}
bool ConfigFile::get_bool(const std::string& section_name, const std::string& entry_name, bool default_value)
{
ConfigEntry* entry = this->get_entry(section_name, entry_name);
@@ -188,6 +209,13 @@ void ConfigFile::set_int(const std::string& section_name, const std::string& ent
this->set(section_name, entry_name, str_value.str(), is_virtual);
}
void ConfigFile::set_int64(const std::string& section_name, const std::string& entry_name, int64_t value, bool is_virtual)
{
std::stringstream str_value;
str_value << value;
this->set(section_name, entry_name, str_value.str(), is_virtual);
}
void ConfigFile::set_bool(const std::string& section_name, const std::string& entry_name, bool value, bool is_virtual)
{
std::string str_value = (value ? "yes" : "no");
@@ -196,94 +224,53 @@ void ConfigFile::set_bool(const std::string& section_name, const std::string& en
void ConfigFile::parse(FILE* file)
{
if(file == NULL)
{
if (file == nullptr)
return;
}
char line[512];
char current_section[512] = { '\0' };
std::string section;
int cline = 0;
while(file && !feof(file))
while (true)
{
if (std::fgets(line, 512, file) == NULL || std::feof(file))
{
if (std::fgets(line, sizeof(line), file) == nullptr)
break;
}
cline++;
if (strlen(line) < 3)
std::string s(line);
s = trim_ws(s, " \r\n");
if (s.empty())
continue;
if (s.length() >= 3 && s[0] == '[' && s[s.length() - 1] == ']')
{
section = s.substr(1, s.length() - 2);
continue;
}
if (line[strlen(line)-1] == '\r' ||
line[strlen(line)-1] == '\n')
auto eqpos = s.find('=');
if (eqpos == std::string::npos)
{
line[strlen(line)-1] = '\0';
}
char* tl = trim_ws(line);
if (tl[0] == '[' && tl[strlen(tl)-1] == ']')
{
tl[strlen(tl)-1] = '\0';
// FIXME: Data loss if buffer is too small
strncpy(current_section, tl+1, sizeof(current_section));
current_section[sizeof(current_section) - 1] = '\0';
trim_ws(current_section);
}
else
{
if (strlen(current_section) == 0)
{
continue; //no open section
}
char* separator = strstr(tl, "=");
if (!separator)
{
WARN_LOG(COMMON, "Malformed entry on config - ignoring @ %d(%s)", cline, tl);
continue;
}
*separator = '\0';
char* name = trim_ws(tl);
char* value = trim_ws(separator + 1);
if (name == NULL || value == NULL)
{
//printf("Malformed entry on config - ignoring @ %d(%s)\n",cline, tl);
continue;
}
else
{
this->set(std::string(current_section), std::string(name), std::string(value));
}
WARN_LOG(COMMON, "Malformed entry on config - ignoring line %d: %s", cline, s.c_str());
continue;
}
std::string property = trim_ws(s.substr(0, eqpos));
std::string value = trim_ws(s.substr(eqpos + 1));
if (value.length() >= 2 && value[0] == '"' && value[value.length() - 1] == '"')
value = value.substr(1, value.length() - 2);
set(section, property, value);
}
}
void ConfigFile::save(FILE* file)
{
for (const auto& section_it : this->sections)
for (const auto& [section_name, section] : this->sections)
{
const std::string& section_name = section_it.first;
const ConfigSection& section = section_it.second;
if (!section_name.empty())
std::fprintf(file, "[%s]\n", section_name.c_str());
std::fprintf(file, "[%s]\n", section_name.c_str());
for (const auto& entry_it : section.entries)
for (const auto& [entry_name, entry] : section.entries)
{
const std::string& entry_name = entry_it.first;
const ConfigEntry& entry = entry_it.second;
std::fprintf(file, "%s = %s\n", entry_name.c_str(), entry.get_string().c_str());
}
std::fputs("\n", file);
if (!section_name.empty())
std::fputc('\n', file);
}
}
+7 -1
View File
@@ -1,6 +1,9 @@
#pragma once
#include "types.h"
#include <cstdio>
#include <map>
#include <string>
#include <cstdint>
namespace emucfg {
@@ -9,6 +12,7 @@ struct ConfigEntry {
const std::string& get_string() const;
int get_int();
bool get_bool();
int64_t get_int64();
};
struct ConfigSection {
@@ -39,10 +43,12 @@ struct ConfigFile {
/* getting values */
std::string get(const std::string& section_name, const std::string& entry_name, const std::string& default_value = "");
int get_int(const std::string& section_name, const std::string& entry_name, int default_value = 0);
int64_t get_int64(const std::string& section_name, const std::string& entry_name, int64_t default_value = 0);
bool get_bool(const std::string& section_name, const std::string& entry_name, bool default_value = false);
/* setting values */
void set(const std::string& section_name, const std::string& entry_name, const std::string& value, bool is_virtual = false);
void set_int(const std::string& section_name, const std::string& entry_name, int value, bool is_virtual = false);
void set_int64(const std::string& section_name, const std::string& entry_name, int64_t value, bool is_virtual = false);
void set_bool(const std::string& section_name, const std::string& entry_name, bool value, bool is_virtual = false);
void delete_section(const std::string& section_name);
+78 -12
View File
@@ -17,14 +17,15 @@
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include "option.h"
#include "network/naomi_network.h"
#include "debug/gdb_server.h"
namespace config {
// Dynarec
Option<bool> DynarecEnabled("Dynarec.Enabled", true);
Option<bool> DynarecIdleSkip("Dynarec.idleskip", true);
Option<bool> DynarecSafeMode("Dynarec.safe-mode");
Option<int> Sh4Clock("Sh4Clock", 200);
// General
@@ -32,14 +33,17 @@ Option<int> Cable("Dreamcast.Cable", 3); // TV Composite
Option<int> Region("Dreamcast.Region", 1); // USA
Option<int> Broadcast("Dreamcast.Broadcast", 0); // NTSC
Option<int> Language("Dreamcast.Language", 1); // English
Option<bool> FullMMU("Dreamcast.FullMMU");
Option<bool> ForceWindowsCE("Dreamcast.ForceWindowsCE");
Option<bool> AutoSavestate("Dreamcast.AutoSavestate");
Option<bool> AutoLoadState("Dreamcast.AutoLoadState");
Option<bool> AutoSaveState("Dreamcast.AutoSaveState");
Option<int, false> SavestateSlot("Dreamcast.SavestateSlot");
Option<bool> ForceFreePlay("ForceFreePlay", true);
Option<bool, false> FetchBoxart("FetchBoxart", true);
Option<bool, false> BoxartDisplayMode("BoxartDisplayMode", true);
Option<int, false> UIScaling("UIScaling", 100);
// Sound
Option<bool> DSPEnabled("aica.DSPEnabled", false);
Option<bool> DisableSound("aica.NoSound");
#if HOST_CPU == CPU_ARM
Option<int> AudioBufferSize("aica.BufferSize", 5644); // 128 ms
#else
@@ -54,6 +58,8 @@ Option<bool> AutoLatency("aica.AutoLatency",
);
OptionString AudioBackend("backend", "auto", "audio");
AudioVolumeOption AudioVolume;
Option<bool> VmuSound("VmuSound", false, "audio");
// Rendering
@@ -75,7 +81,11 @@ Option<bool> Fog("rend.Fog", true);
Option<bool> FloatVMUs("rend.FloatVMUs");
Option<bool> Rotate90("rend.Rotate90");
Option<bool> PerStripSorting("rend.PerStripSorting");
Option<bool> DelayFrameSwapping("rend.DelayFrameSwapping");
#ifdef __APPLE__
Option<bool> DelayFrameSwapping("rend.DelayFrameSwapping", false);
#else
Option<bool> DelayFrameSwapping("rend.DelayFrameSwapping", true);
#endif
Option<bool> WidescreenGameHacks("rend.WidescreenGameHacks");
std::array<Option<int>, 4> CrosshairColor {
Option<int>("rend.CrossHairColor1"),
@@ -83,34 +93,74 @@ std::array<Option<int>, 4> CrosshairColor {
Option<int>("rend.CrossHairColor3"),
Option<int>("rend.CrossHairColor4"),
};
Option<int> CrosshairSize("rend.CrosshairSize", 40);
Option<int> SkipFrame("ta.skip");
Option<int> MaxThreads("pvr.MaxThreads", 3);
Option<int> AutoSkipFrame("pvr.AutoSkipFrame", 0);
Option<int> RenderResolution("rend.Resolution", 480);
Option<bool> VSync("rend.vsync", true);
Option<int64_t> PixelBufferSize("rend.PixelBufferSize", 512_MB);
Option<int> AnisotropicFiltering("rend.AnisotropicFiltering", 1);
Option<int> TextureFiltering("rend.TextureFiltering", 0); // Default
Option<bool> ThreadedRendering("rend.ThreadedRendering", true);
Option<bool> DupeFrames("rend.DupeFrames", false);
Option<int> PerPixelLayers("rend.PerPixelLayers", 32);
Option<bool> NativeDepthInterpolation("rend.NativeDepthInterpolation", false);
Option<bool> EmulateFramebuffer("rend.EmulateFramebuffer", false);
Option<bool> FixUpscaleBleedingEdge("rend.FixUpscaleBleedingEdge", true);
Option<bool> CustomGpuDriver("rend.CustomGpuDriver", false);
#ifdef VIDEO_ROUTING
Option<bool, false> VideoRouting("rend.VideoRouting", false);
Option<bool, false> VideoRoutingScale("rend.VideoRoutingScale", false);
Option<int, false> VideoRoutingVRes("rend.VideoRoutingVRes", 720);
#endif
// Misc
Option<bool> SerialConsole("Debug.SerialConsoleEnabled");
Option<bool> SerialPTY("Debug.SerialPTY");
Option<bool> GDB("Debug.GDBEnabled");
Option<int> GDBPort("Debug.GDBPort", debugger::DEFAULT_PORT);
Option<bool> GDBWaitForConnection("Debug.GDBWaitForConnection");
Option<bool> UseReios("UseReios");
Option<bool> FastGDRomLoad("FastGDRomLoad", false);
Option<bool> RamMod32MB("Dreamcast.RamMod32MB", false);
Option<bool> OpenGlChecks("OpenGlChecks", false, "validate");
Option<std::vector<std::string>, false> ContentPath("Dreamcast.ContentPath");
Option<bool, false> HideLegacyNaomiRoms("Dreamcast.HideLegacyNaomiRoms", true);
Option<bool, false> UploadCrashLogs("UploadCrashLogs", true);
Option<bool, false> DiscordPresence("DiscordPresence", true);
#if defined(__ANDROID__) && !defined(LIBRETRO)
Option<bool, false> UseSafFilePicker("UseSafFilePicker", true);
#endif
// Profiler
Option<bool> ProfilerEnabled("Profiler.Enabled");
Option<bool> ProfilerDrawToGUI("Profiler.DrawGUI");
Option<bool> ProfilerOutputTTY("Profiler.OutputTTY");
Option<float> ProfilerFrameWarningTime("Profiler.FrameWarningTime", 1.0f / 55.0f);
// Network
Option<bool> NetworkEnable("Enable", false, "network");
Option<bool> ActAsServer("ActAsServer", false, "network");
OptionString DNS("DNS", "46.101.91.123", "network");
OptionString DNS("DNS", "dns.flyca.st", "network");
OptionString NetworkServer("server", "", "network");
Option<int> LocalPort("LocalPort", NaomiNetwork::SERVER_PORT, "network");
Option<bool> EmulateBBA("EmulateBBA", false, "network");
#ifdef SUPPORT_DISPMANX
Option<bool> DispmanxMaintainAspect("maintain_aspect", true, "dispmanx");
#endif
Option<bool> EnableUPnP("EnableUPnP", true, "network");
Option<bool> GGPOEnable("GGPO", false, "network");
Option<int> GGPODelay("GGPODelay", 0, "network");
Option<bool> NetworkStats("Stats", true, "network");
Option<int> GGPOAnalogAxes("GGPOAnalogAxes", 0, "network");
Option<bool> GGPOChat("GGPOChat", true, "network");
Option<bool> GGPOChatTimeoutToggle("GGPOChatTimeoutToggle", true, "network");
Option<int> GGPOChatTimeout("GGPOChatTimeout", 10, "network");
Option<bool> NetworkOutput("NetworkOutput", false, "network");
Option<int> MultiboardSlaves("MultiboardSlaves", 1, "network");
Option<bool> BattleCableEnable("BattleCable", false, "network");
#ifdef USE_OMX
Option<int> OmxAudioLatency("audio_latency", 100, "omx");
@@ -121,6 +171,7 @@ Option<bool> OmxAudioHdmi("audio_hdmi", true, "omx");
Option<int> MouseSensitivity("MouseSensitivity", 100, "input");
Option<int> VirtualGamepadVibration("VirtualGamepadVibration", 20, "input");
Option<int> VirtualGamepadTransparency("VirtualGamepadTransparency", 37, "input");
std::array<Option<MapleDeviceType>, 4> MapleMainDevices {
Option<MapleDeviceType>("device1", MDT_SegaController, "input"),
@@ -141,5 +192,20 @@ std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices {
Option<MapleDeviceType>("device4.1", MDT_None, "input"),
Option<MapleDeviceType>("device4.2", MDT_None, "input"),
};
Option<bool> PerGameVmu("PerGameVmu", false, "config");
#ifdef _WIN32
Option<bool, false> UseRawInput("RawInput", false, "input");
#endif
#ifdef USE_LUA
Option<std::string, false> LuaFileName("LuaFileName", "flycast.lua");
#endif
// RetroAchievements
Option<bool> EnableAchievements("Enabled", false, "achievements");
Option<bool> AchievementsHardcoreMode("HardcoreMode", false, "achievements");
OptionString AchievementsUserName("UserName", "", "achievements");
OptionString AchievementsToken("Token", "", "achievements");
} // namespace config
+230 -83
View File
@@ -20,8 +20,13 @@
#include <string>
#include <vector>
#include <array>
#include <cmath>
#include <type_traits>
#include "cfg.h"
#include "hw/maple/maple_cfg.h"
#ifdef LIBRETRO
#include <libretro.h>
#endif
namespace config {
@@ -33,6 +38,10 @@ public:
virtual void reset() = 0;
};
#ifdef LIBRETRO
#include "option_lr.h"
#else
class Settings {
public:
void reset() {
@@ -62,10 +71,6 @@ public:
cfgSetAutoSave(true);
}
const std::string& getGameId() const {
return gameId;
}
void setGameId(const std::string& gameId) {
this->gameId = gameId;
}
@@ -96,10 +101,6 @@ private:
friend class Option;
};
// Missing in C++11
template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;
template<typename T, bool PerGameOption = true>
class Option : public BaseOption {
public:
@@ -117,7 +118,7 @@ public:
void load() override {
if (PerGameOption && settings.hasPerGameConfig())
set(doLoad(settings.getGameId(), section + "." + name));
set(doLoad(settings.gameId, section + "." + name));
else
{
set(doLoad(section, name));
@@ -138,10 +139,14 @@ public:
else if (PerGameOption && settings.hasPerGameConfig())
{
if (value == doLoad(section, name))
{
// delete existing per-game option if any
cfgDeleteEntry(settings.gameId, section + "." + name);
return;
}
}
if (PerGameOption && settings.hasPerGameConfig())
doSave(settings.getGameId(), section + "." + name);
doSave(settings.gameId, section + "." + name);
else
doSave(section, name);
}
@@ -149,8 +154,8 @@ public:
T& get() { return value; }
void set(T v) { value = v; }
void override(T v) {
verify(PerGameOption);
void override(T v)
{
overriddenDefault = v;
overridden = true;
value = v;
@@ -165,40 +170,47 @@ public:
protected:
template <typename U = T>
enable_if_t<std::is_same<U, bool>::value, T>
std::enable_if_t<std::is_same_v<U, bool>, T>
doLoad(const std::string& section, const std::string& name) const
{
return cfgLoadBool(section, name, value);
}
template <typename U = T>
enable_if_t<(std::is_integral<U>::value || std::is_enum<U>::value)
&& !std::is_same<U, bool>::value, T>
std::enable_if_t<std::is_same<U, int64_t>::value, T>
doLoad(const std::string& section, const std::string& name) const
{
return cfgLoadInt64(section, name, value);
}
template <typename U = T>
std::enable_if_t<(std::is_integral_v<U> || std::is_enum_v<U>)
&& !std::is_same_v<U, bool> && !std::is_same_v<U, int64_t>, T>
doLoad(const std::string& section, const std::string& name) const
{
return (T)cfgLoadInt(section, name, (int)value);
}
template <typename U = T>
enable_if_t<std::is_same<U, std::string>::value, T>
std::enable_if_t<std::is_same_v<U, std::string>, T>
doLoad(const std::string& section, const std::string& name) const
{
return cfgLoadStr(section, name, value);
}
template <typename U = T>
enable_if_t<std::is_same<float, U>::value, T>
std::enable_if_t<std::is_same_v<float, U>, T>
doLoad(const std::string& section, const std::string& name) const
{
std::string strValue = cfgLoadStr(section, name, "");
if (strValue.empty())
return value;
else
return atof(strValue.c_str());
return (float)atof(strValue.c_str());
}
template <typename U = T>
enable_if_t<std::is_same<std::vector<std::string>, U>::value, T>
std::enable_if_t<std::is_same_v<std::vector<std::string>, U>, T>
doLoad(const std::string& section, const std::string& name) const
{
std::string paths = cfgLoadStr(section, name, "");
@@ -208,42 +220,85 @@ protected:
std::vector<std::string> newValue;
while (true)
{
std::string::size_type end = paths.find(';', start);
if (end == std::string::npos)
end = paths.size();
if (start != end)
newValue.push_back(paths.substr(start, end - start));
if (end == paths.size())
break;
start = end + 1;
if (paths[start] == '"')
{
std::string v;
start++;
while (true)
{
if (paths[start] == '"')
{
if (start + 1 >= paths.size())
{
newValue.push_back(v);
return newValue;
}
if (paths[start + 1] == '"')
{
v += paths[start++];
start++;
}
else if (paths[start + 1] == ';')
{
newValue.push_back(v);
start += 2;
break;
}
else
{
v += paths[start++];
}
}
else
v += paths[start++];
}
}
else
{
std::string::size_type end = paths.find(';', start);
if (end == std::string::npos)
end = paths.size();
if (start != end)
newValue.push_back(paths.substr(start, end - start));
if (end == paths.size())
break;
start = end + 1;
}
}
return newValue;
}
template <typename U = T>
enable_if_t<std::is_same<U, bool>::value>
std::enable_if_t<std::is_same_v<U, bool>>
doSave(const std::string& section, const std::string& name) const
{
cfgSaveBool(section, name, value);
}
template <typename U = T>
enable_if_t<(std::is_integral<U>::value || std::is_enum<U>::value)
&& !std::is_same<U, bool>::value>
std::enable_if_t<std::is_same<U, int64_t>::value>
doSave(const std::string& section, const std::string& name) const
{
cfgSaveInt64(section, name, value);
}
template <typename U = T>
std::enable_if_t<(std::is_integral_v<U> || std::is_enum_v<U>)
&& !std::is_same_v<U, bool> && !std::is_same_v<U, int64_t>>
doSave(const std::string& section, const std::string& name) const
{
cfgSaveInt(section, name, (int)value);
}
template <typename U = T>
enable_if_t<std::is_same<U, std::string>::value>
std::enable_if_t<std::is_same_v<U, std::string>>
doSave(const std::string& section, const std::string& name) const
{
cfgSaveStr(section, name, value);
}
template <typename U = T>
enable_if_t<std::is_same<float, U>::value>
std::enable_if_t<std::is_same_v<float, U>>
doSave(const std::string& section, const std::string& name) const
{
char buf[64];
@@ -252,16 +307,36 @@ protected:
}
template <typename U = T>
enable_if_t<std::is_same<std::vector<std::string>, U>::value>
std::enable_if_t<std::is_same_v<std::vector<std::string>, U>>
doSave(const std::string& section, const std::string& name) const
{
std::string s;
for (auto& v : value)
for (const auto& v : value)
{
if (s.empty())
s = v;
if (!s.empty())
s += ';';
if (v.find(';') != std::string::npos || (!v.empty() && v[0] == '"'))
{
s += '"';
std::string v2 = v;
while (true)
{
auto pos = v2.find('"');
if (pos != std::string::npos)
{
s += v2.substr(0, pos + 1) + '"';
v2 = v2.substr(pos + 1);
}
else
{
s += v2;
break;
}
}
s += '"';
}
else
s += ";" + v;
s += v;
}
cfgSaveStr(section, name, s);
}
@@ -274,20 +349,16 @@ protected:
bool overridden = false;
Settings& settings;
};
#endif
using OptionString = Option<std::string>;
template<typename T, T value = T()>
class ConstOption {
public:
operator T() const { return value; }
};
// Dynarec
extern Option<bool> DynarecEnabled;
extern Option<bool> DynarecIdleSkip;
extern Option<bool> DynarecSafeMode;
#ifndef LIBRETRO
extern Option<int> Sh4Clock;
#endif
// General
@@ -295,57 +366,74 @@ extern Option<int> Cable; // 0 -> VGA, 1 -> VGA, 2 -> RGB, 3 -> TV Composite
extern Option<int> Region; // 0 -> JP, 1 -> USA, 2 -> EU, 3 -> default
extern Option<int> Broadcast; // 0 -> NTSC, 1 -> PAL, 2 -> PAL/M, 3 -> PAL/N, 4 -> default
extern Option<int> Language; // 0 -> JP, 1 -> EN, 2 -> DE, 3 -> FR, 4 -> SP, 5 -> IT, 6 -> default
extern Option<bool> FullMMU;
extern Option<bool> ForceWindowsCE;
extern Option<bool> AutoSavestate;
extern Option<bool> AutoLoadState;
extern Option<bool> AutoSaveState;
extern Option<int, false> SavestateSlot;
extern Option<bool> ForceFreePlay;
extern Option<bool, false> FetchBoxart;
extern Option<bool, false> BoxartDisplayMode;
extern Option<int, false> UIScaling;
// Sound
constexpr ConstOption<bool, true> LimitFPS;
constexpr bool LimitFPS = true;
extern Option<bool> DSPEnabled;
extern Option<bool> DisableSound;
extern Option<int> AudioBufferSize; //In samples ,*4 for bytes
extern Option<bool> AutoLatency;
extern OptionString AudioBackend;
class AudioVolumeOption : public Option<int> {
public:
AudioVolumeOption() : Option<int>("aica.Volume", 100) {};
float logarithmic_volume_scale = 1.0;
void load() override {
Option<int>::load();
calcDbPower();
}
float dbPower()
{
return logarithmic_volume_scale;
}
void calcDbPower()
{
// dB scaling calculation: https://www.dr-lex.be/info-stuff/volumecontrols.html
logarithmic_volume_scale = std::min(std::exp(4.605f * float(value) / 100.f) / 100.f, 1.f);
if (value < 10)
logarithmic_volume_scale *= value / 10.f;
}
};
extern AudioVolumeOption AudioVolume;
extern Option<bool> VmuSound;
// Rendering
class RendererOption : public Option<RenderType> {
public:
RendererOption()
: Option<RenderType>("pvr.rend", RenderType::OpenGL) {}
#ifdef LIBRETRO
RendererOption() : Option<RenderType>("",
#else
RendererOption() : Option<RenderType>("pvr.rend",
#endif
#if defined(USE_DX11)
RenderType::DirectX11
#elif defined(USE_DX9)
RenderType::DirectX9
#elif !defined(USE_OPENGL)
RenderType::Vulkan
#else
RenderType::OpenGL
#endif
) {}
bool isOpenGL() const {
return value == RenderType::OpenGL || value == RenderType::OpenGL_OIT;
}
void set(RenderType v)
{
newValue = v;
}
RenderType& operator=(const RenderType& v) { set(v); return value; }
void load() override {
RenderType current = value;
Option<RenderType>::load();
newValue = value;
value = current;
}
void reset() override {
// don't reset the value to avoid vk -> gl -> vk quick switching
// don't reset the value to avoid quick switching when starting a game
overridden = false;
}
bool pendingChange() {
return newValue != value;
}
void commit() {
value = newValue;
}
private:
RenderType newValue = RenderType();
};
extern RendererOption RendererType;
extern Option<bool> UseMipmaps;
@@ -355,9 +443,12 @@ extern Option<bool> ShowFPS;
extern Option<bool> RenderToTextureBuffer;
extern Option<bool> TranslucentPolygonDepthMask;
extern Option<bool> ModifierVolumes;
constexpr ConstOption<bool, true> Clipping;
constexpr bool Clipping = true;
#ifndef LIBRETRO
extern Option<int> TextureUpscale;
extern Option<int> MaxFilteredTextureSize;
extern Option<int> PerPixelLayers;
#endif
extern Option<float> ExtraDepthScale;
extern Option<bool> CustomTextures;
extern Option<bool> DumpTextures;
@@ -369,22 +460,53 @@ extern Option<bool> PerStripSorting;
extern Option<bool> DelayFrameSwapping; // Delay swapping frame until FB_R_SOF matches FB_W_SOF
extern Option<bool> WidescreenGameHacks;
extern std::array<Option<int>, 4> CrosshairColor;
extern Option<int> CrosshairSize;
extern Option<int> SkipFrame;
extern Option<int> MaxThreads;
extern Option<int> AutoSkipFrame; // 0: none, 1: some, 2: more
extern Option<int> RenderResolution;
extern Option<bool> VSync;
extern Option<int64_t> PixelBufferSize;
extern Option<int> AnisotropicFiltering;
extern Option<int> TextureFiltering; // 0: default, 1: force nearest, 2: force linear
extern Option<bool> ThreadedRendering;
extern Option<bool> DupeFrames;
extern Option<bool> NativeDepthInterpolation;
extern Option<bool> EmulateFramebuffer;
extern Option<bool> FixUpscaleBleedingEdge;
extern Option<bool> CustomGpuDriver;
#ifdef VIDEO_ROUTING
extern Option<bool, false> VideoRouting;
extern Option<bool, false> VideoRoutingScale;
extern Option<int, false> VideoRoutingVRes;
#endif
// Misc
extern Option<bool> SerialConsole;
extern Option<bool> SerialPTY;
extern Option<bool> GDB;
extern Option<int> GDBPort;
extern Option<bool> GDBWaitForConnection;
extern Option<bool> UseReios;
extern Option<bool> FastGDRomLoad;
extern Option<bool> RamMod32MB;
extern Option<bool> OpenGlChecks;
extern Option<std::vector<std::string>, false> ContentPath;
extern Option<bool, false> HideLegacyNaomiRoms;
extern Option<bool, false> UploadCrashLogs;
extern Option<bool, false> DiscordPresence;
#if defined(__ANDROID__) && !defined(LIBRETRO)
extern Option<bool, false> UseSafFilePicker;
#endif
// Profiling
extern Option<bool> ProfilerEnabled;
extern Option<bool> ProfilerDrawToGUI;
extern Option<bool> ProfilerOutputTTY;
extern Option<float> ProfilerFrameWarningTime;
// Network
@@ -392,11 +514,19 @@ extern Option<bool> NetworkEnable;
extern Option<bool> ActAsServer;
extern OptionString DNS;
extern OptionString NetworkServer;
extern Option<int> LocalPort;
extern Option<bool> EmulateBBA;
#ifdef SUPPORT_DISPMANX
extern Option<bool> DispmanxMaintainAspect;
#endif
extern Option<bool> EnableUPnP;
extern Option<bool> GGPOEnable;
extern Option<int> GGPODelay;
extern Option<bool> NetworkStats;
extern Option<int> GGPOAnalogAxes;
extern Option<bool> GGPOChat;
extern Option<bool> GGPOChatTimeoutToggle;
extern Option<int> GGPOChatTimeout;
extern Option<bool> NetworkOutput;
extern Option<int> MultiboardSlaves;
extern Option<bool> BattleCableEnable;
#ifdef USE_OMX
extern Option<int> OmxAudioLatency;
@@ -407,8 +537,25 @@ extern Option<bool> OmxAudioHdmi;
extern Option<int> MouseSensitivity;
extern Option<int> VirtualGamepadVibration;
extern Option<int> VirtualGamepadTransparency;
extern std::array<Option<MapleDeviceType>, 4> MapleMainDevices;
extern std::array<std::array<Option<MapleDeviceType>, 2>, 4> MapleExpansionDevices;
extern Option<bool> PerGameVmu;
#ifdef _WIN32
extern Option<bool, false> UseRawInput;
#else
constexpr bool UseRawInput = false;
#endif
#ifdef USE_LUA
extern Option<std::string, false> LuaFileName;
#endif
// RetroAchievements
extern Option<bool> EnableAchievements;
extern Option<bool> AchievementsHardcoreMode;
extern OptionString AchievementsUserName;
extern OptionString AchievementsToken;
} // namespace config
+734 -314
View File
File diff suppressed because it is too large. Load diff
+27 -6
View File
@@ -21,12 +21,15 @@
#pragma once
#include "types.h"
#include <vector>
struct WidescreenCheat
{
const char *game_id;
const char *area_or_version;
u32 addresses[16];
u32 values[16];
u32 origValues[16];
};
struct Cheat
@@ -39,17 +42,28 @@ struct Cheat
runNextIfEq,
runNextIfNeq,
runNextIfGt,
runNextIfLt
runNextIfLt,
copy
};
Type type = Type::disabled;
Type type;
std::string description;
bool enabled = false;
u32 size = 0;
u32 address = 0;
u32 value = 0;
bool enabled;
u32 size;
u32 address;
u32 value;
u8 valueMask = 0;
u32 repeatCount = 1;
u32 repeatValueIncrement = 0;
u32 repeatAddressIncrement = 0;
u32 destAddress = 0;
bool builtIn;
Cheat(Type type = Type::disabled, const std::string& description = "", bool enabled = false,
u32 size = 0, u32 address = 0, u32 value = 0, bool builtIn = false)
: type(type), description(description), enabled(enabled),
size(size), address(address), value(value), builtIn(builtIn)
{
}
};
class CheatManager
@@ -62,12 +76,15 @@ public:
bool cheatEnabled(size_t index) const { return cheats[index].enabled; }
void enableCheat(size_t index, bool enabled) { cheats[index].enabled = enabled; }
void loadCheatFile(const std::string& filename);
void saveCheatFile(const std::string& filename);
// Returns true if using 16:9 anamorphic screen ratio
bool isWidescreen() const { return widescreen_cheat != nullptr; }
void addGameSharkCheat(const std::string& name, const std::string& s);
private:
u32 readRam(u32 addr, u32 bits);
void writeRam(u32 addr, u32 value, u32 bits);
void setActive(bool active);
static const WidescreenCheat widescreen_cheats[];
static const WidescreenCheat naomi_widescreen_cheats[];
@@ -75,6 +92,10 @@ private:
bool active = false;
std::vector<Cheat> cheats;
std::string gameId;
friend class CheatManagerTest_TestLoad_Test;
friend class CheatManagerTest_TestGameShark_Test;
friend class CheatManagerTest_TestSave_Test;
};
extern CheatManager cheatManager;
-260
View File
@@ -1,260 +0,0 @@
RZDCY_FILES :=
RZDCY_SRC_DIR ?= $(call my-dir)
VERSION_HEADER := $(RZDCY_SRC_DIR)/version.h
RZDCY_MODULES := cfg/ hw/arm7/ hw/aica/ hw/holly/ hw/ hw/gdrom/ hw/maple/ \
hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/interpr/ hw/sh4/modules/ profiler/ oslib/ \
hw/naomi/ imgread/ ./ deps/libchdr/src/ deps/libchdr/deps/zlib-1.2.11/ \
deps/libelf/ deps/chdpsr/ rend/ reios/ deps/xbrz/ \
deps/imgui/ archive/ input/ log/ wsi/ network/ hw/bba/ debug/ \
hw/modem/ deps/picotcp/modules/ deps/picotcp/stack/
ifndef NO_REC
ifndef NOT_ARM
RZDCY_MODULES += rec-ARM/ deps/vixl/ deps/vixl/aarch32/
endif
ifdef X86_REC
RZDCY_MODULES += rec-x86/
endif
ifdef X64_REC
RZDCY_MODULES += rec-x64/
endif
ifdef CPP_REC
RZDCY_MODULES += rec-cpp/
endif
ifdef ARM64_REC
RZDCY_MODULES += rec-ARM64/ deps/vixl/ deps/vixl/aarch64/
endif
endif
ifndef NO_REND
RZDCY_MODULES += rend/gles/
ifndef USE_GLES
ifndef USE_DISPMANX
RZDCY_MODULES += rend/gl4/
endif
endif
ifdef USE_VULKAN
RZDCY_MODULES += rend/vulkan/ rend/vulkan/oit/ deps/volk/ \
deps/glslang/glslang/MachineIndependent/ \
deps/glslang/glslang/MachineIndependent/preprocessor/ \
deps/glslang/glslang/GenericCodeGen/ \
deps/glslang/OGLCompilersDLL/ \
deps/glslang/SPIRV/
ifdef FOR_WINDOWS
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/glslang/glslang/OSDependent/Windows/ossource.cpp
else
RZDCY_FILES += $(RZDCY_SRC_DIR)/deps/glslang/glslang/OSDependent/Unix/ossource.cpp
endif
endif
else
RZDCY_MODULES += rend/norend/
endif
ifdef USE_SDL
RZDCY_MODULES += sdl/
endif
ifdef FOR_LINUX
ifndef UNIT_TESTS
RZDCY_MODULES += linux-dist/
endif
RZDCY_MODULES += linux/
endif
ifdef FOR_WINDOWS
ifndef UNIT_TESTS
RZDCY_FILES += $(RZDCY_SRC_DIR)/windows/winmain.cpp
endif
RZDCY_FILES += $(RZDCY_SRC_DIR)/windows/win_vmem.cpp
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/dirent
endif
ifdef USE_VULKAN
ifdef FOR_WINDOWS
RZDCY_CFLAGS += -DVK_USE_PLATFORM_WIN32_KHR
else
RZDCY_CFLAGS += -DVK_USE_PLATFORM_XLIB_KHR
endif
RZDCY_CFLAGS += -D USE_VULKAN
endif
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/rend/gles -I$(RZDCY_SRC_DIR)/deps \
-I$(RZDCY_SRC_DIR)/deps/vixl -I$(RZDCY_SRC_DIR)/khronos -I$(RZDCY_SRC_DIR)/deps/glslang \
-I$(RZDCY_SRC_DIR)/deps/glm -I$(RZDCY_SRC_DIR)/deps/xbyak -I$(RZDCY_SRC_DIR)/deps/nowide/include \
-I$(RZDCY_SRC_DIR)/deps/picotcp/include -I$(RZDCY_SRC_DIR)/deps/picotcp/modules \
-I$(RZDCY_SRC_DIR)/deps/libchdr/include -I$(RZDCY_SRC_DIR)/deps/libchdr/deps/zlib-1.2.11/ \
-I$(RZDCY_SRC_DIR)/deps/libchdr/deps/lzma-19.00 -I$(RZDCY_SRC_DIR)/deps/libchdr/deps/lzma-19.00/include
ifdef USE_SYSTEM_MINIUPNPC
RZDCY_CFLAGS += -I/usr/include/miniupnpc
else
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/miniupnpc
endif
ifdef NO_REC
RZDCY_CFLAGS += -DTARGET_NO_REC
else
RZDCY_MODULES += hw/sh4/dyna/
endif
ifdef USE_GLES
RZDCY_CFLAGS += -DGLES -fPIC
endif
ifdef CHD5_FLAC
RZDCY_CFLAGS += -DCHD5_FLAC -I$(RZDCY_SRC_DIR)/deps/flac/src/libFLAC/include/ -I$(RZDCY_SRC_DIR)/deps/flac/include
RZDCY_CFLAGS += -DHAVE_CONFIG_H
RZDCY_MODULES += deps/flac/src/libFLAC/
endif
# 7-Zip/LZMA settings (CHDv5)
ifdef CHD5_LZMA
RZDCY_MODULES += deps/lzma/
RZDCY_CFLAGS += -D_7ZIP_ST -DCHD5_LZMA
endif
RZDCY_CFLAGS += -DXXH_INLINE_ALL -I$(RZDCY_SRC_DIR)/deps/xxHash -I$(RZDCY_SRC_DIR)/deps/stb
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cpp))
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cc))
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.c))
RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.S))
ifdef STATIC_LIBZIP
RZDCY_CFLAGS += -I$(RZDCY_SRC_DIR)/deps/libzip/lib
LIBZIP_DIR = $(RZDCY_SRC_DIR)/deps/libzip/lib
RZDCY_FILES += $(LIBZIP_DIR)/zip_add.c \
$(LIBZIP_DIR)/zip_add_dir.c \
$(LIBZIP_DIR)/zip_add_entry.c \
$(LIBZIP_DIR)/zip_algorithm_deflate.c \
$(LIBZIP_DIR)/zip_buffer.c \
$(LIBZIP_DIR)/zip_close.c \
$(LIBZIP_DIR)/zip_delete.c \
$(LIBZIP_DIR)/zip_dir_add.c \
$(LIBZIP_DIR)/zip_dirent.c \
$(LIBZIP_DIR)/zip_discard.c \
$(LIBZIP_DIR)/zip_entry.c \
$(LIBZIP_DIR)/zip_error.c \
$(LIBZIP_DIR)/zip_error_clear.c \
$(LIBZIP_DIR)/zip_error_get.c \
$(LIBZIP_DIR)/zip_error_get_sys_type.c \
$(LIBZIP_DIR)/zip_error_strerror.c \
$(LIBZIP_DIR)/zip_error_to_str.c \
$(LIBZIP_DIR)/zip_extra_field.c \
$(LIBZIP_DIR)/zip_extra_field_api.c \
$(LIBZIP_DIR)/zip_fclose.c \
$(LIBZIP_DIR)/zip_fdopen.c \
$(LIBZIP_DIR)/zip_file_add.c \
$(LIBZIP_DIR)/zip_file_error_clear.c \
$(LIBZIP_DIR)/zip_file_error_get.c \
$(LIBZIP_DIR)/zip_file_get_comment.c \
$(LIBZIP_DIR)/zip_file_get_external_attributes.c \
$(LIBZIP_DIR)/zip_file_get_offset.c \
$(LIBZIP_DIR)/zip_file_rename.c \
$(LIBZIP_DIR)/zip_file_replace.c \
$(LIBZIP_DIR)/zip_file_set_comment.c \
$(LIBZIP_DIR)/zip_file_set_encryption.c \
$(LIBZIP_DIR)/zip_file_set_external_attributes.c \
$(LIBZIP_DIR)/zip_file_set_mtime.c \
$(LIBZIP_DIR)/zip_file_strerror.c \
$(LIBZIP_DIR)/zip_fopen.c \
$(LIBZIP_DIR)/zip_fopen_encrypted.c \
$(LIBZIP_DIR)/zip_fopen_index.c \
$(LIBZIP_DIR)/zip_fopen_index_encrypted.c \
$(LIBZIP_DIR)/zip_fread.c \
$(LIBZIP_DIR)/zip_fseek.c \
$(LIBZIP_DIR)/zip_ftell.c \
$(LIBZIP_DIR)/zip_get_archive_comment.c \
$(LIBZIP_DIR)/zip_get_archive_flag.c \
$(LIBZIP_DIR)/zip_get_encryption_implementation.c \
$(LIBZIP_DIR)/zip_get_file_comment.c \
$(LIBZIP_DIR)/zip_get_name.c \
$(LIBZIP_DIR)/zip_get_num_entries.c \
$(LIBZIP_DIR)/zip_get_num_files.c \
$(LIBZIP_DIR)/zip_hash.c \
$(LIBZIP_DIR)/zip_io_util.c \
$(LIBZIP_DIR)/zip_libzip_version.c \
$(LIBZIP_DIR)/zip_memdup.c \
$(LIBZIP_DIR)/zip_name_locate.c \
$(LIBZIP_DIR)/zip_new.c \
$(LIBZIP_DIR)/zip_open.c \
$(LIBZIP_DIR)/zip_pkware.c \
$(LIBZIP_DIR)/zip_progress.c \
$(LIBZIP_DIR)/zip_rename.c \
$(LIBZIP_DIR)/zip_replace.c \
$(LIBZIP_DIR)/zip_set_archive_comment.c \
$(LIBZIP_DIR)/zip_set_archive_flag.c \
$(LIBZIP_DIR)/zip_set_default_password.c \
$(LIBZIP_DIR)/zip_set_file_comment.c \
$(LIBZIP_DIR)/zip_set_file_compression.c \
$(LIBZIP_DIR)/zip_set_name.c \
$(LIBZIP_DIR)/zip_source_accept_empty.c \
$(LIBZIP_DIR)/zip_source_begin_write.c \
$(LIBZIP_DIR)/zip_source_begin_write_cloning.c \
$(LIBZIP_DIR)/zip_source_buffer.c \
$(LIBZIP_DIR)/zip_source_call.c \
$(LIBZIP_DIR)/zip_source_close.c \
$(LIBZIP_DIR)/zip_source_commit_write.c \
$(LIBZIP_DIR)/zip_source_compress.c \
$(LIBZIP_DIR)/zip_source_crc.c \
$(LIBZIP_DIR)/zip_source_error.c \
$(LIBZIP_DIR)/zip_source_file_common.c \
$(LIBZIP_DIR)/zip_source_file_stdio.c \
$(LIBZIP_DIR)/zip_source_free.c \
$(LIBZIP_DIR)/zip_source_function.c \
$(LIBZIP_DIR)/zip_source_get_file_attributes.c \
$(LIBZIP_DIR)/zip_source_is_deleted.c \
$(LIBZIP_DIR)/zip_source_layered.c \
$(LIBZIP_DIR)/zip_source_open.c \
$(LIBZIP_DIR)/zip_source_pkware_decode.c \
$(LIBZIP_DIR)/zip_source_pkware_encode.c \
$(LIBZIP_DIR)/zip_source_read.c \
$(LIBZIP_DIR)/zip_source_remove.c \
$(LIBZIP_DIR)/zip_source_rollback_write.c \
$(LIBZIP_DIR)/zip_source_seek.c \
$(LIBZIP_DIR)/zip_source_seek_write.c \
$(LIBZIP_DIR)/zip_source_stat.c \
$(LIBZIP_DIR)/zip_source_supports.c \
$(LIBZIP_DIR)/zip_source_tell.c \
$(LIBZIP_DIR)/zip_source_tell_write.c \
$(LIBZIP_DIR)/zip_source_window.c \
$(LIBZIP_DIR)/zip_source_write.c \
$(LIBZIP_DIR)/zip_source_zip.c \
$(LIBZIP_DIR)/zip_source_zip_new.c \
$(LIBZIP_DIR)/zip_stat.c \
$(LIBZIP_DIR)/zip_stat_index.c \
$(LIBZIP_DIR)/zip_stat_init.c \
$(LIBZIP_DIR)/zip_strerror.c \
$(LIBZIP_DIR)/zip_string.c \
$(LIBZIP_DIR)/zip_unchange.c \
$(LIBZIP_DIR)/zip_unchange_all.c \
$(LIBZIP_DIR)/zip_unchange_archive.c \
$(LIBZIP_DIR)/zip_unchange_data.c \
$(LIBZIP_DIR)/zip_utf-8.c \
$(LIBZIP_DIR)/zip_err_str.c
ifdef FOR_WINDOWS
RZDCY_FILES += $(LIBZIP_DIR)/zip_source_file_win32.c \
$(LIBZIP_DIR)/zip_source_file_win32_named.c \
$(LIBZIP_DIR)/zip_source_file_win32_utf16.c \
$(LIBZIP_DIR)/zip_source_file_win32_utf8.c \
$(LIBZIP_DIR)/zip_source_file_win32_ansi.c \
$(LIBZIP_DIR)/zip_random_win32.c
else
RZDCY_FILES += $(LIBZIP_DIR)/zip_mkstempm.c \
$(LIBZIP_DIR)/zip_source_file_stdio_named.c \
$(LIBZIP_DIR)/zip_random_unix.c
endif
endif
$(VERSION_HEADER):
echo "#define REICAST_VERSION \"`git describe --tags --always`\"" > $(VERSION_HEADER)
echo "#define GIT_HASH \"`git rev-parse --short HEAD`\"" >> $(VERSION_HEADER)
echo "#define BUILD_DATE \"`date '+%Y-%m-%d %H:%M:%S %Z'`\"" >> $(VERSION_HEADER)
+52 -29
View File
@@ -73,20 +73,47 @@ const std::array<Sh4RegType, 59> Sh4RegList {
class DebugAgent
{
public:
struct Breakpoint {
enum Type
{
BP_TYPE_SOFTWARE_BREAK,
BP_TYPE_HARDWARE_BREAK,
BP_TYPE_WRITE_WATCHPOINT,
BP_TYPE_READ_WATCHPOINT,
BP_TYPE_ACCESS_WATCHPOINT,
BP_TYPE_COUNT
};
Breakpoint() = default;
Breakpoint(u16 type, u32 addr) : addr(addr), type(type) { }
u32 addr = 0;
u16 type = 0;
u16 savedOp = 0;
};
void doContinue(u32 pc = 1)
{
if (pc != 1)
Sh4cntx.pc = pc;
dc_resume();
emu.start();
}
void step()
{
bool restoreBreakpoint = removeMatchpoint(0, Sh4cntx.pc, 2);
bool restoreBreakpoint = removeMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, Sh4cntx.pc, 2);
u32 savedPc = Sh4cntx.pc;
dc_step();
emu.step();
if (restoreBreakpoint)
insertMatchpoint(0, savedPc, 2);
insertMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, savedPc, 2);
}
void stepRange(u32 from, u32 to)
{
bool restoreBreakpoint = removeMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, Sh4cntx.pc, 2);
u32 savedPc = Sh4cntx.pc;
emu.stepRange(from, to);
if (restoreBreakpoint)
insertMatchpoint(Breakpoint::BP_TYPE_SOFTWARE_BREAK, savedPc, 2);
}
int readAllRegs(u32 **regs)
@@ -190,31 +217,31 @@ public:
}
}
}
bool insertMatchpoint(char type, u32 addr, u32 len)
bool insertMatchpoint(Breakpoint::Type type, u32 addr, u32 len)
{
if (type == 0 && len != 2) {
if (type == Breakpoint::BP_TYPE_SOFTWARE_BREAK && len != 2) {
WARN_LOG(COMMON, "insertMatchpoint: length != 2: %d", len);
return false;
}
// TODO other matchpoint types
if (breakpoints.find(addr) != breakpoints.end())
if (breakpoints[type].find(addr) != breakpoints[type].end())
return true;
breakpoints[addr] = Breakpoint(type, addr);
breakpoints[addr].savedOp = ReadMem16_nommu(addr);
breakpoints[type][addr] = Breakpoint(type, addr);
breakpoints[type][addr].savedOp = ReadMem16_nommu(addr);
WriteMem16_nommu(addr, 0xC308); // trapa #0x20
return true;
}
bool removeMatchpoint(char type, u32 addr, u32 len)
bool removeMatchpoint(Breakpoint::Type type, u32 addr, u32 len)
{
if (type == 0 && len != 2) {
if (type == Breakpoint::BP_TYPE_SOFTWARE_BREAK && len != 2) {
WARN_LOG(COMMON, "removeMatchpoint: length != 2: %d", len);
return false;
}
auto it = breakpoints.find(addr);
if (it == breakpoints.end())
auto it = breakpoints[type].find(addr);
if (it == breakpoints[type].end())
return false;
WriteMem16_nommu(addr, it->second.savedOp);
breakpoints.erase(it);
breakpoints[type].erase(it);
return true;
}
@@ -222,7 +249,7 @@ public:
{
config::DynarecEnabled = false;
exception = SIGINT;
dc_stop();
emu.stop();
return exception;
}
@@ -236,7 +263,7 @@ public:
void postDebugTrap()
{
// needed to join the emu thread since debugTrap() is called by it
dc_stop();
emu.stop();
}
u32 currentException()
@@ -246,14 +273,14 @@ public:
void restart()
{
dc_stop();
dc_reset(true);
dc_resume();
emu.unloadGame();
emu.loadGame(settings.content.path.c_str());
emu.start();
}
void detach()
{
dc_resume();
emu.start();
}
void kill()
@@ -295,7 +322,10 @@ public:
{
verify(!Sh4cntx.CpuRunning);
size = stack.size() * 8;
return (const u32 *)&stack[0];
if (!stack.empty())
return (const u32 *)&stack[0];
else
return nullptr;
}
void subroutineCall()
@@ -312,13 +342,6 @@ public:
u32 exception = 0;
struct Breakpoint {
Breakpoint() = default;
Breakpoint(u16 type, u32 addr) : addr(addr), type(type) { }
u32 addr = 0;
u16 type = 0;
u16 savedOp = 0;
};
std::map<u32, Breakpoint> breakpoints;
std::map<u32, Breakpoint> breakpoints[Breakpoint::Type::BP_TYPE_COUNT];
std::vector<std::pair<u32, u32>> stack;
};
+128 -35
View File
@@ -22,16 +22,19 @@
#include "gdb_server.h"
#include "debug_agent.h"
#include "network/net_platform.h"
#include "cfg/option.h"
#include "oslib/oslib.h"
#include <stdexcept>
#include <thread>
#include <chrono>
#include <mutex>
#include <cassert>
#define SERVER_PORT 3263
#define MAX_PACKET_LEN 4096
namespace debugger {
static void emuEventCallback(Event event);
static void emuEventCallback(Event event, void *);
class GdbServer
{
@@ -40,7 +43,7 @@ public:
Error(const char *reason) : std::runtime_error(reason) {}
};
void init()
void init(int port)
{
if (VALID(serverSocket))
return;
@@ -55,7 +58,7 @@ public:
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERVER_PORT);
serveraddr.sin_port = htons(port);
if (::bind(serverSocket, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
{
@@ -69,10 +72,16 @@ public:
}
EventManager::listen(Event::Resume, emuEventCallback);
EventManager::listen(Event::Terminate, emuEventCallback);
initialised = true;
}
void term()
{
if (!initialised)
return;
EventManager::unlisten(Event::Resume, emuEventCallback);
EventManager::unlisten(Event::Terminate, emuEventCallback);
stop();
if (VALID(clientSocket))
{
@@ -88,12 +97,21 @@ public:
void run()
{
if (!initialised || thread.joinable())
return;
DEBUG_LOG(COMMON, "GdbServer starting");
thread = std::thread(&GdbServer::serverThread, this);
if (config::GDBWaitForConnection)
{
DEBUG_LOG(COMMON, "Waiting for GDB connection...");
agentInterrupt();
}
}
void stop()
{
if (!initialised)
return;
if (thread.joinable())
{
DEBUG_LOG(COMMON, "GdbServer stopping");
@@ -104,7 +122,7 @@ public:
}
bool isRunning() const {
return thread.joinable();
return initialised && thread.joinable();
}
// called on the emu thread
@@ -123,6 +141,7 @@ private:
void serverThread()
{
ThreadName _("GdbServer");
while (!stopRequested)
{
fd_set fds;
@@ -181,18 +200,22 @@ private:
{
NOTICE_LOG(NETWORK, "gdb: client connection");
attached = true;
agent.interrupt();
agentInterrupt();
}
}
void readCommand()
{
if (postDebugTrapNeeded)
{
postDebugTrapNeeded = false;
agent.postDebugTrap();
}
try {
try {
if (postDebugTrapNeeded)
{
postDebugTrapNeeded = false;
try {
agent.postDebugTrap();
} catch (const FlycastException& e) {
throw Error(e.what());
}
}
std::string packet = recvPacket();
if (packet.empty())
return;
@@ -494,7 +517,12 @@ private:
const u32 *data = agent.getStack(len);
len /= 4;
#if _MSC_VER // Non-const array size is a GCC extension
assert((len * 9 * 2 + 1) < MAX_PACKET_LEN);
char reply[MAX_PACKET_LEN];
#else
char reply[len * 9 * 2 + 1];
#endif
char *r = reply;
for (u32 i = 0; i < len; i++)
{
@@ -513,9 +541,13 @@ private:
sendPacket("");
}
else if (pkt.rfind("qSupported", 0) == 0)
{
// Tell the remote stub about features supported by GDB,
// and query the stub for features it supports
sendPacket("PacketSize=10000");
char qsupported[128];
snprintf(qsupported, 128, "PacketSize=%i;vContSupported+", MAX_PACKET_LEN);
sendPacket(qsupported);
}
else if (pkt.rfind("qSymbol:", 0) == 0)
// Notify the target that GDB is prepared to serve symbol lookup requests
sendPacket("OK");
@@ -568,11 +600,41 @@ private:
if (pkt.rfind("vAttach;", 0) == 0)
sendPacket("S05");
else if (pkt.rfind("vCont?", 0) == 0)
// not supported
sendPacket("vCont;s;c");
// supported vCont actions - (c)ontinue, (C)ontinue with signal, (s)tep, (S)tep with signal, (r)ange-step
sendPacket("vCont;c;C;s;S;t;r");
else if (pkt.rfind("vCont", 0) == 0)
// not supported
WARN_LOG(COMMON, "vCont not supported %s", pkt.c_str());
{
std::string vContCmd = pkt.substr(strlen("vCont;"));
switch (vContCmd[0])
{
case 'c':
case 'C':
sendContinue(vContCmd);
break;
case 's':
step(EXCEPT_NONE);
break;
case 'S':
step();
case 'r':
{
u32 from, to;
if (sscanf(vContCmd.c_str(), "r%x,%x", &from, &to) == 2)
{
stepRange(from, to);
}
else
{
WARN_LOG(COMMON, "Unsupported vCont:r format %s", pkt.c_str());
sendContinue("c");
}
break;
}
default:
WARN_LOG(COMMON, "vCont action not supported %s", pkt.c_str());
}
}
else if (pkt.rfind("vFile:", 0) == 0)
// not supported
sendPacket("");
@@ -597,11 +659,11 @@ private:
sendPacket("OK");
agent.kill();
}
else if (pkt.rfind("vMustReplyEmpty", 0) == 0)
// Reply empty packet
sendPacket("");
else
{
WARN_LOG(COMMON, "unknown v packet: %s", pkt.c_str());
sendPacket("");
}
}
void restart()
@@ -611,8 +673,23 @@ private:
void step(u32 what = 0)
{
agent.step();
sendPacket("S05");
try {
agent.step();
sendPacket("S05");
} catch (const FlycastException& e) {
throw Error(e.what());
}
}
void stepRange(u32 from, u32 to)
{
try {
sendPacket("OK");
agent.stepRange(from, to);
sendPacket("S05");
} catch (const FlycastException& e) {
throw Error(e.what());
}
}
void insertMatchpoint(const std::string& pkt)
@@ -625,22 +702,23 @@ private:
sendPacket("E01");
}
switch (type) {
case 0: // soft bp
if (agent.insertMatchpoint(0, addr, len))
case DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK: // soft bp
if (agent.insertMatchpoint(DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK,
addr, len))
sendPacket("OK");
else
sendPacket("E01");
break;
case 1: // hardware bp
case DebugAgent::Breakpoint::BP_TYPE_HARDWARE_BREAK: // hardware bp
sendPacket("");
break;
case 2: // write watchpoint
case DebugAgent::Breakpoint::BP_TYPE_WRITE_WATCHPOINT: // write watchpoint
sendPacket("");
break;
case 3: // read watchpoint
case DebugAgent::Breakpoint::BP_TYPE_READ_WATCHPOINT: // read watchpoint
sendPacket("");
break;
case 4: // access watchpoint
case DebugAgent::Breakpoint::BP_TYPE_ACCESS_WATCHPOINT: // access watchpoint
sendPacket("");
break;
default:
@@ -660,7 +738,8 @@ private:
}
switch (type) {
case 0: // soft bp
if (agent.removeMatchpoint(0, addr, len))
if (agent.removeMatchpoint(DebugAgent::Breakpoint::BP_TYPE_SOFTWARE_BREAK,
addr, len))
sendPacket("OK");
else
sendPacket("E01");
@@ -685,7 +764,7 @@ private:
void interrupt()
{
u32 signal = agent.interrupt();
u32 signal = agentInterrupt();
char s[10];
sprintf(s, "S%02x", signal);
sendPacket(s);
@@ -825,6 +904,16 @@ private:
throw Error("I/O error");
}
u32 agentInterrupt()
{
try {
return agent.interrupt();
} catch (const FlycastException& e) {
throw Error(e.what());
}
}
bool initialised = false;
bool stopRequested = false;
bool attached = false;
bool postDebugTrapNeeded = false;
@@ -838,9 +927,9 @@ public:
static GdbServer gdbServer;
void init()
void init(int port)
{
gdbServer.init();
gdbServer.init(port);
}
void term()
@@ -863,13 +952,17 @@ void subroutineReturn()
gdbServer.agent.subroutineReturn();
}
static void emuEventCallback(Event event)
static void emuEventCallback(Event event, void *)
{
switch (event)
{
case Event::Resume:
if (!gdbServer.isRunning())
gdbServer.run();
try {
if (!gdbServer.isRunning())
gdbServer.run();
} catch (const GdbServer::Error& e) {
ERROR_LOG(COMMON, "%s", e.what());
}
break;
case Event::Terminate:
gdbServer.stop();
+4 -2
View File
@@ -23,9 +23,11 @@ namespace debugger {
// exception thrown in response to trap
struct Stop { };
static const int DEFAULT_PORT = 3263;
#ifdef GDB_SERVER
void init();
void init(int port);
void term();
void run();
void debugTrap(u32 event);
@@ -33,7 +35,7 @@ struct Stop { };
void subroutineReturn();
#else
static inline void init() {}
static inline void init(int port) {}
static inline void term() {}
static inline void run() {}
static inline void debugTrap(u32 event) {}
+1
Submodule core/deps/Spout added at 2110a918e7.
+1
Submodule core/deps/Syphon added at 486dd8e4ef.
Submodule core/deps/breakpad added at 1ab24bcc81.
+26 -14
View File
@@ -38,7 +38,7 @@ unsigned long track_mode;
/////////////////////////////////////////////////////////////////////////////
void CDI_read_track (FILE *fsource, image_s *image, track_s *track)
bool CDI_read_track (FILE *fsource, image_s *image, track_s *track)
{
unsigned char TRACK_START_MARK[10] = { 0, 0, 0x01, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF };
@@ -49,10 +49,16 @@ void CDI_read_track (FILE *fsource, image_s *image, track_s *track)
fseek(fsource, 8, SEEK_CUR); // extra data (DJ 3.00.780 and up)
fread(&current_start_mark, 10, 1, fsource);
if (memcmp(TRACK_START_MARK, current_start_mark, 10)) printf( "Unsupported format: Could not find the track start mark");
if (memcmp(TRACK_START_MARK, current_start_mark, 10)) {
printf("CDI_read_track: Unsupported format: Could not find the track start mark\n");
return false;
}
fread(&current_start_mark, 10, 1, fsource);
if (memcmp(TRACK_START_MARK, current_start_mark, 10)) printf( "Unsupported format: Could not find the track start mark");
if (memcmp(TRACK_START_MARK, current_start_mark, 10)) {
printf("CDI_read_track: Unsupported format: Could not find the track start mark\n");
return false;
}
fseek(fsource, 4, SEEK_CUR);
fread(&track->filename_length, 1, 1, fsource);
@@ -80,20 +86,25 @@ void CDI_read_track (FILE *fsource, image_s *image, track_s *track)
case 1 : track->sector_size = 2336; break;
case 2 : track->sector_size = 2352; break;
case 4 : track->sector_size = 2448; break;
default: printf("Unsupported sector size. value %ld\n", track->sector_size_value);
break;
default:
printf("CDI_read_track: Unsupported sector size. value %ld\n", track->sector_size_value);
return false;
}
if (track->mode > 2) printf( "Unsupported format: Track mode not supported");
if (track->mode > 2) {
printf("CDI_read_track: Unsupported format: Track mode not supported\n");
return false;
}
fseek(fsource, 29, SEEK_CUR);
if (image->version != CDI_V2)
{
{
fseek(fsource, 5, SEEK_CUR);
fread(&temp_value, 4, 1, fsource);
if (temp_value == 0xffffffff)
fseek(fsource, 78, SEEK_CUR); // extra data (DJ 3.00.780 and up)
}
}
return true;
}
@@ -104,9 +115,9 @@ void CDI_skip_next_session (FILE *fsource, image_s *image)
if (image->version != CDI_V2) fseek(fsource, 1, SEEK_CUR);
}
void CDI_get_tracks (FILE *fsource, image_s *image)
bool CDI_get_tracks (FILE *fsource, image_s *image)
{
fread(&image->tracks, 2, 1, fsource);
return fread(&image->tracks, 2, 1, fsource) == 1;
}
bool CDI_init (FILE *fsource, image_s *image, const char *fsourcename)
@@ -121,8 +132,9 @@ bool CDI_init (FILE *fsource, image_s *image, const char *fsourcename)
}
fseek(fsource, image->length-8, SEEK_SET);
fread(&image->version, 4, 1, fsource);
fread(&image->header_offset, 4, 1, fsource);
if (fread(&image->version, 4, 1, fsource) != 1
|| fread(&image->header_offset, 4, 1, fsource) != 1)
return false;
if ((image->version != CDI_V2 && image->version != CDI_V3 && image->version != CDI_V35)
|| image->header_offset == 0)
@@ -133,7 +145,7 @@ bool CDI_init (FILE *fsource, image_s *image, const char *fsourcename)
return true;
}
void CDI_get_sessions (FILE *fsource, image_s *image)
bool CDI_get_sessions (FILE *fsource, image_s *image)
{
#ifndef DEBUG_CDI
if (image->version == CDI_V35)
@@ -144,6 +156,6 @@ void CDI_get_sessions (FILE *fsource, image_s *image)
#else
fseek(fsource, 0L, SEEK_SET);
#endif
fread(&image->sessions, 2, 1, fsource);
return fread(&image->sessions, 2, 1, fsource) == 1;
}
+3 -3
View File
@@ -38,9 +38,9 @@ typedef struct track_s
unsigned long ask_type(FILE *fsource, long header_position);
bool CDI_init(FILE *fsource, image_s *image, const char *fsourcename);
void CDI_get_sessions(FILE *fsource, image_s *image);
void CDI_get_tracks(FILE *fsource, image_s *image);
void CDI_read_track(FILE *fsource, image_s *image, track_s *track);
bool CDI_get_sessions(FILE *fsource, image_s *image);
bool CDI_get_tracks(FILE *fsource, image_s *image);
bool CDI_read_track(FILE *fsource, image_s *image, track_s *track);
void CDI_skip_next_session(FILE *fsource, image_s *image);
#endif
-239
View File
@@ -1,239 +0,0 @@
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
* Changed so as no longer to depend on Colin Plumb's `usual.h' header
* definitions; now uses stuff from dpkg's config.h.
* - Ian Jackson <[email protected]>.
* Still in the public domain.
*/
#include <string.h> /* for memcpy() */
#include "md5.h"
#ifndef LSB_FIRST
void
byteSwap(UWORD32 *buf, unsigned words)
{
md5byte *p = (md5byte *)buf;
do {
*buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
((unsigned)p[1] << 8 | p[0]);
p += 4;
} while (--words);
}
#else
#define byteSwap(buf,words)
#endif
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void
MD5Init(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bytes[0] = 0;
ctx->bytes[1] = 0;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void
MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
{
UWORD32 t;
/* Update byte count */
t = ctx->bytes[0];
if ((ctx->bytes[0] = t + len) < t)
ctx->bytes[1]++; /* Carry from low to high */
t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
if (t > len) {
memcpy((md5byte *)ctx->in + 64 - t, buf, len);
return;
}
/* First chunk is an odd size */
memcpy((md5byte *)ctx->in + 64 - t, buf, t);
byteSwap(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
buf += t;
len -= t;
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteSwap(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
MD5Final(md5byte digest[16], struct MD5Context *ctx)
{
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
md5byte *p = (md5byte *)ctx->in + count;
/* Set the first char of padding to 0x80. There is always room. */
*p++ = 0x80;
/* Bytes of padding needed to make 56 bytes (-8..55) */
count = 56 - 1 - count;
if (count < 0) { /* Padding forces an extra block */
memset(p, 0, count + 8);
byteSwap(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
p = (md5byte *)ctx->in;
count = 56;
}
memset(p, 0, count);
byteSwap(ctx->in, 14);
/* Append length in bits and transform */
ctx->in[14] = ctx->bytes[0] << 3;
ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
MD5Transform(ctx->buf, ctx->in);
byteSwap(ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}
#ifndef ASM_MD5
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f,w,x,y,z,in,s) \
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void
MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
{
register UWORD32 a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
#endif
-42
View File
@@ -1,42 +0,0 @@
/*
* This is the header file for the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
* Changed so as no longer to depend on Colin Plumb's `usual.h'
* header definitions; now uses stuff from dpkg's config.h
* - Ian Jackson <[email protected]>.
* Still in the public domain.
*/
#ifndef MD5_H
#define MD5_H
typedef unsigned int UWORD32;
#define md5byte unsigned char
struct MD5Context {
UWORD32 buf[4];
UWORD32 bytes[2];
UWORD32 in[16];
};
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
#endif /* !MD5_H */
-387
View File
@@ -1,387 +0,0 @@
/* sha1.h
*
* The sha1 hash function.
*/
/* nettle, low-level cryptographics library
*
* Copyright 2001 Peter Gutmann, Andrew Kuchling, Niels Moeller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "sha1.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
static unsigned int READ_UINT32(const UINT8* data)
{
return ((UINT32)data[0] << 24) |
((UINT32)data[1] << 16) |
((UINT32)data[2] << 8) |
((UINT32)data[3]);
}
static void WRITE_UINT32(unsigned char* data, UINT32 val)
{
data[0] = (val >> 24) & 0xFF;
data[1] = (val >> 16) & 0xFF;
data[2] = (val >> 8) & 0xFF;
data[3] = (val >> 0) & 0xFF;
}
/* A block, treated as a sequence of 32-bit words. */
#define SHA1_DATA_LENGTH 16
/* The SHA f()-functions. The f1 and f3 functions can be optimized to
save one boolean operation each - thanks to Rich Schroeppel,
[email protected] for discovering this */
/* #define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) Rounds 0-19 */
#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
/* #define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) Rounds 40-59 */
#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
/* The SHA Mysterious Constants */
#define K1 0x5A827999L /* Rounds 0-19 */
#define K2 0x6ED9EBA1L /* Rounds 20-39 */
#define K3 0x8F1BBCDCL /* Rounds 40-59 */
#define K4 0xCA62C1D6L /* Rounds 60-79 */
/* SHA initial values */
#define h0init 0x67452301L
#define h1init 0xEFCDAB89L
#define h2init 0x98BADCFEL
#define h3init 0x10325476L
#define h4init 0xC3D2E1F0L
/* 32-bit rotate left - kludged with shifts */
#ifdef _MSC_VER
#define ROTL(n,X) _lrotl(X, n)
#else
#define ROTL(n,X) ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) )
#endif
/* The initial expanding function. The hash function is defined over an
80-word expanded input array W, where the first 16 are copies of the input
data, and the remaining 64 are defined by
W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
This implementation generates these values on the fly in a circular
buffer - thanks to Colin Plumb, [email protected] for this
optimization.
The updated SHA changes the expanding function by adding a rotate of 1
bit. Thanks to Jim Gillogly, [email protected], and an anonymous contributor
for this information */
#define expand(W,i) ( W[ i & 15 ] = \
ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
/* The prototype SHA sub-round. The fundamental sub-round is:
a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
b' = a;
c' = ROTL( 30, b );
d' = c;
e' = d;
but this is implemented by unrolling the loop 5 times and renaming the
variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
This code is then replicated 20 times for each of the 4 functions, using
the next 20 values from the W[] array each time */
#define subRound(a, b, c, d, e, f, k, data) \
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
/* Initialize the SHA values */
void
sha1_init(struct sha1_ctx *ctx)
{
/* Set the h-vars to their initial values */
ctx->digest[ 0 ] = h0init;
ctx->digest[ 1 ] = h1init;
ctx->digest[ 2 ] = h2init;
ctx->digest[ 3 ] = h3init;
ctx->digest[ 4 ] = h4init;
/* Initialize bit count */
ctx->count_low = ctx->count_high = 0;
/* Initialize buffer */
ctx->index = 0;
}
/* Perform the SHA transformation. Note that this code, like MD5, seems to
break some optimizing compilers due to the complexity of the expressions
and the size of the basic block. It may be necessary to split it into
sections, e.g. based on the four subrounds
Note that this function destroys the data area */
static void
sha1_transform(UINT32 *state, UINT32 *data)
{
UINT32 A, B, C, D, E; /* Local vars */
/* Set up first buffer and local data buffer */
A = state[0];
B = state[1];
C = state[2];
D = state[3];
E = state[4];
/* Heavy mangling, in 4 sub-rounds of 20 interations each. */
subRound( A, B, C, D, E, f1, K1, data[ 0] );
subRound( E, A, B, C, D, f1, K1, data[ 1] );
subRound( D, E, A, B, C, f1, K1, data[ 2] );
subRound( C, D, E, A, B, f1, K1, data[ 3] );
subRound( B, C, D, E, A, f1, K1, data[ 4] );
subRound( A, B, C, D, E, f1, K1, data[ 5] );
subRound( E, A, B, C, D, f1, K1, data[ 6] );
subRound( D, E, A, B, C, f1, K1, data[ 7] );
subRound( C, D, E, A, B, f1, K1, data[ 8] );
subRound( B, C, D, E, A, f1, K1, data[ 9] );
subRound( A, B, C, D, E, f1, K1, data[10] );
subRound( E, A, B, C, D, f1, K1, data[11] );
subRound( D, E, A, B, C, f1, K1, data[12] );
subRound( C, D, E, A, B, f1, K1, data[13] );
subRound( B, C, D, E, A, f1, K1, data[14] );
subRound( A, B, C, D, E, f1, K1, data[15] );
subRound( E, A, B, C, D, f1, K1, expand( data, 16 ) );
subRound( D, E, A, B, C, f1, K1, expand( data, 17 ) );
subRound( C, D, E, A, B, f1, K1, expand( data, 18 ) );
subRound( B, C, D, E, A, f1, K1, expand( data, 19 ) );
subRound( A, B, C, D, E, f2, K2, expand( data, 20 ) );
subRound( E, A, B, C, D, f2, K2, expand( data, 21 ) );
subRound( D, E, A, B, C, f2, K2, expand( data, 22 ) );
subRound( C, D, E, A, B, f2, K2, expand( data, 23 ) );
subRound( B, C, D, E, A, f2, K2, expand( data, 24 ) );
subRound( A, B, C, D, E, f2, K2, expand( data, 25 ) );
subRound( E, A, B, C, D, f2, K2, expand( data, 26 ) );
subRound( D, E, A, B, C, f2, K2, expand( data, 27 ) );
subRound( C, D, E, A, B, f2, K2, expand( data, 28 ) );
subRound( B, C, D, E, A, f2, K2, expand( data, 29 ) );
subRound( A, B, C, D, E, f2, K2, expand( data, 30 ) );
subRound( E, A, B, C, D, f2, K2, expand( data, 31 ) );
subRound( D, E, A, B, C, f2, K2, expand( data, 32 ) );
subRound( C, D, E, A, B, f2, K2, expand( data, 33 ) );
subRound( B, C, D, E, A, f2, K2, expand( data, 34 ) );
subRound( A, B, C, D, E, f2, K2, expand( data, 35 ) );
subRound( E, A, B, C, D, f2, K2, expand( data, 36 ) );
subRound( D, E, A, B, C, f2, K2, expand( data, 37 ) );
subRound( C, D, E, A, B, f2, K2, expand( data, 38 ) );
subRound( B, C, D, E, A, f2, K2, expand( data, 39 ) );
subRound( A, B, C, D, E, f3, K3, expand( data, 40 ) );
subRound( E, A, B, C, D, f3, K3, expand( data, 41 ) );
subRound( D, E, A, B, C, f3, K3, expand( data, 42 ) );
subRound( C, D, E, A, B, f3, K3, expand( data, 43 ) );
subRound( B, C, D, E, A, f3, K3, expand( data, 44 ) );
subRound( A, B, C, D, E, f3, K3, expand( data, 45 ) );
subRound( E, A, B, C, D, f3, K3, expand( data, 46 ) );
subRound( D, E, A, B, C, f3, K3, expand( data, 47 ) );
subRound( C, D, E, A, B, f3, K3, expand( data, 48 ) );
subRound( B, C, D, E, A, f3, K3, expand( data, 49 ) );
subRound( A, B, C, D, E, f3, K3, expand( data, 50 ) );
subRound( E, A, B, C, D, f3, K3, expand( data, 51 ) );
subRound( D, E, A, B, C, f3, K3, expand( data, 52 ) );
subRound( C, D, E, A, B, f3, K3, expand( data, 53 ) );
subRound( B, C, D, E, A, f3, K3, expand( data, 54 ) );
subRound( A, B, C, D, E, f3, K3, expand( data, 55 ) );
subRound( E, A, B, C, D, f3, K3, expand( data, 56 ) );
subRound( D, E, A, B, C, f3, K3, expand( data, 57 ) );
subRound( C, D, E, A, B, f3, K3, expand( data, 58 ) );
subRound( B, C, D, E, A, f3, K3, expand( data, 59 ) );
subRound( A, B, C, D, E, f4, K4, expand( data, 60 ) );
subRound( E, A, B, C, D, f4, K4, expand( data, 61 ) );
subRound( D, E, A, B, C, f4, K4, expand( data, 62 ) );
subRound( C, D, E, A, B, f4, K4, expand( data, 63 ) );
subRound( B, C, D, E, A, f4, K4, expand( data, 64 ) );
subRound( A, B, C, D, E, f4, K4, expand( data, 65 ) );
subRound( E, A, B, C, D, f4, K4, expand( data, 66 ) );
subRound( D, E, A, B, C, f4, K4, expand( data, 67 ) );
subRound( C, D, E, A, B, f4, K4, expand( data, 68 ) );
subRound( B, C, D, E, A, f4, K4, expand( data, 69 ) );
subRound( A, B, C, D, E, f4, K4, expand( data, 70 ) );
subRound( E, A, B, C, D, f4, K4, expand( data, 71 ) );
subRound( D, E, A, B, C, f4, K4, expand( data, 72 ) );
subRound( C, D, E, A, B, f4, K4, expand( data, 73 ) );
subRound( B, C, D, E, A, f4, K4, expand( data, 74 ) );
subRound( A, B, C, D, E, f4, K4, expand( data, 75 ) );
subRound( E, A, B, C, D, f4, K4, expand( data, 76 ) );
subRound( D, E, A, B, C, f4, K4, expand( data, 77 ) );
subRound( C, D, E, A, B, f4, K4, expand( data, 78 ) );
subRound( B, C, D, E, A, f4, K4, expand( data, 79 ) );
/* Build message digest */
state[0] += A;
state[1] += B;
state[2] += C;
state[3] += D;
state[4] += E;
}
static void
sha1_block(struct sha1_ctx *ctx, const UINT8 *block)
{
UINT32 data[SHA1_DATA_LENGTH];
int i;
/* Update block count */
if (!++ctx->count_low)
++ctx->count_high;
/* Endian independent conversion */
for (i = 0; i<SHA1_DATA_LENGTH; i++, block += 4)
data[i] = READ_UINT32(block);
sha1_transform(ctx->digest, data);
}
void
sha1_update(struct sha1_ctx *ctx,
unsigned length, const UINT8 *buffer)
{
if (ctx->index)
{ /* Try to fill partial block */
unsigned left = SHA1_DATA_SIZE - ctx->index;
if (length < left)
{
memcpy(ctx->block + ctx->index, buffer, length);
ctx->index += length;
return; /* Finished */
}
else
{
memcpy(ctx->block + ctx->index, buffer, left);
sha1_block(ctx, ctx->block);
buffer += left;
length -= left;
}
}
while (length >= SHA1_DATA_SIZE)
{
sha1_block(ctx, buffer);
buffer += SHA1_DATA_SIZE;
length -= SHA1_DATA_SIZE;
}
ctx->index = length;
if (length)
/* Buffer leftovers */
memcpy(ctx->block, buffer, length);
}
/* Final wrapup - pad to SHA1_DATA_SIZE-byte boundary with the bit pattern
1 0* (64-bit count of bits processed, MSB-first) */
void
sha1_final(struct sha1_ctx *ctx)
{
UINT32 data[SHA1_DATA_LENGTH];
int i;
int words;
i = ctx->index;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
assert(i < SHA1_DATA_SIZE);
ctx->block[i++] = 0x80;
/* Fill rest of word */
for( ; i & 3; i++)
ctx->block[i] = 0;
/* i is now a multiple of the word size 4 */
words = i >> 2;
for (i = 0; i < words; i++)
data[i] = READ_UINT32(ctx->block + 4*i);
if (words > (SHA1_DATA_LENGTH-2))
{ /* No room for length in this block. Process it and
* pad with another one */
for (i = words ; i < SHA1_DATA_LENGTH; i++)
data[i] = 0;
sha1_transform(ctx->digest, data);
for (i = 0; i < (SHA1_DATA_LENGTH-2); i++)
data[i] = 0;
}
else
for (i = words ; i < SHA1_DATA_LENGTH - 2; i++)
data[i] = 0;
/* There are 512 = 2^9 bits in one block */
data[SHA1_DATA_LENGTH-2] = (ctx->count_high << 9) | (ctx->count_low >> 23);
data[SHA1_DATA_LENGTH-1] = (ctx->count_low << 9) | (ctx->index << 3);
sha1_transform(ctx->digest, data);
}
void
sha1_digest(const struct sha1_ctx *ctx,
unsigned length,
UINT8 *digest)
{
unsigned i;
unsigned words;
unsigned leftover;
assert(length <= SHA1_DIGEST_SIZE);
words = length / 4;
leftover = length % 4;
for (i = 0; i < words; i++, digest += 4)
WRITE_UINT32(digest, ctx->digest[i]);
if (leftover)
{
UINT32 word;
unsigned j = leftover;
assert(i < _SHA1_DIGEST_LENGTH);
word = ctx->digest[i];
switch (leftover)
{
default:
/* this is just here to keep the compiler happy; it can never happen */
case 3:
digest[--j] = (word >> 8) & 0xff;
/* Fall through */
case 2:
digest[--j] = (word >> 16) & 0xff;
/* Fall through */
case 1:
digest[--j] = (word >> 24) & 0xff;
}
}
}
-63
View File
@@ -1,63 +0,0 @@
/* sha1.h
*
* The sha1 hash function.
*/
/* nettle, low-level cryptographics library
*
* Copyright 2001 Niels Moeller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#ifndef NETTLE_SHA1_H_INCLUDED
#define NETTLE_SHA1_H_INCLUDED
#include "../chdr/coretypes.h"
#define SHA1_DIGEST_SIZE 20
#define SHA1_DATA_SIZE 64
/* Digest is kept internally as 4 32-bit words. */
#define _SHA1_DIGEST_LENGTH 5
struct sha1_ctx
{
UINT32 digest[_SHA1_DIGEST_LENGTH]; /* Message digest */
UINT32 count_low, count_high; /* 64-bit block count */
UINT8 block[SHA1_DATA_SIZE]; /* SHA1 data buffer */
unsigned int index; /* index into buffer */
};
void
sha1_init(struct sha1_ctx *ctx);
void
sha1_update(struct sha1_ctx *ctx,
unsigned length,
const UINT8 *data);
void
sha1_final(struct sha1_ctx *ctx);
void
sha1_digest(const struct sha1_ctx *ctx,
unsigned length,
UINT8 *digest);
#endif /* NETTLE_SHA1_H_INCLUDED */
-161
View File
@@ -1,161 +0,0 @@
/*********************************************************************
* Filename: sha256.c
* Author: Brad Conte (brad AT bradconte.com)
* Copyright:
* Disclaimer: This code is presented "as is" without any guarantees.
* Details: Implementation of the SHA-256 hashing algorithm.
SHA-256 is one of the three algorithms in the SHA2
specification. The others, SHA-384 and SHA-512, are not
offered in this implementation.
Algorithm specification can be found here:
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
This implementation uses little endian byte order.
*********************************************************************/
/*************************** HEADER FILES ***************************/
#include <stdlib.h>
#include <string.h>
#include "sha256.h"
#define WORD uint32_t
#define BYTE uint8_t
/****************************** MACROS ******************************/
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
/**************************** VARIABLES *****************************/
static const WORD k[64] = {
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
/*********************** FUNCTION DEFINITIONS ***********************/
void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
{
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
for (i = 0, j = 0; i < 16; ++i, j += 4)
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
for ( ; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
f = ctx->state[5];
g = ctx->state[6];
h = ctx->state[7];
for (i = 0; i < 64; ++i) {
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
t2 = EP0(a) + MAJ(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
ctx->state[5] += f;
ctx->state[6] += g;
ctx->state[7] += h;
}
void sha256_init(SHA256_CTX *ctx)
{
ctx->datalen = 0;
ctx->bitlen = 0;
ctx->state[0] = 0x6a09e667;
ctx->state[1] = 0xbb67ae85;
ctx->state[2] = 0x3c6ef372;
ctx->state[3] = 0xa54ff53a;
ctx->state[4] = 0x510e527f;
ctx->state[5] = 0x9b05688c;
ctx->state[6] = 0x1f83d9ab;
ctx->state[7] = 0x5be0cd19;
}
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
{
WORD i;
for (i = 0; i < len; ++i) {
ctx->data[ctx->datalen] = data[i];
ctx->datalen++;
if (ctx->datalen == 64) {
sha256_transform(ctx, ctx->data);
ctx->bitlen += 512;
ctx->datalen = 0;
}
}
}
void sha256_final(SHA256_CTX *ctx, BYTE hash[])
{
WORD i;
i = ctx->datalen;
// Pad whatever data is left in the buffer.
if (ctx->datalen < 56) {
ctx->data[i++] = 0x80;
while (i < 56)
ctx->data[i++] = 0x00;
}
else {
ctx->data[i++] = 0x80;
while (i < 64)
ctx->data[i++] = 0x00;
sha256_transform(ctx, ctx->data);
memset(ctx->data, 0, 56);
}
// Append to the padding the total message's length in bits and transform.
ctx->bitlen += ctx->datalen * 8;
ctx->data[63] = (BYTE)(ctx->bitlen);
ctx->data[62] = (BYTE)(ctx->bitlen >> 8);
ctx->data[61] = (BYTE)(ctx->bitlen >> 16);
ctx->data[60] = (BYTE)(ctx->bitlen >> 24);
ctx->data[59] = (BYTE)(ctx->bitlen >> 32);
ctx->data[58] = (BYTE)(ctx->bitlen >> 40);
ctx->data[57] = (BYTE)(ctx->bitlen >> 48);
ctx->data[56] = (BYTE)(ctx->bitlen >> 56);
sha256_transform(ctx, ctx->data);
// Since this implementation uses little endian byte ordering and SHA uses big endian,
// reverse all the bytes when copying the final state to the output hash.
for (i = 0; i < 4; ++i) {
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
}
}
-37
View File
@@ -1,37 +0,0 @@
/*********************************************************************
* Filename: sha256.h
* Author: Brad Conte (brad AT bradconte.com)
* Copyright:
* Disclaimer: This code is presented "as is" without any guarantees.
* Details: Defines the API for the corresponding SHA1 implementation.
*********************************************************************/
#ifndef SHA256_H
#define SHA256_H
/*************************** HEADER FILES ***************************/
#include <stddef.h>
#include <stdint.h>
/****************************** MACROS ******************************/
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
/**************************** DATA TYPES ****************************/
/*
typedef uint8_t BYTE; // 8-bit byte
typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines
*/
typedef struct {
uint8_t data[64];
uint32_t datalen;
uint64_t bitlen;
uint32_t state[8];
} SHA256_CTX;
/*********************** FUNCTION DECLARATIONS **********************/
void sha256_init(SHA256_CTX *ctx);
void sha256_update(SHA256_CTX *ctx, const uint8_t data[], size_t len);
void sha256_final(SHA256_CTX *ctx, uint8_t hash[]);
#endif // SHA256_H
+7 -1
View File
@@ -29,6 +29,10 @@
#include <sys/stat.h>
#include <errno.h>
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
#define FindFirstFileExW FindFirstFileExFromAppW
#endif
/* Indicates that d_type field is available in dirent structure */
#define _DIRENT_HAVE_D_TYPE
@@ -613,7 +617,7 @@ dirent_first(
/* Failed to re-open directory: no directory entry in memory */
dirp->cached = 0;
datap = NULL;
dirent_set_errno(GetLastError()); /* Not a valid errno but better than nothing */
}
return datap;
}
@@ -647,6 +651,8 @@ dirent_next(
FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
p = NULL;
if (GetLastError() != ERROR_NO_MORE_FILES)
dirent_set_errno(GetLastError());
}
} else {
+598
View File
@@ -0,0 +1,598 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _GGPONET_H_
#define _GGPONET_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
// On windows, export at build time and import at runtime.
// ELF systems don't need an explicit export/import.
#ifdef _WIN32
# if defined(GGPO_SHARED_LIB)
# ifdef GGPO_SDK_EXPORT
# define GGPO_API __declspec(dllexport)
# else
# define GGPO_API __declspec(dllimport)
# endif
# else
# define GGPO_API
# endif
#else
# define GGPO_API
#endif
#ifdef __GNUC__
#if defined(_WIN32) && !defined(_WIN64)
#define __cdecl __attribute__((cdecl))
#elif !defined(__cdecl)
#define __cdecl
#endif
#endif
#define GGPO_MAX_PLAYERS 4
#define GGPO_MAX_PREDICTION_FRAMES 8
#define GGPO_MAX_SPECTATORS 32
#define GGPO_SPECTATOR_INPUT_INTERVAL 4
typedef struct GGPOSession GGPOSession;
typedef int GGPOPlayerHandle;
typedef enum {
GGPO_PLAYERTYPE_LOCAL,
GGPO_PLAYERTYPE_REMOTE,
GGPO_PLAYERTYPE_SPECTATOR,
} GGPOPlayerType;
/*
* The GGPOPlayer structure used to describe players in ggpo_add_player
*
* size: Should be set to the sizeof(GGPOPlayer)
*
* type: One of the GGPOPlayerType values describing how inputs should be handled
* Local players must have their inputs updated every frame via
* ggpo_add_local_inputs. Remote players values will come over the
* network.
*
* player_num: The player number. Should be between 1 and the number of players
* In the game (e.g. in a 2 player game, either 1 or 2).
*
* If type == GGPO_PLAYERTYPE_REMOTE:
*
* u.remote.ip_address: The ip address of the ggpo session which will host this
* player.
*
* u.remote.port: The port where udp packets should be sent to reach this player.
* All the local inputs for this session will be sent to this player at
* ip_address:port.
*
*/
typedef struct GGPOPlayer {
int size;
GGPOPlayerType type;
int player_num;
union {
struct {
bool _unused;
} local;
struct {
char ip_address[32];
unsigned short port;
} remote;
} u;
} GGPOPlayer;
typedef struct GGPOLocalEndpoint {
int player_num;
} GGPOLocalEndpoint;
#define GGPO_ERRORLIST \
GGPO_ERRORLIST_ENTRY(GGPO_OK, 0) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_SUCCESS, 0) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_GENERAL_FAILURE, -1) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INVALID_SESSION, 1) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INVALID_PLAYER_HANDLE, 2) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_PLAYER_OUT_OF_RANGE, 3) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_PREDICTION_THRESHOLD, 4) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_UNSUPPORTED, 5) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_NOT_SYNCHRONIZED, 6) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_IN_ROLLBACK, 7) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INPUT_DROPPED, 8) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_PLAYER_DISCONNECTED, 9) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_TOO_MANY_SPECTATORS, 10) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INVALID_REQUEST, 11) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_INPUT_SIZE_DIFF, 12) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_NETWORK_ERROR, 13) \
GGPO_ERRORLIST_ENTRY(GGPO_ERRORCODE_VERIFICATION_ERROR, 14)
#define GGPO_ERRORLIST_ENTRY(name, value) name = value,
typedef enum {
GGPO_ERRORLIST
} GGPOErrorCode;
#undef GGPO_ERRORLIST_ENTRY
#define GGPO_SUCCEEDED(result) ((result) == GGPO_ERRORCODE_SUCCESS)
#define GGPO_INVALID_HANDLE (-1)
/*
* The GGPOEventCode enumeration describes what type of event just happened.
*
* GGPO_EVENTCODE_CONNECTED_TO_PEER - Handshake with the game running on the
* other side of the network has been completed.
*
* GGPO_EVENTCODE_SYNCHRONIZING_WITH_PEER - Beginning the synchronization
* process with the client on the other end of the networking. The count
* and total fields in the u.synchronizing struct of the GGPOEvent
* object indicate progress.
*
* GGPO_EVENTCODE_SYNCHRONIZED_WITH_PEER - The synchronziation with this
* peer has finished.
*
* GGPO_EVENTCODE_RUNNING - All the clients have synchronized. You may begin
* sending inputs with ggpo_synchronize_inputs.
*
* GGPO_EVENTCODE_DISCONNECTED_FROM_PEER - The network connection on
* the other end of the network has closed.
*
* GGPO_EVENTCODE_TIMESYNC - The time synchronziation code has determined
* that this client is too far ahead of the other one and should slow
* down to ensure fairness. The u.timesync.frames_ahead parameter in
* the GGPOEvent object indicates how many frames the client is.
*
*/
typedef enum {
GGPO_EVENTCODE_CONNECTED_TO_PEER = 1000,
GGPO_EVENTCODE_SYNCHRONIZING_WITH_PEER = 1001,
GGPO_EVENTCODE_SYNCHRONIZED_WITH_PEER = 1002,
GGPO_EVENTCODE_RUNNING = 1003,
GGPO_EVENTCODE_DISCONNECTED_FROM_PEER = 1004,
GGPO_EVENTCODE_TIMESYNC = 1005,
GGPO_EVENTCODE_CONNECTION_INTERRUPTED = 1006,
GGPO_EVENTCODE_CONNECTION_RESUMED = 1007,
} GGPOEventCode;
/*
* The GGPOEvent structure contains an asynchronous event notification sent
* by the on_event callback. See GGPOEventCode, above, for a detailed
* explanation of each event.
*/
typedef struct {
GGPOEventCode code;
union {
struct {
GGPOPlayerHandle player;
} connected;
struct {
GGPOPlayerHandle player;
int count;
int total;
} synchronizing;
struct {
GGPOPlayerHandle player;
} synchronized;
struct {
GGPOPlayerHandle player;
} disconnected;
struct {
int frames_ahead;
} timesync;
struct {
GGPOPlayerHandle player;
int disconnect_timeout;
} connection_interrupted;
struct {
GGPOPlayerHandle player;
} connection_resumed;
} u;
} GGPOEvent;
/*
* The GGPOSessionCallbacks structure contains the callback functions that
* your application must implement. GGPO.net will periodically call these
* functions during the game. All callback functions must be implemented.
*/
typedef struct {
/*
* begin_game callback - This callback has been deprecated. You must
* implement it, but should ignore the 'game' parameter.
*/
bool (__cdecl *begin_game)(const char *game);
/*
* save_game_state - The client should allocate a buffer, copy the
* entire contents of the current game state into it, and copy the
* length into the *len parameter. Optionally, the client can compute
* a checksum of the data and store it in the *checksum argument.
*/
bool (__cdecl *save_game_state)(unsigned char **buffer, int *len, int *checksum, int frame);
/*
* load_game_state - GGPO.net will call this function at the beginning
* of a rollback. The buffer and len parameters contain a previously
* saved state returned from the save_game_state function. The client
* should make the current game state match the state contained in the
* buffer.
*/
bool (__cdecl *load_game_state)(unsigned char *buffer, int len);
/*
* log_game_state - Used in diagnostic testing. The client should use
* the ggpo_log function to write the contents of the specified save
* state in a human readible form.
*/
bool (__cdecl *log_game_state)(char *filename, unsigned char *buffer, int len);
/*
* free_buffer - Frees a game state allocated in save_game_state. You
* should deallocate the memory contained in the buffer.
*/
void (__cdecl *free_buffer)(void *buffer);
/*
* advance_frame - Called during a rollback. You should advance your game
* state by exactly one frame. Before each frame, call ggpo_synchronize_input
* to retrieve the inputs you should use for that frame. After each frame,
* you should call ggpo_advance_frame to notify GGPO.net that you're
* finished.
*
* The flags parameter is reserved. It can safely be ignored at this time.
*/
bool (__cdecl *advance_frame)(int flags);
/*
* on_event - Notification that something has happened. See the GGPOEventCode
* structure above for more information.
*/
bool (__cdecl *on_event)(GGPOEvent *info);
/*
* on_message - Delivers an application message. Allows arbitrary data to be
* exchanged with peers. This callback is optional.
*/
void (__cdecl *on_message)(unsigned char *msg, int len);
} GGPOSessionCallbacks;
/*
* The GGPONetworkStats function contains some statistics about the current
* session.
*
* network.send_queue_len - The length of the queue containing UDP packets
* which have not yet been acknowledged by the end client. The length of
* the send queue is a rough indication of the quality of the connection.
* The longer the send queue, the higher the round-trip time between the
* clients. The send queue will also be longer than usual during high
* packet loss situations.
*
* network.recv_queue_len - The number of inputs currently buffered by the
* GGPO.net network layer which have yet to be validated. The length of
* the prediction queue is roughly equal to the current frame number
* minus the frame number of the last packet in the remote queue.
*
* network.ping - The roundtrip packet transmission time as calcuated
* by GGPO.net. This will be roughly equal to the actual round trip
* packet transmission time + 2 the interval at which you call ggpo_idle
* or ggpo_advance_frame.
*
* network.kbps_sent - The estimated bandwidth used between the two
* clients, in kilobits per second.
*
* timesync.local_frames_behind - The number of frames GGPO.net calculates
* that the local client is behind the remote client at this instant in
* time. For example, if at this instant the current game client is running
* frame 1002 and the remote game client is running frame 1009, this value
* will mostly likely roughly equal 7.
*
* timesync.remote_frames_behind - The same as local_frames_behind, but
* calculated from the perspective of the remote player.
*
*/
typedef struct GGPONetworkStats {
struct {
int send_queue_len;
int recv_queue_len;
int ping;
int kbps_sent;
} network;
struct {
int local_frames_behind;
int remote_frames_behind;
} timesync;
struct {
int predicted_frames;
} sync;
} GGPONetworkStats;
/*
* ggpo_start_session --
*
* Used to being a new GGPO.net session. The ggpo object returned by ggpo_start_session
* uniquely identifies the state for this session and should be passed to all other
* functions.
*
* session - An out parameter to the new ggpo session object.
*
* cb - A GGPOSessionCallbacks structure which contains the callbacks you implement
* to help GGPO.net synchronize the two games. You must implement all functions in
* cb, even if they do nothing but 'return true';
*
* game - The name of the game. This is used internally for GGPO for logging purposes only.
*
* num_players - The number of players which will be in this game. The number of players
* per session is fixed. If you need to change the number of players or any player
* disconnects, you must start a new session.
*
* input_size - The size of the game inputs which will be passsed to ggpo_add_local_input.
*
* local_port - The port GGPO should bind to for UDP traffic.
*
* verification - Some optional data that will be matched with the peers during initial sync.
* Can be set to null if verification_size is zero. This can be used to check that all peers are
* running the same version of the application and of the game, are using the same settings, etc.
*
* verification_size - Size of the verification data. Can be set to zero to not exchange verification data.
* Maximum size is 256 bytes.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_start_session(GGPOSession **session,
GGPOSessionCallbacks *cb,
const char *game,
int num_players,
int input_size,
unsigned short localport,
const void *verification,
int verification_size);
/*
* ggpo_add_player --
*
* Must be called for each player in the session (e.g. in a 3 player session, must
* be called 3 times).
*
* player - A GGPOPlayer struct used to describe the player.
*
* handle - An out parameter to a handle used to identify this player in the future.
* (e.g. in the on_event callbacks).
*/
GGPO_API GGPOErrorCode __cdecl ggpo_add_player(GGPOSession *session,
GGPOPlayer *player,
GGPOPlayerHandle *handle);
/*
* ggpo_start_synctest --
*
* Used to being a new GGPO.net sync test session. During a sync test, every
* frame of execution is run twice: once in prediction mode and once again to
* verify the result of the prediction. If the checksums of your save states
* do not match, the test is aborted.
*
* cb - A GGPOSessionCallbacks structure which contains the callbacks you implement
* to help GGPO.net synchronize the two games. You must implement all functions in
* cb, even if they do nothing but 'return true';
*
* game - The name of the game. This is used internally for GGPO for logging purposes only.
*
* num_players - The number of players which will be in this game. The number of players
* per session is fixed. If you need to change the number of players or any player
* disconnects, you must start a new session.
*
* input_size - The size of the game inputs which will be passsed to ggpo_add_local_input.
*
* frames - The number of frames to run before verifying the prediction. The
* recommended value is 1.
*
*/
GGPO_API GGPOErrorCode __cdecl ggpo_start_synctest(GGPOSession **session,
GGPOSessionCallbacks *cb,
const char *game,
int num_players,
int input_size,
int frames);
/*
* ggpo_start_spectating --
*
* Start a spectator session.
*
* cb - A GGPOSessionCallbacks structure which contains the callbacks you implement
* to help GGPO.net synchronize the two games. You must implement all functions in
* cb, even if they do nothing but 'return true';
*
* game - The name of the game. This is used internally for GGPO for logging purposes only.
*
* num_players - The number of players which will be in this game. The number of players
* per session is fixed. If you need to change the number of players or any player
* disconnects, you must start a new session.
*
* input_size - The size of the game inputs which will be passsed to ggpo_add_local_input.
*
* local_port - The port GGPO should bind to for UDP traffic.
*
* host_ip - The IP address of the host who will serve you the inputs for the game. Any
* player partcipating in the session can serve as a host.
*
* host_port - The port of the session on the host
*
* verification - Some optional data that will be matched with the peers during initial sync.
* Can be set to null if verification_size is zero. This can be used to check that all peers are
* running the same version of the application and of the game, are using the same settings, etc.
*
* verification_size - Size of the verification data. Can be set to zero to not exchange verification data.
* Maximum size is 256 bytes.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_start_spectating(GGPOSession **session,
GGPOSessionCallbacks *cb,
const char *game,
int num_players,
int input_size,
unsigned short local_port,
char *host_ip,
unsigned short host_port,
const void *verification,
int verification_size);
/*
* ggpo_close_session --
* Used to close a session. You must call ggpo_close_session to
* free the resources allocated in ggpo_start_session.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_close_session(GGPOSession *);
/*
* ggpo_set_frame_delay --
*
* Change the amount of frames ggpo will delay local input. Must be called
* before the first call to ggpo_synchronize_input.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_set_frame_delay(GGPOSession *,
GGPOPlayerHandle player,
int frame_delay);
/*
* ggpo_idle --
* Should be called periodically by your application to give GGPO.net
* a chance to do some work. Most packet transmissions and rollbacks occur
* in ggpo_idle.
*
* timeout - The amount of time GGPO.net is allowed to spend in this function,
* in milliseconds.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_idle(GGPOSession *,
int timeout);
/*
* ggpo_add_local_input --
*
* Used to notify GGPO.net of inputs that should be trasmitted to remote
* players. ggpo_add_local_input must be called once every frame for
* all player of type GGPO_PLAYERTYPE_LOCAL.
*
* player - The player handle returned for this player when you called
* ggpo_add_local_player.
*
* values - The controller inputs for this player.
*
* size - The size of the controller inputs. This must be exactly equal to the
* size passed into ggpo_start_session.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_add_local_input(GGPOSession *,
GGPOPlayerHandle player,
void *values,
int size);
/*
* ggpo_synchronize_input --
*
* You should call ggpo_synchronize_input before every frame of execution,
* including those frames which happen during rollback.
*
* values - When the function returns, the values parameter will contain
* inputs for this frame for all players. The values array must be at
* least (size * players) large.
*
* size - The size of the values array.
*
* disconnect_flags - Indicated whether the input in slot (1 << flag) is
* valid. If a player has disconnected, the input in the values array for
* that player will be zeroed and the i-th flag will be set. For example,
* if only player 3 has disconnected, disconnect flags will be 8 (i.e. 1 << 3).
*/
GGPO_API GGPOErrorCode __cdecl ggpo_synchronize_input(GGPOSession *,
void *values,
int size,
int *disconnect_flags);
/*
* ggpo_disconnect_player --
*
* Disconnects a remote player from a game. Will return GGPO_ERRORCODE_PLAYER_DISCONNECTED
* if you try to disconnect a player who has already been disconnected.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_disconnect_player(GGPOSession *,
GGPOPlayerHandle player);
/*
* ggpo_advance_frame --
*
* You should call ggpo_advance_frame to notify GGPO.net that you have
* advanced your gamestate by a single frame. You should call this everytime
* you advance the gamestate by a frame, even during rollbacks. GGPO.net
* may call your save_state callback before this function returns.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_advance_frame(GGPOSession *);
/*
* ggpo_get_network_stats --
*
* Used to fetch some statistics about the quality of the network connection.
*
* player - The player handle returned from the ggpo_add_player function you used
* to add the remote player.
*
* stats - Out parameter to the network statistics.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_get_network_stats(GGPOSession *,
GGPOPlayerHandle player,
GGPONetworkStats *stats);
/*
* ggpo_set_disconnect_timeout --
*
* Sets the disconnect timeout. The session will automatically disconnect
* from a remote peer if it has not received a packet in the timeout window.
* You will be notified of the disconnect via a GGPO_EVENTCODE_DISCONNECTED_FROM_PEER
* event.
*
* Setting a timeout value of 0 will disable automatic disconnects.
*
* timeout - The time in milliseconds to wait before disconnecting a peer.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_timeout(GGPOSession *,
int timeout);
/*
* ggpo_set_disconnect_notify_start --
*
* The time to wait before the first GGPO_EVENTCODE_NETWORK_INTERRUPTED timeout
* will be sent.
*
* timeout - The amount of time which needs to elapse without receiving a packet
* before the GGPO_EVENTCODE_NETWORK_INTERRUPTED event is sent.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_set_disconnect_notify_start(GGPOSession *,
int timeout);
/*
* ggpo_send_message --
*
* Sends application-specific data to other peers. The message is
* delivered by the on_user_message callback.
* If spectators is true, the message is also sent to spectators.
*/
GGPO_API GGPOErrorCode __cdecl ggpo_send_message(GGPOSession *,
const void *msg,
int len,
bool spectators);
#ifdef __cplusplus
};
#endif
#endif
@@ -0,0 +1,33 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _BACKEND_H
#define _BACKEND_H
#include "../ggpo_types.h"
#include "ggponet.h"
struct GGPOSession {
virtual ~GGPOSession() { }
virtual GGPOErrorCode DoPoll(int timeout) { return GGPO_OK; }
virtual GGPOErrorCode AddPlayer(GGPOPlayer *player, GGPOPlayerHandle *handle) = 0;
virtual GGPOErrorCode AddLocalInput(GGPOPlayerHandle player, void *values, int size) = 0;
virtual GGPOErrorCode SyncInput(void *values, int size, int *disconnect_flags) = 0;
virtual GGPOErrorCode IncrementFrame(void) { return GGPO_OK; }
virtual GGPOErrorCode DisconnectPlayer(GGPOPlayerHandle handle) { return GGPO_OK; }
virtual GGPOErrorCode GetNetworkStats(GGPONetworkStats *stats, GGPOPlayerHandle handle) { return GGPO_OK; }
virtual GGPOErrorCode SetFrameDelay(GGPOPlayerHandle player, int delay) { return GGPO_ERRORCODE_UNSUPPORTED; }
virtual GGPOErrorCode SetDisconnectTimeout(int timeout) { return GGPO_ERRORCODE_UNSUPPORTED; }
virtual GGPOErrorCode SetDisconnectNotifyStart(int timeout) { return GGPO_ERRORCODE_UNSUPPORTED; }
virtual GGPOErrorCode SendMessage(const void *msg, int len, bool spectators) { return GGPO_ERRORCODE_UNSUPPORTED; }
};
typedef struct GGPOSession Quark, IQuarkBackend; /* XXX: nuke this */
#endif
+664
View File
@@ -0,0 +1,664 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "p2p.h"
#include <chrono>
#include <thread>
static const int RECOMMENDATION_INTERVAL = 240;
static const int DEFAULT_DISCONNECT_TIMEOUT = 5000;
static const int DEFAULT_DISCONNECT_NOTIFY_START = 750;
Peer2PeerBackend::Peer2PeerBackend(GGPOSessionCallbacks *cb,
const char *gamename,
uint16 localport,
int num_players,
int input_size,
const void *verification,
int verification_size) :
_sync(_local_connect_status),
_endpoints(nullptr),
_num_spectators(0),
_input_size(input_size),
_num_players(num_players),
_next_spectator_frame(0),
_disconnect_timeout(DEFAULT_DISCONNECT_TIMEOUT),
_disconnect_notify_start(DEFAULT_DISCONNECT_NOTIFY_START)
{
_callbacks = *cb;
_synchronizing = true;
_next_recommended_sleep = 0;
/*
* Initialize the synchronziation layer
*/
Sync::Config config = { 0 };
config.num_players = num_players;
config.input_size = input_size;
config.callbacks = _callbacks;
config.num_prediction_frames = MAX_PREDICTION_FRAMES;
_sync.Init(config);
/*
* Initialize the UDP port
*/
_udp.Init(localport, &_poll, this);
_endpoints = new UdpProtocol[_num_players];
for (int i = 0; i < _num_players; i++)
_endpoints[i].SetVerificationData(verification, verification_size);
memset(_local_connect_status, 0, sizeof(_local_connect_status));
for (unsigned i = 0; i < ARRAY_SIZE(_local_connect_status); i++) {
_local_connect_status[i].last_frame = -1;
}
/*
* Preload the ROM
*/
_callbacks.begin_game(gamename);
}
Peer2PeerBackend::~Peer2PeerBackend()
{
delete [] _endpoints;
}
void
Peer2PeerBackend::AddRemotePlayer(char *ip,
uint16 port,
int queue)
{
/*
* Start the state machine (xxx: no)
*/
_synchronizing = true;
_endpoints[queue].Init(&_udp, _poll, queue, ip, port, _local_connect_status);
_endpoints[queue].SetDisconnectTimeout(_disconnect_timeout);
_endpoints[queue].SetDisconnectNotifyStart(_disconnect_notify_start);
_endpoints[queue].Synchronize();
}
GGPOErrorCode Peer2PeerBackend::AddSpectator(char *ip,
uint16 port)
{
if (_num_spectators == GGPO_MAX_SPECTATORS) {
return GGPO_ERRORCODE_TOO_MANY_SPECTATORS;
}
/*
* Currently, we can only add spectators before the game starts.
*/
if (!_synchronizing) {
return GGPO_ERRORCODE_INVALID_REQUEST;
}
int queue = _num_spectators++;
_spectators[queue].Init(&_udp, _poll, queue + 1000, ip, port, _local_connect_status);
_spectators[queue].SetDisconnectTimeout(_disconnect_timeout);
_spectators[queue].SetDisconnectNotifyStart(_disconnect_notify_start);
_spectators[queue].Synchronize();
return GGPO_OK;
}
GGPOErrorCode
Peer2PeerBackend::DoPoll(int timeout)
{
if (!_sync.InRollback()) {
_poll.Pump(0);
PollUdpProtocolEvents();
if (!_synchronizing) {
_sync.CheckSimulation(timeout);
// notify all of our endpoints of their local frame number for their
// next connection quality report
int current_frame = _sync.GetFrameCount();
for (int i = 0; i < _num_players; i++) {
_endpoints[i].SetLocalFrameNumber(current_frame);
}
int total_min_confirmed;
if (_num_players <= 2) {
total_min_confirmed = Poll2Players(current_frame);
} else {
total_min_confirmed = PollNPlayers(current_frame);
}
Log("last confirmed frame in p2p backend is %d.", total_min_confirmed);
if (total_min_confirmed >= 0) {
ASSERT(total_min_confirmed != INT_MAX);
if (_num_spectators > 0) {
while (_next_spectator_frame <= total_min_confirmed) {
Log("pushing frame %d to spectators.", _next_spectator_frame);
GameInput input;
input.frame = _next_spectator_frame;
input.size = _input_size * _num_players;
_sync.GetConfirmedInputs(input.bits, _input_size * _num_players, _next_spectator_frame);
for (int i = 0; i < _num_spectators; i++) {
_spectators[i].SendInput(input);
}
_next_spectator_frame++;
}
}
Log("setting confirmed frame in sync to %d.", total_min_confirmed);
_sync.SetLastConfirmedFrame(total_min_confirmed);
}
// send timesync notifications if now is the proper time
if (current_frame > _next_recommended_sleep) {
int interval = 0;
for (int i = 0; i < _num_players; i++) {
interval = MAX(interval, _endpoints[i].RecommendFrameDelay());
}
if (interval > 0) {
GGPOEvent info;
info.code = GGPO_EVENTCODE_TIMESYNC;
info.u.timesync.frames_ahead = interval;
_callbacks.on_event(&info);
_next_recommended_sleep = current_frame + RECOMMENDATION_INTERVAL;
}
}
// XXX: this is obviously a farce...
if (timeout)
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
return GGPO_OK;
}
int Peer2PeerBackend::Poll2Players(int current_frame)
{
int i;
// discard confirmed frames as appropriate
int total_min_confirmed = MAX_INT;
for (i = 0; i < _num_players; i++) {
bool queue_connected = true;
if (_endpoints[i].IsRunning()) {
int ignore;
queue_connected = _endpoints[i].GetPeerConnectStatus(i, &ignore);
}
if (!_local_connect_status[i].disconnected) {
total_min_confirmed = MIN(_local_connect_status[i].last_frame, total_min_confirmed);
}
Log(" local endp: connected = %d, last_received = %d, total_min_confirmed = %d.", !_local_connect_status[i].disconnected, _local_connect_status[i].last_frame, total_min_confirmed);
if (!queue_connected && !_local_connect_status[i].disconnected) {
Log("disconnecting i %d by remote request.", i);
DisconnectPlayerQueue(i, total_min_confirmed);
}
Log(" total_min_confirmed = %d.", total_min_confirmed);
}
return total_min_confirmed;
}
int Peer2PeerBackend::PollNPlayers(int current_frame)
{
int i, queue, last_received;
// discard confirmed frames as appropriate
int total_min_confirmed = MAX_INT;
for (queue = 0; queue < _num_players; queue++) {
bool queue_connected = true;
int queue_min_confirmed = MAX_INT;
Log("considering queue %d.", queue);
for (i = 0; i < _num_players; i++) {
// we're going to do a lot of logic here in consideration of endpoint i.
// keep accumulating the minimum confirmed point for all n*n packets and
// throw away the rest.
if (_endpoints[i].IsRunning()) {
bool connected = _endpoints[i].GetPeerConnectStatus(queue, &last_received);
queue_connected = queue_connected && connected;
queue_min_confirmed = MIN(last_received, queue_min_confirmed);
Log(" endpoint %d: connected = %d, last_received = %d, queue_min_confirmed = %d.", i, connected, last_received, queue_min_confirmed);
} else {
Log(" endpoint %d: ignoring... not running.", i);
}
}
// merge in our local status only if we're still connected!
if (!_local_connect_status[queue].disconnected) {
queue_min_confirmed = MIN(_local_connect_status[queue].last_frame, queue_min_confirmed);
}
Log(" local endp: connected = %d, last_received = %d, queue_min_confirmed = %d.", !_local_connect_status[queue].disconnected, _local_connect_status[queue].last_frame, queue_min_confirmed);
if (queue_connected) {
total_min_confirmed = MIN(queue_min_confirmed, total_min_confirmed);
} else {
// check to see if this disconnect notification is further back than we've been before. If
// so, we need to re-adjust. This can happen when we detect our own disconnect at frame n
// and later receive a disconnect notification for frame n-1.
if (!_local_connect_status[queue].disconnected || _local_connect_status[queue].last_frame > queue_min_confirmed) {
Log("disconnecting queue %d by remote request.", queue);
DisconnectPlayerQueue(queue, queue_min_confirmed);
}
}
Log(" total_min_confirmed = %d.", total_min_confirmed);
}
return total_min_confirmed;
}
GGPOErrorCode
Peer2PeerBackend::AddPlayer(GGPOPlayer *player,
GGPOPlayerHandle *handle)
{
if (player->type == GGPO_PLAYERTYPE_SPECTATOR) {
return AddSpectator(player->u.remote.ip_address, player->u.remote.port);
}
int queue = player->player_num - 1;
if (player->player_num < 1 || player->player_num > _num_players) {
return GGPO_ERRORCODE_PLAYER_OUT_OF_RANGE;
}
*handle = QueueToPlayerHandle(queue);
if (player->type == GGPO_PLAYERTYPE_REMOTE) {
AddRemotePlayer(player->u.remote.ip_address, player->u.remote.port, queue);
}
return GGPO_OK;
}
GGPOErrorCode
Peer2PeerBackend::AddLocalInput(GGPOPlayerHandle player,
void *values,
int size)
{
int queue;
GameInput input;
GGPOErrorCode result;
if (_sync.InRollback()) {
return GGPO_ERRORCODE_IN_ROLLBACK;
}
if (_synchronizing) {
return GGPO_ERRORCODE_NOT_SYNCHRONIZED;
}
result = PlayerHandleToQueue(player, &queue);
if (!GGPO_SUCCEEDED(result)) {
return result;
}
input.init(-1, (char *)values, size);
// Feed the input for the current frame into the synchronzation layer.
if (!_sync.AddLocalInput(queue, input)) {
return GGPO_ERRORCODE_PREDICTION_THRESHOLD;
}
if (input.frame != GameInput::NullFrame) { // xxx: <- comment why this is the case
// Update the local connect status state to indicate that we've got a
// confirmed local frame for this player. this must come first so it
// gets incorporated into the next packet we send.
Log("setting local connect status for local queue %d to %d", queue, input.frame);
_local_connect_status[queue].last_frame = input.frame;
// Send the input to all the remote players.
for (int i = 0; i < _num_players; i++) {
if (_endpoints[i].IsInitialized()) {
_endpoints[i].SendInput(input);
}
}
}
return GGPO_OK;
}
GGPOErrorCode
Peer2PeerBackend::SyncInput(void *values,
int size,
int *disconnect_flags)
{
int flags;
// Wait until we've started to return inputs.
if (_synchronizing) {
return GGPO_ERRORCODE_NOT_SYNCHRONIZED;
}
flags = _sync.SynchronizeInputs(values, size);
if (disconnect_flags) {
*disconnect_flags = flags;
}
return GGPO_OK;
}
GGPOErrorCode
Peer2PeerBackend::IncrementFrame(void)
{
Log("End of frame (%d)...", _sync.GetFrameCount());
_sync.IncrementFrame();
DoPoll(0);
PollSyncEvents();
return GGPO_OK;
}
void
Peer2PeerBackend::PollSyncEvents(void)
{
Sync::Event e;
while (_sync.GetEvent(e)) {
OnSyncEvent(e);
}
return;
}
void
Peer2PeerBackend::PollUdpProtocolEvents(void)
{
UdpProtocol::Event evt;
for (int i = 0; i < _num_players; i++) {
while (_endpoints[i].GetEvent(evt)) {
OnUdpProtocolPeerEvent(evt, i);
}
}
for (int i = 0; i < _num_spectators; i++) {
while (_spectators[i].GetEvent(evt)) {
OnUdpProtocolSpectatorEvent(evt, i);
}
}
}
void
Peer2PeerBackend::OnUdpProtocolPeerEvent(UdpProtocol::Event &evt, int queue)
{
OnUdpProtocolEvent(evt, QueueToPlayerHandle(queue));
switch (evt.type) {
case UdpProtocol::Event::Input:
if (!_local_connect_status[queue].disconnected) {
int current_remote_frame = _local_connect_status[queue].last_frame;
int new_remote_frame = evt.u.input.input.frame;
ASSERT(current_remote_frame == -1 || new_remote_frame == (current_remote_frame + 1));
_sync.AddRemoteInput(queue, evt.u.input.input);
// Notify the other endpoints which frame we received from a peer
Log("setting remote connect status for queue %d to %d", queue, evt.u.input.input.frame);
_local_connect_status[queue].last_frame = evt.u.input.input.frame;
}
break;
case UdpProtocol::Event::Disconnected:
DisconnectPlayer(QueueToPlayerHandle(queue));
break;
case UdpProtocol::Event::AppData:
if (evt.u.app_data.spectators)
for (int i = 0; i < _num_spectators; i++)
if (_spectators[i].IsInitialized())
_spectators[i].SendAppData(evt.u.app_data.data, evt.u.app_data.size, true);
Log("calling on_message callback with %d bytes", evt.u.app_data.size);
if (_callbacks.on_message != nullptr)
_callbacks.on_message(evt.u.app_data.data, evt.u.app_data.size);
break;
default:
break;
}
}
void
Peer2PeerBackend::OnUdpProtocolSpectatorEvent(UdpProtocol::Event &evt, int queue)
{
GGPOPlayerHandle handle = QueueToSpectatorHandle(queue);
OnUdpProtocolEvent(evt, handle);
if (evt.type == UdpProtocol::Event::Disconnected)
{
_spectators[queue].Disconnect();
GGPOEvent info;
info.code = GGPO_EVENTCODE_DISCONNECTED_FROM_PEER;
info.u.disconnected.player = handle;
_callbacks.on_event(&info);
}
}
void
Peer2PeerBackend::OnUdpProtocolEvent(UdpProtocol::Event &evt, GGPOPlayerHandle handle)
{
GGPOEvent info;
switch (evt.type) {
case UdpProtocol::Event::Connected:
info.code = GGPO_EVENTCODE_CONNECTED_TO_PEER;
info.u.connected.player = handle;
_callbacks.on_event(&info);
break;
case UdpProtocol::Event::Synchronizing:
info.code = GGPO_EVENTCODE_SYNCHRONIZING_WITH_PEER;
info.u.synchronizing.player = handle;
info.u.synchronizing.count = evt.u.synchronizing.count;
info.u.synchronizing.total = evt.u.synchronizing.total;
_callbacks.on_event(&info);
break;
case UdpProtocol::Event::Synchronzied:
info.code = GGPO_EVENTCODE_SYNCHRONIZED_WITH_PEER;
info.u.synchronized.player = handle;
_callbacks.on_event(&info);
CheckInitialSync();
break;
case UdpProtocol::Event::NetworkInterrupted:
info.code = GGPO_EVENTCODE_CONNECTION_INTERRUPTED;
info.u.connection_interrupted.player = handle;
info.u.connection_interrupted.disconnect_timeout = evt.u.network_interrupted.disconnect_timeout;
_callbacks.on_event(&info);
break;
case UdpProtocol::Event::NetworkResumed:
info.code = GGPO_EVENTCODE_CONNECTION_RESUMED;
info.u.connection_resumed.player = handle;
_callbacks.on_event(&info);
break;
default:
break;
}
}
/*
* Called only as the result of a local decision to disconnect. The remote
* decisions to disconnect are a result of us parsing the peer_connect_settings
* blob in every endpoint periodically.
*/
GGPOErrorCode
Peer2PeerBackend::DisconnectPlayer(GGPOPlayerHandle player)
{
int queue;
GGPOErrorCode result;
result = PlayerHandleToQueue(player, &queue);
if (!GGPO_SUCCEEDED(result)) {
return result;
}
if (_local_connect_status[queue].disconnected) {
return GGPO_ERRORCODE_PLAYER_DISCONNECTED;
}
if (!_endpoints[queue].IsInitialized()) {
int current_frame = _sync.GetFrameCount();
// xxx: we should be tracking who the local player is, but for now assume
// that if the endpoint is not initalized, this must be the local player.
Log("Disconnecting local player %d at frame %d by user request.", queue, _local_connect_status[queue].last_frame);
for (int i = 0; i < _num_players; i++) {
if (_endpoints[i].IsInitialized()) {
DisconnectPlayerQueue(i, current_frame);
}
}
} else {
Log("Disconnecting queue %d at frame %d by user request.", queue, _local_connect_status[queue].last_frame);
DisconnectPlayerQueue(queue, _local_connect_status[queue].last_frame);
}
return GGPO_OK;
}
void
Peer2PeerBackend::DisconnectPlayerQueue(int queue, int syncto)
{
GGPOEvent info;
int framecount = _sync.GetFrameCount();
_endpoints[queue].Disconnect();
Log("Changing queue %d local connect status for last frame from %d to %d on disconnect request (current: %d).",
queue, _local_connect_status[queue].last_frame, syncto, framecount);
_local_connect_status[queue].disconnected = 1;
_local_connect_status[queue].last_frame = syncto;
if (syncto != GameInput::NullFrame && syncto < framecount) {
Log("adjusting simulation to account for the fact that %d disconnected @ %d.", queue, syncto);
_sync.AdjustSimulation(syncto);
Log("finished adjusting simulation.");
}
info.code = GGPO_EVENTCODE_DISCONNECTED_FROM_PEER;
info.u.disconnected.player = QueueToPlayerHandle(queue);
_callbacks.on_event(&info);
CheckInitialSync();
}
GGPOErrorCode
Peer2PeerBackend::GetNetworkStats(GGPONetworkStats *stats, GGPOPlayerHandle player)
{
int queue;
GGPOErrorCode result;
result = PlayerHandleToQueue(player, &queue);
if (!GGPO_SUCCEEDED(result)) {
return result;
}
memset(stats, 0, sizeof *stats);
_endpoints[queue].GetNetworkStats(stats);
stats->sync.predicted_frames = _sync.GetPredictedFrames();
return GGPO_OK;
}
GGPOErrorCode
Peer2PeerBackend::SetFrameDelay(GGPOPlayerHandle player, int delay)
{
int queue;
GGPOErrorCode result;
result = PlayerHandleToQueue(player, &queue);
if (!GGPO_SUCCEEDED(result)) {
return result;
}
_sync.SetFrameDelay(queue, delay);
return GGPO_OK;
}
GGPOErrorCode
Peer2PeerBackend::SetDisconnectTimeout(int timeout)
{
_disconnect_timeout = timeout;
for (int i = 0; i < _num_players; i++) {
if (_endpoints[i].IsInitialized()) {
_endpoints[i].SetDisconnectTimeout(_disconnect_timeout);
}
}
return GGPO_OK;
}
GGPOErrorCode
Peer2PeerBackend::SetDisconnectNotifyStart(int timeout)
{
_disconnect_notify_start = timeout;
for (int i = 0; i < _num_players; i++) {
if (_endpoints[i].IsInitialized()) {
_endpoints[i].SetDisconnectNotifyStart(_disconnect_notify_start);
}
}
return GGPO_OK;
}
GGPOErrorCode
Peer2PeerBackend::PlayerHandleToQueue(GGPOPlayerHandle player, int *queue)
{
int offset = ((int)player - 1);
if (offset < 0 || offset >= _num_players) {
return GGPO_ERRORCODE_INVALID_PLAYER_HANDLE;
}
*queue = offset;
return GGPO_OK;
}
void
Peer2PeerBackend::OnMsg(sockaddr_in &from, UdpMsg *msg, int len)
{
for (int i = 0; i < _num_players; i++) {
if (_endpoints[i].HandlesMsg(from, msg)) {
_endpoints[i].OnMsg(msg, len);
return;
}
}
for (int i = 0; i < _num_spectators; i++) {
if (_spectators[i].HandlesMsg(from, msg)) {
_spectators[i].OnMsg(msg, len);
return;
}
}
}
void
Peer2PeerBackend::CheckInitialSync()
{
int i;
if (_synchronizing) {
// Check to see if everyone is now synchronized. If so,
// go ahead and tell the client that we're ok to accept input.
for (i = 0; i < _num_players; i++) {
// xxx: IsInitialized() must go... we're actually using it as a proxy for "represents the local player"
if (_endpoints[i].IsInitialized() && !_endpoints[i].IsSynchronized() && !_local_connect_status[i].disconnected) {
return;
}
}
for (i = 0; i < _num_spectators; i++) {
if (_spectators[i].IsInitialized() && !_spectators[i].IsSynchronized()) {
return;
}
}
GGPOEvent info;
info.code = GGPO_EVENTCODE_RUNNING;
_callbacks.on_event(&info);
_synchronizing = false;
}
}
GGPOErrorCode Peer2PeerBackend::SendMessage(const void *msg, int len, bool spectators)
{
if (_synchronizing)
return GGPO_ERRORCODE_NOT_SYNCHRONIZED;
if (len > MAX_APPDATA_SIZE)
return GGPO_ERRORCODE_INVALID_REQUEST;
for (int i = 0; i < _num_players; i++)
if (_endpoints[i].IsInitialized())
_endpoints[i].SendAppData(msg, len, spectators);
if (spectators)
for (int i = 0; i < _num_spectators; i++)
if (_spectators[i].IsInitialized())
_spectators[i].SendAppData(msg, len, spectators);
return GGPO_ERRORCODE_SUCCESS;
}
+79
View File
@@ -0,0 +1,79 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _P2P_H
#define _P2P_H
#include "ggpo_types.h"
#include "ggpo_poll.h"
#include "sync.h"
#include "backend.h"
#include "timesync.h"
#include "network/udp_proto.h"
class Peer2PeerBackend : public IQuarkBackend, IPollSink, Udp::Callbacks {
public:
Peer2PeerBackend(GGPOSessionCallbacks *cb, const char *gamename, uint16 localport, int num_players, int input_size,
const void *verification, int verification_size);
virtual ~Peer2PeerBackend();
public:
GGPOErrorCode DoPoll(int timeout) override;
GGPOErrorCode AddPlayer(GGPOPlayer *player, GGPOPlayerHandle *handle) override;
GGPOErrorCode AddLocalInput(GGPOPlayerHandle player, void *values, int size) override;
GGPOErrorCode SyncInput(void *values, int size, int *disconnect_flags) override;
GGPOErrorCode IncrementFrame(void) override;
GGPOErrorCode DisconnectPlayer(GGPOPlayerHandle handle) override;
GGPOErrorCode GetNetworkStats(GGPONetworkStats *stats, GGPOPlayerHandle handle) override;
GGPOErrorCode SetFrameDelay(GGPOPlayerHandle player, int delay) override;
GGPOErrorCode SetDisconnectTimeout(int timeout) override;
GGPOErrorCode SetDisconnectNotifyStart(int timeout) override;
GGPOErrorCode SendMessage(const void *msg, int len, bool spectators) override;
public:
void OnMsg(sockaddr_in &from, UdpMsg *msg, int len) override;
protected:
GGPOErrorCode PlayerHandleToQueue(GGPOPlayerHandle player, int *queue);
GGPOPlayerHandle QueueToPlayerHandle(int queue) { return (GGPOPlayerHandle)(queue + 1); }
GGPOPlayerHandle QueueToSpectatorHandle(int queue) { return (GGPOPlayerHandle)(queue + 1000); } /* out of range of the player array, basically */
void DisconnectPlayerQueue(int queue, int syncto);
void PollSyncEvents(void);
void PollUdpProtocolEvents(void);
void CheckInitialSync(void);
int Poll2Players(int current_frame);
int PollNPlayers(int current_frame);
void AddRemotePlayer(char *remoteip, uint16 reportport, int queue);
GGPOErrorCode AddSpectator(char *remoteip, uint16 reportport);
virtual void OnSyncEvent(Sync::Event &e) { }
virtual void OnUdpProtocolEvent(UdpProtocol::Event &e, GGPOPlayerHandle handle);
virtual void OnUdpProtocolPeerEvent(UdpProtocol::Event &e, int queue);
virtual void OnUdpProtocolSpectatorEvent(UdpProtocol::Event &e, int queue);
protected:
GGPOSessionCallbacks _callbacks;
Poll _poll;
Sync _sync;
Udp _udp;
UdpProtocol *_endpoints;
UdpProtocol _spectators[GGPO_MAX_SPECTATORS];
int _num_spectators;
int _input_size;
bool _synchronizing;
int _num_players;
int _next_recommended_sleep;
int _next_spectator_frame;
int _disconnect_timeout;
int _disconnect_notify_start;
UdpMsg::connect_status _local_connect_status[UDP_MSG_MAX_PLAYERS];
};
#endif
@@ -0,0 +1,189 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "spectator.h"
SpectatorBackend::SpectatorBackend(GGPOSessionCallbacks *cb,
const char* gamename,
uint16 localport,
int num_players,
int input_size,
char *hostip,
u_short hostport,
const void *verification,
int verification_size) :
_input_size(input_size),
_num_players(num_players),
_next_input_to_send(0)
{
_callbacks = *cb;
_synchronizing = true;
for (size_t i = 0; i < ARRAY_SIZE(_inputs); i++) {
_inputs[i].frame = -1;
}
/*
* Initialize the UDP port
*/
_udp.Init(localport, &_poll, this);
/*
* Init the host endpoint
*/
_host.SetVerificationData(verification, verification_size);
_host.Init(&_udp, _poll, 0, hostip, hostport, NULL);
_host.Synchronize();
/*
* Preload the ROM
*/
_callbacks.begin_game(gamename);
}
SpectatorBackend::~SpectatorBackend()
{
}
GGPOErrorCode
SpectatorBackend::DoPoll(int timeout)
{
_poll.Pump(0);
PollUdpProtocolEvents();
return GGPO_OK;
}
GGPOErrorCode
SpectatorBackend::SyncInput(void *values,
int size,
int *disconnect_flags)
{
// Wait until we've started to return inputs.
if (_synchronizing) {
return GGPO_ERRORCODE_NOT_SYNCHRONIZED;
}
GameInput &input = _inputs[_next_input_to_send % SPECTATOR_FRAME_BUFFER_SIZE];
if (input.frame < _next_input_to_send) {
// Haven't received the input from the host yet. Wait
return GGPO_ERRORCODE_PREDICTION_THRESHOLD;
}
if (input.frame > _next_input_to_send) {
// The host is way way way far ahead of the spectator. How'd this
// happen? Anyway, the input we need is gone forever.
return GGPO_ERRORCODE_GENERAL_FAILURE;
}
ASSERT(size >= _input_size * _num_players);
memcpy(values, input.bits, _input_size * _num_players);
if (disconnect_flags) {
*disconnect_flags = 0; // xxx: should get them from the host!
}
_next_input_to_send++;
return GGPO_OK;
}
GGPOErrorCode
SpectatorBackend::IncrementFrame(void)
{
Log("End of frame (%d)...", _next_input_to_send - 1);
DoPoll(0);
PollUdpProtocolEvents();
return GGPO_OK;
}
void
SpectatorBackend::PollUdpProtocolEvents(void)
{
UdpProtocol::Event evt;
while (_host.GetEvent(evt)) {
OnUdpProtocolEvent(evt);
}
}
void
SpectatorBackend::OnUdpProtocolEvent(UdpProtocol::Event &evt)
{
GGPOEvent info;
switch (evt.type) {
case UdpProtocol::Event::Connected:
info.code = GGPO_EVENTCODE_CONNECTED_TO_PEER;
info.u.connected.player = 0;
_callbacks.on_event(&info);
break;
case UdpProtocol::Event::Synchronizing:
info.code = GGPO_EVENTCODE_SYNCHRONIZING_WITH_PEER;
info.u.synchronizing.player = 0;
info.u.synchronizing.count = evt.u.synchronizing.count;
info.u.synchronizing.total = evt.u.synchronizing.total;
_callbacks.on_event(&info);
break;
case UdpProtocol::Event::Synchronzied:
if (_synchronizing) {
info.code = GGPO_EVENTCODE_SYNCHRONIZED_WITH_PEER;
info.u.synchronized.player = 0;
_callbacks.on_event(&info);
info.code = GGPO_EVENTCODE_RUNNING;
_callbacks.on_event(&info);
_synchronizing = false;
}
break;
case UdpProtocol::Event::NetworkInterrupted:
info.code = GGPO_EVENTCODE_CONNECTION_INTERRUPTED;
info.u.connection_interrupted.player = 0;
info.u.connection_interrupted.disconnect_timeout = evt.u.network_interrupted.disconnect_timeout;
_callbacks.on_event(&info);
break;
case UdpProtocol::Event::NetworkResumed:
info.code = GGPO_EVENTCODE_CONNECTION_RESUMED;
info.u.connection_resumed.player = 0;
_callbacks.on_event(&info);
break;
case UdpProtocol::Event::Disconnected:
info.code = GGPO_EVENTCODE_DISCONNECTED_FROM_PEER;
info.u.disconnected.player = 0;
_callbacks.on_event(&info);
break;
case UdpProtocol::Event::Input:
{
GameInput& input = evt.u.input.input;
_host.SetLocalFrameNumber(input.frame);
_host.SendInputAck();
_inputs[input.frame % SPECTATOR_FRAME_BUFFER_SIZE] = input;
}
break;
case UdpProtocol::Event::AppData:
Log("calling on_message callback with %d bytes", evt.u.app_data.size);
if (_callbacks.on_message != nullptr)
_callbacks.on_message(evt.u.app_data.data, evt.u.app_data.size);
break;
default:
break;
}
}
void
SpectatorBackend::OnMsg(sockaddr_in &from, UdpMsg *msg, int len)
{
if (_host.HandlesMsg(from, msg)) {
_host.OnMsg(msg, len);
}
}
@@ -0,0 +1,60 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _SPECTATOR_H
#define _SPECTATOR_H
#include "../ggpo_poll.h"
#include "../ggpo_types.h"
#include "sync.h"
#include "backend.h"
#include "timesync.h"
#include "network/udp_proto.h"
#define SPECTATOR_FRAME_BUFFER_SIZE 64
class SpectatorBackend : public IQuarkBackend, IPollSink, Udp::Callbacks {
public:
SpectatorBackend(GGPOSessionCallbacks *cb, const char *gamename, uint16 localport, int num_players, int input_size, char *hostip, u_short hostport,
const void *verification, int verification_size);
virtual ~SpectatorBackend();
public:
GGPOErrorCode DoPoll(int timeout) override;
GGPOErrorCode AddPlayer(GGPOPlayer *player, GGPOPlayerHandle *handle) override { return GGPO_ERRORCODE_UNSUPPORTED; }
GGPOErrorCode AddLocalInput(GGPOPlayerHandle player, void *values, int size) override { return GGPO_OK; }
GGPOErrorCode SyncInput(void *values, int size, int *disconnect_flags) override;
GGPOErrorCode IncrementFrame(void) override;
GGPOErrorCode DisconnectPlayer(GGPOPlayerHandle handle) override { return GGPO_ERRORCODE_UNSUPPORTED; }
GGPOErrorCode GetNetworkStats(GGPONetworkStats *stats, GGPOPlayerHandle handle) override { return GGPO_ERRORCODE_UNSUPPORTED; }
GGPOErrorCode SetFrameDelay(GGPOPlayerHandle player, int delay) override { return GGPO_ERRORCODE_UNSUPPORTED; }
GGPOErrorCode SetDisconnectTimeout(int timeout) override { return GGPO_ERRORCODE_UNSUPPORTED; }
GGPOErrorCode SetDisconnectNotifyStart(int timeout) override { return GGPO_ERRORCODE_UNSUPPORTED; }
public:
void OnMsg(sockaddr_in &from, UdpMsg *msg, int len) override;
protected:
void PollUdpProtocolEvents(void);
void CheckInitialSync(void);
void OnUdpProtocolEvent(UdpProtocol::Event &e);
protected:
GGPOSessionCallbacks _callbacks;
Poll _poll;
Udp _udp;
UdpProtocol _host;
bool _synchronizing;
int _input_size;
int _num_players;
int _next_input_to_send;
GameInput _inputs[SPECTATOR_FRAME_BUFFER_SIZE];
};
#endif
@@ -0,0 +1,184 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "synctest.h"
SyncTestBackend::SyncTestBackend(GGPOSessionCallbacks *cb,
const char *gamename,
int frames,
int num_players) :
_sync(NULL)
{
_callbacks = *cb;
_num_players = num_players;
_check_distance = frames;
_last_verified = 0;
_rollingback = false;
_running = false;
_logfp = NULL;
_current_input.erase();
strcpy(_game, gamename);
/*
* Initialize the synchronziation layer
*/
Sync::Config config = { 0 };
config.callbacks = _callbacks;
config.num_prediction_frames = MAX_PREDICTION_FRAMES;
_sync.Init(config);
/*
* Preload the ROM
*/
_callbacks.begin_game(gamename);
}
SyncTestBackend::~SyncTestBackend()
{
}
GGPOErrorCode
SyncTestBackend::DoPoll(int timeout)
{
if (!_running) {
GGPOEvent info;
info.code = GGPO_EVENTCODE_RUNNING;
_callbacks.on_event(&info);
_running = true;
}
return GGPO_OK;
}
GGPOErrorCode
SyncTestBackend::AddPlayer(GGPOPlayer *player, GGPOPlayerHandle *handle)
{
if (player->player_num < 1 || player->player_num > _num_players) {
return GGPO_ERRORCODE_PLAYER_OUT_OF_RANGE;
}
*handle = (GGPOPlayerHandle)(player->player_num - 1);
return GGPO_OK;
}
GGPOErrorCode
SyncTestBackend::AddLocalInput(GGPOPlayerHandle player, void *values, int size)
{
if (!_running) {
return GGPO_ERRORCODE_NOT_SYNCHRONIZED;
}
int index = (int)player;
for (int i = 0; i < size; i++) {
_current_input.bits[(index * size) + i] |= ((char *)values)[i];
}
return GGPO_OK;
}
GGPOErrorCode
SyncTestBackend::SyncInput(void *values,
int size,
int *disconnect_flags)
{
if (_rollingback) {
_last_input = _saved_frames.front().input;
} else {
if (_sync.GetFrameCount() == 0 && _sync.GetLastSavedFrame().buf == nullptr) {
_sync.SaveCurrentFrame();
}
_last_input = _current_input;
}
memcpy(values, _last_input.bits, size);
if (disconnect_flags) {
*disconnect_flags = 0;
}
return GGPO_OK;
}
GGPOErrorCode
SyncTestBackend::IncrementFrame(void)
{
_sync.IncrementFrame();
_current_input.erase();
DEBUG_LOG(NETWORK, "End of frame(%d)...", _sync.GetFrameCount());
if (_rollingback) {
return GGPO_OK;
}
int frame = _sync.GetFrameCount();
// Hold onto the current frame in our queue of saved states. We'll need
// the checksum later to verify that our replay of the same frame got the
// same results.
SavedInfo info;
info.frame = frame;
info.input = _last_input;
info.cbuf = _sync.GetLastSavedFrame().cbuf;
info.buf = (char *)malloc(info.cbuf);
memcpy(info.buf, _sync.GetLastSavedFrame().buf, info.cbuf);
info.checksum = _sync.GetLastSavedFrame().checksum;
_saved_frames.push(info);
if (frame - _last_verified == _check_distance) {
// We've gone far enough ahead and should now start replaying frames.
// Load the last verified frame and set the rollback flag to true.
_sync.LoadFrame(_last_verified);
_rollingback = true;
while(!_saved_frames.empty()) {
_callbacks.advance_frame(0);
// Verify that the checksumn of this frame is the same as the one in our
// list.
info = _saved_frames.front();
_saved_frames.pop();
if (info.frame != _sync.GetFrameCount()) {
RaiseSyncError("Frame number %d does not match saved frame number %d", info.frame, frame);
}
int checksum = _sync.GetLastSavedFrame().checksum;
if (info.checksum != checksum) {
LogSaveStates(info);
RaiseSyncError("Checksum for frame %d does not match saved (%d != %d)", frame, checksum, info.checksum);
}
else
printf("Checksum %08d for frame %d matches.\n", checksum, info.frame);
free(info.buf);
}
_last_verified = frame;
_rollingback = false;
}
return GGPO_OK;
}
void
SyncTestBackend::RaiseSyncError(const char *fmt, ...)
{
char buf[1024];
va_list args;
va_start(args, fmt);
vsnprintf(buf, ARRAY_SIZE(buf), fmt, args);
va_end(args);
puts(buf);
#ifdef _WIN32
OutputDebugStringA(buf);
#endif
// DebugBreak();
}
void
SyncTestBackend::LogSaveStates(SavedInfo &info)
{
char filename[MAX_PATH];
snprintf(filename, ARRAY_SIZE(filename), "synclogs/state-%04d-original.log", _sync.GetFrameCount());
_callbacks.log_game_state(filename, (unsigned char *)info.buf, info.cbuf);
snprintf(filename, ARRAY_SIZE(filename), "synclogs/state-%04d-replay.log", _sync.GetFrameCount());
_callbacks.log_game_state(filename, _sync.GetLastSavedFrame().buf, _sync.GetLastSavedFrame().cbuf);
}
@@ -0,0 +1,57 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _SYNCTEST_H
#define _SYNCTEST_H
#include "ggpo_types.h"
#include "backend.h"
#include "sync.h"
#include "ring_buffer.h"
class SyncTestBackend : public IQuarkBackend {
public:
SyncTestBackend(GGPOSessionCallbacks *cb, const char *gamename, int frames, int num_players);
virtual ~SyncTestBackend();
virtual GGPOErrorCode DoPoll(int timeout);
virtual GGPOErrorCode AddPlayer(GGPOPlayer *player, GGPOPlayerHandle *handle);
virtual GGPOErrorCode AddLocalInput(GGPOPlayerHandle player, void *values, int size);
virtual GGPOErrorCode SyncInput(void *values, int size, int *disconnect_flags);
virtual GGPOErrorCode IncrementFrame(void);
protected:
struct SavedInfo {
int frame;
int checksum;
char *buf;
int cbuf;
GameInput input;
};
void RaiseSyncError(const char *fmt, ...);
void LogSaveStates(SavedInfo &info);
protected:
GGPOSessionCallbacks _callbacks;
Sync _sync;
int _num_players;
int _check_distance;
int _last_verified;
bool _rollingback;
bool _running;
FILE *_logfp;
char _game[128];
GameInput _current_input;
GameInput _last_input;
RingBuffer<SavedInfo, 32> _saved_frames;
};
#endif
+55
View File
@@ -0,0 +1,55 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "ggpo_types.h"
#include "bitvector.h"
void
BitVector_SetBit(uint8 *vector, int *offset)
{
vector[(*offset) / 8] |= (1 << ((*offset) % 8));
*offset += 1;
}
void
BitVector_ClearBit(uint8 *vector, int *offset)
{
vector[(*offset) / 8] &= ~(1 << ((*offset) % 8));
*offset += 1;
}
void
BitVector_WriteNibblet(uint8 *vector, int nibble, int *offset)
{
ASSERT(nibble < (1 << BITVECTOR_NIBBLE_SIZE));
for (int i = 0; i < BITVECTOR_NIBBLE_SIZE; i++) {
if (nibble & (1 << i)) {
BitVector_SetBit(vector, offset);
} else {
BitVector_ClearBit(vector, offset);
}
}
}
int
BitVector_ReadBit(uint8 *vector, int *offset)
{
int retval = !!(vector[(*offset) / 8] & (1 << ((*offset) % 8)));
*offset += 1;
return retval;
}
int
BitVector_ReadNibblet(uint8 *vector, int *offset)
{
int nibblet = 0;
for (int i = 0; i < BITVECTOR_NIBBLE_SIZE; i++) {
nibblet |= (BitVector_ReadBit(vector, offset) << i);
}
return nibblet;
}
+19
View File
@@ -0,0 +1,19 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _BITVECTOR_H
#define _BITVECTOR_H
#define BITVECTOR_NIBBLE_SIZE 8
void BitVector_SetBit(uint8 *vector, int *offset);
void BitVector_ClearBit(uint8 *vector, int *offset);
void BitVector_WriteNibblet(uint8 *vector, int nibble, int *offset);
int BitVector_ReadBit(uint8 *vector, int *offset);
int BitVector_ReadNibblet(uint8 *vector, int *offset);
#endif // _BITVECTOR_H
+86
View File
@@ -0,0 +1,86 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "game_input.h"
#include "ggpo_types.h"
void
GameInput::init(int iframe, char *ibits, int isize, int offset)
{
ASSERT(isize);
ASSERT(isize <= GAMEINPUT_MAX_BYTES);
frame = iframe;
size = isize;
memset(bits, 0, sizeof(bits));
if (ibits) {
memcpy(bits + (offset * isize), ibits, isize);
}
}
void
GameInput::init(int iframe, char *ibits, int isize)
{
ASSERT(isize);
ASSERT(isize <= GAMEINPUT_MAX_BYTES * GAMEINPUT_MAX_PLAYERS);
frame = iframe;
size = isize;
memset(bits, 0, sizeof(bits));
if (ibits) {
memcpy(bits, ibits, isize);
}
}
void
GameInput::desc(char *buf, size_t buf_size, bool show_frame) const
{
ASSERT(size);
size_t remaining = buf_size;
if (show_frame) {
remaining -= snprintf(buf, buf_size, "(frame:%d size:%d ", frame, size);
} else {
remaining -= snprintf(buf, buf_size, "(size:%d ", size);
}
for (int i = 0; i < size * 8; i++) {
char buf2[16];
if (value(i)) {
int c = snprintf(buf2, ARRAY_SIZE(buf2), "%2d ", i);
strncat(buf, buf2, ARRAY_SIZE(buf2));
remaining -= c;
}
}
strcat(buf, ")");
}
void
GameInput::log(char *prefix, bool show_frame) const
{
char buf[1024];
size_t c = strlen(prefix);
strcpy(buf, prefix);
desc(buf + c, ARRAY_SIZE(buf) - c, show_frame);
Log("%s", buf);
}
bool
GameInput::equal(GameInput &other, bool bitsonly)
{
if (!bitsonly && frame != other.frame) {
Log("frames don't match: %d, %d", frame, other.frame);
}
if (size != other.size) {
Log("sizes don't match: %d, %d", size, other.size);
}
bool match = memcmp(bits, other.bits, size) == 0;
if (!match)
Log("bits don't match");
ASSERT(size && other.size);
return (bitsonly || frame == other.frame) &&
size == other.size && match;
}
+40
View File
@@ -0,0 +1,40 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _GAMEINPUT_H
#define _GAMEINPUT_H
#include <stdio.h>
#include <memory.h>
// GAMEINPUT_MAX_BYTES * GAMEINPUT_MAX_PLAYERS * 8 must be less than
// 2^BITVECTOR_NIBBLE_SIZE (see bitvector.h)
#define GAMEINPUT_MAX_BYTES 9
#define GAMEINPUT_MAX_PLAYERS 2
struct GameInput {
enum Constants {
NullFrame = -1
};
int frame;
int size; /* size in bytes of the entire input for all players */
char bits[GAMEINPUT_MAX_BYTES * GAMEINPUT_MAX_PLAYERS];
bool is_null() { return frame == NullFrame; }
void init(int frame, char *bits, int size, int offset);
void init(int frame, char *bits, int size);
bool value(int i) const { return (bits[i/8] & (1 << (i%8))) != 0; }
void set(int i) { bits[i/8] |= (1 << (i%8)); }
void clear(int i) { bits[i/8] &= ~(1 << (i%8)); }
void erase() { memset(bits, 0, sizeof(bits)); }
void desc(char *buf, size_t buf_size, bool show_frame = true) const;
void log(char *prefix, bool show_frame = true) const;
bool equal(GameInput &input, bool bitsonly = false);
};
#endif
+66
View File
@@ -0,0 +1,66 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _POLL_H
#define _POLL_H
#include "static_buffer.h"
#define MAX_POLLABLE_HANDLES 64
class IPollSink {
public:
virtual ~IPollSink() { }
virtual bool OnHandlePoll(void *) { return true; }
virtual bool OnMsgPoll(void *) { return true; }
virtual bool OnPeriodicPoll(void *, int ) { return true; }
virtual bool OnLoopPoll(void *) { return true; }
};
class Poll {
public:
Poll(void);
// void RegisterHandle(IPollSink *sink, HANDLE h, void *cookie = NULL);
void RegisterMsgLoop(IPollSink *sink, void *cookie = NULL);
void RegisterPeriodic(IPollSink *sink, int interval, void *cookie = NULL);
void RegisterLoop(IPollSink *sink, void *cookie = NULL);
void Run();
bool Pump(int timeout);
protected:
int ComputeWaitTime(int elapsed);
struct PollSinkCb {
IPollSink *sink;
void *cookie;
PollSinkCb() : sink(NULL), cookie(NULL) { }
PollSinkCb(IPollSink *s, void *c) : sink(s), cookie(c) { }
};
struct PollPeriodicSinkCb : public PollSinkCb {
int interval;
int last_fired;
PollPeriodicSinkCb() : PollSinkCb(NULL, NULL), interval(0), last_fired(0) { }
PollPeriodicSinkCb(IPollSink *s, void *c, int i) :
PollSinkCb(s, c), interval(i), last_fired(0) { }
};
int _start_time;
int _handle_count;
#ifdef _WIN32
HANDLE _handles[MAX_POLLABLE_HANDLES];
#endif
PollSinkCb _handle_sinks[MAX_POLLABLE_HANDLES];
StaticBuffer<PollSinkCb, 16> _msg_sinks;
StaticBuffer<PollSinkCb, 16> _loop_sinks;
StaticBuffer<PollPeriodicSinkCb, 16> _periodic_sinks;
};
#endif
+96
View File
@@ -0,0 +1,96 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _TYPES_H
#define _TYPES_H
/*
* Keep the compiler happy
*/
#ifdef _MSC_VER
/*
* Disable specific compiler warnings
* 4018 - '<' : signed/unsigned mismatch
* 4100 - 'xxx' : unreferenced formal parameter
* 4127 - conditional expression is constant
* 4201 - nonstandard extension used : nameless struct/union
* 4389 - '!=' : signed/unsigned mismatch
* 4800 - 'int' : forcing value to bool 'true' or 'false' (performance warning)
*/
#pragma warning(disable: 4018 4100 4127 4201 4389 4800)
#endif
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#define TARGET_UWP
#endif
/*
* Simple types
*/
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned char byte;
typedef char int8;
typedef short int16;
typedef int int32;
#include "ggponet.h"
#include "log/Log.h"
#include <stdexcept>
class GGPOException : public std::runtime_error {
public:
GGPOException(const char *what, GGPOErrorCode ggpoError)
: std::runtime_error(what), ggpoError(ggpoError) {}
GGPOErrorCode ggpoError;
};
/*
* Additional headers
*/
#if defined(_WIN32)
# include "platform_windows.h"
#elif defined(__unix__) || defined(__APPLE__) || defined(__SWITCH__)
# include "platform_linux.h"
#else
# error Unsupported platform
#endif
/*
* Macros
*/
#define ASSERT(x) \
do { \
if (!(x)) { \
char assert_buf[1024]; \
snprintf(assert_buf, sizeof(assert_buf) - 1, "Assertion: %s @ %s:%d", #x, __FILE__, __LINE__); \
GGPOPlatform::AssertFailed(assert_buf); \
throw GGPOException(assert_buf, GGPO_ERRORCODE_GENERAL_FAILURE); \
} \
} while (false)
#define Log(...) DEBUG_LOG(NETWORK, __VA_ARGS__)
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
#ifndef MAX_INT
# define MAX_INT 0xEFFFFFF
#endif
#ifndef MAX
# define MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
#ifndef MIN
# define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
#endif // _TYPES_H
+305
View File
@@ -0,0 +1,305 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "input_queue.h"
#include "ggpo_types.h"
#define PREVIOUS_FRAME(offset) (((offset) == 0) ? (INPUT_QUEUE_LENGTH - 1) : ((offset) - 1))
InputQueue::InputQueue(int input_size)
{
Init(-1, input_size);
}
InputQueue::~InputQueue()
{
}
void
InputQueue::Init(int id, int input_size)
{
_id = id;
_head = 0;
_tail = 0;
_length = 0;
_frame_delay = 0;
_first_frame = true;
_last_user_added_frame = GameInput::NullFrame;
_first_incorrect_frame = GameInput::NullFrame;
_last_frame_requested = GameInput::NullFrame;
_last_added_frame = GameInput::NullFrame;
_prediction.init(GameInput::NullFrame, NULL, input_size);
/*
* This is safe because we know the GameInput is a proper structure (as in,
* no virtual methods, no contained classes, etc.).
*/
memset(_inputs, 0, sizeof _inputs);
for (size_t i = 0; i < ARRAY_SIZE(_inputs); i++) {
_inputs[i].size = input_size;
}
}
int
InputQueue::GetLastConfirmedFrame()
{
Log("input q%d | returning last confirmed frame %d.", _id, _last_added_frame);
return _last_added_frame;
}
int
InputQueue::GetFirstIncorrectFrame()
{
return _first_incorrect_frame;
}
void
InputQueue::DiscardConfirmedFrames(int frame)
{
ASSERT(frame >= 0);
if (_last_frame_requested != GameInput::NullFrame) {
frame = MIN(frame, _last_frame_requested);
}
Log("input q%d | discarding confirmed frames up to %d (last_added:%d length:%d [head:%d tail:%d]).", _id,
frame, _last_added_frame, _length, _head, _tail);
if (frame >= _last_added_frame) {
_tail = _head;
} else {
int offset = frame - _inputs[_tail].frame + 1;
Log("input q%d | difference of %d frames.", _id, offset);
ASSERT(offset >= 0);
_tail = (_tail + offset) % INPUT_QUEUE_LENGTH;
_length -= offset;
}
Log("input q%d | after discarding, new tail is %d (frame:%d).", _id, _tail, _inputs[_tail].frame);
ASSERT(_length >= 0);
}
void
InputQueue::ResetPrediction(int frame)
{
ASSERT(_first_incorrect_frame == GameInput::NullFrame || frame <= _first_incorrect_frame);
Log("input q%d | resetting all prediction errors back to frame %d.", _id, frame);
/*
* There's nothing really to do other than reset our prediction
* state and the incorrect frame counter...
*/
_prediction.frame = GameInput::NullFrame;
_first_incorrect_frame = GameInput::NullFrame;
_last_frame_requested = GameInput::NullFrame;
}
bool
InputQueue::GetConfirmedInput(int requested_frame, GameInput *input)
{
ASSERT(_first_incorrect_frame == GameInput::NullFrame || requested_frame < _first_incorrect_frame);
int offset = requested_frame % INPUT_QUEUE_LENGTH;
if (_inputs[offset].frame != requested_frame) {
return false;
}
*input = _inputs[offset];
return true;
}
bool
InputQueue::GetInput(int requested_frame, GameInput *input)
{
Log("input q%d | requesting input frame %d.", _id, requested_frame);
/*
* No one should ever try to grab any input when we have a prediction
* error. Doing so means that we're just going further down the wrong
* path. ASSERT this to verify that it's true.
*/
ASSERT(_first_incorrect_frame == GameInput::NullFrame);
/*
* Remember the last requested frame number for later. We'll need
* this in AddInput() to drop out of prediction mode.
*/
_last_frame_requested = requested_frame;
ASSERT(requested_frame >= _inputs[_tail].frame);
if (_prediction.frame == GameInput::NullFrame) {
/*
* If the frame requested is in our range, fetch it out of the queue and
* return it.
*/
int offset = requested_frame - _inputs[_tail].frame;
if (offset < _length) {
offset = (offset + _tail) % INPUT_QUEUE_LENGTH;
ASSERT(_inputs[offset].frame == requested_frame);
*input = _inputs[offset];
Log("input q%d | returning confirmed frame number %d.", _id, input->frame);
return true;
}
/*
* The requested frame isn't in the queue. Bummer. This means we need
* to return a prediction frame. Predict that the user will do the
* same thing they did last time.
*/
if (requested_frame == 0) {
Log("input q%d | basing new prediction frame from nothing, you're client wants frame 0.", _id);
_prediction.erase();
} else if (_last_added_frame == GameInput::NullFrame) {
Log("input q%d | basing new prediction frame from nothing, since we have no frames yet.", _id);
_prediction.erase();
} else {
Log("input q%d | basing new prediction frame from previously added frame (queue entry:%d, frame:%d).", _id,
PREVIOUS_FRAME(_head), _inputs[PREVIOUS_FRAME(_head)].frame);
_prediction = _inputs[PREVIOUS_FRAME(_head)];
}
_prediction.frame++;
}
ASSERT(_prediction.frame >= 0);
/*
* If we've made it this far, we must be predicting. Go ahead and
* forward the prediction frame contents. Be sure to return the
* frame number requested by the client, though.
*/
*input = _prediction;
input->frame = requested_frame;
Log("input q%d | returning prediction frame number %d (%d).", _id, input->frame, _prediction.frame);
return false;
}
void
InputQueue::AddInput(GameInput &input)
{
int new_frame;
Log("input q%d | adding input frame number %d to queue.", _id, input.frame);
/*
* These next two lines simply verify that inputs are passed in
* sequentially by the user, regardless of frame delay.
*/
ASSERT(_last_user_added_frame == GameInput::NullFrame ||
input.frame == _last_user_added_frame + 1);
_last_user_added_frame = input.frame;
/*
* Move the queue head to the correct point in preparation to
* input the frame into the queue.
*/
new_frame = AdvanceQueueHead(input.frame);
if (new_frame != GameInput::NullFrame) {
AddDelayedInputToQueue(input, new_frame);
}
/*
* Update the frame number for the input. This will also set the
* frame to GameInput::NullFrame for frames that get dropped (by
* design).
*/
input.frame = new_frame;
}
void
InputQueue::AddDelayedInputToQueue(GameInput &input, int frame_number)
{
Log("input q%d | adding delayed input frame number %d to queue.", _id, frame_number);
if (input.size != _prediction.size)
throw GGPOException("Input size differs from peer", GGPO_ERRORCODE_INPUT_SIZE_DIFF);
ASSERT(_last_added_frame == GameInput::NullFrame || frame_number == _last_added_frame + 1);
ASSERT(frame_number == 0 || _inputs[PREVIOUS_FRAME(_head)].frame == frame_number - 1);
/*
* Add the frame to the back of the queue
*/
_inputs[_head] = input;
_inputs[_head].frame = frame_number;
_head = (_head + 1) % INPUT_QUEUE_LENGTH;
_length++;
_first_frame = false;
_last_added_frame = frame_number;
if (_prediction.frame != GameInput::NullFrame) {
ASSERT(frame_number == _prediction.frame);
/*
* We've been predicting... See if the inputs we've gotten match
* what we've been predicting. If so, don't worry about it. If not,
* remember the first input which was incorrect so we can report it
* in GetFirstIncorrectFrame()
*/
if (_first_incorrect_frame == GameInput::NullFrame && !_prediction.equal(input, true)) {
Log("input q%d | frame %d does not match prediction. marking error.", _id, frame_number);
_first_incorrect_frame = frame_number;
}
/*
* If this input is the same frame as the last one requested and we
* still haven't found any mis-predicted inputs, we can dump out
* of predition mode entirely! Otherwise, advance the prediction frame
* count up.
*/
if (_prediction.frame == _last_frame_requested && _first_incorrect_frame == GameInput::NullFrame) {
Log("input q%d | prediction is correct! dumping out of prediction mode.", _id);
_prediction.frame = GameInput::NullFrame;
} else {
_prediction.frame++;
}
}
ASSERT(_length <= INPUT_QUEUE_LENGTH);
}
int
InputQueue::AdvanceQueueHead(int frame)
{
Log("input q%d | advancing queue head to frame %d.", _id, frame);
int expected_frame = _first_frame ? 0 : _inputs[PREVIOUS_FRAME(_head)].frame + 1;
frame += _frame_delay;
if (expected_frame > frame) {
/*
* This can occur when the frame delay has dropped since the last
* time we shoved a frame into the system. In this case, there's
* no room on the queue. Toss it.
*/
Log("input q%d | Dropping input frame %d (expected next frame to be %d).", _id,
frame, expected_frame);
return GameInput::NullFrame;
}
while (expected_frame < frame) {
/*
* This can occur when the frame delay has been increased since the last
* time we shoved a frame into the system. We need to replicate the
* last frame in the queue several times in order to fill the space
* left.
*/
Log("input q%d | Adding padding frame %d to account for change in frame delay.", _id,
expected_frame);
GameInput &last_frame = _inputs[PREVIOUS_FRAME(_head)];
AddDelayedInputToQueue(last_frame, expected_frame);
expected_frame++;
}
ASSERT(frame == 0 || frame == _inputs[PREVIOUS_FRAME(_head)].frame + 1);
return frame;
}
+59
View File
@@ -0,0 +1,59 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _INPUT_QUEUE_H
#define _INPUT_QUEUE_H
#include "game_input.h"
#define INPUT_QUEUE_LENGTH 128
#define DEFAULT_INPUT_SIZE 4
class InputQueue {
public:
InputQueue(int input_size = DEFAULT_INPUT_SIZE);
~InputQueue();
public:
void Init(int id, int input_size);
int GetLastConfirmedFrame();
int GetFirstIncorrectFrame();
int GetLength() { return _length; }
void SetFrameDelay(int delay) { _frame_delay = delay; }
void ResetPrediction(int frame);
void DiscardConfirmedFrames(int frame);
bool GetConfirmedInput(int frame, GameInput *input);
bool GetInput(int frame, GameInput *input);
void AddInput(GameInput &input);
protected:
int AdvanceQueueHead(int frame);
void AddDelayedInputToQueue(GameInput &input, int i);
protected:
int _id;
int _head;
int _tail;
int _length;
bool _first_frame;
int _last_user_added_frame;
int _last_added_frame;
int _first_incorrect_frame;
int _last_frame_requested;
int _frame_delay;
GameInput _inputs[INPUT_QUEUE_LENGTH];
GameInput _prediction;
};
#endif
+260
View File
@@ -0,0 +1,260 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "backends/p2p.h"
#include "backends/synctest.h"
#include "backends/spectator.h"
#include "ggpo_types.h"
#include "ggponet.h"
struct Init
{
Init() {
srand(GGPOPlatform::GetCurrentTimeMS() + GGPOPlatform::GetProcessID());
#ifdef _WIN32
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 0), &wsaData);
#endif
}
};
static Init init;
GGPOErrorCode
ggpo_start_session(GGPOSession **session,
GGPOSessionCallbacks *cb,
const char *game,
int num_players,
int input_size,
unsigned short localport,
const void *verification,
int verification_size)
{
try {
*session= (GGPOSession *)new Peer2PeerBackend(cb,
game,
localport,
num_players,
input_size,
verification,
verification_size);
return GGPO_OK;
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_start_session: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_add_player(GGPOSession *ggpo,
GGPOPlayer *player,
GGPOPlayerHandle *handle)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->AddPlayer(player, handle);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_add_player: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_start_synctest(GGPOSession **ggpo,
GGPOSessionCallbacks *cb,
const char *game,
int num_players,
int input_size,
int frames)
{
try {
*ggpo = (GGPOSession *)new SyncTestBackend(cb, game, frames, num_players);
return GGPO_OK;
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_start_synctest: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_set_frame_delay(GGPOSession *ggpo,
GGPOPlayerHandle player,
int frame_delay)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->SetFrameDelay(player, frame_delay);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_set_frame_delay: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_idle(GGPOSession *ggpo, int timeout)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->DoPoll(timeout);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_idle: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_add_local_input(GGPOSession *ggpo,
GGPOPlayerHandle player,
void *values,
int size)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->AddLocalInput(player, values, size);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_add_local_input: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_synchronize_input(GGPOSession *ggpo,
void *values,
int size,
int *disconnect_flags)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->SyncInput(values, size, disconnect_flags);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_synchronize_input: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode ggpo_disconnect_player(GGPOSession *ggpo,
GGPOPlayerHandle player)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->DisconnectPlayer(player);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_disconnect_player: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_advance_frame(GGPOSession *ggpo)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->IncrementFrame();
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_advance_frame: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_get_network_stats(GGPOSession *ggpo,
GGPOPlayerHandle player,
GGPONetworkStats *stats)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->GetNetworkStats(stats, player);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_get_network_stats: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_close_session(GGPOSession *ggpo)
{
if (!ggpo) {
return GGPO_ERRORCODE_INVALID_SESSION;
}
delete ggpo;
return GGPO_OK;
}
GGPOErrorCode
ggpo_set_disconnect_timeout(GGPOSession *ggpo, int timeout)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->SetDisconnectTimeout(timeout);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_set_disconnect_timeout: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode
ggpo_set_disconnect_notify_start(GGPOSession *ggpo, int timeout)
{
if (!ggpo)
return GGPO_ERRORCODE_INVALID_SESSION;
try {
return ggpo->SetDisconnectNotifyStart(timeout);
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_set_disconnect_notify_start: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode ggpo_start_spectating(GGPOSession **session,
GGPOSessionCallbacks *cb,
const char *game,
int num_players,
int input_size,
unsigned short local_port,
char *host_ip,
unsigned short host_port,
const void *verification,
int verification_size)
{
try {
*session= (GGPOSession *)new SpectatorBackend(cb,
game,
local_port,
num_players,
input_size,
host_ip,
host_port,
verification,
verification_size);
return GGPO_OK;
} catch (const GGPOException& e) {
ERROR_LOG(NETWORK, "GGPOException in ggpo_start_spectating: %s", e.what());
return e.ggpoError;
}
}
GGPOErrorCode ggpo_send_message(GGPOSession *ggpo,
const void *msg,
int len,
bool spectators)
{
if (ggpo == nullptr)
return GGPO_ERRORCODE_INVALID_SESSION;
return ggpo->SendMessage(msg, len, spectators);
}
+113
View File
@@ -0,0 +1,113 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "ggpo_types.h"
#include "udp.h"
SOCKET
CreateSocket(uint16 bind_port, int retries)
{
SOCKET s;
sockaddr_in sin;
uint16 port;
int optval = 1;
s = socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof optval);
optval = 0;
setsockopt(s, SOL_SOCKET, SO_LINGER, (const char *)&optval, sizeof optval);
// non-blocking...
#ifndef _WIN32
fcntl(s, F_SETFL, O_NONBLOCK);
#else
u_long iMode = 1;
ioctlsocket(s, FIONBIO, &iMode);
#endif
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
for (port = bind_port; port <= bind_port + retries; port++) {
sin.sin_port = htons(port);
if (bind(s, (sockaddr *)&sin, sizeof sin) == 0) {
Log("Udp bound to port: %d.", port);
return s;
}
}
closesocket(s);
return INVALID_SOCKET;
}
Udp::Udp() :
_socket(INVALID_SOCKET),
_callbacks(NULL)
{
}
Udp::~Udp(void)
{
if (_socket != INVALID_SOCKET) {
closesocket(_socket);
_socket = INVALID_SOCKET;
}
}
void
Udp::Init(uint16 port, Poll *poll, Callbacks *callbacks)
{
_callbacks = callbacks;
poll->RegisterLoop(this);
Log("binding udp socket to port %d.", port);
_socket = CreateSocket(port, 0);
if (_socket == INVALID_SOCKET)
throw GGPOException("Socket creation or bind failed", GGPO_ERRORCODE_NETWORK_ERROR);
}
void
Udp::SendTo(char *buffer, int len, int flags, struct sockaddr *dst, int destlen)
{
struct sockaddr_in *to = (struct sockaddr_in *)dst;
int res = sendto(_socket, buffer, len, flags, dst, destlen);
if (res == SOCKET_ERROR) {
int err = WSAGetLastError();
Log("unknown error in sendto (erro: %d wsaerr: %d).", res, err);
ASSERT(false && "Unknown error in sendto");
}
char dst_ip[1024];
Log("sent packet length %d to %s:%d (ret:%d).", len, inet_ntop(AF_INET, (void *)&to->sin_addr, dst_ip, ARRAY_SIZE(dst_ip)), ntohs(to->sin_port), res);
}
bool
Udp::OnLoopPoll(void *cookie)
{
uint8 recv_buf[MAX_UDP_PACKET_SIZE];
sockaddr_in recv_addr;
socklen_t recv_addr_len;
for (;;) {
recv_addr_len = sizeof(recv_addr);
int len = recvfrom(_socket, (char *)recv_buf, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&recv_addr, &recv_addr_len);
// TODO: handle len == 0... indicates a disconnect.
if (len == -1) {
int error = WSAGetLastError();
if (error != WSAEWOULDBLOCK) {
Log("recvfrom WSAGetLastError returned %d (%x).", error, error);
}
break;
} else if (len > 0) {
char src_ip[1024];
Log("recvfrom returned (len:%d from:%s:%d).", len, inet_ntop(AF_INET, (void*)&recv_addr.sin_addr, src_ip, ARRAY_SIZE(src_ip)), ntohs(recv_addr.sin_port) );
UdpMsg *msg = (UdpMsg *)recv_buf;
_callbacks->OnMsg(recv_addr, msg, len);
}
}
return true;
}
+53
View File
@@ -0,0 +1,53 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _UDP_H
#define _UDP_H
#include "ggpo_poll.h"
#include "udp_msg.h"
#include "ggponet.h"
#include "ring_buffer.h"
#define MAX_UDP_ENDPOINTS 16
constexpr size_t MAX_UDP_PACKET_SIZE = sizeof(UdpMsg);
class Udp : public IPollSink
{
public:
struct Stats {
int bytes_sent;
int packets_sent;
float kbps_sent;
};
struct Callbacks {
virtual ~Callbacks() { }
virtual void OnMsg(sockaddr_in &from, UdpMsg *msg, int len) = 0;
};
Udp();
void Init(uint16 port, Poll *p, Callbacks *callbacks);
void SendTo(char *buffer, int len, int flags, struct sockaddr *dst, int destlen);
virtual bool OnLoopPoll(void *cookie);
public:
~Udp(void);
protected:
// Network transmission information
SOCKET _socket;
// state management
Callbacks *_callbacks;
};
#endif
+121
View File
@@ -0,0 +1,121 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _UDP_MSG_H
#define _UDP_MSG_H
#define MAX_COMPRESSED_BITS 4096
#define UDP_MSG_MAX_PLAYERS 4
#define MAX_VERIFICATION_SIZE 256
#define MAX_APPDATA_SIZE 512
#pragma pack(push, 1)
struct UdpMsg
{
enum MsgType {
Invalid = 0,
SyncRequest = 1,
SyncReply = 2,
Input = 3,
QualityReport = 4,
QualityReply = 5,
KeepAlive = 6,
InputAck = 7,
AppData = 8
};
struct connect_status {
unsigned int disconnected:1;
int last_frame:31;
};
struct {
uint16 magic;
uint16 sequence_number;
uint8 type; /* packet type */
} hdr;
union {
struct {
uint32 random_request; /* please reply back with this random data */
uint16 remote_magic;
uint8 remote_endpoint;
uint8 verification[MAX_VERIFICATION_SIZE];
} sync_request;
struct {
uint32 random_reply; /* OK, here's your random data back */
uint8 verification_failure; /* set to one by peer if verification failed */
} sync_reply;
struct {
int8 frame_advantage; /* what's the other guy's frame advantage? */
uint32 ping;
} quality_report;
struct {
uint32 pong;
} quality_reply;
struct {
connect_status peer_connect_status[UDP_MSG_MAX_PLAYERS];
uint32 start_frame;
int disconnect_requested:1;
int ack_frame:31;
uint16 num_bits;
uint8 input_size; // XXX: shouldn't be in every single packet!
uint8 bits[MAX_COMPRESSED_BITS / 8]; /* must be last */
} input;
struct {
int ack_frame:31;
} input_ack;
struct {
uint16 size;
uint8 spectators;
uint8 data[MAX_APPDATA_SIZE];
} app_data;
} u;
int verification_size = 0;
public:
int PacketSize() {
return sizeof(hdr) + PayloadSize();
}
int PayloadSize() {
switch (hdr.type) {
case SyncRequest: return (int)(&u.sync_request.verification[0] - (uint8 *)&u) + verification_size;
case SyncReply: return sizeof(u.sync_reply);
case QualityReport: return sizeof(u.quality_report);
case QualityReply: return sizeof(u.quality_reply);
case InputAck: return sizeof(u.input_ack);
case KeepAlive: return 0;
case Input:
{
int size = (int)((char *)&u.input.bits - (char *)&u.input);
size += (u.input.num_bits + 7) / 8;
return size;
}
case AppData: return sizeof(u.app_data) - sizeof(u.app_data.data) + u.app_data.size;
}
ASSERT(false);
return 0;
}
UdpMsg(MsgType t) { hdr.type = (uint8)t; }
};
#pragma pack(pop)
#endif
@@ -0,0 +1,815 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "udp_proto.h"
#include "../ggpo_types.h"
#include "bitvector.h"
static const int UDP_HEADER_SIZE = 28; /* Size of IP + UDP headers */
static const int NUM_SYNC_PACKETS = 5;
static const int SYNC_RETRY_INTERVAL = 2000;
static const int SYNC_FIRST_RETRY_INTERVAL = 500;
static const int RUNNING_RETRY_INTERVAL = 200;
static const int KEEP_ALIVE_INTERVAL = 200;
static const int QUALITY_REPORT_INTERVAL = 1000;
static const int NETWORK_STATS_INTERVAL = 1000;
static const int UDP_SHUTDOWN_TIMER = 5000;
static const int MAX_SEQ_DISTANCE = (1 << 15);
UdpProtocol::UdpProtocol() :
_udp(NULL),
_magic_number(0),
_queue(-1),
_remote_magic_number(0),
_connected(false),
_packets_sent(0),
_bytes_sent(0),
_stats_start_time(0),
_local_frame_advantage(0),
_remote_frame_advantage(0),
_last_send_time(0),
_shutdown_timeout(0),
_disconnect_event_sent(false),
_disconnect_timeout(0),
_disconnect_notify_start(0),
_disconnect_notify_sent(false),
_next_send_seq(0),
_next_recv_seq(0)
{
_last_sent_input.init(-1, NULL, 1);
_last_received_input.init(-1, NULL, 1);
_last_acked_input.init(-1, NULL, 1);
memset(&_state, 0, sizeof _state);
memset(_peer_connect_status, 0, sizeof(_peer_connect_status));
for (unsigned i = 0; i < ARRAY_SIZE(_peer_connect_status); i++) {
_peer_connect_status[i].last_frame = -1;
}
memset(&_peer_addr, 0, sizeof _peer_addr);
_oo_packet.msg = NULL;
_send_latency = GGPOPlatform::GetConfigInt("GGPO_NETWORK_DELAY");
_oop_percent = GGPOPlatform::GetConfigInt("GGPO_OOP_PERCENT");
}
UdpProtocol::~UdpProtocol()
{
ClearSendQueue();
}
void
UdpProtocol::Init(Udp *udp,
Poll &poll,
int queue,
char *ip,
u_short port,
UdpMsg::connect_status *status)
{
_udp = udp;
_queue = queue;
_local_connect_status = status;
_peer_addr.sin_family = AF_INET;
if (ip != nullptr && ip[0] != '\0')
{
_peer_addr.sin_port = htons(port);
inet_pton(AF_INET, ip, &_peer_addr.sin_addr.s_addr);
}
do {
_magic_number = (uint16)rand();
} while (_magic_number == 0);
poll.RegisterLoop(this);
}
void
UdpProtocol::SendInput(GameInput &input)
{
if (_udp) {
if (_current_state == Running) {
/*
* Check to see if this is a good time to adjust for the rift...
*/
_timesync.advance_frame(input, _local_frame_advantage, _remote_frame_advantage);
/*
* Save this input packet
*
* XXX: This queue may fill up for spectators who do not ack input packets in a timely
* manner. When this happens, we can either resize the queue (ug) or disconnect them
* (better, but still ug). For the meantime, make this queue really big to decrease
* the odds of this happening...
*/
_pending_output.push(input);
}
SendPendingOutput();
}
}
void
UdpProtocol::SendPendingOutput()
{
UdpMsg *msg = new UdpMsg(UdpMsg::Input);
int i, j, offset = 0;
uint8 *bits;
GameInput last;
if (_pending_output.size()) {
last = _last_acked_input;
bits = msg->u.input.bits;
msg->u.input.start_frame = _pending_output.front().frame;
msg->u.input.input_size = (uint8)_pending_output.front().size;
ASSERT(last.frame == -1 || last.frame + 1 == (int)msg->u.input.start_frame);
for (j = 0; j < _pending_output.size(); j++) {
GameInput &current = _pending_output.item(j);
if (memcmp(current.bits, last.bits, current.size) != 0) {
ASSERT((GAMEINPUT_MAX_BYTES * GAMEINPUT_MAX_PLAYERS * 8) < (1 << BITVECTOR_NIBBLE_SIZE));
for (i = 0; i < current.size * 8; i++) {
ASSERT(i < (1 << BITVECTOR_NIBBLE_SIZE));
if (current.value(i) != last.value(i)) {
BitVector_SetBit(msg->u.input.bits, &offset);
(current.value(i) ? BitVector_SetBit : BitVector_ClearBit)(bits, &offset);
BitVector_WriteNibblet(bits, i, &offset);
}
}
}
BitVector_ClearBit(msg->u.input.bits, &offset);
last = _last_sent_input = current;
}
} else {
msg->u.input.start_frame = 0;
msg->u.input.input_size = 0;
}
msg->u.input.ack_frame = _last_received_input.frame;
msg->u.input.num_bits = (uint16)offset;
msg->u.input.disconnect_requested = _current_state == Disconnected;
if (_local_connect_status) {
memcpy(msg->u.input.peer_connect_status, _local_connect_status, sizeof(UdpMsg::connect_status) * UDP_MSG_MAX_PLAYERS);
} else {
memset(msg->u.input.peer_connect_status, 0, sizeof(UdpMsg::connect_status) * UDP_MSG_MAX_PLAYERS);
}
ASSERT(offset < MAX_COMPRESSED_BITS);
SendMsg(msg);
}
void
UdpProtocol::SendInputAck()
{
UdpMsg *msg = new UdpMsg(UdpMsg::InputAck);
msg->u.input_ack.ack_frame = _last_received_input.frame;
SendMsg(msg);
}
bool
UdpProtocol::GetEvent(UdpProtocol::Event &e)
{
if (_event_queue.size() == 0) {
return false;
}
e = _event_queue.front();
_event_queue.pop();
return true;
}
bool
UdpProtocol::OnLoopPoll(void *cookie)
{
if (!_udp) {
return true;
}
unsigned int now = GGPOPlatform::GetCurrentTimeMS();
unsigned int next_interval;
PumpSendQueue();
switch (_current_state) {
case Syncing:
next_interval = (_state.sync.roundtrips_remaining == NUM_SYNC_PACKETS) ? SYNC_FIRST_RETRY_INTERVAL : SYNC_RETRY_INTERVAL;
if (_last_send_time && _last_send_time + next_interval < now && _peer_addr.sin_addr.s_addr != 0) {
Log("udpproto%d | No luck syncing after %d ms... Re-queueing sync packet.", _queue, next_interval);
SendSyncRequest();
}
break;
case Running:
// xxx: rig all this up with a timer wrapper
if (!_state.running.last_input_packet_recv_time || _state.running.last_input_packet_recv_time + RUNNING_RETRY_INTERVAL < now) {
Log("udpproto%d | Haven't exchanged packets in a while (last received:%d last sent:%d). Resending.", _queue, _last_received_input.frame, _last_sent_input.frame);
SendPendingOutput();
_state.running.last_input_packet_recv_time = now;
}
if (!_state.running.last_quality_report_time || _state.running.last_quality_report_time + QUALITY_REPORT_INTERVAL < now) {
UdpMsg *msg = new UdpMsg(UdpMsg::QualityReport);
msg->u.quality_report.ping = GGPOPlatform::GetCurrentTimeMS();
msg->u.quality_report.frame_advantage = (uint8)_local_frame_advantage;
SendMsg(msg);
_state.running.last_quality_report_time = now;
}
if (!_state.running.last_network_stats_interval || _state.running.last_network_stats_interval + NETWORK_STATS_INTERVAL < now) {
UpdateNetworkStats();
_state.running.last_network_stats_interval = now;
}
if (_last_send_time && _last_send_time + KEEP_ALIVE_INTERVAL < now) {
Log("udpproto%d | Sending keep alive packet", _queue);
SendMsg(new UdpMsg(UdpMsg::KeepAlive));
}
if (_disconnect_timeout && _disconnect_notify_start &&
!_disconnect_notify_sent && (_last_recv_time + _disconnect_notify_start < now)) {
Log("udpproto%d | Endpoint has stopped receiving packets for %d ms. Sending notification.", _queue, _disconnect_notify_start);
Event e(Event::NetworkInterrupted);
e.u.network_interrupted.disconnect_timeout = _disconnect_timeout - _disconnect_notify_start;
QueueEvent(e);
_disconnect_notify_sent = true;
}
if (_disconnect_timeout && (_last_recv_time + _disconnect_timeout < now)) {
if (!_disconnect_event_sent) {
Log("udpproto%d | Endpoint has stopped receiving packets for %d ms. Disconnecting.", _queue, _disconnect_timeout);
QueueEvent(Event(Event::Disconnected));
_disconnect_event_sent = true;
}
}
break;
case Disconnected:
if (_shutdown_timeout < now) {
Log("udpproto%d | Shutting down udp connection.", _queue);
_udp = NULL;
_shutdown_timeout = 0;
}
break;
default:
break;
}
return true;
}
void
UdpProtocol::Disconnect()
{
_current_state = Disconnected;
_shutdown_timeout = GGPOPlatform::GetCurrentTimeMS() + UDP_SHUTDOWN_TIMER;
}
void
UdpProtocol::SendSyncRequest()
{
_state.sync.random = rand() & 0xFFFF;
UdpMsg *msg = new UdpMsg(UdpMsg::SyncRequest);
msg->u.sync_request.random_request = _state.sync.random;
msg->verification_size = verification.size();
if (!verification.empty())
memcpy(&msg->u.sync_request.verification[0], &verification[0], verification.size());
SendMsg(msg);
}
void
UdpProtocol::SendMsg(UdpMsg *msg)
{
LogMsg("send", msg);
{
std::lock_guard<std::mutex> lock(_send_mutex);
_packets_sent++;
_last_send_time = GGPOPlatform::GetCurrentTimeMS();
_bytes_sent += msg->PacketSize();
msg->hdr.magic = _magic_number;
msg->hdr.sequence_number = _next_send_seq++;
_send_queue.push(QueueEntry(GGPOPlatform::GetCurrentTimeMS(), _peer_addr, msg));
}
PumpSendQueue();
}
bool
UdpProtocol::HandlesMsg(sockaddr_in &from,
UdpMsg *msg)
{
if (!_udp) {
return false;
}
if (_peer_addr.sin_addr.s_addr == 0)
{
_peer_addr.sin_addr.s_addr = from.sin_addr.s_addr;
_peer_addr.sin_port = from.sin_port;
return true;
}
return _peer_addr.sin_addr.s_addr == from.sin_addr.s_addr &&
_peer_addr.sin_port == from.sin_port;
}
void
UdpProtocol::OnMsg(UdpMsg *msg, int len)
{
bool handled = false;
typedef bool (UdpProtocol::*DispatchFn)(UdpMsg *msg, int len);
static const DispatchFn table[] = {
&UdpProtocol::OnInvalid, /* Invalid */
&UdpProtocol::OnSyncRequest, /* SyncRequest */
&UdpProtocol::OnSyncReply, /* SyncReply */
&UdpProtocol::OnInput, /* Input */
&UdpProtocol::OnQualityReport, /* QualityReport */
&UdpProtocol::OnQualityReply, /* QualityReply */
&UdpProtocol::OnKeepAlive, /* KeepAlive */
&UdpProtocol::OnInputAck, /* InputAck */
&UdpProtocol::OnAppData, /* AppData */
};
// filter out messages that don't match what we expect
uint16 seq = msg->hdr.sequence_number;
if (msg->hdr.type != UdpMsg::SyncRequest &&
msg->hdr.type != UdpMsg::SyncReply) {
if (msg->hdr.magic != _remote_magic_number) {
LogMsg("recv rejecting", msg);
return;
}
// filter out out-of-order packets
uint16 skipped = (uint16)((int)seq - (int)_next_recv_seq);
// Log("udpproto%d | checking sequence number -> next - seq : %d - %d = %d", _queue, seq, _next_recv_seq, skipped);
if (skipped > MAX_SEQ_DISTANCE) {
Log("udpproto%d | dropping out of order packet (seq: %d, last seq:%d)", _queue, seq, _next_recv_seq);
return;
}
}
_next_recv_seq = seq;
LogMsg("recv", msg);
if (msg->hdr.type >= ARRAY_SIZE(table)) {
OnInvalid(msg, len);
} else {
handled = (this->*(table[msg->hdr.type]))(msg, len);
}
if (handled) {
_last_recv_time = GGPOPlatform::GetCurrentTimeMS();
if (_disconnect_notify_sent && _current_state == Running) {
QueueEvent(Event(Event::NetworkResumed));
_disconnect_notify_sent = false;
}
}
}
void
UdpProtocol::UpdateNetworkStats(void)
{
int now = GGPOPlatform::GetCurrentTimeMS();
if (_stats_start_time == 0) {
_stats_start_time = now;
}
int total_bytes_sent = _bytes_sent + (UDP_HEADER_SIZE * _packets_sent);
float seconds = (float)((now - _stats_start_time) / 1000.0);
float Bps = total_bytes_sent / seconds;
float udp_overhead = (float)(100.0 * (UDP_HEADER_SIZE * _packets_sent) / _bytes_sent);
_kbps_sent = int(Bps / 1024);
Log("udpproto%d | Network Stats -- Bandwidth: %.2f KBps Packets Sent: %5d (%.2f pps) "
"KB Sent: %.2f UDP Overhead: %.2f %%.", _queue,
(float)_kbps_sent,
_packets_sent,
(float)_packets_sent * 1000 / (now - _stats_start_time),
total_bytes_sent / 1024.0,
udp_overhead);
}
void
UdpProtocol::QueueEvent(const UdpProtocol::Event &evt)
{
LogEvent("Queuing event", evt);
_event_queue.push(evt);
}
void
UdpProtocol::Synchronize()
{
if (_udp) {
_current_state = Syncing;
_state.sync.roundtrips_remaining = NUM_SYNC_PACKETS;
if (_peer_addr.sin_addr.s_addr != 0)
SendSyncRequest();
}
}
bool
UdpProtocol::GetPeerConnectStatus(int id, int *frame)
{
*frame = _peer_connect_status[id].last_frame;
return !_peer_connect_status[id].disconnected;
}
void
UdpProtocol::LogMsg(const char *prefix, UdpMsg *msg)
{
switch (msg->hdr.type) {
case UdpMsg::SyncRequest:
Log("udpproto%d | %s sync-request (%d).", _queue, prefix,
msg->u.sync_request.random_request);
break;
case UdpMsg::SyncReply:
Log("udpproto%d | %s sync-reply (%d).", _queue, prefix,
msg->u.sync_reply.random_reply);
break;
case UdpMsg::QualityReport:
Log("udpproto%d | %s quality report.", _queue, prefix);
break;
case UdpMsg::QualityReply:
Log("udpproto%d | %s quality reply.", _queue, prefix);
break;
case UdpMsg::KeepAlive:
Log("udpproto%d | %s keep alive.", _queue, prefix);
break;
case UdpMsg::Input:
Log("udpproto%d | %s game-compressed-input %d (+ %d bits).", _queue, prefix, msg->u.input.start_frame, msg->u.input.num_bits);
break;
case UdpMsg::InputAck:
Log("udpproto%d | %s input ack.", _queue, prefix);
break;
case UdpMsg::AppData:
Log("udpproto%d | %s app data (%d bytes).", _queue, prefix, msg->u.app_data.size);
break;
default:
ASSERT(false && "Unknown UdpMsg type.");
}
}
void
UdpProtocol::LogEvent(const char *prefix, const UdpProtocol::Event &evt)
{
if (evt.type == UdpProtocol::Event::Synchronzied)
Log("udpproto%d | %s (event: Synchronized).", _queue, prefix);
}
bool
UdpProtocol::OnInvalid(UdpMsg *msg, int len)
{
ASSERT(false && "Invalid msg in UdpProtocol");
return false;
}
bool
UdpProtocol::OnSyncRequest(UdpMsg *msg, int len)
{
if (_remote_magic_number != 0 && msg->hdr.magic != _remote_magic_number) {
Log("udpproto%d | Ignoring sync request from unknown endpoint (%d != %d).", _queue,
msg->hdr.magic, _remote_magic_number);
return false;
}
UdpMsg *reply = new UdpMsg(UdpMsg::SyncReply);
reply->u.sync_reply.random_reply = msg->u.sync_request.random_request;
// Calculate incoming verif data size
msg->verification_size = 0;
int msgVerifSize = len - msg->PacketSize();
if (msgVerifSize != (int)verification.size()
|| (msgVerifSize != 0 && memcmp(&msg->u.sync_request.verification[0], &verification[0], msgVerifSize)))
{
Log("udpproto%d | Verification mismatch: size received %d expected %d", _queue, msgVerifSize, (int)verification.size());
reply->u.sync_reply.verification_failure = 1;
SendMsg(reply);
throw GGPOException("Verification mismatch", GGPO_ERRORCODE_VERIFICATION_ERROR);
}
// FIXME
if (_state.sync.roundtrips_remaining == NUM_SYNC_PACKETS && msg->hdr.sequence_number == 0) {
Log("udpproto%d | Sync request 0 received... Re-queueing sync packet.", _queue);
SendSyncRequest();
}
reply->u.sync_reply.verification_failure = 0;
SendMsg(reply);
return true;
}
bool
UdpProtocol::OnSyncReply(UdpMsg *msg, int len)
{
if (_current_state != Syncing) {
Log("udpproto%d | Ignoring SyncReply while not synching.", _queue);
return msg->hdr.magic == _remote_magic_number;
}
if (msg->u.sync_reply.random_reply != _state.sync.random) {
Log("udpproto%d | sync reply %d != %d. Keep looking...", _queue,
msg->u.sync_reply.random_reply, _state.sync.random);
return false;
}
if (msg->u.sync_reply.verification_failure == 1)
throw GGPOException("Peer reported verification failure", GGPO_ERRORCODE_VERIFICATION_ERROR);
if (!_connected) {
QueueEvent(Event(Event::Connected));
_connected = true;
}
Log("udpproto%d | Checking sync state (%d round trips remaining).", _queue, _state.sync.roundtrips_remaining);
if (--_state.sync.roundtrips_remaining == 0) {
Log("udpproto%d | Synchronized!", _queue);
QueueEvent(UdpProtocol::Event(UdpProtocol::Event::Synchronzied));
_current_state = Running;
_last_received_input.frame = -1;
_remote_magic_number = msg->hdr.magic;
} else {
UdpProtocol::Event evt(UdpProtocol::Event::Synchronizing);
evt.u.synchronizing.total = NUM_SYNC_PACKETS;
evt.u.synchronizing.count = NUM_SYNC_PACKETS - _state.sync.roundtrips_remaining;
QueueEvent(evt);
SendSyncRequest();
}
return true;
}
bool
UdpProtocol::OnInput(UdpMsg *msg, int len)
{
/*
* If a disconnect is requested, go ahead and disconnect now.
*/
bool disconnect_requested = msg->u.input.disconnect_requested;
if (disconnect_requested) {
if (_current_state != Disconnected && !_disconnect_event_sent) {
Log("udpproto%d | Disconnecting endpoint on remote request.", _queue);
QueueEvent(Event(Event::Disconnected));
_disconnect_event_sent = true;
}
} else {
/*
* Update the peer connection status if this peer is still considered to be part
* of the network.
*/
UdpMsg::connect_status* remote_status = msg->u.input.peer_connect_status;
for (unsigned i = 0; i < ARRAY_SIZE(_peer_connect_status); i++) {
ASSERT(remote_status[i].last_frame >= _peer_connect_status[i].last_frame);
_peer_connect_status[i].disconnected = _peer_connect_status[i].disconnected || remote_status[i].disconnected;
_peer_connect_status[i].last_frame = MAX(_peer_connect_status[i].last_frame, remote_status[i].last_frame);
}
}
/*
* Decompress the input.
*/
int last_received_frame_number = _last_received_input.frame;
if (msg->u.input.num_bits) {
int offset = 0;
uint8 *bits = (uint8 *)msg->u.input.bits;
int numBits = msg->u.input.num_bits;
int currentFrame = msg->u.input.start_frame;
_last_received_input.size = msg->u.input.input_size;
if (_last_received_input.frame < 0) {
_last_received_input.frame = msg->u.input.start_frame - 1;
}
while (offset < numBits) {
/*
* Keep walking through the frames (parsing bits) until we reach
* the inputs for the frame right after the one we're on.
*/
ASSERT(currentFrame <= (_last_received_input.frame + 1));
bool useInputs = currentFrame == _last_received_input.frame + 1;
while (BitVector_ReadBit(bits, &offset)) {
int on = BitVector_ReadBit(bits, &offset);
int button = BitVector_ReadNibblet(bits, &offset);
if (useInputs) {
if (on) {
_last_received_input.set(button);
} else {
_last_received_input.clear(button);
}
}
}
ASSERT(offset <= numBits);
/*
* Now if we want to use these inputs, go ahead and send them to
* the emulator.
*/
if (useInputs) {
/*
* Move forward 1 frame in the stream.
*/
char desc[1024];
ASSERT(currentFrame == _last_received_input.frame + 1);
_last_received_input.frame = currentFrame;
/*
* Send the event to the emulator
*/
UdpProtocol::Event evt(UdpProtocol::Event::Input);
evt.u.input.input = _last_received_input;
if (LogTypes::LDEBUG <= MAX_LOGLEVEL)
_last_received_input.desc(desc, ARRAY_SIZE(desc));
_state.running.last_input_packet_recv_time = GGPOPlatform::GetCurrentTimeMS();
Log("udpproto%d | Sending frame %d to emu queue %d (%s).", _queue, _last_received_input.frame, _queue, desc);
QueueEvent(evt);
} else {
Log("udpproto%d | Skipping past frame:(%d) current is %d.", _queue, currentFrame, _last_received_input.frame);
}
/*
* Move forward 1 frame in the input stream.
*/
currentFrame++;
}
}
ASSERT(_last_received_input.frame >= last_received_frame_number);
/*
* Get rid of our buffered input
*/
while (_pending_output.size() && _pending_output.front().frame < msg->u.input.ack_frame) {
Log("udpproto%d | Throwing away pending output frame %d", _queue, _pending_output.front().frame);
_last_acked_input = _pending_output.front();
_pending_output.pop();
}
return true;
}
bool
UdpProtocol::OnInputAck(UdpMsg *msg, int len)
{
/*
* Get rid of our buffered input
*/
while (_pending_output.size() && _pending_output.front().frame < msg->u.input_ack.ack_frame) {
Log("udpproto%d | Throwing away pending output frame %d", _queue, _pending_output.front().frame);
_last_acked_input = _pending_output.front();
_pending_output.pop();
}
return true;
}
bool
UdpProtocol::OnQualityReport(UdpMsg *msg, int len)
{
// send a reply so the other side can compute the round trip transmit time.
UdpMsg *reply = new UdpMsg(UdpMsg::QualityReply);
reply->u.quality_reply.pong = msg->u.quality_report.ping;
SendMsg(reply);
_remote_frame_advantage = msg->u.quality_report.frame_advantage;
return true;
}
bool
UdpProtocol::OnQualityReply(UdpMsg *msg, int len)
{
_round_trip_time = GGPOPlatform::GetCurrentTimeMS() - msg->u.quality_reply.pong;
return true;
}
bool
UdpProtocol::OnKeepAlive(UdpMsg *msg, int len)
{
return true;
}
void
UdpProtocol::GetNetworkStats(struct GGPONetworkStats *s)
{
s->network.ping = _round_trip_time;
s->network.send_queue_len = _pending_output.size();
s->network.kbps_sent = _kbps_sent;
s->timesync.remote_frames_behind = _remote_frame_advantage;
s->timesync.local_frames_behind = _local_frame_advantage;
}
void
UdpProtocol::SetLocalFrameNumber(int localFrame)
{
/*
* Estimate which frame the other guy is one by looking at the
* last frame they gave us plus some delta for the one-way packet
* trip time.
*/
int remoteFrame = _last_received_input.frame + (_round_trip_time * 60 / 1000);
/*
* Our frame advantage is how many frames *behind* the other guy
* we are. Counter-intuative, I know. It's an advantage because
* it means they'll have to predict more often and our moves will
* pop more frequenetly.
*/
_local_frame_advantage = remoteFrame - localFrame;
}
int
UdpProtocol::RecommendFrameDelay()
{
// XXX: require idle input should be a configuration parameter
return _timesync.recommend_frame_wait_duration(false);
}
void
UdpProtocol::SetDisconnectTimeout(int timeout)
{
_disconnect_timeout = timeout;
}
void
UdpProtocol::SetDisconnectNotifyStart(int timeout)
{
_disconnect_notify_start = timeout;
}
void
UdpProtocol::PumpSendQueue()
{
std::lock_guard<std::mutex> lock(_send_mutex);
while (!_send_queue.empty()) {
QueueEntry &entry = _send_queue.front();
if (_send_latency) {
// should really come up with a gaussian distributation based on the configured
// value, but this will do for now.
int jitter = (_send_latency * 2 / 3) + ((rand() % _send_latency) / 3);
if ((int)GGPOPlatform::GetCurrentTimeMS() < _send_queue.front().queue_time + jitter) {
break;
}
}
if (_oop_percent && !_oo_packet.msg && ((rand() % 100) < _oop_percent)) {
int delay = rand() % (_send_latency * 10 + 1000);
Log("udpproto%d | creating rogue oop (seq: %d delay: %d)", _queue, entry.msg->hdr.sequence_number, delay);
_oo_packet.send_time = GGPOPlatform::GetCurrentTimeMS() + delay;
_oo_packet.msg = entry.msg;
_oo_packet.dest_addr = entry.dest_addr;
} else {
ASSERT(entry.dest_addr.sin_addr.s_addr);
_udp->SendTo((char *)entry.msg, entry.msg->PacketSize(), 0,
(struct sockaddr *)&entry.dest_addr, sizeof entry.dest_addr);
delete entry.msg;
}
_send_queue.pop();
}
if (_oo_packet.msg && _oo_packet.send_time < (int)GGPOPlatform::GetCurrentTimeMS()) {
Log("udpproto%d | sending rogue oop!", _queue);
_udp->SendTo((char *)_oo_packet.msg, _oo_packet.msg->PacketSize(), 0,
(struct sockaddr *)&_oo_packet.dest_addr, sizeof _oo_packet.dest_addr);
delete _oo_packet.msg;
_oo_packet.msg = NULL;
}
}
void
UdpProtocol::ClearSendQueue()
{
std::lock_guard<std::mutex> lock(_send_mutex);
while (!_send_queue.empty()) {
delete _send_queue.front().msg;
_send_queue.pop();
}
}
void UdpProtocol::SendAppData(const void *data, int len, bool spectators)
{
if (_udp == nullptr)
return;
if (_current_state != Synchronzied && _current_state != Running)
return;
UdpMsg *msg = new UdpMsg(UdpMsg::AppData);
msg->u.app_data.spectators = spectators;
msg->u.app_data.size = len;
memcpy(msg->u.app_data.data, data, len);
SendMsg(msg);
}
bool UdpProtocol::OnAppData(UdpMsg *msg, int len)
{
UdpProtocol::Event evt(UdpProtocol::Event::AppData);
evt.u.app_data.spectators = msg->u.app_data.spectators != 0;
evt.u.app_data.size = msg->u.app_data.size;
memcpy(evt.u.app_data.data, msg->u.app_data.data, msg->u.app_data.size);
QueueEvent(evt);
return true;
}
+223
View File
@@ -0,0 +1,223 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _UDP_PROTO_H_
#define _UDP_PROTO_H_
#include "ggpo_poll.h"
#include "udp.h"
#include "udp_msg.h"
#include "game_input.h"
#include "timesync.h"
#include "ggponet.h"
#include "ring_buffer.h"
#include <vector>
#include <mutex>
class UdpProtocol : public IPollSink
{
public:
struct Stats {
int ping;
int remote_frame_advantage;
int local_frame_advantage;
int send_queue_len;
Udp::Stats udp;
};
struct Event {
enum Type {
Unknown = -1,
Connected,
Synchronizing,
Synchronzied,
Input,
Disconnected,
NetworkInterrupted,
NetworkResumed,
AppData,
};
Type type;
union {
struct {
GameInput input;
} input;
struct {
int total;
int count;
} synchronizing;
struct {
int disconnect_timeout;
} network_interrupted;
struct {
bool spectators;
int size;
uint8 data[MAX_APPDATA_SIZE];
} app_data;
} u;
Event(Type t = Unknown) : type(t) { }
};
public:
virtual bool OnLoopPoll(void *cookie);
public:
UdpProtocol();
virtual ~UdpProtocol();
void Init(Udp *udp, Poll &p, int queue, char *ip, u_short port, UdpMsg::connect_status *status);
void Synchronize();
bool GetPeerConnectStatus(int id, int *frame);
bool IsInitialized() { return _udp != NULL; }
bool IsSynchronized() { return _current_state == Running; }
bool IsRunning() { return _current_state == Running; }
void SendInput(GameInput &input);
void SendInputAck();
bool HandlesMsg(sockaddr_in &from, UdpMsg *msg);
void OnMsg(UdpMsg *msg, int len);
void Disconnect();
void SendAppData(const void *data, int len, bool spectators);
void GetNetworkStats(struct GGPONetworkStats *stats);
bool GetEvent(UdpProtocol::Event &e);
void GGPONetworkStats(Stats *stats);
void SetLocalFrameNumber(int num);
int RecommendFrameDelay();
void SetVerificationData(const void *verification, int verification_size) {
ASSERT(verification_size <= MAX_VERIFICATION_SIZE);
this->verification.resize(verification_size);
memcpy(&this->verification[0], verification, verification_size);
}
void SetDisconnectTimeout(int timeout);
void SetDisconnectNotifyStart(int timeout);
protected:
enum State {
Syncing,
Synchronzied,
Running,
Disconnected
};
struct QueueEntry {
int queue_time;
sockaddr_in dest_addr;
UdpMsg *msg;
QueueEntry() {}
QueueEntry(int time, sockaddr_in &dst, UdpMsg *m) : queue_time(time), dest_addr(dst), msg(m) { }
};
bool CreateSocket(int retries);
void UpdateNetworkStats(void);
void QueueEvent(const UdpProtocol::Event &evt);
void ClearSendQueue(void);
void LogMsg(const char *prefix, UdpMsg *msg);
void LogEvent(const char *prefix, const UdpProtocol::Event &evt);
void SendSyncRequest();
void SendMsg(UdpMsg *msg);
void PumpSendQueue();
void SendPendingOutput();
bool OnInvalid(UdpMsg *msg, int len);
bool OnSyncRequest(UdpMsg *msg, int len);
bool OnSyncReply(UdpMsg *msg, int len);
bool OnInput(UdpMsg *msg, int len);
bool OnInputAck(UdpMsg *msg, int len);
bool OnQualityReport(UdpMsg *msg, int len);
bool OnQualityReply(UdpMsg *msg, int len);
bool OnKeepAlive(UdpMsg *msg, int len);
bool OnAppData(UdpMsg *msg, int len);
protected:
/*
* Network transmission information
*/
Udp *_udp;
sockaddr_in _peer_addr;
uint16 _magic_number;
int _queue;
uint16 _remote_magic_number;
bool _connected;
int _send_latency;
int _oop_percent;
struct {
int send_time;
sockaddr_in dest_addr;
UdpMsg* msg;
} _oo_packet;
RingBuffer<QueueEntry, 64> _send_queue;
std::mutex _send_mutex;
std::vector<uint8> verification;
/*
* Stats
*/
int _round_trip_time;
int _packets_sent;
int _bytes_sent;
int _kbps_sent;
int _stats_start_time;
/*
* The state machine
*/
UdpMsg::connect_status *_local_connect_status;
UdpMsg::connect_status _peer_connect_status[UDP_MSG_MAX_PLAYERS];
State _current_state;
union {
struct {
uint32 roundtrips_remaining;
uint32 random;
} sync;
struct {
uint32 last_quality_report_time;
uint32 last_network_stats_interval;
uint32 last_input_packet_recv_time;
} running;
} _state;
/*
* Fairness.
*/
int _local_frame_advantage;
int _remote_frame_advantage;
/*
* Packet loss...
*/
RingBuffer<GameInput, 64> _pending_output;
GameInput _last_received_input;
GameInput _last_sent_input;
GameInput _last_acked_input;
unsigned int _last_send_time;
unsigned int _last_recv_time;
unsigned int _shutdown_timeout;
unsigned int _disconnect_event_sent;
unsigned int _disconnect_timeout;
unsigned int _disconnect_notify_start;
bool _disconnect_notify_sent;
uint16 _next_send_seq;
uint16 _next_recv_seq;
/*
* Rift synchronization.
*/
TimeSync _timesync;
/*
* Event queue
*/
RingBuffer<UdpProtocol::Event, 64> _event_queue;
};
#endif
@@ -0,0 +1,38 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#if defined(__unix__) || defined(__APPLE__) || defined(__SWITCH__)
#include "platform_linux.h"
#include <time.h>
#include <strings.h>
#include <chrono>
uint32_t GGPOPlatform::GetCurrentTimeMS()
{
using namespace std::chrono;
static steady_clock::time_point startTime = steady_clock::now();
return (uint32_t)duration_cast<milliseconds>(steady_clock::now() - startTime).count();
}
int GGPOPlatform::GetConfigInt(const char* name)
{
char *buf = getenv(name);
if (buf == nullptr)
return 0;
return atoi(buf);
}
bool GGPOPlatform::GetConfigBool(const char* name)
{
char *buf = getenv(name);
if (buf == nullptr)
return false;
return atoi(buf) != 0 || strcasecmp(buf, "true") == 0;
}
#endif
+69
View File
@@ -0,0 +1,69 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _GGPO_LINUX_H_
#define _GGPO_LINUX_H_
#include <limits>
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstdint>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef __SWITCH__
#include "nswitch.h"
#else
#include <netinet/ip.h>
#endif
#include <netinet/tcp.h>
#include <arpa/inet.h>
using SOCKET = int;
#define closesocket close
#define INVALID_SOCKET (-1)
#define SOCKET_ERROR (-1)
#define WSAEWOULDBLOCK EWOULDBLOCK
constexpr size_t MAX_PATH = 4096;
#ifdef INT_MAX
#undef INT_MAX
#endif
constexpr int INT_MAX = std::numeric_limits<int>::max();
class GGPOPlatform {
public: // types
typedef pid_t ProcessID;
public: // functions
static ProcessID GetProcessID() { return getpid(); }
static void AssertFailed(char *msg) { fprintf(stderr, "%s", msg); }
static uint32_t GetCurrentTimeMS();
static int GetConfigInt(const char* name);
static bool GetConfigBool(const char* name);
};
extern "C" {
inline static void DebugBreak()
{
__builtin_trap();
}
inline static int WSAGetLastError() {
return errno;
}
}
#endif
@@ -0,0 +1,28 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifdef _WIN32
#include "platform_windows.h"
int
GGPOPlatform::GetConfigInt(const char* name)
{
char buf[1024];
if (GetEnvironmentVariableA(name, buf, ARRAY_SIZE(buf)) == 0) {
return 0;
}
return atoi(buf);
}
bool GGPOPlatform::GetConfigBool(const char* name)
{
char buf[1024];
if (GetEnvironmentVariableA(name, buf, ARRAY_SIZE(buf)) == 0) {
return false;
}
return atoi(buf) != 0 || _stricmp(buf, "true") == 0;
}
#endif
@@ -0,0 +1,44 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _GGPO_WINDOWS_H_
#define _GGPO_WINDOWS_H_
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdio.h>
#include <chrono>
#include "ggpo_types.h"
class GGPOPlatform {
public: // types
typedef DWORD ProcessID;
public: // functions
static ProcessID GetProcessID() { return GetCurrentProcessId(); }
static void AssertFailed(char *msg) {
#ifndef TARGET_UWP
MessageBoxA(NULL, msg, "GGPO Assertion Failed", MB_OK | MB_ICONEXCLAMATION);
#endif
}
static uint32 GetCurrentTimeMS() {
#ifdef TARGET_UWP
using namespace std::chrono;
static steady_clock::time_point startTime = steady_clock::now();
return (uint32_t)duration_cast<milliseconds>(steady_clock::now() - startTime).count();
#else
return timeGetTime();
#endif
}
static int GetConfigInt(const char* name);
static bool GetConfigBool(const char* name);
};
#endif
+127
View File
@@ -0,0 +1,127 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "ggpo_poll.h"
#include "ggpo_types.h"
#ifndef _WIN32
#include <chrono>
#include <thread>
constexpr int INFINITE = -1;
#endif
Poll::Poll(void) :
_start_time(0),
_handle_count(0)
{
/*
* Create a dummy handle to simplify things.
*/
#ifdef _WIN32
_handles[_handle_count++] = CreateEvent(NULL, true, false, NULL);
#endif
}
#if 0
void
Poll::RegisterHandle(IPollSink *sink, HANDLE h, void *cookie)
{
ASSERT(_handle_count < MAX_POLLABLE_HANDLES - 1);
_handles[_handle_count] = h;
_handle_sinks[_handle_count] = PollSinkCb(sink, cookie);
_handle_count++;
}
#endif
void
Poll::RegisterMsgLoop(IPollSink *sink, void *cookie)
{
_msg_sinks.push_back(PollSinkCb(sink, cookie));
}
void
Poll::RegisterLoop(IPollSink *sink, void *cookie)
{
_loop_sinks.push_back(PollSinkCb(sink, cookie));
}
void
Poll::RegisterPeriodic(IPollSink *sink, int interval, void *cookie)
{
_periodic_sinks.push_back(PollPeriodicSinkCb(sink, cookie, interval));
}
void
Poll::Run()
{
while (Pump(100)) {
continue;
}
}
bool
Poll::Pump(int timeout)
{
int i;
bool finished = false;
if (_start_time == 0) {
_start_time = GGPOPlatform::GetCurrentTimeMS();
}
int elapsed = GGPOPlatform::GetCurrentTimeMS() - _start_time;
int maxwait = ComputeWaitTime(elapsed);
if (maxwait != INFINITE) {
timeout = MIN(timeout, maxwait);
}
#ifdef _WIN32
DWORD res = WaitForMultipleObjects(_handle_count, _handles, false, timeout);
if (res >= WAIT_OBJECT_0 && res < WAIT_OBJECT_0 + _handle_count) {
i = res - WAIT_OBJECT_0;
finished = !_handle_sinks[i].sink->OnHandlePoll(_handle_sinks[i].cookie) || finished;
}
#else
if (timeout > 0)
std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
#endif
for (i = 0; i < _msg_sinks.size(); i++) {
PollSinkCb &cb = _msg_sinks[i];
finished = !cb.sink->OnMsgPoll(cb.cookie) || finished;
}
for (i = 0; i < _periodic_sinks.size(); i++) {
PollPeriodicSinkCb &cb = _periodic_sinks[i];
if (cb.interval + cb.last_fired <= elapsed) {
cb.last_fired = (elapsed / cb.interval) * cb.interval;
finished = !cb.sink->OnPeriodicPoll(cb.cookie, cb.last_fired) || finished;
}
}
for (i = 0; i < _loop_sinks.size(); i++) {
PollSinkCb &cb = _loop_sinks[i];
finished = !cb.sink->OnLoopPoll(cb.cookie) || finished;
}
return finished;
}
int
Poll::ComputeWaitTime(int elapsed)
{
int waitTime = INFINITE;
size_t count = _periodic_sinks.size();
if (count > 0) {
for (size_t i = 0; i < count; i++) {
PollPeriodicSinkCb &cb = _periodic_sinks[i];
int timeout = (cb.interval + cb.last_fired) - elapsed;
if (waitTime == INFINITE || (timeout < waitTime)) {
waitTime = MAX(timeout, 0);
}
}
}
return waitTime;
}
+60
View File
@@ -0,0 +1,60 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _RING_BUFFER_H
#define _RING_BUFFER_H
#include "ggpo_types.h"
template<class T, int N> class RingBuffer
{
public:
RingBuffer<T, N>() :
_head(0),
_tail(0),
_size(0) {
}
T &front() {
ASSERT(_size != N);
return _elements[_tail];
}
T &item(int i) {
ASSERT(i < _size);
return _elements[(_tail + i) % N];
}
void pop() {
ASSERT(_size != N);
_tail = (_tail + 1) % N;
_size--;
}
void push(const T &t) {
ASSERT(_size != (N-1));
_elements[_head] = t;
_head = (_head + 1) % N;
_size++;
}
int size() {
return _size;
}
bool empty() {
return _size == 0;
}
protected:
T _elements[N];
int _head;
int _tail;
int _size;
};
#endif
+40
View File
@@ -0,0 +1,40 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _STATIC_BUFFER_H
#define _STATIC_BUFFER_H
#include "ggpo_types.h"
template<class T, int N> class StaticBuffer
{
public:
StaticBuffer<T, N>() :
_size(0) {
}
T& operator[](int i) {
ASSERT(i >= 0 && i < _size);
return _elements[i];
}
void push_back(const T &t) {
ASSERT(_size != (N-1));
_elements[_size++] = t;
}
int size() {
return _size;
}
protected:
T _elements[N];
int _size;
};
#endif
+304
View File
@@ -0,0 +1,304 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include "sync.h"
Sync::Sync(UdpMsg::connect_status *connect_status) :
_input_queues(NULL),
_local_connect_status(connect_status)
{
_framecount = 0;
_last_confirmed_frame = -1;
_max_prediction_frames = 0;
memset(&_savedstate, 0, sizeof(_savedstate));
}
Sync::~Sync()
{
/*
* Delete frames manually here rather than in a destructor of the SavedFrame
* structure so we can efficently copy frames via weak references.
*/
for (size_t i = 0; i < ARRAY_SIZE(_savedstate.frames); i++) {
_callbacks.free_buffer(_savedstate.frames[i].buf);
}
delete [] _input_queues;
_input_queues = NULL;
}
void
Sync::Init(Sync::Config &config)
{
_config = config;
_callbacks = config.callbacks;
_framecount = 0;
_rollingback = false;
_max_prediction_frames = config.num_prediction_frames;
CreateQueues(config);
}
void
Sync::SetLastConfirmedFrame(int frame)
{
_last_confirmed_frame = frame;
if (_last_confirmed_frame > 0) {
for (int i = 0; i < _config.num_players; i++) {
_input_queues[i].DiscardConfirmedFrames(frame - 1);
}
}
}
bool
Sync::AddLocalInput(int queue, GameInput &input)
{
int frames_behind = _framecount - _last_confirmed_frame;
if (_framecount >= _max_prediction_frames && frames_behind >= _max_prediction_frames) {
Log("Rejecting input from emulator: reached prediction barrier.");
return false;
}
if (_framecount == 0) {
SaveCurrentFrame();
}
Log("Sending undelayed local frame %d to queue %d.", _framecount, queue);
input.frame = _framecount;
_input_queues[queue].AddInput(input);
return true;
}
void
Sync::AddRemoteInput(int queue, GameInput &input)
{
_input_queues[queue].AddInput(input);
}
int
Sync::GetConfirmedInputs(void *values, int size, int frame)
{
int disconnect_flags = 0;
char *output = (char *)values;
ASSERT(size >= _config.num_players * _config.input_size);
memset(output, 0, size);
for (int i = 0; i < _config.num_players; i++) {
GameInput input;
if (_local_connect_status[i].disconnected && frame > _local_connect_status[i].last_frame) {
disconnect_flags |= (1 << i);
input.erase();
} else {
_input_queues[i].GetConfirmedInput(frame, &input);
}
memcpy(output + (i * _config.input_size), input.bits, _config.input_size);
}
return disconnect_flags;
}
int
Sync::SynchronizeInputs(void *values, int size)
{
int disconnect_flags = 0;
char *output = (char *)values;
ASSERT(size >= _config.num_players * _config.input_size);
memset(output, 0, size);
for (int i = 0; i < _config.num_players; i++) {
GameInput input;
if (_local_connect_status[i].disconnected && _framecount > _local_connect_status[i].last_frame) {
disconnect_flags |= (1 << i);
input.erase();
} else {
_input_queues[i].GetInput(_framecount, &input);
}
memcpy(output + (i * _config.input_size), input.bits, _config.input_size);
}
return disconnect_flags;
}
void
Sync::CheckSimulation(int timeout)
{
int seek_to;
if (!CheckSimulationConsistency(&seek_to)) {
AdjustSimulation(seek_to);
}
}
void
Sync::IncrementFrame(void)
{
_framecount++;
SaveCurrentFrame();
}
void
Sync::AdjustSimulation(int seek_to)
{
int framecount = _framecount;
int count = _framecount - seek_to;
Log("Catching up");
_rollingback = true;
/*
* Flush our input queue and load the last frame.
*/
LoadFrame(seek_to);
ASSERT(_framecount == seek_to);
/*
* Advance frame by frame (stuffing notifications back to
* the master).
*/
ResetPrediction(_framecount);
for (int i = 0; i < count; i++) {
_callbacks.advance_frame(0);
}
ASSERT(_framecount == framecount);
_rollingback = false;
Log("---");
}
void
Sync::LoadFrame(int frame)
{
// find the frame in question
if (frame == _framecount) {
Log("Skipping NOP.");
return;
}
// Move the head pointer back and load it up
_savedstate.head = FindSavedFrameIndex(frame);
SavedFrame *state = _savedstate.frames + _savedstate.head;
Log("=== Loading frame info %d (size: %d checksum: %08x).",
state->frame, state->cbuf, state->checksum);
ASSERT(state->buf && state->cbuf);
_callbacks.load_game_state(state->buf, state->cbuf);
// Reset framecount and the head of the state ring-buffer to point in
// advance of the current frame (as if we had just finished executing it).
_framecount = state->frame;
_savedstate.head = (_savedstate.head + 1) % ARRAY_SIZE(_savedstate.frames);
}
void
Sync::SaveCurrentFrame()
{
/*
* See StateCompress for the real save feature implemented by FinalBurn.
* Write everything into the head, then advance the head pointer.
*/
SavedFrame *state = _savedstate.frames + _savedstate.head;
if (state->buf) {
_callbacks.free_buffer(state->buf);
state->buf = NULL;
}
state->frame = _framecount;
_callbacks.save_game_state(&state->buf, &state->cbuf, &state->checksum, state->frame);
Log("=== Saved frame info %d (size: %d checksum: %08x).", state->frame, state->cbuf, state->checksum);
_savedstate.head = (_savedstate.head + 1) % ARRAY_SIZE(_savedstate.frames);
}
Sync::SavedFrame&
Sync::GetLastSavedFrame()
{
int i = _savedstate.head - 1;
if (i < 0) {
i = ARRAY_SIZE(_savedstate.frames) - 1;
}
return _savedstate.frames[i];
}
int
Sync::FindSavedFrameIndex(int frame)
{
int i, count = ARRAY_SIZE(_savedstate.frames);
for (i = 0; i < count; i++) {
if (_savedstate.frames[i].frame == frame) {
break;
}
}
if (i == count) {
ASSERT(false);
}
return i;
}
bool
Sync::CreateQueues(Config &config)
{
delete [] _input_queues;
_input_queues = new InputQueue[_config.num_players];
for (int i = 0; i < _config.num_players; i++) {
_input_queues[i].Init(i, _config.input_size);
}
return true;
}
bool
Sync::CheckSimulationConsistency(int *seekTo)
{
int first_incorrect = GameInput::NullFrame;
for (int i = 0; i < _config.num_players; i++) {
int incorrect = _input_queues[i].GetFirstIncorrectFrame();
Log("considering incorrect frame %d reported by queue %d.", incorrect, i);
if (incorrect != GameInput::NullFrame && (first_incorrect == GameInput::NullFrame || incorrect < first_incorrect)) {
first_incorrect = incorrect;
}
}
if (first_incorrect == GameInput::NullFrame) {
Log("prediction ok. proceeding.");
return true;
}
*seekTo = first_incorrect;
return false;
}
void
Sync::SetFrameDelay(int queue, int delay)
{
_input_queues[queue].SetFrameDelay(delay);
}
void
Sync::ResetPrediction(int frameNumber)
{
for (int i = 0; i < _config.num_players; i++) {
_input_queues[i].ResetPrediction(frameNumber);
}
}
bool
Sync::GetEvent(Event &e)
{
if (_event_queue.size()) {
e = _event_queue.front();
_event_queue.pop();
return true;
}
return false;
}
+105
View File
@@ -0,0 +1,105 @@
/* -----------------------------------------------------------------------
* GGPO.net (http://ggpo.net) - Copyright 2009 GroundStorm Studios, LLC.
*
* Use of this software is governed by the MIT license that can be found
* in the LICENSE file.
*/
#ifndef _SYNC_H
#define _SYNC_H
#include "ggponet.h"
#include "game_input.h"
#include "ggpo_types.h"
#include "input_queue.h"
#include "ring_buffer.h"
#include "network/udp_msg.h"
#define MAX_PREDICTION_FRAMES 8
class SyncTestBackend;
class Sync {
public:
struct Config {
GGPOSessionCallbacks callbacks;
int num_prediction_frames;
int num_players;
int input_size;
};
struct Event {
enum {
ConfirmedInput,
} type;
union {
struct {
GameInput input;
} confirmedInput;
} u;
};
public:
Sync(UdpMsg::connect_status *connect_status);
virtual ~Sync();
void Init(Config &config);
void SetLastConfirmedFrame(int frame);
void SetFrameDelay(int queue, int delay);
bool AddLocalInput(int queue, GameInput &input);
void AddRemoteInput(int queue, GameInput &input);
int GetConfirmedInputs(void *values, int size, int frame);
int SynchronizeInputs(void *values, int size);
void CheckSimulation(int timeout);
void AdjustSimulation(int seek_to);
void IncrementFrame(void);
int GetFrameCount() { return _framecount; }
bool InRollback() { return _rollingback; }
int GetPredictedFrames() { return _framecount - _last_confirmed_frame; }
bool GetEvent(Event &e);
protected:
friend SyncTestBackend;
struct SavedFrame {
byte *buf;
int cbuf;
int frame;
int checksum;
SavedFrame() : buf(NULL), cbuf(0), frame(-1), checksum(0) { }
};
struct SavedState {
SavedFrame frames[MAX_PREDICTION_FRAMES + 2];
int head;
};
void LoadFrame(int frame);
void SaveCurrentFrame();
int FindSavedFrameIndex(int frame);
SavedFrame &GetLastSavedFrame();
bool CreateQueues(Config &config);
bool CheckSimulationConsistency(int *seekTo);
void ResetPrediction(int frameNumber);
protected:
GGPOSessionCallbacks _callbacks;
SavedState _savedstate;
Config _config;
bool _rollingback;
int _last_confirmed_frame;
int _framecount;
int _max_prediction_frames;
InputQueue *_input_queues;
RingBuffer<Event, 32> _event_queue;
UdpMsg::connect_status *_local_connect_status;
};
#endif
Loaded 100 of 4668 files, more files were not shown because too many files have changed in this diff. Show more