--- /dev/null
+*.o
+*.swp
--- /dev/null
+libpicofe, or LIB-PICOdrive's-FrontEnd, is an attempt to reuse PicoDrive's
+frontend code for other projects. To accommodate various needs, this is
+tripple-licensed with these licenses:
+ - GNU GPL, version 2 or later.
+ - GNU LGPL, version 2.1 or later.
+ - MAME license.
+When used as part of another project, host project's license usually applies
+to combined source code as a whole.
+
+
+- notaz
+++ /dev/null
-#\r
-PicoDrive 1.xx\r
-\r
-About\r
------\r
-\r
-#ifdef PSP\r
-This is yet another Megadrive / Genesis emulator for PSP, but with\r
-Sega CD / Mega CD support. Although it has been originally written having\r
-ARM CPU based devices in mind, it has now been ported to PSP too, by\r
-replacing ARM specific parts with portable C code.\r
-The base code originates from Dave's (fdave, finalburn) PicoDrive 0.30 for\r
-Pocket PC. The Sega/Mega CD code is roughly based on Stephane Dallongeville's\r
-Gens.\r
-#else\r
-This is yet another Megadrive / Genesis / Sega CD / Mega CD / 32X / SMS\r
-emulator, which was written having ARM-based handheld devices in mind\r
-(such as PDAs, smartphones and handheld consoles like GP2X and Gizmondo\r
-of course).\r
-The emulator is heavily optimized for ARM, features assembly cores for\r
-68k, Z80 and VDP chip emulation, also has dynamic recompilers for SH2 and\r
-SSP16 (for 32X and SVP emulation). It was started by Dave (aka fdave,\r
-finalburn author) as basic Genesis/Megadrive emulator for Pocket PC,\r
-then taken over by notaz and developed primarily for GPH devices.\r
-#endif\r
-\r
-PicoDrive is the first emulator ever to properly emulate Virtua Racing and\r
-it's SVP chip.\r
-\r
-\r
-How to make it run\r
-------------------\r
-\r
-#ifdef GP2X\r
-Extract all files to some directory on your SD and run PicoDrive.gpe from your\r
-GP2X/Wiz/Caanoo menu. The same .gpe supports GP2X F100/F200, Wiz and Caanoo,\r
-there is no need to use separate versions.\r
-Then load a ROM and enjoy! ROMs can be in .smd or .bin format and can be zipped.\r
-Sega/Mega CD images can be in ISO/CSO+MP3/WAV or CUE+BIN formats (read below\r
-for more details).\r
-#endif\r
-#ifdef GIZ\r
-First make sure you have homebrew-enabled Service Pack installed. Then copy\r
-PicoDrive.exe and KGSDK.dll to any place in your filesystem (both files must\r
-be in the same directory) and run PicoDrive.exe using the launcher of your choice\r
-(some of them might require renaming PicoDrive.exe to Autorun.exe, placing it in\r
-the root of SD, etc). Then load a ROM and enjoy! ROMs can be placed anywhere, can\r
-be in .smd or .bin format and can be zipped (one ROM per zip).\r
-#endif\r
-#ifdef PSP\r
-If you are running a custom firmware, just copy the whole PicoDrive directory to\r
-/PSP/GAME or /PSP/GAMEXXX directory in your memory stick (it shouldn't matter\r
-which one GAME* directory to use).\r
-\r
-If you are on 1.5, there is a separate KXploited version for it.\r
-#endif\r
-#ifdef UIQ\r
-Copy SIS and some ROMs to any directory in your memory stick, and install the SIS.\r
-Then load a ROM and enjoy! ROMs can be in .smd or .bin format and can be zipped.\r
-#endif\r
-#ifdef PANDORA\r
-Just copy the .pnd to <sd card>/pandora/menu or <sd card>/pandora/desktop.\r
-#endif\r
-#ifndef UIQ\r
-\r
-This emulator has lots of options with various tweaks (for improved speed mostly),\r
-but it should have best compatibility in it's default config. If suddently you\r
-start getting glitches or change something and forget what, use "Restore defaults"\r
-option.\r
-#endif\r
-\r
-\r
-How to run Sega/Mega CD games\r
------------------------------\r
-\r
-To play any game, you need BIOS files. These files must be copied to\r
-#ifdef UIQ\r
-D:\other\PicoDrive\ directory.\r
-#else\r
-#ifdef PANDORA\r
-<sd card>/pandora/appdata/PicoDrive/ directory\r
-(if you run PicoDrive once it will create that directory for you).\r
-#else\r
-the same directory as PicoDrive files.\r
-#endif\r
-#endif\r
-Files can be named as follows:\r
-\r
-US: us_scd1_9210.bin us_scd2_9306.bin SegaCDBIOS9303.bin\r
-EU: eu_mcd1_9210.bin eu_mcd2_9303.bin eu_mcd2_9306.bin\r
-JP: jp_mcd1_9112.bin jp_mcd1_9111.bin\r
-these files can also be zipped.\r
-\r
-The game must be dumped to ISO/CSO+MP3/WAV or CUE+BIN format. When using\r
-CUE/BIN, you must load .cue file from the menu, or else the emu will not find\r
-audio tracks.\r
-CUE/BIN usually takes a lot of space, so it can be converted to cue/cso/mp3 by\r
-#ifdef PANDORA\r
-using bin_to_cso_mp3 tool, which can be downloaded from:\r
-http://notaz.gp2x.de/releases/misc/bin_to_cso_mp3.zip\r
-See readme in the bin_to_cso_mp3/ directory for details.\r
-#else\r
-using bin_to_cso_mp3 tool, which is included with the emulator. See readme in\r
-the bin_to_cso_mp3/ directory for details.\r
-#endif\r
-\r
-ISO+mp3 files can be named similarly as for other emus.\r
-Here are some examples:\r
-\r
-SonicCD.iso data track\r
-SonicCD_02.mp3 audio track 1 (CD track 2)\r
-SonicCD_03.mp3\r
-...\r
-\r
-Sonic the Hedgehog CD (US) - Track 01.iso\r
-Sonic the Hedgehog CD (US) - Track 02.mp3\r
-Sonic the Hedgehog CD (US) - Track 03.mp3\r
-...\r
-\r
-In case there is a .cue file with properly specified files names in it,\r
-file naming doesn't matter. Just be sure to load .cue from the menu.\r
-\r
-It is very important to have the MP3s encoded at 44kHz sample rate and they\r
-must be stereo, or else they will play too fast/slow or won't play at all.\r
-Be sure NOT to use anything but classic mp3 format (don't use things like\r
-mp3pro).\r
-\r
-ISO files can also be .cso compressed or zipped (but not mp3 files, as they\r
-are already compressed). CSO will cause slightly longer loading times, and\r
-is not very good for FMV games. Zipping ISOs is not recommended, as it will\r
-cause very long (several minute) loading times, and make some games\r
-unplayable. File naming is similar as with uncompressed ISOs.\r
-Example:\r
-\r
-SonicCD.cso data track\r
-SonicCD_02.mp3 audio track 1 (CD track 2)\r
-SonicCD_03.mp3\r
-...\r
-\r
-\r
-Other important stuff\r
----------------------\r
-\r
-* Sega/Mega CD: If the game hangs after Sega logo, you may need to enable\r
- "better sync" and/or "Scale/Rot. fx" options, found in "Sega/Mega CD options"\r
- submenu, and then reset the game. Some other games may also require\r
- "CDDA audio" and "PCM audio" to be enabled to work (enabled by default).\r
- Incorrectly named/missing mp3s may also be the cause.\r
-* Sega/Mega CD: If the background music is missing, you might have named your\r
- MP3s incorrectly. Read "How to run Sega/Mega CD games" section again.\r
-* Sega/Mega CD: If the game music plays too fast/too slow/out of sync, you have\r
- encoded your MP3s incorrectly. You will have to re-encode and/or resample them.\r
- PicoDrive is not a mp3 player, so all mp3s MUST be encoded at 44.1kHz stereo.\r
- Badly encoded mp3s can cause various kind of problems, like noises, incorrect\r
- playback speeds, not repeating music or even prevent game from starting.\r
- Some games (like Snatcher) may hang in certain scenes because of this.\r
- Some mp3 rippers/encoders remove silence and beginning/end of audio tracks,\r
- what causes audio desyncs and/or mentioned problems.\r
- If you have cue/bin rip, you can use the bin_to_cso_mp3 tool (included with\r
- the emulator) to make a proper iso/mp3 rip.\r
-* Sega/Mega CD: If your games hangs at the BIOS screen (with planets shown),\r
- you may be using a bad BIOS dump. Try another from a different source.\r
-* Some Sega/Mega CD games don't use Z80 for anything, but they leave it active,\r
- so disabling Z80 manually (in advanced options) improves performance.\r
-* Use lower bitrate for better performance (96 or 128kbps CBRs recommended).\r
-#ifdef GP2X\r
-* GP2X F100/F200: When you use both GP2X CPUs, keep in mind that you can't\r
- overclock as high as when using ARM920 only. For example my GP2X when run\r
- singlecore can reach 280MHz, but with both cores it's about 250MHz. When\r
- overclocked too much, it may start hanging and producing random noise, or\r
- causing ARM940 crashes ("940 crashed" message displayed).\r
-* GP2X F100/F200: Due to internal implementation mp3s must not be larger that\r
- 12MB (12582912 bytes). Larger mp3s will not be fully loaded.\r
-#endif\r
-\r
-\r
-Configuration\r
--------------\r
-\r
-#ifdef UIQ\r
-#include "config.txt"\r
-#else\r
-@@0. "Save slot"\r
-This is a slot number to use for savestates, when done by a button press outside\r
-menu. This can also be configured to be changed with a button\r
-(see "key configuration").\r
-\r
-@@0. "Frameskip"\r
-How many frames to skip rendering before displaying another.\r
-"Auto" is recommended.\r
-\r
-@@0. "Region"\r
-This option lets you force the game to think it is running on machine from the\r
-specified region, or just to set autodetection order. Also affects Sega/Mega CD.\r
-\r
-@@0. "Show FPS"\r
-Self-explanatory. Format is XX/YY, where XX is the number of rendered frames and\r
-YY is the number of emulated frames per second.\r
-\r
-@@0. "Enable sound"\r
-Does what it says. You must enable at least YM2612 or SN76496 (in advanced options,\r
-see below) for this to make sense (already done by default).\r
-\r
-@@0. "Sound Quality"\r
-#ifdef PSP\r
-Sound sample rate, affects sound quality and emulation performance.\r
-22050Hz setting is the recommended one.\r
-#else\r
-Sound sample rate and stereo mode. Mono is not available in Sega/Mega CD mode.\r
-#endif\r
-\r
-@@0. "Confirm savestate"\r
-Allows to enable confirmation on savestate saving (to prevent savestate overwrites),\r
-on loading (to prevent destroying current game progress), and on both or none, when\r
-using shortcut buttons (not menu) for saving/loading.\r
-\r
-#ifdef GP2X\r
-@@0. "GP2X CPU clocks"\r
-Here you can change clocks of both GP2X's CPUs. Larger values increase performance.\r
-There is no separate option for the second CPU because both CPUs use the same clock\r
-source. Setting this option to 200 will cause PicoDrive NOT to change GP2X's clocks\r
-at all (this is if you use external program to set clock).\r
-#endif\r
-#ifdef PSP\r
-@@0. "CPU/bus clock"\r
-This allows to change CPU and bus clocks for PSP. 333MHz is recommended.\r
-#endif\r
-\r
-@@0. "[Display options]"\r
-Enters Display options menu (see below).\r
-\r
-@@0. "[Sega/Mega CD options]"\r
-Enters Sega/Mega CD options menu (see below).\r
-\r
-@@0. "[32X options]"\r
-Enters 32X options menu (see below).\r
-\r
-@@0. "[Advanced options]"\r
-Enters advanced options menu (see below).\r
-\r
-@@0. "Save cfg as default"\r
-If you save your config here it will be loaded on next ROM load, but only if there\r
-is no game specific config saved (which will be loaded in that case).\r
-You can press left/right to switch to a different config profile.\r
-\r
-@@0. "Save cfg for current game only"\r
-Whenever you load current ROM again these settings will be loaded.\r
-\r
-@@0. "Restore defaults"\r
-Restores all options (except controls) to defaults.\r
-\r
-\r
-Display options\r
----------------\r
-\r
-#ifndef PANDORA\r
-@@1. "Renderer"\r
-#ifdef GP2X\r
-8bit fast:\r
-This enables alternative heavily optimized tile-based renderer, which renders\r
-pixels not line-by-line (this is what accurate renderers do), but in 8x8 tiles,\r
-which is much faster. But because of the way it works it can't render any\r
-mid-frame image changes (raster effects), so it is useful only with some games.\r
-\r
-Other two are accurate line-based renderers. The 8bit is faster but does not\r
-run well with some games like Street Racer.\r
-\r
-#endif\r
-#ifdef GIZ\r
-This option allows to switch between 16bit and 8bit renderers. The 8bit one is\r
-a bit faster for some games, but not much, because colors still need to be\r
-converted to 16bit, as this is what Gizmondo requires. It also introduces\r
-graphics problems for some games, so it's best to use 16bit one.\r
-\r
-#endif\r
-#ifdef PSP\r
-This option allows to switch between fast and accurate renderers. The fast one\r
-is much faster, because it draws the whole frame at a time, instead of doing it\r
-line by line, like the accurate one does. But because of the way it works it\r
-can't render any mid-frame image changes (raster effects), so it is useful only\r
-for some games.\r
-\r
-#endif\r
-#endif\r
-#ifdef GP2X\r
-@@1. "Tearing Fix"\r
-Wiz only: works around the tearing problem by using portrait mode. Causes ~5-10%\r
-performance hit, but eliminates the tearing effect.\r
-\r
-@@1. "Gamma correction"\r
-F100/F200 only: Alters image gamma through GP2X hardware. Larger values make\r
-image to look brighter, lower - darker (default is 1.0).\r
-\r
-@@1. "A_SN's gamma curve"\r
-F100/F200 only: If this is enabled, different gamma adjustment method will be\r
-used (suggested by A_SN from gp32x boards). Intended to be used for F100, makes\r
-difference for dark and bright colors.\r
-\r
-@@1. "Vsync"\r
-This one adjusts the LCD refresh rate to better match game's refresh rate and\r
-starts synchronizing rendering with it. Should make scrolling smoother and\r
-eliminate tearing on F100/F200.\r
-#endif\r
-#ifdef GIZ\r
-@@1. "Scanline mode"\r
-This option was designed to work around slow framebuffer access (the Gizmondo's\r
-main bottleneck) by drawing every other line (even numbered lines only).\r
-This improves performance greatly, but looses detail.\r
-\r
-@@1. "Scale low res mode"\r
-The Genesis/Megadrive had several graphics modes, some of which were only 256\r
-pixels wide. This option scales their width to 320 by using simple\r
-pixel averaging scaling. Works only when 16bit renderer is enabled.\r
-\r
-@@1. "Double buffering"\r
-Draws the display to offscreen buffer, and flips it with visible one when done.\r
-Unfortunately this causes serious tearing, unless v-sync is used (next option).\r
-\r
-@@1. "Wait for V-sync"\r
-Waits for vertical sync before drawing (or flipping buffers, if previous option\r
-is enabled). Emulation is stopped while waiting, so this causes large performance\r
-hit.\r
-#endif\r
-#ifdef PSP\r
-@@1. "Scale factor"\r
-This allows to resize the displayed image by using the PSP's hardware. The number is\r
-used to multiply width and height of the game image to get the size of image to be\r
-displayed. If you just want to make it fullscreen, just use "Set to fullscreen"\r
-setting below.\r
-\r
-@@1. "Hor. scale (for low res. games)"\r
-This one works similarly as the previous setting, but can be used to apply additional\r
-scaling horizontally, and is used for games which use lower (256 pixel wide) Gen/MD\r
-resolution.\r
-\r
-@@1. "Hor. scale (for hi res. games)"\r
-Same as above, only for higher (320 pixel wide) resolution using games.\r
-\r
-@@1. "Bilinear filtering"\r
-If this is enabled, PSP hardware will apply bilinear filtering on the resulting image,\r
-making it smoother, but blurry.\r
-\r
-@@1. "Gamma adjustment"\r
-Color gamma can be adjusted with this.\r
-\r
-@@1. "Black level"\r
-This can be used to reduce unwanted "ghosting" effect for dark games, by making\r
-black pixels brighter. Use in conjunction with "gamma adjustment" for more effect.\r
-\r
-@@1. "Wait for v-sync"\r
-Wait for the screen to finish updating before switching to next frame, to avoid tearing.\r
-There are 3 options:\r
-* never: don't wait for vsync.\r
-* sometimes: wait only if emulator is running fast enough.\r
-* always: always wait (causes emulation slowdown).\r
-\r
-@@1. "Set to unscaled centered"\r
-Adjust the resizing options to set game image to it's original size.\r
-\r
-@@1. "Set to 4:3 scaled"\r
-Scale the image up, but keep 4:3 aspect, by adding black borders.\r
-\r
-@@1. "Set to fullscreen"\r
-Adjust the resizing options to make the game image fullscreen.\r
-#endif\r
-#ifdef PANDORA\r
-Allows to set up scaling, filtering and vertical sync.\r
-#endif\r
-\r
-\r
-Sega/Mega CD options \r
---------------------\r
-\r
-@@2. "CD LEDs"\r
-The Sega/Mega CD unit had two blinking LEDs (red and green) on it. This option\r
-will display them on top-left corner of the screen.\r
-\r
-@@2. "CDDA audio"\r
-This option enables CD audio playback.\r
-\r
-@@2. "PCM audio"\r
-This enables 8 channel PCM sound source. It is required for some games to run,\r
-because they monitor state of this audio chip.\r
-\r
-@@2. "ReadAhead buffer"\r
-This option can prefetch more data from the CD image than requested by game\r
-(to avoid accessing card later), what can improve performance in some cases.\r
-#ifndef PSP\r
-"OFF" is the recommended setting.\r
-#endif\r
-\r
-@@2. "Save RAM cart"\r
-Here you can enable 64K RAM cart. Format it in BIOS if you do.\r
-\r
-@@2. "Scale/Rot. fx"\r
-The Sega/Mega CD had scaling/rotation chip, which allows effects similar to\r
-"Mode 7" effects in SNES. Disabling may improve performance but cause graphical\r
-glitches.\r
-\r
-@@2. "Better sync"\r
-This option is similar to "Perfect synchro" in Gens. Some games require it to run,\r
-for example most (all?) Wolfteam games, and some other ones. Don't use it for\r
-games which don't need it, it will just slow them down.\r
-\r
-\r
-32X options\r
------------\r
-\r
-@@3. "32X enabled"\r
-Enables emulation of addon. Option only takes effect when ROM is reloaded.\r
-\r
-#ifdef GP2X\r
-@@3. "32X renderer"\r
-This currently only affects how the Genesis/MD layers are rendered, which is\r
-same as "Renderer" in display options.\r
-\r
-#endif\r
-@@3. "PWM sound"\r
-Emulates PWM sound portion of 32X hardware. Disabling this may greatly improve\r
-performance for games that dedicate one of SD2s for sound, but will cause\r
-missing sound effects and instruments.\r
-\r
-@@3. "Master SH2 cycles" / "Slave SH2 cycles"\r
-This allows underclocking the 32X CPUs for better emulation performance. The\r
-number has the same meaning as cycles in DOSBox, which is cycles per millisecond.\r
-Underclocking too much may cause various in-game glitches.\r
-\r
-\r
-Advanced configuration\r
-----------------------\r
-\r
-@@4. "Use SRAM/BRAM savestates"\r
-This will automatically read/write SRAM (or BRAM for Sega/Mega CD) savestates for\r
-games which are using them. SRAM is saved whenever you enter the menu or exit the\r
-emulator.\r
-\r
-@@4. "Disable sprite limit"\r
-The MegaDrive/Genesis had a limit on how many sprites (usually smaller moving\r
-objects) can be displayed on single line. This option allows to disable that\r
-limit. Note that some games used this to hide unwanted things, so it is not\r
-always good to enable this option.\r
-\r
-@@4. "Emulate Z80"\r
-Enables emulation of Z80 chip, which was mostly used to drive the other sound chips.\r
-Some games do complex sync with it, so you must enable it even if you don't use\r
-sound to be able to play them.\r
-\r
-@@4. "Emulate YM2612 (FM)"\r
-This enables emulation of six-channel FM sound synthesizer chip, which was used to\r
-produce sound effects and music.\r
-\r
-@@4. "Emulate SN76496 (PSG)"\r
-This enables emulation of PSG (programmable sound generation) sound chip for\r
-additional effects.\r
-\r
-Note: if you change sound settings AFTER loading a ROM, you may need to reset\r
-game to get sound. This is because most games initialize sound chips on\r
-startup, and this data is lost when sound chips are being enabled/disabled.\r
-\r
-@@4. "gzip savestates"\r
-This will always apply gzip compression on your savestates, allowing you to\r
-save some space and load/save time.\r
-\r
-@@4. "Don't save last used ROM"\r
-This will disable writing last used ROM to config on exit (what might cause SD\r
-card corruption according to DaveC).\r
-\r
-@@4. "Disable idle loop patching"\r
-Idle loop patching is used to improve performance, but may cause compatibility\r
-problems in some rare cases. Try disabling this if your game has problems.\r
-\r
-@@4. "Disable frame limiter"\r
-This allows games to run faster then 50/60fps, useful for benchmarking.\r
-\r
-#ifdef GP2X\r
-@@4. "Use ARM940 core for sound"\r
-F100/F200: This option causes PicoDrive to use ARM940T core (GP2X's second CPU)\r
-for sound (i.e. to generate YM2612 samples) to improve performance noticeably.\r
-It also decodes MP3s in Sega/Mega CD mode.\r
-\r
-@@4. "RAM overclock"\r
-This overclocks the GP2X RAM chips for improved performance, but may cause\r
-instability. Keep it enabled if it doesn't cause problems.\r
-\r
-@@4. "MMU hack"\r
-Makes framebuffer bufferable for improved performance. There are no drawbacks\r
-so it should be left enabled.\r
-\r
-@@4. "SVP dynarec"\r
-This enables dynamic recompilation for SVP chip emulated for Virtua Racing game,\r
-what improves it's emulation performance greatly.\r
-#endif\r
-\r
-\r
-Key configuration\r
------------------\r
-\r
-Select "Configure controls" from the main menu. Then select "Player 1" and you will\r
-see two columns. The left column lists names of Genesis/MD controller buttons, and\r
-the right column your handheld ones, which are assigned.\r
-#ifndef PANDORA\r
-If you bind 2 different buttons to the same action, you will get a combo\r
-(which means that you will have to press both buttons for that action to happen).\r
-#endif\r
-\r
-There is also option to enable 6 button pad (will allow you to configure XYZ\r
-buttons), and an option to set turbo rate (in Hz) for turbo buttons.\r
-#ifndef UIQ\r
-\r
-\r
-Cheat support\r
--------------\r
-\r
-To use GG/patch codes, you must type them into your favorite text editor, one\r
-per line. Comments may follow code after a whitespace. Only GameGenie and\r
-Genecyst patch formats are supported.\r
-Examples:\r
-\r
-Genecyst patch (this example is for Sonic):\r
-\r
-00334A:0005 Start with five lives\r
-012D24:0001 Keep invincibility until end of stage\r
-009C76:5478 each ring worth 2\r
-009C76:5678 each ring worth 3\r
-...\r
-\r
-Game Genie patch (for Sonic 2):\r
-\r
-ACLA-ATD4 Hidden palace instead of death egg in level select\r
-...\r
-\r
-Both GG and patch codes can be mixed in one file.\r
-\r
-When the file is ready, name it just like your ROM file, but with additional\r
-.pat extension, making sure that case matches.\r
-\r
-Examples:\r
-\r
-ROM: Sonic.zip\r
-PATCH FILE: Sonic.zip.pat\r
-\r
-ROM: Sonic 2.bin\r
-PATCH FILE: Sonic 2.bin.pat\r
-\r
-Put the file into your ROMs directory. Then load the .pat file as you would\r
-a ROM. Then Cheat Menu Option should appear in main menu.\r
-#endif\r
-\r
-\r
-What is emulated?\r
------------------\r
-\r
-Genesis/MegaDrive:\r
-#ifdef PSP\r
-main 68k @ 7.6MHz: yes, FAME/C core\r
-z80 @ 3.6MHz: yes, CZ80 core\r
-#else\r
-main 68k @ 7.6MHz: yes, Cyclone core\r
-z80 @ 3.6MHz: yes, DrZ80 core\r
-#endif\r
-VDP: yes, except some quirks and modes not used by games\r
-YM2612 FM: yes, optimized MAME core\r
-SN76489 PSG: yes, MAME core\r
-SVP chip: yes! This is first emu to ever do this.\r
-Some in-cart mappers are also supported.\r
-\r
-Sega/Mega CD:\r
-#ifdef PSP\r
-another 68k @ 12.5MHz: yes, FAME/C too\r
-#else\r
-another 68k @ 12.5MHz: yes, Cyclone too\r
-#endif\r
-gfx scaling/rotation chip (custom ASIC): yes\r
-PCM sound source: yes\r
-CD-ROM controller: yes (mostly)\r
-bram (internal backup RAM): yes\r
-\r
-32X:\r
-2x SH2 @ 23MHz: yes, custom recompiler\r
-Super VDP: yes\r
-PWM: yes\r
-\r
-\r
-Problems / limitations\r
-----------------------\r
-\r
-#ifdef PSP\r
-* SVP emulation is terribly slow.\r
-#endif\r
-* Various VDP modes and quirks (window bug, scroll size 2, etc.) are not\r
- emulated, as very few games use this (if any at all).\r
-* The emulator is not 100% accurate, so some things may not work as expected.\r
-* The FM sound core doesn't support all features and has some accuracy issues.\r
-\r
-\r
-Credits\r
--------\r
-\r
-This emulator is made of the code from following people/projects:\r
-\r
-notaz\r
-GP2X, UIQ, PSP, Gizmondo ports, CPU core hacks, dynamic recompilers,\r
-lots of additional coding (see changelog).\r
-Homepage: http://notaz.gp2x.de/\r
-\r
-fDave\r
-one who started it all:\r
-Cyclone 68000 core and PicoDrive itself\r
-\r
-#ifdef PSP\r
-Chui\r
-FAME/C 68k interpreter core\r
-(based on C68K by Stephane Dallongeville)\r
-\r
-Stephane Dallongeville (written), NJ (optimized)\r
-CZ80 Z80 interpreter core\r
-\r
-#else\r
-Reesy & FluBBa\r
-DrZ80, the Z80 interpreter written in ARM assembly.\r
-Homepage: http://reesy.gp32x.de/\r
-\r
-#endif\r
-Tatsuyuki Satoh, Jarek Burczynski, MAME development\r
-software implementation of Yamaha FM sound generator\r
-\r
-MAME development\r
-Texas Instruments SN76489 / SN76496 programmable tone/noise generator\r
-Homepage: http://www.mame.net/\r
-\r
-Stephane Dallongeville\r
-Gens, MD/Mega CD/32X emulator. Most Sega CD code is based on this emu.\r
-#ifdef PSP\r
-\r
-people @ ps2dev.org forums / PSPSDK crew\r
-libaudiocodec code (by cooleyes)\r
-other sample code\r
-#else\r
-\r
-Helix community\r
-Helix mp3 decoder\r
-#endif\r
-\r
-\r
-Additional thanks\r
------------------\r
-\r
-* Charles MacDonald (http://cgfm2.emuviews.com/) for old but still very useful\r
- info about genesis hardware.\r
-* Steve Snake for all that he has done for Genesis emulation scene.\r
-* Tasco Deluxe for his reverse engineering work on SVP and some mappers.\r
-* Bart Trzynadlowski for his SSFII and 68000 docs.\r
-* Haze for his research (http://haze.mameworld.info).\r
-* Lordus, Exophase and Rokas for various ideas.\r
-* Nemesis for his YM2612 research.\r
-* Many posters at spritesmind.net forums for valuable information.\r
-* Mark and Jean-loup for zlib library.\r
-* ketchupgun for the skin.\r
-#ifdef GP2X\r
-* rlyeh and all the other people behind the minimal library.\r
-* Squidge for his famous squidgehack(tm).\r
-* Dzz for his ARM940 sample code.\r
-* A_SN for his gamma code.\r
-* craigix for supplying the GP2X hardware and making this port possible.\r
-* Alex for the icon.\r
-* All the people from gp32x boards for their support.\r
-#endif\r
-#ifdef GIZ\r
-* Kingcdr's for the SDK and Reesy for the DLL and sound code.\r
-* jens.l for supplying the Gizmondo hardware and making this port possible.\r
-#endif\r
-#ifdef UIQ\r
-* Peter van Sebille for his various open-source Symbian projects to learn from.\r
-* Steve Fischer for his open-source Motorola projects.\r
-* The development team behind "Symbian GCC Improvement Project"\r
- (http://www.inf.u-szeged.hu/symbian-gcc/) for their updated pre-SymbianOS9\r
- compile tools.\r
-* AnotherGuest for all his Symbian stuff and support.\r
-#endif\r
-* Inder for some graphics.\r
-* Anyone else I forgot. You know who you are.\r
-\r
-\r
-Changelog\r
----------\r
-1.80\r
- + Added Caanoo support. Now the GP2X binary supports GP2X F100/F200, Wiz\r
- and Caanoo. Lots of internal refactoring to support this.\r
- + Enabled 32X and SMS code. It's still unfinished but better release something\r
- now than wait even more (it has been in development for more then a year now\r
- due to various other projects or simply lack of time).\r
- + Pandora: added hardware scaler support, including ability to resize the\r
- layer and control filtering.\r
- + GP2X: Added basic line-doubling vertical scaling option.\r
- * Changed the way keys are bound, no need to unbind old one any more.\r
- * Handle MP3s with ID3 tags better (some MP3s with ID3 did not play).\r
- * Improved shadow/hilight color levels.\r
- * Fixed broken cheat support.\r
-\r
-1.80beta2\r
- * Pandora: updated documentation.\r
-\r
-1.80beta1\r
- + Added pandora port.\r
- * Internal refactoring for 32x/SMS support.\r
- * Move mapper database to external file.\r
- + Added preliminary SMS emulation.\r
- + Added emulation of 32x peripherals including VDP. More work is needed here.\r
- + ARM: Added new SH2 recompiler for 32x. Some unification with SVP one.\r
- - Disabled most of the above bacause I'm not yet happy with the results.\r
-\r
-1.56\r
- * Changed sync in Sega CD emulation again. Should fix games that\r
- broke after changes in 1.51a.\r
- * Fixed default keys rebinding when they shouldn't.\r
- * Fixed sram being loaded from wrong game.\r
- * Emu should no longer hang shortly after using fast-forward.\r
- * Fixed save states sometimes no longer showing up in save state menu.\r
- * ARM: some asm code refactoring for slight speed improvement.\r
-\r
-1.55\r
- + Added Wiz support. Now the same GP2X binary supports F100/F200 and Wiz.\r
- * Changed shadow/hilight handling a bit, fixes some effects in Pirates! Gold.\r
- * Complete input code rewrite. This fixes some limitations like not allowing\r
- to control both players using single input device. It also allows to use\r
- more devices (like keyboards) on Linux based devices.\r
- * Options menu has been reordered, "restore defaults" option added.\r
-\r
-1.51b\r
- * Fixed a crash when uncompressed savestate is loaded.\r
- * Fixed an idle loop detection related hanging problem.\r
- * PSP: fixed another palette related regression.\r
- * UIQ3: updated frontend for the latest emu core.\r
-\r
-1.51a\r
- * Fixed a sync problem between main and sub 68k. Should fix the hanging\r
- problem for some games.\r
- * ARM: fixed a crash when CD savestate is loaded just after loading ROM.\r
-\r
-1.51\r
- * Improved bin_to_cso_mp3 tool, it should no longer complain about\r
- missing lame.exe even if it's in working dir.\r
- * Fixed a regression from 1.50, which caused slowdowns in Final Fight.\r
- * Fixed some regressions from 1.50 related to sprite limit and palette\r
- handling (caused graphical glitches in some games).\r
- + Added ABC turbo actions to key config.\r
- * Some other minor adjustments.\r
-\r
-1.50\r
- + Added some basic support for Sega Pico, a MegaDrive-based toy.\r
- + Added proper support for cue/bin images, including cdda playback.\r
- .cue sheets with iso/cso/mp3/wav files listed in them are now\r
- supported too (but 44kHz restriction still applies).\r
- + Added bin_to_cso_mp3 tool, based on Exophase's bin_to_iso_ogg.\r
- The tool can convert .cue/.bin Sega CD images to .cso/.mp3.\r
- * Greatly improved Sega CD load times.\r
- * Changed how scheduling between 68k and z80 is handled. Improves\r
- performance for some games. Credits to Lordus for the idea.\r
- * YM2612 state was not 100% saved, this should be better now.\r
- * Improved renderer performance for shadow/hilight mode.\r
- * Added a hack for YM2612 frequency overflow issue (bleep noises\r
- in Shaq Fu, Spider-Man - The Animated Series (intro music), etc.)\r
- Credits to Nemesis @ spritesmind forum. Works only if sound rate\r
- is set to 44kHz.\r
- + Implemented some sprite rendering improvements, as suggested by\r
- Exophase. Games with lots of sprites now perform better.\r
- + Added better idle loop detection, based on Lordus' idea again.\r
- - "accurate timing" option removed, as disabling it no longer\r
- improves performance.\r
- - "accurate sprites" was removed too, the new sprite code can\r
- properly handle sprite priorities in all cases.\r
- * Timers adjusted again.\r
- * Improved .smd detection code.\r
- * ARM: fixed a bug in DrZ80 core, which could cause problems in\r
- some rare cases.\r
- * ARM: fixed a problem of occasional clicks on MP3 music start.\r
- * Minor general optimizations and menu improvements.\r
- * Fixed a bug in Sega CD savestate loader, where the game would\r
- sometimes crash after load.\r
- * Fixed a crash of games using eeprom (introduced in 1.40b).\r
- * PSP: fixed suspend/resume (hopefully for real).\r
-\r
-1.40c\r
- * Fixed a problem with sound in Marble Madness.\r
- * GP2X: Fixed minor problem with key config.\r
-\r
-1.40b\r
- * Fixed sprite masking code. Thanks to Lordus for explaining how it works.\r
- + Added "disable sprite limit" option.\r
- + PSP: added black level adjustment to display options.\r
- * Changed reset to act as 'soft' reset.\r
- + Added detection for Puggsy (it doesn't really have sram).\r
- * Some small timing adjustments.\r
-\r
-1.40a\r
- * GP2X: Fixed a binding problem with up and down keys.\r
- * Default game config no longer overrides global user config.\r
-\r
-1.40\r
- + Added support for SVP (Sega Virtua Processor) to emulate Virtua Racing,\r
- wrote ARM recompiler and some HLE code for VR. Credits to Exophase and\r
- Rokas for various ideas.\r
- * Changed config file format, files are now human-readable. Game specific\r
- configs are now held in single file (but old game config files are still\r
- read when new one is missing).\r
- * Fixed a bug where some key combos didn't work as expected.\r
- * Fixed a regression in renderer (ARM ports only, some graphic glitches in\r
- rare cases).\r
- * Adjusted fast renderer to work with more games, including VR.\r
- * Fixed a problem where SegaCD RAM cart data was getting lost on reset.\r
- * GP2X: Greatly reduced SegaCD FMV game slowdowns by disabling read-ahead\r
- in the Linux kernel and C library (thanks to Rokas and Exophase for ideas\r
- again). Be sure to keep "ReadAhead buffer" OFF to avoid slowdowns.\r
- + PicoDrive now comes with a game config file for some games which need\r
- special settings, so they should now work out-of-the-box. More games will\r
- be added with later updates.\r
- + GP2X: Files now can be deleted by pressing A+SELECT in the file browser.\r
-\r
-1.35b\r
- * PSP: mp3 code should no longer fail on 1.5 firmware.\r
- + PSP: added gamma adjustment option.\r
- + Added .cso ISO format support. Useful for non-FMV games.\r
- * It is now possile to force a region after the ROM is loaded.\r
- * Fixed a sram bug in memhandlers (fixes Shining in the Darkness saves).\r
- * PSP: fixed another bug in memhanlers, which crashed the emu for some games\r
- (like NBA Jam and NHL 9x).\r
- + PSP: added suspend/resume handling for Sega CD games.\r
- + GP2X: added additional low volume levels for my late-night gaming sessions\r
- (in stereo mode only).\r
- + GP2X: added "fast forward" action in key config. Not recommended to use for\r
- Sega CD, may case problems there.\r
- * Some other small tweaks I forgot about.\r
-\r
-1.35a\r
- * PSP: fixed a bug which prevented to load any ROMs after testing the BIOS.\r
- * PSP: fixed incorrect CZ80 memory map setup, which caused Z80 crashes and\r
- graphics corruption in EU Mega CD model1 BIOS menus.\r
- + PSP: added additional "set to 4:3 scaled" display option for convenience.\r
- + PSP: Added an option to disable frame limitter (works only with non-auto frameskip).\r
-\r
-1.35\r
- + PSP port added. Lots of new code for it. Integrated modified FAME/C, CZ80 cores.\r
- + Some minor generic optimizations.\r
- * Patched some code which was crashing under PSP, but was working in GP2X/Giz\r
- (although it should have crashed there too).\r
- * Readme updated.\r
-\r
-1.34\r
- + Gizmondo port added.\r
- + Some new optimizations in memory handlers, and for shadow/hilight mode.\r
- + Added some hacks to make more games work without enabling "accurate timing".\r
- * Adjusted timing for "accurate timing" mode and added preliminary VDP FIFO\r
- emulation. Fixes Double Dragon 2, tearing in Chaos Engine and some other games.\r
- * Fixed a few games not having sound at startup.\r
- * Updated serial EEPROM code to support more games. Thanks to EkeEke for\r
- providing info about additional EEPROM types and game mappers.\r
- * The above change fixed hang of NBA Jam.\r
- * Minor adjustments to control configurator.\r
-\r
-1.33\r
- * Updated Cyclone core to 0.0088.\r
- + Added A r k's usbjoy fix.\r
- + Added "perfect vsync" option, which adjusts GP2X LCD refresh rate and syncs\r
- emulation to it to eliminate tearing and ensure smoothest scrolling possible.\r
- + Added an option to use A_SN's gamma curve for gamma correction (improves dark\r
- and bright color display for mk2s).\r
- * Sometimes stray sounds were played after loading a savestate. Fixed.\r
- * Fixed a problem where >6MB mp3s were corrupted in memory (sound glitches in\r
- Snatcher).\r
- * PD no longer overwrites video player code in memory, video player now can be\r
- used after exiting PicoDrive.\r
- * Fixed a bug which was causing Sonic 3 code to deadlock in some rare conditions\r
- if "accurate timing" was not enabled.\r
- * Fixed support for large hacked ROMs like "Ultimate Mortal Kombat Trilogy".\r
- Upto 10MB hacked ROMs are supported now.\r
- + Config profiles added (press left/right when saving config).\r
- * Changed key configuration behavior to the one from gpfce (should be more\r
- intuitive).\r
- + Added some skinning capabilities to the menu system with default skin by\r
- ketchupgun. Delete skin directory if you want old behaviour.\r
- * Some other little tweaks I forgot about.\r
-\r
-1.32\r
- + Added some new scaling options.\r
- + Added ability to reload CD images while game is running (needed for games\r
- with multiple CDs, like Night Trap).\r
- + Added RAM cart emulation.\r
- * Fixed DMA timing emulation (caused lock-ups for some genesis games).\r
- * Idle loop detection was picking up wrong code and causing glitches, fixed.\r
- * The ym2612 code on 940 now can handle multiple updates per frame\r
- (fixes Thunger Force III "seiren" level drums for example).\r
- * Memory handlers were ignoring some writes to PSG chip, fixed (missing sounds in\r
- Popful Mail, Silpheed).\r
- * Improved z80 timing, should fix some sound problems.\r
- * Fixed a bug with sram register (fixes Phantasy Star 4).\r
- * ROM loader was incorrectly identifying some ROMs as invalid. Fixed.\r
- * Added code for PRG ram write protection register (Dungeon Explorer).\r
- * The memory mode register change in 1.31 was unsafe and caused some glitches in\r
- AH-3 Thunderstrike. Fixed.\r
- * Fixed a file descriptor leak.\r
- * Updated documentation, added Gmenu2x manual.\r
-\r
-1.31\r
- * Changed the way memory mode register is read (fixes Lunar 2, broken in 1.30).\r
- * Fixed TAS opcode on sub-68k side (fixes Batman games).\r
- * File browser now filters out mp3s, saves and some other files, which are not ROMS.\r
-\r
-1.30\r
- + ISO files now can be zipped. Note that this causes VERY long loading times.\r
- + Added data pre-buffering support, this allows to reduce frequency of short pauses\r
- in FMV games (caused by SD access), but makes those pauses longer.\r
- * Fixed PCM DMA transfers (intro FMV in Popful Mail).\r
- + Properly implemented "decode" data transformation (Jaguar XJ220).\r
- * Integrated "better sync" code into cyclone code, what made this mode much faster.\r
- * Fixed a bug related to game specific config saving.\r
- * Frameskipper was skipping sound processing, what caused some audio desyncs. Fixed.\r
- * Fixed reset not working for some games.\r
- + New assembly optimized memory handlers for CD (gives at least a few fps).\r
- Also re-enabled all optimizations from 0.964 release.\r
- + New idle-loop detection code for sub-68k. Speeds up at least a few games.\r
-\r
-1.201\r
- + Added basic cheat support (GameGenie and Genecyst patches).\r
-\r
-1.20\r
- * Fixed a long-standing problem in audio mixing code which caused slight distortions\r
- at lower sample rates.\r
- * Changed the way 920 and 940 communicates (again), should be more reliable and give\r
- slight performance increase.\r
- * Some optimizations in audio mixing code.\r
- * Some menu changes (background added, smaller font in ROM browser, savestate loader\r
- now can select slots).\r
- + 1M mode DMA transfers implemented (used by FMV games like Night Trap and Sewer Shark).\r
- + Games now can run code from WORD RAM in 1M mode (fixes Adventures of Willy Beamish).\r
- + "Cell arrange" address mapping is now emulated (Heart of the alien).\r
- + "Color numeric operation" is now emulated (text in Lunar 2, Silpheed intro graphics).\r
- + "Better sync" option added (prevents some games from hanging).\r
-\r
-1.14\r
- + Region autodetection now can be customized.\r
- * When CDDA music tracks changed, old buffer contents were incorrectly played. Fixed.\r
- * BRAM is now automatically formatted (no need to enter BIOS menu and format any more).\r
- * Games now can be reset, CDDA music no longer breaks after loading another ISO.\r
- * Fixed a race condition between 920 and 940 which sometimes caused CDDA music not to play.\r
- + Savestates implemented for Sega/Mega CD.\r
- + PCM sound added.\r
- * Some mixer code rewritten in asm. 22kHz and 11kHz sound rates are now supported in\r
- Mega CD mode (but mp3s must still be 44kHz stereo).\r
- + Timer emulation added.\r
- * CDC DMA tansfers fixed. Snatcher and probably some more games now boot.\r
- * 2M word RAM -> VDP transfers fixed, no more corruption in Ecco and some other games.\r
-\r
-1.10\r
- + GP2X: Added experimental Sega CD support.\r
- + GP2X: Added partial gmv movie playback support.\r
-\r
-0.964\r
- * GP2X: Fixed a sound buffer underflow issue on lower sample rate modes, which was\r
- happening for NTSC games and causing sound clicks.\r
- * GP2X: Redone key config to better support USB joysticks (now multiple joysticks\r
- should be useable and configurable).\r
- + GP2X: Added save confirmation option.\r
- + GP2X: Added 940 CPU crash detection.\r
- + ALL: UIQ3 port added.\r
-\r
-0.963\r
- * GP2X: Gamma-reset-on-entering-menu bug fixed.\r
- * GP2X: Recompiled PicoDrive with gcc profiling option set as described here:\r
- http://www.gp32x.com/board/index.php?showtopic=28490\r
-\r
-0.962\r
- * GP2X: Fixed an issue with incorrect sounds in some games when dualcore operation\r
- was enabled (for example punch sound in SOR).\r
- * GP2X: Limited max volume to 90, because higher values often cause distortions.\r
- * GP2X: Fixed a bug with lower res scaling.\r
- * GP2X: Gamma is now reset on exit.\r
-\r
-0.96\r
- * ALL: Severely optimized MAME's YM2612 core, part of it is now rewritten in asm.\r
- + GP2X: The YM2612's code now can be run in GP2X's ARM940T CPU, what causes large\r
- performance increase.\r
- * ALL: Accurate renderers are slightly faster now.\r
- + GP2X: Using quadruple buffering instead of doublebuffer now, also updated\r
- framelimitter, this should eliminate some scrolling and tearing problems.\r
- * GP2X: Fixed some flickering issues of 8bit accurate renderer.\r
- + GP2X: craigix's RAM timings now can be enabled in the menu (see advanced options).\r
- + GP2X: Added ability to save config for specific games only.\r
- + GP2X: Gamma control added (using GP2X's hardware capabilities for this).\r
- * GP2X: Volume keys are now configurable.\r
- + GP2X: GnoStiC added USB joystick support, I made it possible to use it for\r
- player 2 control (currently untested).\r
- * GP2X: squidgehack is now applied through kernel module (cleaner way).\r
-\r
-0.95\r
- * ALL: Fixed a bug in sprite renderer which was causing slowdowns for some games.\r
- + GP2X: Added command line support\r
- + GP2X: Added optional hardware scaling for lower-res games like Shining Force.\r
- * ALL: Sound chips are now sampled 2 times per frame. This fixed some games which\r
- had missing sounds (Vectorman 2 1st level, Thunder Force 3 water level,\r
- etc.).\r
- + ALL: Added another accurate 8-bit renderer which is slightly faster and made it\r
- default.\r
-\r
-0.945\r
- + GP2X: Added frame limiter for frameskipped modes.\r
- * GP2X: Increased brightness a bit (unused pixel bits now also contain data).\r
- * GP2X: Suidgehack was not applied correctly (was applied before allocating some\r
- high memory and had no effect).\r
-\r
-0.94\r
- + Added GP2X port.\r
- * Improved interrupt timing, Mazin Saga and Burning Force now works.\r
- * Rewritten renderer code to better suit GP2X, should be faster on other\r
- ports too.\r
- + Added support for banking used by 12-in-1 and 4-in-1 ROMs (thanks Haze).\r
- + Added some protection device faking, used by some unlicensed games like\r
- Super Bubble Bobble, King of Fighters, Elf Wor, ... (thanks to Haze again)\r
- + Added primitive Virtua Racing SVP faking, so menus can be seen now.\r
-\r
-0.93\r
- * Fixed a problem with P900/P910 key configuration in FC mode.\r
- * Improved shadow/hilight mode emulation. Still not perfect, but should be\r
- enough for most games.\r
- + Save state slots added.\r
- + Region selector added.\r
-\r
-0.92\r
- VDP changes:\r
- * VDP emulation is now more accurate (fixes flickering in Chase HQ II,\r
- Super Hang-On and some other problems in other games).\r
- * HV counter emulation is now much more accurate. Fixes the Asterix games,\r
- line in Road Rash 3, etc.\r
- * Minor sprite and layer scroll masking bugs fixed.\r
- + Added partial interlace mode renderer (Sonic 2 vs mode)\r
- * Fixed a crash in both renderers when certain size window layers were used.\r
- + Added emulation of shadow/hilight operator sprites. Other shadow/hilight\r
- effects are still unemulated.\r
- + Sprite emulation is more accurate, sprite limit is emulated.\r
- + Added "accurate sprites" option, which always draws sprites in correct\r
- order and emulates sprite collision bit, but is significantly slower.\r
-\r
- Emulation changes:\r
- * Improved interrupt handling, added deferred interrupt emulation\r
- (Lemmings, etc).\r
- + Added serial EEPROM SRAM support (Wonder Boy in Monster World,\r
- Megaman - The Wily Wars and many EA sports games like NBA Jam).\r
- + Implemented ROM banking for Super Street Fighter II - The New Challengers\r
- * Updated to the latest version of DrZ80 core, integrated memory handlers\r
- in it for better performance. A noticeable performance increase, but save\r
- states may not work from the previous version (you can only use them with\r
- sound disabled in that case).\r
- + SRAM word read handler was using incorrect byte order, fixed.\r
-\r
- Changes in Cyclone 0.0086:\r
- + Added missing CHK opcode handler (used by SeaQuest DSV).\r
- + Added missing TAS opcode handler (Gargoyles,Bubba N Stix,...). As in real genesis,\r
- memory write-back phase is ignored (but can be enabled in config.h if needed).\r
- + Added missing NBCD and TRAPV opcode handlers.\r
- + Added missing addressing mode for CMP/EOR.\r
- + Added some minor optimizations.\r
- - Removed 216 handlers for 2927 opcodes which were generated for invalid addressing modes.\r
- + Fixed flags for ASL, NEG, NEGX, DIVU, ADDX, SUBX, ROXR.\r
- + Bugs fixed in MOVEP, LINK, ADDQ, DIVS handlers.\r
- * Undocumented flags for CHK, ABCD, SBCD and NBCD are now emulated the same way as in Musashi.\r
- + Added Uninitialized Interrupt emulation.\r
- + Altered timing for about half of opcodes to match Musashi's.\r
-\r
-0.80\r
- * Nearly all VDP code was rewritten in ARM asm. Gives ~10-25% performance\r
- increase (depends on game).\r
- * Optimized 32-column renderer not to render tiles offscreen, games which\r
- use 32-column display (like Shining Force) run ~50% faster.\r
- + Added new "Alternative renderer", which gives another ~30-45% performance\r
- increase (in addition to mentioned above), but works only with some games,\r
- because it is missing some features (it uses tile-based rendering\r
- instead of default line-based and disables H-ints).\r
- + Added "fit2" display mode for all FC gamers. It always uses 208x146 for\r
- P800 and 208x208 for all other phones.\r
- + Added volume control for Motorolas (experimental).\r
-\r
- VDP changes:\r
- + Added support for vertical window (used by Vapor Trail, Mercs, GRIND\r
- Stormer and others).\r
- + Added sprite masking (hiding), adds some speed.\r
- + Added preliminary H counter emulation. Comix Zone and Sonic 3D Blast\r
- special stage are now playable.\r
- + Added column based vertical scrolling (Gunstar Heroes battleship level,\r
- Sonic and Knuckles lava boss, etc).\r
-\r
- Emulation changes:\r
- + Re-added and improved Z80 faking when Z80 is disabled. Many games now can\r
- be played without enabling Z80 (Lost Vikings, Syndicate, etc), but some\r
- still need it (International Superstar Soccer Deluxe).\r
- * Improved ym2612 timers, Outrun music plays at correct speed, voices in\r
- Earthworm Jim play better, more games play sound.\r
- * I/O registers now remember their values (needed for Pirates! Gold)\r
- + Added support for 6 button pad.\r
-\r
- Changes in Cyclone 0.0083wip:\r
- + Added missing CHK opcode (used by SeaQuest DSV).\r
- + Added missing TAS opcode (Gargoyles). As in real genesis, write-back phase\r
- is ignored (but is enabled for other systems).\r
-\r
- Backported stuff from Snes9x:\r
- * Fixed Pxxx jog up/down which were not working in game.\r
- + Added an option to gzip save states to save space.\r
- + The emulator now pauses whenever it is loosing focus, so it will now pause\r
- when alarm/ponecall/battery low/... windows come up.\r
- - Removed 'pause on phonecall' feature, as it is no longer needed.\r
- + Video fix for asian A1000s.\r
-\r
-0.70\r
- * Started using tools from "Symbian GCC Improvement Project", which give\r
- considerable speed increase (~4fps in "center 90" mode).\r
- * Rewrote some drawing routines in ARM assembly (gives ~6 more fps in\r
- "center 90" mode).\r
- * Minor improvement to 0 and 180 "fit" modes. Now they look slightly better\r
- and are faster.\r
- * Minor stability improvements (emulator is less likely to crash).\r
- + Added some background for OSD text for better readability.\r
- + Added Pal/NTSC detection. This is needed for proper sound speed.\r
- + Implemented Reesy's DrZ80 Z80 emu. Made some changes to it with hope to make\r
- it faster.\r
- + Implemented ym2612 emu from the MAME project. Runs well but sometimes sounds\r
- a bit weird. Could be a little faster, so made some changes too.\r
- + Implemented SN76489 emu from the MAME project.\r
- + Added two separate sound output methods (mediaserver and cmaudiofb) with\r
- autodetection (needs testing).\r
- * Fixed VDP DMA fill emulation (as described in Charles MacDonald's docs),\r
- fixes Contra and some other games.\r
-\r
-0.301\r
- Launcher:\r
- * Launcher now starts emulation process from current directory,\r
- not from hardcoded paths.\r
- * Improved 'pause on call' feature, should hopefully work with Motorola phones.\r
-\r
-0.30\r
- Initial release.\r
-\r
-\r
-Disclaimer\r
-----------\r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" \r
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE \r
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE \r
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR \r
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF \r
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS \r
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN \r
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \r
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \r
-POSSIBILITY OF SUCH DAMAGE. \r
-\r
-SEGA/Genesis/MegaDrive/SEGA-CD/Mega-CD/32X are trademarks of\r
-Sega Enterprises Ltd.\r
-\r
+++ /dev/null
-// (c) Copyright 2006-2009 notaz, All rights reserved.\r
-// Free for non-commercial use.\r
-\r
-// For commercial use, separate licencing terms must be obtained.\r
-\r
-void bgr444_to_rgb32(void *to, void *from);\r
-void bgr444_to_rgb32_sh(void *to, void *from);\r
-\r
-void vidcpy_m2(void *dest, void *src, int m32col, int with_32c_border);\r
-void vidcpy_m2_rot(void *dest, void *src, int m32col, int with_32c_border);\r
-void spend_cycles(int c); // utility\r
-\r
-void rotated_blit8 (void *dst, void *linesx4, int y, int is_32col);\r
-void rotated_blit16(void *dst, void *linesx4, int y, int is_32col);\r
+++ /dev/null
-@ vim:filetype=armasm\r
-@ some color conversion and blitting routines\r
-\r
-@ (c) Copyright 2006, 2007 notaz\r
-@ All Rights Reserved\r
-\r
-@ vim:filetype=armasm\r
-\r
-.text\r
-.align 4\r
-\r
-@ Convert 0000bbb0 ggg0rrr0 0000bbb0 ggg0rrr0\r
-@ to 00000000 rrr00000 ggg00000 bbb00000 ...\r
-\r
-@ lr = 0x00e000e0, out: r3=lower_pix, r2=higher_pix; trashes rin\r
-.macro convRGB32_2 rin sh=0\r
- and r2, lr, \rin, lsr #4 @ blue\r
- and r3, \rin, lr\r
- orr r2, r2, r3, lsl #8 @ g0b0g0b0\r
-\r
- mov r3, r2, lsl #16 @ g0b00000\r
- and \rin,lr, \rin, ror #12 @ 00r000r0 (reversed)\r
- orr r3, r3, \rin, lsr #16 @ g0b000r0\r
-.if \sh == 1\r
- mov r3, r3, ror #17 @ shadow mode\r
-.elseif \sh == 2\r
- adds r3, r3, #0x40000000 @ green\r
- orrcs r3, r3, #0xe0000000\r
- mov r3, r3, ror #8\r
- adds r3, r3, #0x40000000\r
- orrcs r3, r3, #0xe0000000\r
- mov r3, r3, ror #16\r
- adds r3, r3, #0x40000000\r
- orrcs r3, r3, #0xe0000000\r
- mov r3, r3, ror #24\r
-.else\r
- mov r3, r3, ror #16 @ r3=low\r
-.endif\r
-\r
- orr r3, r3, r3, lsr #3\r
- str r3, [r0], #4\r
-\r
- mov r2, r2, lsr #16\r
- orr r2, r2, \rin, lsl #16\r
-.if \sh == 1\r
- mov r2, r2, lsr #1\r
-.elseif \sh == 2\r
- mov r2, r2, ror #8\r
- adds r2, r2, #0x40000000 @ blue\r
- orrcs r2, r2, #0xe0000000\r
- mov r2, r2, ror #8\r
- adds r2, r2, #0x40000000\r
- orrcs r2, r2, #0xe0000000\r
- mov r2, r2, ror #8\r
- adds r2, r2, #0x40000000\r
- orrcs r2, r2, #0xe0000000\r
- mov r2, r2, ror #8\r
-.endif\r
-\r
- orr r2, r2, r2, lsr #3\r
-.if \sh == 1\r
- str r2, [r0, #0x40*2*4]\r
-.endif\r
- str r2, [r0], #4\r
-.endm\r
-\r
-\r
-.global bgr444_to_rgb32 @ void *to, void *from\r
-\r
-bgr444_to_rgb32:\r
- stmfd sp!, {r4-r7,lr}\r
-\r
- mov r12, #0x40>>3 @ repeats\r
- mov lr, #0x00e00000\r
- orr lr, lr, #0x00e0\r
-\r
-.loopRGB32:\r
- subs r12, r12, #1\r
-\r
- ldmia r1!, {r4-r7}\r
- convRGB32_2 r4\r
- convRGB32_2 r5\r
- convRGB32_2 r6\r
- convRGB32_2 r7\r
- bgt .loopRGB32\r
-\r
- ldmfd sp!, {r4-r7,pc}\r
-\r
-\r
-.global bgr444_to_rgb32_sh @ void *to, void *from\r
-\r
-bgr444_to_rgb32_sh:\r
- stmfd sp!, {r4-r7,lr}\r
-\r
- mov r12, #0x40>>3 @ repeats\r
- add r0, r0, #0x40*4\r
- mov lr, #0x00e00000\r
- orr lr, lr, #0x00e0\r
-\r
-.loopRGB32sh:\r
- subs r12, r12, #1\r
-\r
- ldmia r1!, {r4-r7}\r
- convRGB32_2 r4, 1\r
- convRGB32_2 r5, 1\r
- convRGB32_2 r6, 1\r
- convRGB32_2 r7, 1\r
- bgt .loopRGB32sh\r
-\r
- mov r12, #0x40>>3 @ repeats\r
- sub r1, r1, #0x40*2\r
-\r
-.loopRGB32hi:\r
- ldmia r1!, {r4-r7}\r
- convRGB32_2 r4, 2\r
- convRGB32_2 r5, 2\r
- convRGB32_2 r6, 2\r
- convRGB32_2 r7, 2\r
-\r
- subs r12, r12, #1\r
- bgt .loopRGB32hi\r
-\r
- ldmfd sp!, {r4-r7,lr}\r
- bx lr\r
-\r
-\r
-@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
-\r
-\r
-@ mode2 blitter\r
-.global vidcpy_m2 @ void *dest, void *src, int m32col, int with_32c_border\r
-vidcpy_m2:\r
- stmfd sp!, {r4-r6,lr}\r
-\r
- mov r12, #224 @ lines\r
- add r0, r0, #320*8\r
- add r1, r1, #8\r
- mov lr, #0\r
-\r
- tst r2, r2\r
- movne lr, #64\r
- tstne r3, r3\r
- addne r0, r0, #32\r
-\r
-vidCpyM2_loop_out:\r
- mov r6, #10\r
- sub r6, r6, lr, lsr #5 @ -= 2 in 32col mode\r
-vidCpyM2_loop:\r
- subs r6, r6, #1\r
- ldmia r1!, {r2-r5}\r
- stmia r0!, {r2-r5}\r
- ldmia r1!, {r2-r5}\r
- stmia r0!, {r2-r5}\r
- bne vidCpyM2_loop\r
-\r
- subs r12,r12,#1\r
- add r0, r0, lr\r
- add r1, r1, #8\r
- add r1, r1, lr\r
- bne vidCpyM2_loop_out\r
-\r
- ldmfd sp!, {r4-r6,pc}\r
-\r
-\r
-.global vidcpy_m2_rot @ void *dest, void *src, int m32col, int with_32c_border\r
-vidcpy_m2_rot:\r
- stmfd sp!,{r4-r8,lr}\r
- add r1, r1, #8\r
- tst r2, r2\r
- subne r1, r1, #32 @ adjust\r
-\r
- mov r4, r0\r
- mov r5, r1\r
- mov r6, r2\r
- mov r7, #8+4\r
-\r
-vidcpy_m2_rot_loop:\r
- @ a bit lame but oh well..\r
- mov r0, r4\r
- mov r1, r5\r
- mov r2, r7\r
- mov r3, r6\r
- mov r8, #328\r
- adr lr, after_rot_blit8\r
- stmfd sp!,{r4-r8,lr}\r
- b rotated_blit8_2\r
-\r
-after_rot_blit8:\r
- add r5, r5, #328*4\r
- add r7, r7, #4\r
- cmp r7, #224+8+4\r
- ldmgefd sp!,{r4-r8,pc}\r
- b vidcpy_m2_rot_loop\r
-\r
-\r
-.global rotated_blit8 @ void *dst, void *linesx4, u32 y, int is_32col\r
-rotated_blit8:\r
- stmfd sp!,{r4-r8,lr}\r
- mov r8, #320\r
-\r
-rotated_blit8_2:\r
- add r0, r0, #(240*320)\r
- sub r0, r0, #(240+4) @ y starts from 4\r
- add r0, r0, r2\r
-\r
- tst r3, r3\r
- subne r0, r0, #(240*32)\r
- addne r1, r1, #32\r
- movne lr, #256/4\r
- moveq lr, #320/4\r
-\r
-rotated_blit_loop8:\r
- mov r6, r1\r
- ldr r2, [r6], r8\r
- ldr r3, [r6], r8\r
- ldr r4, [r6], r8\r
- ldr r5, [r6], r8\r
-\r
- mov r6, r2, lsl #24\r
- mov r6, r6, lsr #8\r
- orr r6, r6, r3, lsl #24\r
- mov r6, r6, lsr #8\r
- orr r6, r6, r4, lsl #24\r
- mov r6, r6, lsr #8\r
- orr r6, r6, r5, lsl #24\r
- str r6, [r0], #-240\r
-\r
- and r6, r3, #0xff00\r
- and r7, r2, #0xff00\r
- orr r6, r6, r7, lsr #8\r
- and r7, r4, #0xff00\r
- orr r6, r6, r7, lsl #8\r
- and r7, r5, #0xff00\r
- orr r6, r6, r7, lsl #16\r
- str r6, [r0], #-240\r
-\r
- and r6, r4, #0xff0000\r
- and r7, r2, #0xff0000\r
- orr r6, r6, r7, lsr #16\r
- and r7, r3, #0xff0000\r
- orr r6, r6, r7, lsr #8\r
- and r7, r5, #0xff0000\r
- orr r6, r6, r7, lsl #8\r
- str r6, [r0], #-240\r
-\r
- mov r6, r5, lsr #24\r
- mov r6, r6, lsl #8\r
- orr r6, r6, r4, lsr #24\r
- mov r6, r6, lsl #8\r
- orr r6, r6, r3, lsr #24\r
- mov r6, r6, lsl #8\r
- orr r6, r6, r2, lsr #24\r
- str r6, [r0], #-240\r
-\r
- subs lr, lr, #1\r
- add r1, r1, #4\r
- bne rotated_blit_loop8\r
-\r
- ldmfd sp!,{r4-r8,pc}\r
-\r
-\r
-@ input: r2-r5\r
-@ output: r7,r8\r
-@ trash: r6\r
-.macro rb_line_low\r
- mov r6, r2, lsl #16\r
- mov r7, r3, lsl #16\r
- orr r7, r7, r6, lsr #16\r
- mov r6, r4, lsl #16\r
- mov r8, r5, lsl #16\r
- orr r8, r8, r6, lsr #16\r
-.endm\r
-\r
-.macro rb_line_hi\r
- mov r6, r2, lsr #16\r
- mov r7, r3, lsr #16\r
- orr r7, r6, r7, lsl #16\r
- mov r6, r4, lsr #16\r
- mov r8, r5, lsr #16\r
- orr r8, r6, r8, lsl #16\r
-.endm\r
-\r
-.global rotated_blit16 @ void *dst, void *linesx4, u32 y, int is_32col\r
-rotated_blit16:\r
- stmfd sp!,{r4-r8,lr}\r
-\r
- add r0, r0, #(240*320)*2\r
- sub r0, r0, #(240+4)*2 @ y starts from 4\r
- add r0, r0, r2, lsl #1\r
-\r
- tst r3, r3\r
- subne r0, r0, #(240*32)*2\r
- addne r1, r1, #32*2\r
- movne lr, #256/4\r
- moveq lr, #320/4\r
-\r
-rotated_blit_loop16:\r
- ldr r2, [r1, #320*0*2]\r
- ldr r3, [r1, #320*1*2]\r
- ldr r4, [r1, #320*2*2]\r
- ldr r5, [r1, #320*3*2]\r
- rb_line_low\r
- stmia r0, {r7,r8}\r
- sub r0, r0, #240*2\r
- rb_line_hi\r
- stmia r0, {r7,r8}\r
- sub r0, r0, #240*2\r
-\r
- ldr r2, [r1, #320*0*2+4]\r
- ldr r3, [r1, #320*1*2+4]\r
- ldr r4, [r1, #320*2*2+4]\r
- ldr r5, [r1, #320*3*2+4]\r
- rb_line_low\r
- stmia r0, {r7,r8}\r
- sub r0, r0, #240*2\r
- rb_line_hi\r
- stmia r0, {r7,r8}\r
- sub r0, r0, #240*2\r
-\r
- subs lr, lr, #1\r
- add r1, r1, #8\r
- bne rotated_blit_loop16\r
-\r
- ldmfd sp!,{r4-r8,pc}\r
-\r
-\r
-.global spend_cycles @ c\r
-\r
-spend_cycles:\r
- mov r0, r0, lsr #2 @ 4 cycles/iteration\r
- sub r0, r0, #2 @ entry/exit/init\r
-.sc_loop:\r
- subs r0, r0, #1\r
- bpl .sc_loop\r
-\r
- bx lr\r
-\r
+++ /dev/null
-ifneq ($(DEBUG),)
-CFLAGS += -ggdb
-endif
-ifeq "$(profile)" "1"
-CFLAGS += -fprofile-generate
-endif
-ifeq "$(profile)" "2"
-CFLAGS += -fprofile-use
-endif
-ifeq "$(pdb)" "1"
-DEFINES += PDB
-OBJS += cpu/debug.o
- ifeq "$(pdb_net)" "1"
- DEFINES += PDB_NET
- endif
- ifeq "$(readline)" "1"
- DEFINES += HAVE_READLINE
- LDFLAGS += -lreadline
- endif
-endif
-ifeq "$(pprof)" "1"
-DEFINES += PPROF
-OBJS += platform/linux/pprof.o
-endif
-
-# === Pico core ===
-# Pico
-OBJS += pico/state.o pico/cart.o pico/memory.o pico/pico.o pico/sek.o pico/z80if.o \
- pico/videoport.o pico/draw2.o pico/draw.o pico/mode4.o \
- pico/misc.o pico/eeprom.o pico/patch.o pico/debug.o
-# SMS
-ifneq "$(no_sms)" "1"
-OBJS += pico/sms.o
-else
-DEFINES += NO_SMS
-endif
-# CD
-OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \
- pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \
- pico/cd/misc.o pico/cd/pcm.o pico/cd/buffering.o
-# 32X
-ifneq "$(no_32x)" "1"
-OBJS += pico/32x/32x.o pico/32x/memory.o pico/32x/draw.o pico/32x/pwm.o
-else
-DEFINES += NO_32X
-endif
-# Pico
-OBJS += pico/pico/pico.o pico/pico/memory.o pico/pico/xpcm.o
-# carthw
-OBJS += pico/carthw/carthw.o
-# SVP
-OBJS += pico/carthw/svp/svp.o pico/carthw/svp/memory.o \
- pico/carthw/svp/ssp16.o
-# sound
-OBJS += pico/sound/sound.o
-OBJS += pico/sound/sn76496.o pico/sound/ym2612.o
-
-# === CPU cores ===
-# --- M68k ---
-ifeq "$(use_musashi)" "1"
-DEFINES += EMU_M68K
-OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o
-#OBJS += cpu/musashi/m68kdasm.o
-endif
-ifeq "$(use_cyclone)" "1"
-DEFINES += EMU_C68K
-OBJS += pico/m68kif_cyclone.o cpu/Cyclone/proj/Cyclone.o cpu/Cyclone/tools/idle.o
-endif
-ifeq "$(use_fame)" "1"
-DEFINES += EMU_F68K
-OBJS += cpu/fame/famec.o
-endif
-
-# --- Z80 ---
-ifeq "$(use_drz80)" "1"
-DEFINES += _USE_DRZ80
-OBJS += cpu/DrZ80/drz80.o
-endif
-#
-ifeq "$(use_cz80)" "1"
-DEFINES += _USE_CZ80
-OBJS += cpu/cz80/cz80.o
-endif
-
-# --- SH2 ---
-OBJS += cpu/drc/cmn.o
-ifneq "$(no_32x)" "1"
-OBJS += cpu/sh2/sh2.o
-#
-ifeq "$(use_sh2drc)" "1"
-DEFINES += DRC_SH2
-OBJS += cpu/sh2/compiler.o
-ifdef drc_debug
-DEFINES += DRC_DEBUG=$(drc_debug)
-OBJS += cpu/sh2/mame/sh2dasm.o
-OBJS += platform/linux/host_dasm.o
-LDFLAGS += -lbfd -lopcodes -liberty
-endif
-ifeq "$(drc_debug_interp)" "1"
-DEFINES += DRC_DEBUG_INTERP
-use_sh2mame = 1
-endif
-endif # use_sh2drc
-#
-ifeq "$(use_sh2mame)" "1"
-OBJS += cpu/sh2/mame/sh2pico.o
-endif
-endif # !no_32x
-
-
-DIRS += platform platform/common pico pico/cd pico/pico pico/32x pico/sound pico/carthw/svp \
- cpu cpu/musashi cpu/cz80 cpu/fame cpu/sh2/mame cpu/drc
-
-
-# common rules
-.c.o:
- @echo ">>>" $<
- $(CC) $(CFLAGS) -c $< -o $@
-.s.o:
- @echo ">>>" $<
- $(CC) $(CFLAGS) -c $< -o $@
-
-clean_prof:
- find ../.. -name '*.gcno' -delete
- find ../.. -name '*.gcda' -delete
-
-mkdirs:
- mkdir -p $(DIRS)
-
-../../tools/textfilter: ../../tools/textfilter.c
- make -C ../../tools/ textfilter
-
-
-# random deps
-pico/carthw/svp/compiler.o : ../../cpu/drc/emit_$(ARCH).c
-cpu/sh2/compiler.o : ../../cpu/drc/emit_$(ARCH).c
-cpu/sh2/mame/sh2pico.o : ../../cpu/sh2/mame/sh2.c
-pico/pico.o pico/cd/pico.o : ../../pico/pico_cmn.c ../../pico/pico_int.h
-pico/memory.o pico/cd/memory.o : ../../pico/pico_int.h ../../pico/memory.h
-
-../../cpu/musashi/m68kops.c :
- @make -C ../../cpu/musashi
-
-../../cpu/mz80/mz80.asm :
- @make -C ../../cpu/mz80/
-
-cpu/fame/famec.o : ../../cpu/fame/famec.c ../../cpu/fame/famec_opcodes.h
- @echo ">>>" $<
- $(CC) $(CFLAGS) -Wno-unused -c $< -o $@
-
-../../cpu/Cyclone/proj/Cyclone.s:
- @echo building Cyclone...
- @make -C ../../cpu/Cyclone/proj CONFIG_FILE=config_pico.h
-
+++ /dev/null
-# asm stuff
-ifeq "$(asm_render)" "1"
-DEFINES += _ASM_DRAW_C
-OBJS += pico/draw_arm.o pico/draw2_arm.o
-endif
-ifeq "$(asm_memory)" "1"
-DEFINES += _ASM_MEMORY_C
-OBJS += pico/memory_arm.o
-endif
-ifeq "$(asm_ym2612)" "1"
-DEFINES += _ASM_YM2612_C
-OBJS += pico/sound/ym2612_arm.o
-endif
-ifeq "$(asm_misc)" "1"
-DEFINES += _ASM_MISC_C
-OBJS += pico/misc_arm.o
-OBJS += pico/cd/misc_arm.o
-endif
-ifeq "$(asm_cdpico)" "1"
-DEFINES += _ASM_CD_PICO_C
-OBJS += pico/cd/pico_arm.o
-endif
-ifeq "$(asm_cdmemory)" "1"
-DEFINES += _ASM_CD_MEMORY_C
-OBJS += pico/cd/memory_arm.o
-endif
-ifeq "$(asm_32xdraw)" "1"
-DEFINES += _ASM_32X_DRAW
-OBJS += pico/32x/draw_arm.o
-endif
-
-
-DIRS += cpu/Cyclone cpu/Cyclone/proj cpu/Cyclone/tools cpu/DrZ80
-
-
-# build helix libs
-../common/helix/$(CROSS)helix-mp3.a:
- make -C ../common/helix CROSS=$(CROSS) clean all
-
+++ /dev/null
-/*
- * Human-readable config file management for PicoDrive
- * (c) notaz, 2008
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#ifdef __EPOC32__
-#include <unistd.h>
-#endif
-#include "config.h"
-#include "plat.h"
-#include "input.h"
-#include "lprintf.h"
-
-static char *mystrip(char *str);
-
-#ifndef _MSC_VER
-
-#include "menu.h"
-#include "menu_pico.h"
-#include "emu.h"
-#include <pico/pico.h>
-
-// always output DOS endlines
-#ifdef _WIN32
-#define NL "\n"
-#else
-#define NL "\r\n"
-#endif
-
-static int seek_sect(FILE *f, const char *section)
-{
- char line[128], *tmp;
- int len;
-
- len = strlen(section);
- // seek to the section needed
- while (!feof(f))
- {
- tmp = fgets(line, sizeof(line), f);
- if (tmp == NULL) break;
-
- if (line[0] != '[') continue; // not section start
- if (strncmp(line + 1, section, len) == 0 && line[len+1] == ']')
- return 1; // found it
- }
-
- return 0;
-}
-
-
-static void keys_write(FILE *fn, const char *bind_str, int dev_id, const int *binds, int no_defaults)
-{
- char act[48];
- int key_count = 0, k, i;
- const int *def_binds;
-
- in_get_config(dev_id, IN_CFG_BIND_COUNT, &key_count);
- def_binds = in_get_dev_def_binds(dev_id);
-
- for (k = 0; k < key_count; k++)
- {
- const char *name;
- int t, mask;
- act[0] = act[31] = 0;
-
- for (t = 0; t < IN_BINDTYPE_COUNT; t++)
- if (binds[IN_BIND_OFFS(k, t)] != def_binds[IN_BIND_OFFS(k, t)])
- break;
-
- if (no_defaults && t == IN_BINDTYPE_COUNT)
- continue; /* no change from defaults */
-
- name = in_get_key_name(dev_id, k);
-
- for (t = 0; t < IN_BINDTYPE_COUNT; t++)
- if (binds[IN_BIND_OFFS(k, t)] != 0 || def_binds[IN_BIND_OFFS(k, t)] == 0)
- break;
-
- if (t == IN_BINDTYPE_COUNT) {
- /* key has default bind removed */
- fprintf(fn, "%s %s =" NL, bind_str, name);
- continue;
- }
-
- for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
- mask = me_ctrl_actions[i].mask;
- if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)]) {
- strncpy(act, me_ctrl_actions[i].name, 31);
- fprintf(fn, "%s %s = player1 %s" NL, bind_str, name, mystrip(act));
- }
- mask = me_ctrl_actions[i].mask << 16;
- if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)]) {
- strncpy(act, me_ctrl_actions[i].name, 31);
- fprintf(fn, "%s %s = player2 %s" NL, bind_str, name, mystrip(act));
- }
- }
-
- for (i = 0; emuctrl_actions[i].name != NULL; i++) {
- mask = emuctrl_actions[i].mask;
- if (mask & binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)]) {
- strncpy(act, emuctrl_actions[i].name, 31);
- fprintf(fn, "%s %s = %s" NL, bind_str, name, mystrip(act));
- }
- }
- }
-}
-
-/* XXX: this should go to menu structures instead */
-static int default_var(const menu_entry *me)
-{
- switch (me->id)
- {
- case MA_OPT2_ENABLE_YM2612:
- case MA_OPT2_ENABLE_SN76496:
- case MA_OPT2_ENABLE_Z80:
- case MA_OPT_6BUTTON_PAD:
- case MA_OPT_ACC_SPRITES:
- case MA_OPT_ARM940_SOUND:
- case MA_CDOPT_PCM:
- case MA_CDOPT_CDDA:
- case MA_CDOPT_SCALEROT_CHIP:
- case MA_CDOPT_BETTER_SYNC:
- case MA_CDOPT_SAVERAM:
- case MA_32XOPT_ENABLE_32X:
- case MA_32XOPT_PWM:
- case MA_OPT2_SVP_DYNAREC:
- case MA_OPT2_NO_SPRITE_LIM:
- case MA_OPT2_NO_IDLE_LOOPS:
- return defaultConfig.s_PicoOpt;
-
- case MA_OPT_SRAM_STATES:
- case MA_OPT_SHOW_FPS:
- case MA_OPT_ENABLE_SOUND:
- case MA_OPT2_GZIP_STATES:
- case MA_OPT2_SQUIDGEHACK:
- case MA_OPT2_NO_LAST_ROM:
- case MA_OPT2_RAMTIMINGS:
- case MA_CDOPT_LEDS:
- case MA_OPT2_A_SN_GAMMA:
- case MA_OPT2_VSYNC:
- case MA_OPT_INTERLACED:
- case MA_OPT2_DBLBUFF:
- case MA_OPT2_STATUS_LINE:
- case MA_OPT2_NO_FRAME_LIMIT:
- case MA_OPT_TEARING_FIX:
- return defaultConfig.EmuOpt;
-
- case MA_CTRL_TURBO_RATE: return defaultConfig.turbo_rate;
- case MA_OPT_SCALING: return defaultConfig.scaling;
- case MA_OPT_ROTATION: return defaultConfig.rotation;
- case MA_OPT2_GAMMA: return defaultConfig.gamma;
- case MA_OPT_FRAMESKIP: return defaultConfig.Frameskip;
- case MA_OPT_CONFIRM_STATES: return defaultConfig.confirm_save;
- case MA_OPT_CPU_CLOCKS: return defaultConfig.CPUclock;
- case MA_OPT_RENDERER: return defaultConfig.renderer;
- case MA_32XOPT_RENDERER: return defaultConfig.renderer32x;
-
- case MA_OPT_SAVE_SLOT:
- return 0;
-
- default:
- lprintf("missing default for %d\n", me->id);
- return 0;
- }
-}
-
-static int is_cust_val_default(const menu_entry *me)
-{
- switch (me->id)
- {
- case MA_OPT_REGION:
- return defaultConfig.s_PicoRegion == PicoRegionOverride &&
- defaultConfig.s_PicoAutoRgnOrder == PicoAutoRgnOrder;
- case MA_OPT_SOUND_QUALITY:
- return defaultConfig.s_PsndRate == PsndRate &&
- ((defaultConfig.s_PicoOpt ^ PicoOpt) & POPT_EN_STEREO) == 0;
- case MA_CDOPT_READAHEAD:
- return defaultConfig.s_PicoCDBuffers == PicoCDBuffers;
- case MA_32XOPT_MSH2_CYCLES:
- return p32x_msh2_multiplier == MSH2_MULTI_DEFAULT;
- case MA_32XOPT_SSH2_CYCLES:
- return p32x_ssh2_multiplier == SSH2_MULTI_DEFAULT;
- default:break;
- }
-
- lprintf("is_cust_val_default: unhandled id %i\n", me->id);
- return 0;
-}
-
-int config_writesect(const char *fname, const char *section)
-{
- FILE *fo = NULL, *fn = NULL; // old and new
- int no_defaults = 0; // avoid saving defaults
- menu_entry *me;
- int t, tlen, ret;
- char line[128], *tmp;
-
- if (section != NULL)
- {
- no_defaults = 1;
-
- fo = fopen(fname, "r");
- if (fo == NULL) {
- fn = fopen(fname, "w");
- goto write;
- }
-
- ret = seek_sect(fo, section);
- if (!ret) {
- // sect not found, we can simply append
- fclose(fo); fo = NULL;
- fn = fopen(fname, "a");
- goto write;
- }
-
- // use 2 files..
- fclose(fo);
- rename(fname, "tmp.cfg");
- fo = fopen("tmp.cfg", "r");
- fn = fopen(fname, "w");
- if (fo == NULL || fn == NULL) goto write;
-
- // copy everything until sect
- tlen = strlen(section);
- while (!feof(fo))
- {
- tmp = fgets(line, sizeof(line), fo);
- if (tmp == NULL) break;
-
- if (line[0] == '[' && strncmp(line + 1, section, tlen) == 0 && line[tlen+1] == ']')
- break;
- fputs(line, fn);
- }
-
- // now skip to next sect
- while (!feof(fo))
- {
- tmp = fgets(line, sizeof(line), fo);
- if (tmp == NULL) break;
- if (line[0] == '[') {
- fseek(fo, -strlen(line), SEEK_CUR);
- break;
- }
- }
- if (feof(fo))
- {
- fclose(fo); fo = NULL;
- remove("tmp.cfg");
- }
- }
- else
- {
- fn = fopen(fname, "w");
- }
-
-write:
- if (fn == NULL) {
- if (fo) fclose(fo);
- return -1;
- }
- if (section != NULL)
- fprintf(fn, "[%s]" NL, section);
-
- for (me = me_list_get_first(); me != NULL; me = me_list_get_next())
- {
- int dummy;
- if (!me->need_to_save)
- continue;
- if (me->name == NULL || me->name[0] == 0)
- continue;
-
- if (me->beh == MB_OPT_ONOFF || me->beh == MB_OPT_CUSTONOFF) {
- if (!no_defaults || ((*(int *)me->var ^ default_var(me)) & me->mask))
- fprintf(fn, "%s = %i" NL, me->name, (*(int *)me->var & me->mask) ? 1 : 0);
- }
- else if (me->beh == MB_OPT_RANGE || me->beh == MB_OPT_CUSTRANGE) {
- if (!no_defaults || (*(int *)me->var ^ default_var(me)))
- fprintf(fn, "%s = %i" NL, me->name, *(int *)me->var);
- }
- else if (me->beh == MB_OPT_ENUM && me->data != NULL) {
- const char **names = (const char **)me->data;
- for (t = 0; names[t] != NULL; t++)
- if (*(int *)me->var == t && (!no_defaults || (*(int *)me->var ^ default_var(me)))) {
- strncpy(line, names[t], sizeof(line));
- goto write_line;
- }
- }
- else if (me->generate_name != NULL) {
- if (!no_defaults || !is_cust_val_default(me)) {
- strncpy(line, me->generate_name(0, &dummy), sizeof(line));
- goto write_line;
- }
- }
- else
- lprintf("config: unhandled write: %i\n", me->id);
- continue;
-
-write_line:
- line[sizeof(line) - 1] = 0;
- mystrip(line);
- fprintf(fn, "%s = %s" NL, me->name, line);
- }
-
- /* input: save device names */
- for (t = 0; t < IN_MAX_DEVS; t++)
- {
- const int *binds = in_get_dev_binds(t);
- const char *name = in_get_dev_name(t, 0, 0);
- if (binds == NULL || name == NULL)
- continue;
-
- fprintf(fn, "input%d = %s" NL, t, name);
- }
-
- /* input: save binds */
- for (t = 0; t < IN_MAX_DEVS; t++)
- {
- const int *binds = in_get_dev_binds(t);
- const char *name = in_get_dev_name(t, 0, 0);
- char strbind[16];
- int count = 0;
-
- if (binds == NULL || name == NULL)
- continue;
-
- sprintf(strbind, "bind%d", t);
- if (t == 0) strbind[4] = 0;
-
- in_get_config(t, IN_CFG_BIND_COUNT, &count);
- keys_write(fn, strbind, t, binds, no_defaults);
- }
-
-#ifndef PSP
- if (section == NULL)
- fprintf(fn, "Sound Volume = %i" NL, currentConfig.volume);
-#endif
-
- fprintf(fn, NL);
-
- if (fo != NULL)
- {
- // copy whatever is left
- while (!feof(fo))
- {
- tmp = fgets(line, sizeof(line), fo);
- if (tmp == NULL) break;
-
- fputs(line, fn);
- }
- fclose(fo);
- remove("tmp.cfg");
- }
-
- fclose(fn);
- return 0;
-}
-
-
-int config_writelrom(const char *fname)
-{
- char line[128], *tmp, *optr = NULL;
- char *old_data = NULL;
- int size;
- FILE *f;
-
- if (strlen(rom_fname_loaded) == 0) return -1;
-
- f = fopen(fname, "r");
- if (f != NULL)
- {
- fseek(f, 0, SEEK_END);
- size = ftell(f);
- fseek(f, 0, SEEK_SET);
- old_data = malloc(size + size/8);
- if (old_data != NULL)
- {
- optr = old_data;
- while (!feof(f))
- {
- tmp = fgets(line, sizeof(line), f);
- if (tmp == NULL) break;
- mystrip(line);
- if (strncasecmp(line, "LastUsedROM", 11) == 0)
- continue;
- sprintf(optr, "%s", line);
- optr += strlen(optr);
- }
- }
- fclose(f);
- }
-
- f = fopen(fname, "w");
- if (f == NULL) return -1;
-
- if (old_data != NULL) {
- fwrite(old_data, 1, optr - old_data, f);
- free(old_data);
- }
- fprintf(f, "LastUsedROM = %s" NL, rom_fname_loaded);
- fclose(f);
- return 0;
-}
-
-/* --------------------------------------------------------------------------*/
-
-int config_readlrom(const char *fname)
-{
- char line[128], *tmp;
- int i, len, ret = -1;
- FILE *f;
-
- f = fopen(fname, "r");
- if (f == NULL) return -1;
-
- // seek to the section needed
- while (!feof(f))
- {
- tmp = fgets(line, sizeof(line), f);
- if (tmp == NULL) break;
-
- if (strncasecmp(line, "LastUsedROM", 11) != 0) continue;
- len = strlen(line);
- for (i = 0; i < len; i++)
- if (line[i] == '#' || line[i] == '\r' || line[i] == '\n') { line[i] = 0; break; }
- tmp = strchr(line, '=');
- if (tmp == NULL) break;
- tmp++;
- mystrip(tmp);
-
- len = sizeof(rom_fname_loaded);
- strncpy(rom_fname_loaded, tmp, len);
- rom_fname_loaded[len-1] = 0;
- ret = 0;
- break;
- }
- fclose(f);
- return ret;
-}
-
-
-static int custom_read(menu_entry *me, const char *var, const char *val)
-{
- char *tmp;
-
- switch (me->id)
- {
- case MA_OPT_FRAMESKIP:
- if (strcasecmp(var, "Frameskip") != 0) return 0;
- if (strcasecmp(val, "Auto") == 0)
- currentConfig.Frameskip = -1;
- else currentConfig.Frameskip = atoi(val);
- return 1;
-
- case MA_OPT_SOUND_QUALITY:
- if (strcasecmp(var, "Sound Quality") != 0) return 0;
- PsndRate = strtoul(val, &tmp, 10);
- if (PsndRate < 8000 || PsndRate > 44100)
- PsndRate = 22050;
- if (*tmp == 'H' || *tmp == 'h') tmp++;
- if (*tmp == 'Z' || *tmp == 'z') tmp++;
- while (*tmp == ' ') tmp++;
- if (strcasecmp(tmp, "stereo") == 0) {
- PicoOpt |= POPT_EN_STEREO;
- } else if (strcasecmp(tmp, "mono") == 0) {
- PicoOpt &= ~POPT_EN_STEREO;
- } else
- return 0;
- return 1;
-
- case MA_OPT_REGION:
- if (strcasecmp(var, "Region") != 0) return 0;
- if (strncasecmp(val, "Auto: ", 6) == 0)
- {
- const char *p = val + 5, *end = val + strlen(val);
- int i;
- PicoRegionOverride = PicoAutoRgnOrder = 0;
- for (i = 0; p < end && i < 3; i++)
- {
- while (*p == ' ') p++;
- if (p[0] == 'J' && p[1] == 'P') {
- PicoAutoRgnOrder |= 1 << (i*4);
- } else if (p[0] == 'U' && p[1] == 'S') {
- PicoAutoRgnOrder |= 4 << (i*4);
- } else if (p[0] == 'E' && p[1] == 'U') {
- PicoAutoRgnOrder |= 8 << (i*4);
- }
- while (*p != ' ' && *p != 0) p++;
- if (*p == 0) break;
- }
- }
- else if (strcasecmp(val, "Auto") == 0) {
- PicoRegionOverride = 0;
- } else if (strcasecmp(val, "Japan NTSC") == 0) {
- PicoRegionOverride = 1;
- } else if (strcasecmp(val, "Japan PAL") == 0) {
- PicoRegionOverride = 2;
- } else if (strcasecmp(val, "USA") == 0) {
- PicoRegionOverride = 4;
- } else if (strcasecmp(val, "Europe") == 0) {
- PicoRegionOverride = 8;
- } else
- return 0;
- return 1;
-
- case MA_OPT2_GAMMA:
- if (strcasecmp(var, "Gamma correction") != 0) return 0;
- currentConfig.gamma = (int) (atof(val) * 100.0);
- return 1;
-
- case MA_CDOPT_READAHEAD:
- if (strcasecmp(var, "ReadAhead buffer") != 0) return 0;
- PicoCDBuffers = atoi(val) / 2;
- return 1;
-
- case MA_32XOPT_MSH2_CYCLES:
- case MA_32XOPT_SSH2_CYCLES: {
- int *mul = (me->id == MA_32XOPT_MSH2_CYCLES) ? &p32x_msh2_multiplier : &p32x_ssh2_multiplier;
- *mul = ((unsigned int)atoi(val) << SH2_MULTI_SHIFT) / 7670;
- return 1;
- }
-
- /* PSP */
- case MA_OPT3_SCALE:
- if (strcasecmp(var, "Scale factor") != 0) return 0;
- currentConfig.scale = atof(val);
- return 1;
- case MA_OPT3_HSCALE32:
- if (strcasecmp(var, "Hor. scale (for low res. games)") != 0) return 0;
- currentConfig.hscale32 = atof(val);
- return 1;
- case MA_OPT3_HSCALE40:
- if (strcasecmp(var, "Hor. scale (for hi res. games)") != 0) return 0;
- currentConfig.hscale40 = atof(val);
- return 1;
- case MA_OPT3_VSYNC:
- // XXX: use enum
- if (strcasecmp(var, "Wait for vsync") != 0) return 0;
- if (strcasecmp(val, "never") == 0) {
- currentConfig.EmuOpt &= ~0x12000;
- } else if (strcasecmp(val, "sometimes") == 0) {
- currentConfig.EmuOpt |= 0x12000;
- } else if (strcasecmp(val, "always") == 0) {
- currentConfig.EmuOpt &= ~0x12000;
- currentConfig.EmuOpt |= 0x02000;
- } else
- return 0;
- return 1;
-
- default:
- lprintf("unhandled custom_read %i: %s\n", me->id, var);
- return 0;
- }
-}
-
-
-static unsigned int keys_encountered = 0;
-
-static int parse_bind_val(const char *val, int *type)
-{
- int i;
-
- *type = IN_BINDTYPE_NONE;
- if (val[0] == 0)
- return 0;
-
- if (strncasecmp(val, "player", 6) == 0)
- {
- int player, shift = 0;
- player = atoi(val + 6) - 1;
-
- if (player > 1)
- return -1;
- if (player == 1)
- shift = 16;
-
- *type = IN_BINDTYPE_PLAYER12;
- for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
- if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0)
- return me_ctrl_actions[i].mask << shift;
- }
- }
- for (i = 0; emuctrl_actions[i].name != NULL; i++) {
- if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) {
- *type = IN_BINDTYPE_EMU;
- return emuctrl_actions[i].mask;
- }
- }
-
- return -1;
-}
-
-static void keys_parse(const char *key, const char *val, int dev_id)
-{
- int acts, type;
-
- acts = parse_bind_val(val, &type);
- if (acts == -1) {
- lprintf("config: unhandled action \"%s\"\n", val);
- return;
- }
-
- in_config_bind_key(dev_id, key, acts, type);
-}
-
-static int get_numvar_num(const char *var)
-{
- char *p = NULL;
- int num;
-
- if (var[0] == ' ')
- return 0;
-
- num = strtoul(var, &p, 10);
- if (*p == 0 || *p == ' ')
- return num;
-
- return -1;
-}
-
-/* map dev number in confing to input dev number */
-static unsigned char input_dev_map[IN_MAX_DEVS];
-
-static void parse(const char *var, const char *val)
-{
- menu_entry *me;
- int tmp;
-
- if (strcasecmp(var, "LastUsedROM") == 0)
- return; /* handled elsewhere */
-
- if (strcasecmp(var, "Sound Volume") == 0) {
- currentConfig.volume = atoi(val);
- return;
- }
-
- /* input: device name */
- if (strncasecmp(var, "input", 5) == 0) {
- int num = get_numvar_num(var + 5);
- if (num >= 0 && num < IN_MAX_DEVS)
- input_dev_map[num] = in_config_parse_dev(val);
- else
- lprintf("config: failed to parse: %s\n", var);
- return;
- }
-
- // key binds
- if (strncasecmp(var, "bind", 4) == 0) {
- const char *p = var + 4;
- int num = get_numvar_num(p);
- if (num < 0 || num >= IN_MAX_DEVS) {
- lprintf("config: failed to parse: %s\n", var);
- return;
- }
-
- num = input_dev_map[num];
- if (num < 0 || num >= IN_MAX_DEVS) {
- lprintf("config: invalid device id: %s\n", var);
- return;
- }
-
- while (*p && *p != ' ') p++;
- while (*p && *p == ' ') p++;
- keys_parse(p, val, num);
- return;
- }
-
- for (me = me_list_get_first(); me != NULL; me = me_list_get_next())
- {
- char *p;
-
- if (!me->need_to_save)
- continue;
- if (me->name == NULL || strcasecmp(var, me->name) != 0)
- continue;
-
- if (me->beh == MB_OPT_ONOFF) {
- tmp = strtol(val, &p, 0);
- if (*p != 0)
- goto bad_val;
- if (tmp) *(int *)me->var |= me->mask;
- else *(int *)me->var &= ~me->mask;
- return;
- }
- else if (me->beh == MB_OPT_RANGE) {
- tmp = strtol(val, &p, 0);
- if (*p != 0)
- goto bad_val;
- if (tmp < me->min) tmp = me->min;
- if (tmp > me->max) tmp = me->max;
- *(int *)me->var = tmp;
- return;
- }
- else if (me->beh == MB_OPT_ENUM) {
- const char **names, *p1;
- int i;
-
- names = (const char **)me->data;
- if (names == NULL)
- goto bad_val;
- for (i = 0; names[i] != NULL; i++) {
- for (p1 = names[i]; *p1 == ' '; p1++)
- ;
- if (strcasecmp(p1, val) == 0) {
- *(int *)me->var = i;
- return;
- }
- }
- goto bad_val;
- }
- else if (custom_read(me, var, val))
- return;
- }
-
- lprintf("config_readsect: unhandled var: \"%s\"\n", var);
- return;
-
-bad_val:
- lprintf("config_readsect: unhandled val for \"%s\": %s\n", var, val);
-}
-
-
-int config_havesect(const char *fname, const char *section)
-{
- FILE *f;
- int ret;
-
- f = fopen(fname, "r");
- if (f == NULL) return 0;
-
- ret = seek_sect(f, section);
- fclose(f);
- return ret;
-}
-
-int config_readsect(const char *fname, const char *section)
-{
- char line[128], *var, *val;
- FILE *f;
- int ret;
-
- f = fopen(fname, "r");
- if (f == NULL) return -1;
-
- if (section != NULL)
- {
- ret = seek_sect(f, section);
- if (!ret) {
- lprintf("config_readsect: %s: missing section [%s]\n", fname, section);
- fclose(f);
- return -1;
- }
- }
-
- keys_encountered = 0;
- memset(input_dev_map, 0xff, sizeof(input_dev_map));
-
- while (!feof(f))
- {
- ret = config_get_var_val(f, line, sizeof(line), &var, &val);
- if (ret == 0) break;
- if (ret == -1) continue;
-
- parse(var, val);
- }
-
- fclose(f);
- return 0;
-}
-
-#endif // _MSC_VER
-
-static char *mystrip(char *str)
-{
- int i, len;
-
- len = strlen(str);
- for (i = 0; i < len; i++)
- if (str[i] != ' ') break;
- if (i > 0) memmove(str, str + i, len - i + 1);
-
- len = strlen(str);
- for (i = len - 1; i >= 0; i--)
- if (str[i] != ' ') break;
- str[i+1] = 0;
-
- return str;
-}
-
-/* returns:
- * 0 - EOF, end
- * 1 - parsed ok
- * -1 - failed to parse line
- */
-int config_get_var_val(void *file, char *line, int lsize, char **rvar, char **rval)
-{
- char *var, *val, *tmp;
- FILE *f = file;
- int len, i;
-
- tmp = fgets(line, lsize, f);
- if (tmp == NULL) return 0;
-
- if (line[0] == '[') return 0; // other section
-
- // strip comments, linefeed, spaces..
- len = strlen(line);
- for (i = 0; i < len; i++)
- if (line[i] == '#' || line[i] == '\r' || line[i] == '\n') { line[i] = 0; break; }
- mystrip(line);
- len = strlen(line);
- if (len <= 0) return -1;;
-
- // get var and val
- for (i = 0; i < len; i++)
- if (line[i] == '=') break;
- if (i >= len || strchr(&line[i+1], '=') != NULL) {
- lprintf("config_readsect: can't parse: %s\n", line);
- return -1;
- }
- line[i] = 0;
- var = line;
- val = &line[i+1];
- mystrip(var);
- mystrip(val);
-
-#ifndef _MSC_VER
- if (strlen(var) == 0 || (strlen(val) == 0 && strncasecmp(var, "bind", 4) != 0)) {
- lprintf("config_readsect: something's empty: \"%s\" = \"%s\"\n", var, val);
- return -1;;
- }
-#endif
-
- *rvar = var;
- *rval = val;
- return 1;
-}
-
+++ /dev/null
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int config_writesect(const char *fname, const char *section);
-int config_writelrom(const char *fname);
-int config_readsect(const char *fname, const char *section);
-int config_readlrom(const char *fname);
-int config_havesect(const char *fname, const char *section);
-int config_get_var_val(void *file, char *line, int lsize, char **rvar, char **rval);
-
-#ifdef __cplusplus
-}
-#endif
-
+++ /dev/null
-// (c) Copyright 2006-2009 notaz, All rights reserved.\r
-// Free for non-commercial use.\r
-\r
-// For commercial use, separate licencing terms must be obtained.\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <stdarg.h>\r
-#ifndef NO_SYNC\r
-#include <unistd.h>\r
-#endif\r
-\r
-#include "emu.h"\r
-#include "menu.h"\r
-#include "fonts.h"\r
-#include "lprintf.h"\r
-#include "config.h"\r
-#include "plat.h"\r
-#include "input.h"\r
-#include "posix.h"\r
-\r
-#include <pico/pico_int.h>\r
-#include <pico/patch.h>\r
-#include <pico/cd/cue.h>\r
-\r
-\r
-#define STATUS_MSG_TIMEOUT 2000\r
-\r
-void *g_screen_ptr;\r
-\r
-#if !SCREEN_SIZE_FIXED\r
-int g_screen_width = SCREEN_WIDTH;\r
-int g_screen_height = SCREEN_HEIGHT;\r
-#endif\r
-\r
-char *PicoConfigFile = "config.cfg";\r
-currentConfig_t currentConfig, defaultConfig;\r
-int state_slot = 0;\r
-int config_slot = 0, config_slot_current = 0;\r
-int pico_pen_x = 320/2, pico_pen_y = 240/2;\r
-int pico_inp_mode = 0;\r
-int engineState = PGS_Menu;\r
-\r
-/* tmp buff to reduce stack usage for plats with small stack */\r
-static char static_buff[512];\r
-/* TODO: len checking */\r
-char rom_fname_reload[512];\r
-char rom_fname_loaded[512];\r
-int rom_loaded = 0;\r
-int reset_timing = 0;\r
-static unsigned int notice_msg_time; /* when started showing */\r
-static char noticeMsg[40];\r
-\r
-unsigned char *movie_data = NULL;\r
-static int movie_size = 0;\r
-\r
-\r
-/* don't use tolower() for easy old glibc binary compatibility */\r
-static void strlwr_(char *string)\r
-{\r
- char *p;\r
- for (p = string; *p; p++)\r
- if ('A' <= *p && *p <= 'Z')\r
- *p += 'a' - 'A';\r
-}\r
-\r
-static int try_rfn_cut(char *fname)\r
-{\r
- FILE *tmp;\r
- char *p;\r
-\r
- p = fname + strlen(fname) - 1;\r
- for (; p > fname; p--)\r
- if (*p == '.') break;\r
- *p = 0;\r
-\r
- if((tmp = fopen(fname, "rb"))) {\r
- fclose(tmp);\r
- return 1;\r
- }\r
- return 0;\r
-}\r
-\r
-static void get_ext(const char *file, char *ext)\r
-{\r
- const char *p;\r
-\r
- p = file + strlen(file) - 4;\r
- if (p < file) p = file;\r
- strncpy(ext, p, 4);\r
- ext[4] = 0;\r
- strlwr_(ext);\r
-}\r
-\r
-static void fname_ext(char *dst, int dstlen, const char *prefix, const char *ext, const char *fname)\r
-{\r
- int prefix_len = 0;\r
- const char *p;\r
-\r
- *dst = 0;\r
- if (prefix) {\r
- int len = plat_get_root_dir(dst, dstlen);\r
- strcpy(dst + len, prefix);\r
- prefix_len = len + strlen(prefix);\r
- }\r
-\r
- p = fname + strlen(fname) - 1;\r
- for (; p >= fname && *p != PATH_SEP_C; p--)\r
- ;\r
- p++;\r
- strncpy(dst + prefix_len, p, dstlen - prefix_len - 1);\r
-\r
- dst[dstlen - 8] = 0;\r
- if (dst[strlen(dst) - 4] == '.')\r
- dst[strlen(dst) - 4] = 0;\r
- if (ext)\r
- strcat(dst, ext);\r
-}\r
-\r
-static void romfname_ext(char *dst, int dstlen, const char *prefix, const char *ext)\r
-{\r
- fname_ext(dst, dstlen, prefix, ext, rom_fname_loaded);\r
-}\r
-\r
-void emu_status_msg(const char *format, ...)\r
-{\r
- va_list vl;\r
- int ret;\r
-\r
- va_start(vl, format);\r
- ret = vsnprintf(noticeMsg, sizeof(noticeMsg), format, vl);\r
- va_end(vl);\r
-\r
- /* be sure old text gets overwritten */\r
- for (; ret < 28; ret++)\r
- noticeMsg[ret] = ' ';\r
- noticeMsg[ret] = 0;\r
-\r
- notice_msg_time = plat_get_ticks_ms();\r
-}\r
-\r
-static const char * const biosfiles_us[] = { "us_scd1_9210", "us_scd2_9306", "SegaCDBIOS9303" };\r
-static const char * const biosfiles_eu[] = { "eu_mcd1_9210", "eu_mcd2_9306", "eu_mcd2_9303" };\r
-static const char * const biosfiles_jp[] = { "jp_mcd1_9112", "jp_mcd1_9111" };\r
-\r
-static int find_bios(int region, char **bios_file)\r
-{\r
- int i, count;\r
- const char * const *files;\r
- FILE *f = NULL;\r
-\r
- if (region == 4) { // US\r
- files = biosfiles_us;\r
- count = sizeof(biosfiles_us) / sizeof(char *);\r
- } else if (region == 8) { // EU\r
- files = biosfiles_eu;\r
- count = sizeof(biosfiles_eu) / sizeof(char *);\r
- } else if (region == 1 || region == 2) {\r
- files = biosfiles_jp;\r
- count = sizeof(biosfiles_jp) / sizeof(char *);\r
- } else {\r
- return 0;\r
- }\r
-\r
- for (i = 0; i < count; i++)\r
- {\r
- emu_make_path(static_buff, files[i], sizeof(static_buff) - 4);\r
- strcat(static_buff, ".bin");\r
- f = fopen(static_buff, "rb");\r
- if (f) break;\r
-\r
- static_buff[strlen(static_buff) - 4] = 0;\r
- strcat(static_buff, ".zip");\r
- f = fopen(static_buff, "rb");\r
- if (f) break;\r
- }\r
-\r
- if (f) {\r
- lprintf("using bios: %s\n", static_buff);\r
- fclose(f);\r
- if (bios_file)\r
- *bios_file = static_buff;\r
- return 1;\r
- } else {\r
- sprintf(static_buff, "no %s BIOS files found, read docs",\r
- region != 4 ? (region == 8 ? "EU" : "JAP") : "USA");\r
- me_update_msg(static_buff);\r
- return 0;\r
- }\r
-}\r
-\r
-/* check if the name begins with BIOS name */\r
-/*\r
-static int emu_isBios(const char *name)\r
-{\r
- int i;\r
- for (i = 0; i < sizeof(biosfiles_us)/sizeof(biosfiles_us[0]); i++)\r
- if (strstr(name, biosfiles_us[i]) != NULL) return 1;\r
- for (i = 0; i < sizeof(biosfiles_eu)/sizeof(biosfiles_eu[0]); i++)\r
- if (strstr(name, biosfiles_eu[i]) != NULL) return 1;\r
- for (i = 0; i < sizeof(biosfiles_jp)/sizeof(biosfiles_jp[0]); i++)\r
- if (strstr(name, biosfiles_jp[i]) != NULL) return 1;\r
- return 0;\r
-}\r
-*/\r
-\r
-static unsigned char id_header[0x100];\r
-\r
-/* checks if fname points to valid MegaCD image */\r
-static int emu_cd_check(int *pregion, const char *fname_in)\r
-{\r
- const char *fname = fname_in;\r
- unsigned char buf[32];\r
- pm_file *cd_f;\r
- int region = 4; // 1: Japan, 4: US, 8: Europe\r
- char ext[5];\r
- cue_track_type type = CT_UNKNOWN;\r
- cue_data_t *cue_data = NULL;\r
-\r
- get_ext(fname_in, ext);\r
- if (strcasecmp(ext, ".cue") == 0) {\r
- cue_data = cue_parse(fname_in);\r
- if (cue_data != NULL) {\r
- fname = cue_data->tracks[1].fname;\r
- type = cue_data->tracks[1].type;\r
- }\r
- else\r
- return -1;\r
- }\r
-\r
- cd_f = pm_open(fname);\r
- if (cue_data != NULL)\r
- cue_destroy(cue_data);\r
-\r
- if (cd_f == NULL) return 0; // let the upper level handle this\r
-\r
- if (pm_read(buf, 32, cd_f) != 32) {\r
- pm_close(cd_f);\r
- return -1;\r
- }\r
-\r
- if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) {\r
- if (type && type != CT_ISO)\r
- elprintf(EL_STATUS, ".cue has wrong type: %i", type);\r
- type = CT_ISO; // Sega CD (ISO)\r
- }\r
- if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x10, 14)) {\r
- if (type && type != CT_BIN)\r
- elprintf(EL_STATUS, ".cue has wrong type: %i", type);\r
- type = CT_BIN; // Sega CD (BIN)\r
- }\r
-\r
- if (type == CT_UNKNOWN) {\r
- pm_close(cd_f);\r
- return 0;\r
- }\r
-\r
- pm_seek(cd_f, (type == CT_ISO) ? 0x100 : 0x110, SEEK_SET);\r
- pm_read(id_header, sizeof(id_header), cd_f);\r
-\r
- /* it seems we have a CD image here. Try to detect region now.. */\r
- pm_seek(cd_f, (type == CT_ISO) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET);\r
- pm_read(buf, 1, cd_f);\r
- pm_close(cd_f);\r
-\r
- if (buf[0] == 0x64) region = 8; // EU\r
- if (buf[0] == 0xa1) region = 1; // JAP\r
-\r
- lprintf("detected %s Sega/Mega CD image with %s region\n",\r
- type == CT_BIN ? "BIN" : "ISO", region != 4 ? (region == 8 ? "EU" : "JAP") : "USA");\r
-\r
- if (pregion != NULL) *pregion = region;\r
-\r
- return type;\r
-}\r
-\r
-static int detect_media(const char *fname)\r
-{\r
- static const short sms_offsets[] = { 0x7ff0, 0x3ff0, 0x1ff0 };\r
- static const char *sms_exts[] = { "sms", "gg", "sg" };\r
- static const char *md_exts[] = { "gen", "bin", "smd" };\r
- char buff0[32], buff[32];\r
- unsigned short *d16;\r
- pm_file *pmf;\r
- char ext[5];\r
- int i;\r
-\r
- get_ext(fname, ext);\r
-\r
- // detect wrong extensions\r
- if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) // s.gz ~ .mds.gz\r
- return PM_BAD;\r
-\r
- /* don't believe in extensions, except .cue */\r
- if (strcasecmp(ext, ".cue") == 0)\r
- return PM_CD;\r
-\r
- pmf = pm_open(fname);\r
- if (pmf == NULL)\r
- return PM_BAD;\r
-\r
- if (pm_read(buff0, 32, pmf) != 32) {\r
- pm_close(pmf);\r
- return PM_BAD;\r
- }\r
-\r
- if (strncasecmp("SEGADISCSYSTEM", buff0 + 0x00, 14) == 0 ||\r
- strncasecmp("SEGADISCSYSTEM", buff0 + 0x10, 14) == 0) {\r
- pm_close(pmf);\r
- return PM_CD;\r
- }\r
-\r
- /* check for SMD evil */\r
- if (pmf->size >= 0x4200 && (pmf->size & 0x3fff) == 0x200) {\r
- if (pm_seek(pmf, sms_offsets[0] + 0x200, SEEK_SET) == sms_offsets[0] + 0x200 &&\r
- pm_read(buff, 16, pmf) == 16 &&\r
- strncmp("TMR SEGA", buff, 8) == 0)\r
- goto looks_like_sms;\r
-\r
- /* could parse further but don't bother */\r
- goto extension_check;\r
- }\r
-\r
- /* MD header? Act as TMSS BIOS here */\r
- if (pm_seek(pmf, 0x100, SEEK_SET) == 0x100 && pm_read(buff, 16, pmf) == 16) {\r
- if (strncmp(buff, "SEGA", 4) == 0 || strncmp(buff, " SEG", 4) == 0)\r
- goto looks_like_md;\r
- }\r
-\r
- for (i = 0; i < array_size(sms_offsets); i++) {\r
- if (pm_seek(pmf, sms_offsets[i], SEEK_SET) != sms_offsets[i])\r
- continue;\r
-\r
- if (pm_read(buff, 16, pmf) != 16)\r
- continue;\r
-\r
- if (strncmp("TMR SEGA", buff, 8) == 0)\r
- goto looks_like_sms;\r
- }\r
-\r
-extension_check:\r
- /* probably some headerless thing. Maybe check the extension after all. */\r
- for (i = 0; i < array_size(md_exts); i++)\r
- if (strcasecmp(pmf->ext, md_exts[i]) == 0)\r
- goto looks_like_md;\r
-\r
- for (i = 0; i < array_size(sms_exts); i++)\r
- if (strcasecmp(pmf->ext, sms_exts[i]) == 0)\r
- goto looks_like_sms;\r
-\r
- /* If everything else fails, make a guess on the reset vector */\r
- d16 = (unsigned short *)(buff0 + 4);\r
- if ((((d16[0] << 16) | d16[1]) & 0xffffff) >= pmf->size) {\r
- lprintf("bad MD reset vector, assuming SMS\n");\r
- goto looks_like_sms;\r
- }\r
-\r
-looks_like_md:\r
- pm_close(pmf);\r
- return PM_MD_CART;\r
-\r
-looks_like_sms:\r
- pm_close(pmf);\r
- return PM_MARK3;\r
-}\r
-\r
-static int extract_text(char *dest, const unsigned char *src, int len, int swab)\r
-{\r
- char *p = dest;\r
- int i;\r
-\r
- if (swab) swab = 1;\r
-\r
- for (i = len - 1; i >= 0; i--)\r
- {\r
- if (src[i^swab] != ' ') break;\r
- }\r
- len = i + 1;\r
-\r
- for (i = 0; i < len; i++)\r
- {\r
- unsigned char s = src[i^swab];\r
- if (s >= 0x20 && s < 0x7f && s != '#' && s != '|' &&\r
- s != '[' && s != ']' && s != '\\')\r
- {\r
- *p++ = s;\r
- }\r
- else\r
- {\r
- sprintf(p, "\\%02x", s);\r
- p += 3;\r
- }\r
- }\r
-\r
- return p - dest;\r
-}\r
-\r
-static char *emu_make_rom_id(const char *fname)\r
-{\r
- static char id_string[3+0xe*3+0x3*3+0x30*3+3];\r
- int pos, swab = 1;\r
-\r
- if (PicoAHW & PAHW_MCD) {\r
- strcpy(id_string, "CD|");\r
- swab = 0;\r
- }\r
- else if (PicoAHW & PAHW_SMS)\r
- strcpy(id_string, "MS|");\r
- else strcpy(id_string, "MD|");\r
- pos = 3;\r
-\r
- if (!(PicoAHW & PAHW_SMS)) {\r
- pos += extract_text(id_string + pos, id_header + 0x80, 0x0e, swab); // serial\r
- id_string[pos] = '|'; pos++;\r
- pos += extract_text(id_string + pos, id_header + 0xf0, 0x03, swab); // region\r
- id_string[pos] = '|'; pos++;\r
- pos += extract_text(id_string + pos, id_header + 0x50, 0x30, swab); // overseas name\r
- id_string[pos] = 0;\r
- if (pos > 5)\r
- return id_string;\r
- pos = 3;\r
- }\r
-\r
- // can't find name in ROM, use filename\r
- fname_ext(id_string + 3, sizeof(id_string) - 3, NULL, NULL, fname);\r
-\r
- return id_string;\r
-}\r
-\r
-// buffer must be at least 150 byte long\r
-void emu_get_game_name(char *str150)\r
-{\r
- int ret, swab = (PicoAHW & PAHW_MCD) ? 0 : 1;\r
- char *s, *d;\r
-\r
- ret = extract_text(str150, id_header + 0x50, 0x30, swab); // overseas name\r
-\r
- for (s = d = str150 + 1; s < str150+ret; s++)\r
- {\r
- if (*s == 0) break;\r
- if (*s != ' ' || d[-1] != ' ')\r
- *d++ = *s;\r
- }\r
- *d = 0;\r
-}\r
-\r
-static void shutdown_MCD(void)\r
-{\r
- if ((PicoAHW & PAHW_MCD) && Pico_mcd != NULL)\r
- Stop_CD();\r
- PicoAHW &= ~PAHW_MCD;\r
-}\r
-\r
-static void system_announce(void)\r
-{\r
- const char *sys_name, *tv_standard, *extra = "";\r
- int fps;\r
-\r
- if (PicoAHW & PAHW_SMS) {\r
- sys_name = "Master System";\r
-#ifdef NO_SMS\r
- extra = " [no support]";\r
-#endif\r
- } else if (PicoAHW & PAHW_PICO) {\r
- sys_name = "Pico";\r
- } else if (PicoAHW & PAHW_MCD) {\r
- sys_name = "Mega CD";\r
- if ((Pico.m.hardware & 0xc0) == 0x80)\r
- sys_name = "Sega CD";\r
- } else if (PicoAHW & PAHW_32X) {\r
- sys_name = "32X";\r
- } else {\r
- sys_name = "MegaDrive";\r
- if ((Pico.m.hardware & 0xc0) == 0x80)\r
- sys_name = "Genesis";\r
- }\r
- tv_standard = Pico.m.pal ? "PAL" : "NTSC";\r
- fps = Pico.m.pal ? 50 : 60;\r
-\r
- emu_status_msg("%s %s / %dFPS%s", tv_standard, sys_name, fps, extra);\r
-}\r
-\r
-// note: this function might mangle rom_fname\r
-// XXX: portions of this code should move to pico/\r
-int emu_reload_rom(char *rom_fname)\r
-{\r
- unsigned int rom_size = 0;\r
- char *used_rom_name = rom_fname;\r
- unsigned char *rom_data = NULL;\r
- char ext[5];\r
- pm_file *rom = NULL;\r
- int cd_state = CIT_NOT_CD;\r
- int ret, media_type, cd_region;\r
- int cfg_loaded = 0, bad_rom = 0;\r
-\r
- lprintf("emu_ReloadRom(%s)\n", rom_fname);\r
-\r
- get_ext(rom_fname, ext);\r
-\r
- // early cleanup\r
- PicoPatchUnload();\r
- if (movie_data) {\r
- free(movie_data);\r
- movie_data = 0;\r
- }\r
-\r
- if (!strcmp(ext, ".gmv"))\r
- {\r
- // check for both gmv and rom\r
- int dummy;\r
- FILE *movie_file = fopen(rom_fname, "rb");\r
- if (!movie_file) {\r
- me_update_msg("Failed to open movie.");\r
- return 0;\r
- }\r
- fseek(movie_file, 0, SEEK_END);\r
- movie_size = ftell(movie_file);\r
- fseek(movie_file, 0, SEEK_SET);\r
- if (movie_size < 64+3) {\r
- me_update_msg("Invalid GMV file.");\r
- fclose(movie_file);\r
- return 0;\r
- }\r
- movie_data = malloc(movie_size);\r
- if (movie_data == NULL) {\r
- me_update_msg("low memory.");\r
- fclose(movie_file);\r
- return 0;\r
- }\r
- dummy = fread(movie_data, 1, movie_size, movie_file);\r
- fclose(movie_file);\r
- if (strncmp((char *)movie_data, "Gens Movie TEST", 15) != 0) {\r
- me_update_msg("Invalid GMV file.");\r
- return 0;\r
- }\r
- dummy = try_rfn_cut(rom_fname) || try_rfn_cut(rom_fname);\r
- if (!dummy) {\r
- me_update_msg("Could't find a ROM for movie.");\r
- return 0;\r
- }\r
- get_ext(rom_fname, ext);\r
- lprintf("gmv loaded for %s\n", rom_fname);\r
- }\r
- else if (!strcmp(ext, ".pat"))\r
- {\r
- int dummy;\r
- PicoPatchLoad(rom_fname);\r
- dummy = try_rfn_cut(rom_fname) || try_rfn_cut(rom_fname);\r
- if (!dummy) {\r
- me_update_msg("Could't find a ROM to patch.");\r
- return 0;\r
- }\r
- get_ext(rom_fname, ext);\r
- }\r
-\r
- media_type = detect_media(rom_fname);\r
- if (media_type == PM_BAD) {\r
- me_update_msg("Not a ROM/CD img selected.");\r
- return 0;\r
- }\r
-\r
- shutdown_MCD();\r
- PicoCartUnload();\r
- rom_loaded = 0;\r
-\r
- PicoAHW = 0;\r
-\r
- if (media_type == PM_CD)\r
- {\r
- // check for MegaCD image\r
- cd_state = emu_cd_check(&cd_region, rom_fname);\r
- if (cd_state >= 0 && cd_state != CIT_NOT_CD)\r
- {\r
- // valid CD image, check for BIOS..\r
-\r
- // we need to have config loaded at this point\r
- ret = emu_read_config(rom_fname, 0);\r
- if (!ret) emu_read_config(NULL, 0);\r
- cfg_loaded = 1;\r
-\r
- if (PicoRegionOverride) {\r
- cd_region = PicoRegionOverride;\r
- lprintf("override region to %s\n", cd_region != 4 ?\r
- (cd_region == 8 ? "EU" : "JAP") : "USA");\r
- }\r
- if (!find_bios(cd_region, &used_rom_name))\r
- return 0;\r
-\r
- get_ext(used_rom_name, ext);\r
- PicoAHW |= PAHW_MCD;\r
- }\r
- else {\r
- me_update_msg("Invalid CD image");\r
- return 0;\r
- }\r
- }\r
- else if (media_type == PM_MARK3) {\r
- lprintf("detected SMS ROM\n");\r
- PicoAHW = PAHW_SMS;\r
- }\r
-\r
- rom = pm_open(used_rom_name);\r
- if (rom == NULL) {\r
- me_update_msg("Failed to open ROM");\r
- return 0;\r
- }\r
-\r
- menu_romload_prepare(used_rom_name); // also CD load\r
- used_rom_name = NULL; // uses static_buff\r
-\r
- ret = PicoCartLoad(rom, &rom_data, &rom_size, (PicoAHW & PAHW_SMS) ? 1 : 0);\r
- pm_close(rom);\r
- if (ret != 0) {\r
- if (ret == 2) me_update_msg("Out of memory");\r
- else if (ret == 3) me_update_msg("Read failed");\r
- else me_update_msg("PicoCartLoad() failed.");\r
- goto fail;\r
- }\r
-\r
- // detect wrong files\r
- if (strncmp((char *)rom_data, "Pico", 4) == 0)\r
- bad_rom = 1;\r
- else if (!(PicoAHW & PAHW_SMS)) {\r
- unsigned short *d = (unsigned short *)(rom_data + 4);\r
- if ((((d[0] << 16) | d[1]) & 0xffffff) >= (int)rom_size) {\r
- lprintf("bad reset vector\n");\r
- bad_rom = 1;\r
- }\r
- }\r
-\r
- if (bad_rom) {\r
- me_update_msg("Bad ROM detected.");\r
- goto fail;\r
- }\r
-\r
- // load config for this ROM (do this before insert to get correct region)\r
- if (!(PicoAHW & PAHW_MCD))\r
- memcpy(id_header, rom_data + 0x100, sizeof(id_header));\r
- if (!cfg_loaded) {\r
- ret = emu_read_config(rom_fname, 0);\r
- if (!ret) emu_read_config(NULL, 0);\r
- }\r
-\r
- emu_make_path(static_buff, "carthw.cfg", sizeof(static_buff));\r
- if (PicoCartInsert(rom_data, rom_size, static_buff)) {\r
- me_update_msg("Failed to load ROM.");\r
- goto fail;\r
- }\r
-\r
- // insert CD if it was detected\r
- if (cd_state != CIT_NOT_CD) {\r
- ret = Insert_CD(rom_fname, cd_state);\r
- if (ret != 0) {\r
- PicoCartUnload();\r
- rom_data = NULL; // freed by unload\r
- me_update_msg("Insert_CD() failed, invalid CD image?");\r
- goto fail;\r
- }\r
- }\r
-\r
- menu_romload_end();\r
-\r
- if (PicoPatches) {\r
- PicoPatchPrepare();\r
- PicoPatchApply();\r
- }\r
-\r
- // additional movie stuff\r
- if (movie_data)\r
- {\r
- if (movie_data[0x14] == '6')\r
- PicoOpt |= POPT_6BTN_PAD; // 6 button pad\r
- else PicoOpt &= ~POPT_6BTN_PAD;\r
- PicoOpt |= POPT_DIS_VDP_FIFO; // no VDP fifo timing\r
- if (movie_data[0xF] >= 'A') {\r
- if (movie_data[0x16] & 0x80) {\r
- PicoRegionOverride = 8;\r
- } else {\r
- PicoRegionOverride = 4;\r
- }\r
- PicoReset();\r
- // TODO: bits 6 & 5\r
- }\r
- movie_data[0x18+30] = 0;\r
- emu_status_msg("MOVIE: %s", (char *) &movie_data[0x18]);\r
- }\r
- else\r
- {\r
- system_announce();\r
- PicoOpt &= ~POPT_DIS_VDP_FIFO;\r
- }\r
-\r
- strncpy(rom_fname_loaded, rom_fname, sizeof(rom_fname_loaded)-1);\r
- rom_fname_loaded[sizeof(rom_fname_loaded)-1] = 0;\r
- rom_loaded = 1;\r
-\r
- // load SRAM for this ROM\r
- if (currentConfig.EmuOpt & EOPT_EN_SRAM)\r
- emu_save_load_game(1, 1);\r
-\r
- return 1;\r
-\r
-fail:\r
- if (rom_data)\r
- free(rom_data);\r
- menu_romload_end();\r
- return 0;\r
-}\r
-\r
-int emu_swap_cd(const char *fname)\r
-{\r
- cd_img_type cd_type;\r
- int ret = -1;\r
-\r
- cd_type = emu_cd_check(NULL, fname);\r
- if (cd_type != CIT_NOT_CD)\r
- ret = Insert_CD(fname, cd_type);\r
- if (ret != 0) {\r
- me_update_msg("Load failed, invalid CD image?");\r
- return 0;\r
- }\r
-\r
- strncpy(rom_fname_loaded, fname, sizeof(rom_fname_loaded)-1);\r
- rom_fname_loaded[sizeof(rom_fname_loaded)-1] = 0;\r
- return 1;\r
-}\r
-\r
-// <base dir><end>\r
-void emu_make_path(char *buff, const char *end, int size)\r
-{\r
- int pos, end_len;\r
-\r
- end_len = strlen(end);\r
- pos = plat_get_root_dir(buff, size);\r
- strncpy(buff + pos, end, size - pos);\r
- buff[size - 1] = 0;\r
- if (pos + end_len > size - 1)\r
- lprintf("Warning: path truncated: %s\n", buff);\r
-}\r
-\r
-static void make_config_cfg(char *cfg_buff_512)\r
-{\r
- emu_make_path(cfg_buff_512, PicoConfigFile, 512-6);\r
- if (config_slot != 0)\r
- {\r
- char *p = strrchr(cfg_buff_512, '.');\r
- if (p == NULL)\r
- p = cfg_buff_512 + strlen(cfg_buff_512);\r
- sprintf(p, ".%i.cfg", config_slot);\r
- }\r
- cfg_buff_512[511] = 0;\r
-}\r
-\r
-void emu_prep_defconfig(void)\r
-{\r
- memset(&defaultConfig, 0, sizeof(defaultConfig));\r
- defaultConfig.EmuOpt = 0x9d | EOPT_RAM_TIMINGS|EOPT_EN_CD_LEDS;\r
- defaultConfig.s_PicoOpt = POPT_EN_STEREO|POPT_EN_FM|POPT_EN_PSG|POPT_EN_Z80 |\r
- POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_SVP_DRC|POPT_ACC_SPRITES |\r
- POPT_EN_32X|POPT_EN_PWM;\r
- defaultConfig.s_PsndRate = 44100;\r
- defaultConfig.s_PicoRegion = 0; // auto\r
- defaultConfig.s_PicoAutoRgnOrder = 0x184; // US, EU, JP\r
- defaultConfig.s_PicoCDBuffers = 0;\r
- defaultConfig.confirm_save = EOPT_CONFIRM_SAVE;\r
- defaultConfig.Frameskip = -1; // auto\r
- defaultConfig.volume = 50;\r
- defaultConfig.gamma = 100;\r
- defaultConfig.scaling = 0;\r
- defaultConfig.turbo_rate = 15;\r
-\r
- // platform specific overrides\r
- pemu_prep_defconfig();\r
-}\r
-\r
-void emu_set_defconfig(void)\r
-{\r
- memcpy(¤tConfig, &defaultConfig, sizeof(currentConfig));\r
- PicoOpt = currentConfig.s_PicoOpt;\r
- PsndRate = currentConfig.s_PsndRate;\r
- PicoRegionOverride = currentConfig.s_PicoRegion;\r
- PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder;\r
- PicoCDBuffers = currentConfig.s_PicoCDBuffers;\r
- p32x_msh2_multiplier = MSH2_MULTI_DEFAULT;\r
- p32x_ssh2_multiplier = SSH2_MULTI_DEFAULT;\r
-}\r
-\r
-int emu_read_config(const char *rom_fname, int no_defaults)\r
-{\r
- char cfg[512];\r
- int ret;\r
-\r
- if (!no_defaults)\r
- emu_set_defconfig();\r
-\r
- if (rom_fname == NULL)\r
- {\r
- // global config\r
- make_config_cfg(cfg);\r
- ret = config_readsect(cfg, NULL);\r
- }\r
- else\r
- {\r
- char *sect = emu_make_rom_id(rom_fname);\r
-\r
- if (config_slot != 0)\r
- sprintf(cfg, "game.%i.cfg", config_slot);\r
- else strcpy(cfg, "game.cfg");\r
-\r
- ret = -1;\r
- if (config_havesect(cfg, sect))\r
- {\r
- // read user's config\r
- int vol = currentConfig.volume;\r
- emu_set_defconfig();\r
- ret = config_readsect(cfg, sect);\r
- currentConfig.volume = vol; // make vol global (bah)\r
- }\r
- else\r
- {\r
- // read global config, and apply game_def.cfg on top\r
- make_config_cfg(cfg);\r
- config_readsect(cfg, NULL);\r
- emu_make_path(cfg, "game_def.cfg", sizeof(cfg));\r
- ret = config_readsect(cfg, sect);\r
- }\r
-\r
- if (ret == 0)\r
- {\r
- lprintf("loaded cfg from sect \"%s\"\n", sect);\r
- }\r
- }\r
-\r
- pemu_validate_config();\r
-\r
- // some sanity checks\r
-#ifdef PSP\r
- /* TODO: mv to plat_validate_config() */\r
- if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200;\r
- if (currentConfig.gamma < -4 || currentConfig.gamma > 16) currentConfig.gamma = 0;\r
- if (currentConfig.gamma2 < 0 || currentConfig.gamma2 > 2) currentConfig.gamma2 = 0;\r
-#endif\r
- if (currentConfig.volume < 0 || currentConfig.volume > 99)\r
- currentConfig.volume = 50;\r
-\r
- if (ret == 0)\r
- config_slot_current = config_slot;\r
-\r
- return (ret == 0);\r
-}\r
-\r
-\r
-int emu_write_config(int is_game)\r
-{\r
- char cfg[512], *game_sect = NULL;\r
- int ret, write_lrom = 0;\r
-\r
- if (!is_game)\r
- {\r
- make_config_cfg(cfg);\r
- write_lrom = 1;\r
- } else {\r
- if (config_slot != 0)\r
- sprintf(cfg, "game.%i.cfg", config_slot);\r
- else strcpy(cfg, "game.cfg");\r
- game_sect = emu_make_rom_id(rom_fname_loaded);\r
- lprintf("emu_write_config: sect \"%s\"\n", game_sect);\r
- }\r
-\r
- lprintf("emu_write_config: %s ", cfg);\r
- ret = config_writesect(cfg, game_sect);\r
- if (write_lrom) config_writelrom(cfg);\r
-#ifndef NO_SYNC\r
- sync();\r
-#endif\r
- lprintf((ret == 0) ? "(ok)\n" : "(failed)\n");\r
-\r
- if (ret == 0) config_slot_current = config_slot;\r
- return ret == 0;\r
-}\r
-\r
-\r
-/* always using built-in font */\r
-\r
-#define mk_text_out(name, type, val, topleft, step_x, step_y) \\r
-void name(int x, int y, const char *text) \\r
-{ \\r
- int i, l, len = strlen(text); \\r
- type *screen = (type *)(topleft) + x * step_x + y * step_y; \\r
- \\r
- for (i = 0; i < len; i++, screen += 8 * step_x) \\r
- { \\r
- for (l = 0; l < 8; l++) \\r
- { \\r
- unsigned char fd = fontdata8x8[text[i] * 8 + l];\\r
- type *s = screen + l * step_y; \\r
- if (fd&0x80) s[step_x * 0] = val; \\r
- if (fd&0x40) s[step_x * 1] = val; \\r
- if (fd&0x20) s[step_x * 2] = val; \\r
- if (fd&0x10) s[step_x * 3] = val; \\r
- if (fd&0x08) s[step_x * 4] = val; \\r
- if (fd&0x04) s[step_x * 5] = val; \\r
- if (fd&0x02) s[step_x * 6] = val; \\r
- if (fd&0x01) s[step_x * 7] = val; \\r
- } \\r
- } \\r
-}\r
-\r
-mk_text_out(emu_text_out8, unsigned char, 0xf0, g_screen_ptr, 1, g_screen_width)\r
-mk_text_out(emu_text_out16, unsigned short, 0xffff, g_screen_ptr, 1, g_screen_width)\r
-mk_text_out(emu_text_out8_rot, unsigned char, 0xf0,\r
- (char *)g_screen_ptr + (g_screen_width - 1) * g_screen_height, -g_screen_height, 1)\r
-mk_text_out(emu_text_out16_rot, unsigned short, 0xffff,\r
- (short *)g_screen_ptr + (g_screen_width - 1) * g_screen_height, -g_screen_height, 1)\r
-\r
-#undef mk_text_out\r
-\r
-\r
-void update_movie(void)\r
-{\r
- int offs = Pico.m.frame_count*3 + 0x40;\r
- if (offs+3 > movie_size) {\r
- free(movie_data);\r
- movie_data = 0;\r
- emu_status_msg("END OF MOVIE.");\r
- lprintf("END OF MOVIE.\n");\r
- } else {\r
- // MXYZ SACB RLDU\r
- PicoPad[0] = ~movie_data[offs] & 0x8f; // ! SCBA RLDU\r
- if(!(movie_data[offs] & 0x10)) PicoPad[0] |= 0x40; // C\r
- if(!(movie_data[offs] & 0x20)) PicoPad[0] |= 0x10; // A\r
- if(!(movie_data[offs] & 0x40)) PicoPad[0] |= 0x20; // B\r
- PicoPad[1] = ~movie_data[offs+1] & 0x8f; // ! SCBA RLDU\r
- if(!(movie_data[offs+1] & 0x10)) PicoPad[1] |= 0x40; // C\r
- if(!(movie_data[offs+1] & 0x20)) PicoPad[1] |= 0x10; // A\r
- if(!(movie_data[offs+1] & 0x40)) PicoPad[1] |= 0x20; // B\r
- PicoPad[0] |= (~movie_data[offs+2] & 0x0A) << 8; // ! MZYX\r
- if(!(movie_data[offs+2] & 0x01)) PicoPad[0] |= 0x0400; // X\r
- if(!(movie_data[offs+2] & 0x04)) PicoPad[0] |= 0x0100; // Z\r
- PicoPad[1] |= (~movie_data[offs+2] & 0xA0) << 4; // ! MZYX\r
- if(!(movie_data[offs+2] & 0x10)) PicoPad[1] |= 0x0400; // X\r
- if(!(movie_data[offs+2] & 0x40)) PicoPad[1] |= 0x0100; // Z\r
- }\r
-}\r
-\r
-static int try_ropen_file(const char *fname)\r
-{\r
- FILE *f;\r
-\r
- f = fopen(fname, "rb");\r
- if (f) {\r
- fclose(f);\r
- return 1;\r
- }\r
- return 0;\r
-}\r
-\r
-char *emu_get_save_fname(int load, int is_sram, int slot)\r
-{\r
- char *saveFname = static_buff;\r
- char ext[16];\r
-\r
- if (is_sram)\r
- {\r
- strcpy(ext, (PicoAHW & PAHW_MCD) ? ".brm" : ".srm");\r
- romfname_ext(saveFname, sizeof(static_buff),\r
- (PicoAHW & PAHW_MCD) ? "brm"PATH_SEP : "srm"PATH_SEP, ext);\r
- if (!load)\r
- return saveFname;\r
-\r
- if (try_ropen_file(saveFname))\r
- return saveFname;\r
-\r
- romfname_ext(saveFname, sizeof(static_buff), NULL, ext);\r
- if (try_ropen_file(saveFname))\r
- return saveFname;\r
- }\r
- else\r
- {\r
- const char *ext_main = (currentConfig.EmuOpt & EOPT_GZIP_SAVES) ? ".mds.gz" : ".mds";\r
- const char *ext_othr = (currentConfig.EmuOpt & EOPT_GZIP_SAVES) ? ".mds" : ".mds.gz";\r
- ext[0] = 0;\r
- if (slot > 0 && slot < 10)\r
- sprintf(ext, ".%i", slot);\r
- strcat(ext, ext_main);\r
-\r
- if (!load) {\r
- romfname_ext(saveFname, sizeof(static_buff), "mds" PATH_SEP, ext);\r
- return saveFname;\r
- }\r
- else {\r
- romfname_ext(saveFname, sizeof(static_buff), "mds" PATH_SEP, ext);\r
- if (try_ropen_file(saveFname))\r
- return saveFname;\r
-\r
- romfname_ext(saveFname, sizeof(static_buff), NULL, ext);\r
- if (try_ropen_file(saveFname))\r
- return saveFname;\r
-\r
- // try the other ext\r
- ext[0] = 0;\r
- if (slot > 0 && slot < 10)\r
- sprintf(ext, ".%i", slot);\r
- strcat(ext, ext_othr);\r
-\r
- romfname_ext(saveFname, sizeof(static_buff), "mds"PATH_SEP, ext);\r
- if (try_ropen_file(saveFname))\r
- return saveFname;\r
- }\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-int emu_check_save_file(int slot, int *time)\r
-{\r
- return emu_get_save_fname(1, 0, slot) ? 1 : 0;\r
-}\r
-\r
-int emu_save_load_game(int load, int sram)\r
-{\r
- int ret = 0;\r
- char *saveFname;\r
-\r
- // make save filename\r
- saveFname = emu_get_save_fname(load, sram, state_slot);\r
- if (saveFname == NULL) {\r
- if (!sram)\r
- emu_status_msg(load ? "LOAD FAILED (missing file)" : "SAVE FAILED");\r
- return -1;\r
- }\r
-\r
- lprintf("saveLoad (%i, %i): %s\n", load, sram, saveFname);\r
-\r
- if (sram)\r
- {\r
- FILE *sramFile;\r
- int sram_size;\r
- unsigned char *sram_data;\r
- int truncate = 1;\r
- if (PicoAHW & PAHW_MCD)\r
- {\r
- if (PicoOpt & POPT_EN_MCD_RAMCART) {\r
- sram_size = 0x12000;\r
- sram_data = SRam.data;\r
- if (sram_data)\r
- memcpy32((int *)sram_data, (int *)Pico_mcd->bram, 0x2000/4);\r
- } else {\r
- sram_size = 0x2000;\r
- sram_data = Pico_mcd->bram;\r
- truncate = 0; // the .brm may contain RAM cart data after normal brm\r
- }\r
- } else {\r
- sram_size = SRam.size;\r
- sram_data = SRam.data;\r
- }\r
- if (sram_data == NULL)\r
- return 0; // SRam forcefully disabled for this game\r
-\r
- if (load)\r
- {\r
- sramFile = fopen(saveFname, "rb");\r
- if (!sramFile)\r
- return -1;\r
- ret = fread(sram_data, 1, sram_size, sramFile);\r
- ret = ret > 0 ? 0 : -1;\r
- fclose(sramFile);\r
- if ((PicoAHW & PAHW_MCD) && (PicoOpt&POPT_EN_MCD_RAMCART))\r
- memcpy32((int *)Pico_mcd->bram, (int *)sram_data, 0x2000/4);\r
- } else {\r
- // sram save needs some special processing\r
- // see if we have anything to save\r
- for (; sram_size > 0; sram_size--)\r
- if (sram_data[sram_size-1]) break;\r
-\r
- if (sram_size) {\r
- sramFile = fopen(saveFname, truncate ? "wb" : "r+b");\r
- if (!sramFile) sramFile = fopen(saveFname, "wb"); // retry\r
- if (!sramFile) return -1;\r
- ret = fwrite(sram_data, 1, sram_size, sramFile);\r
- ret = (ret != sram_size) ? -1 : 0;\r
- fclose(sramFile);\r
-#ifndef NO_SYNC\r
- sync();\r
-#endif\r
- }\r
- }\r
- return ret;\r
- }\r
- else\r
- {\r
- ret = PicoState(saveFname, !load);\r
- if (!ret) {\r
-#ifndef NO_SYNC\r
- if (!load) sync();\r
-#endif\r
- emu_status_msg(load ? "STATE LOADED" : "STATE SAVED");\r
- } else {\r
- emu_status_msg(load ? "LOAD FAILED" : "SAVE FAILED");\r
- ret = -1;\r
- }\r
-\r
- return ret;\r
- }\r
-}\r
-\r
-void emu_set_fastforward(int set_on)\r
-{\r
- static void *set_PsndOut = NULL;\r
- static int set_Frameskip, set_EmuOpt, is_on = 0;\r
-\r
- if (set_on && !is_on) {\r
- set_PsndOut = PsndOut;\r
- set_Frameskip = currentConfig.Frameskip;\r
- set_EmuOpt = currentConfig.EmuOpt;\r
- PsndOut = NULL;\r
- currentConfig.Frameskip = 8;\r
- currentConfig.EmuOpt &= ~4;\r
- currentConfig.EmuOpt |= 0x40000;\r
- is_on = 1;\r
- emu_status_msg("FAST FORWARD");\r
- }\r
- else if (!set_on && is_on) {\r
- PsndOut = set_PsndOut;\r
- currentConfig.Frameskip = set_Frameskip;\r
- currentConfig.EmuOpt = set_EmuOpt;\r
- PsndRerate(1);\r
- is_on = 0;\r
- }\r
-}\r
-\r
-static void emu_tray_open(void)\r
-{\r
- engineState = PGS_TrayMenu;\r
-}\r
-\r
-static void emu_tray_close(void)\r
-{\r
- emu_status_msg("CD tray closed.");\r
-}\r
-\r
-void emu_32x_startup(void)\r
-{\r
- plat_video_toggle_renderer(0, 0); // HACK\r
- system_announce();\r
-\r
- // force mode change event\r
- rendstatus_old = -1;\r
-}\r
-\r
-void emu_reset_game(void)\r
-{\r
- PicoReset();\r
- reset_timing = 1;\r
-}\r
-\r
-void run_events_pico(unsigned int events)\r
-{\r
- int lim_x;\r
-\r
- if (events & PEV_PICO_SWINP) {\r
- pico_inp_mode++;\r
- if (pico_inp_mode > 2)\r
- pico_inp_mode = 0;\r
- switch (pico_inp_mode) {\r
- case 2: emu_status_msg("Input: Pen on Pad"); break;\r
- case 1: emu_status_msg("Input: Pen on Storyware"); break;\r
- case 0: emu_status_msg("Input: Joystick");\r
- PicoPicohw.pen_pos[0] = PicoPicohw.pen_pos[1] = 0x8000;\r
- break;\r
- }\r
- }\r
- if (events & PEV_PICO_PPREV) {\r
- PicoPicohw.page--;\r
- if (PicoPicohw.page < 0)\r
- PicoPicohw.page = 0;\r
- emu_status_msg("Page %i", PicoPicohw.page);\r
- }\r
- if (events & PEV_PICO_PNEXT) {\r
- PicoPicohw.page++;\r
- if (PicoPicohw.page > 6)\r
- PicoPicohw.page = 6;\r
- emu_status_msg("Page %i", PicoPicohw.page);\r
- }\r
-\r
- if (pico_inp_mode == 0)\r
- return;\r
-\r
- /* handle other input modes */\r
- if (PicoPad[0] & 1) pico_pen_y--;\r
- if (PicoPad[0] & 2) pico_pen_y++;\r
- if (PicoPad[0] & 4) pico_pen_x--;\r
- if (PicoPad[0] & 8) pico_pen_x++;\r
- PicoPad[0] &= ~0x0f; // release UDLR\r
-\r
- lim_x = (Pico.video.reg[12]&1) ? 319 : 255;\r
- if (pico_pen_y < 8)\r
- pico_pen_y = 8;\r
- if (pico_pen_y > 224 - PICO_PEN_ADJUST_Y)\r
- pico_pen_y = 224 - PICO_PEN_ADJUST_Y;\r
- if (pico_pen_x < 0)\r
- pico_pen_x = 0;\r
- if (pico_pen_x > lim_x - PICO_PEN_ADJUST_X)\r
- pico_pen_x = lim_x - PICO_PEN_ADJUST_X;\r
-\r
- PicoPicohw.pen_pos[0] = pico_pen_x;\r
- if (!(Pico.video.reg[12] & 1))\r
- PicoPicohw.pen_pos[0] += pico_pen_x / 4;\r
- PicoPicohw.pen_pos[0] += 0x3c;\r
- PicoPicohw.pen_pos[1] = pico_inp_mode == 1 ? (0x2f8 + pico_pen_y) : (0x1fc + pico_pen_y);\r
-}\r
-\r
-static void do_turbo(int *pad, int acts)\r
-{\r
- static int turbo_pad = 0;\r
- static unsigned char turbo_cnt[3] = { 0, 0, 0 };\r
- int inc = currentConfig.turbo_rate * 2;\r
-\r
- if (acts & 0x1000) {\r
- turbo_cnt[0] += inc;\r
- if (turbo_cnt[0] >= 60)\r
- turbo_pad ^= 0x10, turbo_cnt[0] = 0;\r
- }\r
- if (acts & 0x2000) {\r
- turbo_cnt[1] += inc;\r
- if (turbo_cnt[1] >= 60)\r
- turbo_pad ^= 0x20, turbo_cnt[1] = 0;\r
- }\r
- if (acts & 0x4000) {\r
- turbo_cnt[2] += inc;\r
- if (turbo_cnt[2] >= 60)\r
- turbo_pad ^= 0x40, turbo_cnt[2] = 0;\r
- }\r
- *pad |= turbo_pad & (acts >> 8);\r
-}\r
-\r
-static void run_events_ui(unsigned int which)\r
-{\r
- if (which & (PEV_STATE_LOAD|PEV_STATE_SAVE))\r
- {\r
- int do_it = 1;\r
- if ( emu_check_save_file(state_slot, NULL) &&\r
- (((which & PEV_STATE_LOAD) && (currentConfig.confirm_save & EOPT_CONFIRM_LOAD)) ||\r
- ((which & PEV_STATE_SAVE) && (currentConfig.confirm_save & EOPT_CONFIRM_SAVE))) )\r
- {\r
- const char *nm;\r
- char tmp[64];\r
- int keys, len;\r
-\r
- strcpy(tmp, (which & PEV_STATE_LOAD) ? "LOAD STATE?" : "OVERWRITE SAVE?");\r
- len = strlen(tmp);\r
- nm = in_get_key_name(-1, -PBTN_MA3);\r
- snprintf(tmp + len, sizeof(tmp) - len, "(%s=yes, ", nm);\r
- len = strlen(tmp);\r
- nm = in_get_key_name(-1, -PBTN_MBACK);\r
- snprintf(tmp + len, sizeof(tmp) - len, "%s=no)", nm);\r
-\r
- plat_status_msg_busy_first(tmp);\r
-\r
- in_set_config_int(0, IN_CFG_BLOCKING, 1);\r
- while (in_menu_wait_any(NULL, 50) & (PBTN_MA3|PBTN_MBACK))\r
- ;\r
- while ( !((keys = in_menu_wait_any(NULL, 50)) & (PBTN_MA3|PBTN_MBACK)) )\r
- ;\r
- if (keys & PBTN_MBACK)\r
- do_it = 0;\r
- while (in_menu_wait_any(NULL, 50) & (PBTN_MA3|PBTN_MBACK))\r
- ;\r
- in_set_config_int(0, IN_CFG_BLOCKING, 0);\r
- }\r
- if (do_it) {\r
- plat_status_msg_busy_first((which & PEV_STATE_LOAD) ? "LOADING STATE" : "SAVING STATE");\r
- PicoStateProgressCB = plat_status_msg_busy_next;\r
- emu_save_load_game((which & PEV_STATE_LOAD) ? 1 : 0, 0);\r
- PicoStateProgressCB = NULL;\r
- }\r
- }\r
- if (which & PEV_SWITCH_RND)\r
- {\r
- plat_video_toggle_renderer(1, 0);\r
- }\r
- if (which & (PEV_SSLOT_PREV|PEV_SSLOT_NEXT))\r
- {\r
- if (which & PEV_SSLOT_PREV) {\r
- state_slot -= 1;\r
- if (state_slot < 0)\r
- state_slot = 9;\r
- } else {\r
- state_slot += 1;\r
- if (state_slot > 9)\r
- state_slot = 0;\r
- }\r
-\r
- emu_status_msg("SAVE SLOT %i [%s]", state_slot,\r
- emu_check_save_file(state_slot, NULL) ? "USED" : "FREE");\r
- }\r
- if (which & PEV_MENU)\r
- engineState = PGS_Menu;\r
-}\r
-\r
-void emu_update_input(void)\r
-{\r
- static int prev_events = 0;\r
- int actions[IN_BINDTYPE_COUNT] = { 0, };\r
- int pl_actions[2];\r
- int events;\r
-\r
- in_update(actions);\r
-\r
- pl_actions[0] = actions[IN_BINDTYPE_PLAYER12];\r
- pl_actions[1] = actions[IN_BINDTYPE_PLAYER12] >> 16;\r
-\r
- PicoPad[0] = pl_actions[0] & 0xfff;\r
- PicoPad[1] = pl_actions[1] & 0xfff;\r
-\r
- if (pl_actions[0] & 0x7000)\r
- do_turbo(&PicoPad[0], pl_actions[0]);\r
- if (pl_actions[1] & 0x7000)\r
- do_turbo(&PicoPad[1], pl_actions[1]);\r
-\r
- events = actions[IN_BINDTYPE_EMU] & PEV_MASK;\r
-\r
- // volume is treated in special way and triggered every frame\r
- if (events & (PEV_VOL_DOWN|PEV_VOL_UP))\r
- plat_update_volume(1, events & PEV_VOL_UP);\r
-\r
- if ((events ^ prev_events) & PEV_FF) {\r
- emu_set_fastforward(events & PEV_FF);\r
- plat_update_volume(0, 0);\r
- reset_timing = 1;\r
- }\r
-\r
- events &= ~prev_events;\r
-\r
- if (PicoAHW == PAHW_PICO)\r
- run_events_pico(events);\r
- if (events)\r
- run_events_ui(events);\r
- if (movie_data)\r
- update_movie();\r
-\r
- prev_events = actions[IN_BINDTYPE_EMU] & PEV_MASK;\r
-}\r
-\r
-static void mkdir_path(char *path_with_reserve, int pos, const char *name)\r
-{\r
- strcpy(path_with_reserve + pos, name);\r
- if (plat_is_dir(path_with_reserve))\r
- return;\r
- if (mkdir(path_with_reserve, 0777) < 0)\r
- lprintf("failed to create: %s\n", path_with_reserve);\r
-}\r
-\r
-void emu_cmn_forced_frame(int no_scale, int do_emu)\r
-{\r
- int po_old = PicoOpt;\r
-\r
- memset32(g_screen_ptr, 0, g_screen_width * g_screen_height * 2 / 4);\r
-\r
- PicoOpt &= ~POPT_ALT_RENDERER;\r
- PicoOpt |= POPT_ACC_SPRITES;\r
- if (!no_scale)\r
- PicoOpt |= POPT_EN_SOFTSCALE;\r
-\r
- PicoDrawSetOutFormat(PDF_RGB555, 1);\r
- Pico.m.dirtyPal = 1;\r
- if (do_emu)\r
- PicoFrame();\r
- else\r
- PicoFrameDrawOnly();\r
-\r
- PicoOpt = po_old;\r
-}\r
-\r
-void emu_init(void)\r
-{\r
- char path[512];\r
- int pos;\r
-\r
-#if 0\r
- // FIXME: handle through menu, etc\r
- FILE *f;\r
- f = fopen("32X_M_BIOS.BIN", "rb");\r
- p32x_bios_m = malloc(2048);\r
- fread(p32x_bios_m, 1, 2048, f);\r
- fclose(f);\r
- f = fopen("32X_S_BIOS.BIN", "rb");\r
- p32x_bios_s = malloc(1024);\r
- fread(p32x_bios_s, 1, 1024, f);\r
- fclose(f);\r
-#endif\r
-\r
- /* make dirs for saves */\r
- pos = plat_get_root_dir(path, sizeof(path) - 4);\r
- mkdir_path(path, pos, "mds");\r
- mkdir_path(path, pos, "srm");\r
- mkdir_path(path, pos, "brm");\r
-\r
- pprof_init();\r
-\r
- make_config_cfg(path);\r
- config_readlrom(path);\r
-\r
- PicoInit();\r
- PicoMessage = plat_status_msg_busy_next;\r
- PicoMCDopenTray = emu_tray_open;\r
- PicoMCDcloseTray = emu_tray_close;\r
-}\r
-\r
-void emu_finish(void)\r
-{\r
- // save SRAM\r
- if ((currentConfig.EmuOpt & EOPT_EN_SRAM) && SRam.changed) {\r
- emu_save_load_game(0, 1);\r
- SRam.changed = 0;\r
- }\r
-\r
- if (!(currentConfig.EmuOpt & EOPT_NO_AUTOSVCFG)) {\r
- char cfg[512];\r
- make_config_cfg(cfg);\r
- config_writelrom(cfg);\r
-#ifndef NO_SYNC\r
- sync();\r
-#endif\r
- }\r
-\r
- pprof_finish();\r
-\r
- PicoExit();\r
-}\r
-\r
-static void skip_frame(int do_audio)\r
-{\r
- PicoSkipFrame = do_audio ? 1 : 2;\r
- PicoFrame();\r
- PicoSkipFrame = 0;\r
-}\r
-\r
-/* our tick here is 1 us right now */\r
-#define ms_to_ticks(x) (unsigned int)(x * 1000)\r
-#define get_ticks() plat_get_ticks_us()\r
-\r
-void emu_loop(void)\r
-{\r
- int pframes_done; /* "period" frames, used for sync */\r
- int frames_done, frames_shown; /* actual frames for fps counter */\r
- int target_fps, target_frametime;\r
- unsigned int timestamp_base = 0, timestamp_fps;\r
- char *notice_msg = NULL;\r
- char fpsbuff[24];\r
- int i;\r
-\r
- fpsbuff[0] = 0;\r
-\r
- /* make sure we are in correct mode */\r
- Pico.m.dirtyPal = 1;\r
- rendstatus_old = -1;\r
-\r
- PicoLoopPrepare();\r
-\r
- // prepare CD buffer\r
- if (PicoAHW & PAHW_MCD)\r
- PicoCDBufferInit();\r
-\r
- pemu_loop_prep();\r
-\r
- /* number of ticks per frame */\r
- if (Pico.m.pal) {\r
- target_fps = 50;\r
- target_frametime = ms_to_ticks(1000) / 50;\r
- } else {\r
- target_fps = 60;\r
- target_frametime = ms_to_ticks(1000) / 60 + 1;\r
- }\r
-\r
- timestamp_fps = get_ticks();\r
- reset_timing = 1;\r
-\r
- frames_done = frames_shown = pframes_done = 0;\r
-\r
- plat_video_wait_vsync();\r
-\r
- /* loop with resync every 1 sec. */\r
- while (engineState == PGS_Running)\r
- {\r
- unsigned int timestamp;\r
- int diff, diff_lim;\r
-\r
- pprof_start(main);\r
-\r
- timestamp = get_ticks();\r
- if (reset_timing) {\r
- reset_timing = 0;\r
- timestamp_base = timestamp;\r
- pframes_done = 0;\r
- }\r
-\r
- // show notice_msg message?\r
- if (notice_msg_time != 0)\r
- {\r
- static int noticeMsgSum;\r
- if (timestamp - ms_to_ticks(notice_msg_time) > ms_to_ticks(STATUS_MSG_TIMEOUT)) {\r
- notice_msg_time = 0;\r
- plat_status_msg_clear();\r
- notice_msg = NULL;\r
- } else {\r
- int sum = noticeMsg[0] + noticeMsg[1] + noticeMsg[2];\r
- if (sum != noticeMsgSum) {\r
- plat_status_msg_clear();\r
- noticeMsgSum = sum;\r
- }\r
- notice_msg = noticeMsg;\r
- }\r
- }\r
-\r
- // second changed?\r
- if (timestamp - timestamp_fps >= ms_to_ticks(1000))\r
- {\r
-#ifdef BENCHMARK\r
- static int bench = 0, bench_fps = 0, bench_fps_s = 0, bfp = 0, bf[4];\r
- if (++bench == 10) {\r
- bench = 0;\r
- bench_fps_s = bench_fps;\r
- bf[bfp++ & 3] = bench_fps;\r
- bench_fps = 0;\r
- }\r
- bench_fps += frames_shown;\r
- sprintf(fpsbuff, "%02i/%02i/%02i", frames_shown, bench_fps_s, (bf[0]+bf[1]+bf[2]+bf[3])>>2);\r
- printf("%s\n", fpsbuff);\r
-#else\r
- if (currentConfig.EmuOpt & EOPT_SHOW_FPS) {\r
- sprintf(fpsbuff, "%02i/%02i", frames_shown, frames_done);\r
- if (fpsbuff[5] == 0) { fpsbuff[5] = fpsbuff[6] = ' '; fpsbuff[7] = 0; }\r
- }\r
-#endif\r
- frames_shown = frames_done = 0;\r
- timestamp_fps += ms_to_ticks(1000);\r
- }\r
-#ifdef PFRAMES\r
- sprintf(fpsbuff, "%i", Pico.m.frame_count);\r
-#endif\r
-\r
- if (timestamp - timestamp_base >= ms_to_ticks(1000))\r
- {\r
- if ((currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) && currentConfig.Frameskip >= 0)\r
- pframes_done = 0;\r
- else\r
- pframes_done -= target_fps;\r
- if (pframes_done < -2) {\r
- /* don't drag more than 2 frames behind */\r
- pframes_done = -2;\r
- timestamp_base = timestamp - 2 * target_frametime;\r
- }\r
- else\r
- timestamp_base += ms_to_ticks(1000);\r
- }\r
-\r
- diff = timestamp - timestamp_base;\r
- diff_lim = (pframes_done + 1) * target_frametime;\r
-\r
- if (currentConfig.Frameskip >= 0) // frameskip enabled\r
- {\r
- for (i = 0; i < currentConfig.Frameskip; i++) {\r
- emu_update_input();\r
- skip_frame(1);\r
- pframes_done++; frames_done++;\r
- diff_lim += target_frametime;\r
-\r
- if (!(currentConfig.EmuOpt & (EOPT_NO_FRMLIMIT|EOPT_EXT_FRMLIMIT))) {\r
- timestamp = get_ticks();\r
- diff = timestamp - timestamp_base;\r
- if (!reset_timing && diff < diff_lim) // we are too fast\r
- plat_wait_till_us(timestamp_base + diff_lim);\r
- }\r
- }\r
- }\r
- else if (diff > diff_lim)\r
- {\r
- /* no time left for this frame - skip */\r
- /* limit auto frameskip to 8 */\r
- if (frames_done / 8 <= frames_shown) {\r
- emu_update_input();\r
- skip_frame(diff < diff_lim + target_frametime * 16);\r
- pframes_done++; frames_done++;\r
- continue;\r
- }\r
- }\r
-\r
- emu_update_input();\r
- PicoFrame();\r
- pemu_finalize_frame(fpsbuff, notice_msg);\r
-\r
- // plat_video_flip();\r
-\r
- /* frame limiter */\r
- if (!reset_timing && !(currentConfig.EmuOpt & (EOPT_NO_FRMLIMIT|EOPT_EXT_FRMLIMIT)))\r
- {\r
- timestamp = get_ticks();\r
- diff = timestamp - timestamp_base;\r
-\r
- // sleep or vsync if we are still too fast\r
- if (diff < diff_lim)\r
- {\r
- // we are too fast\r
- plat_wait_till_us(timestamp_base + diff_lim - target_frametime / 4);\r
- if (currentConfig.EmuOpt & EOPT_VSYNC)\r
- plat_video_wait_vsync();\r
- }\r
- }\r
-\r
- // XXX: for some plats it might be better to flip before vsync\r
- // (due to shadow registers in display hw)\r
- plat_video_flip();\r
-\r
- pframes_done++; frames_done++; frames_shown++;\r
-\r
- pprof_end(main);\r
- }\r
-\r
- emu_set_fastforward(0);\r
-\r
- // save SRAM\r
- if ((currentConfig.EmuOpt & EOPT_EN_SRAM) && SRam.changed) {\r
- plat_status_msg_busy_first("Writing SRAM/BRAM...");\r
- emu_save_load_game(0, 1);\r
- SRam.changed = 0;\r
- }\r
-\r
- pemu_loop_end();\r
-\r
- // pemu_loop_end() might want to do 1 frame for bg image,\r
- // so free CD buffer here\r
- if (PicoAHW & PAHW_MCD)\r
- PicoCDBufferFree();\r
-}\r
-\r
+++ /dev/null
-// (c) Copyright 2006-2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-#include "port_config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define array_size(x) (sizeof(x) / sizeof(x[0]))
-
-extern void *g_screen_ptr;
-
-#if SCREEN_SIZE_FIXED
-#define g_screen_width SCREEN_WIDTH
-#define g_screen_height SCREEN_HEIGHT
-#else
-extern int g_screen_width;
-extern int g_screen_height;
-#endif
-
-
-#define EOPT_EN_SRAM (1<<0)
-#define EOPT_SHOW_FPS (1<<1)
-#define EOPT_EN_SOUND (1<<2)
-#define EOPT_GZIP_SAVES (1<<3)
-#define EOPT_MMUHACK (1<<4)
-#define EOPT_NO_AUTOSVCFG (1<<5)
-#define EOPT_16BPP (1<<7) // depreceted for .renderer
-#define EOPT_RAM_TIMINGS (1<<8)
-#define EOPT_EN_CD_LEDS (1<<10)
-#define EOPT_A_SN_GAMMA (1<<12)
-#define EOPT_VSYNC (1<<13)
-#define EOPT_GIZ_SCANLN (1<<14)
-#define EOPT_GIZ_DBLBUF (1<<15)
-#define EOPT_VSYNC_MODE (1<<16)
-#define EOPT_SHOW_RTC (1<<17)
-#define EOPT_NO_FRMLIMIT (1<<18)
-#define EOPT_WIZ_TEAR_FIX (1<<19)
-#define EOPT_EXT_FRMLIMIT (1<<20) // no internal frame limiter (limited by snd, etc)
-
-enum {
- EOPT_SCALE_NONE = 0,
- EOPT_SCALE_SW,
- EOPT_SCALE_HW,
-};
-
-enum {
- EOPT_CONFIRM_NONE = 0,
- EOPT_CONFIRM_SAVE = 1,
- EOPT_CONFIRM_LOAD = 2,
- EOPT_CONFIRM_BOTH = 3,
-};
-
-typedef struct _currentConfig_t {
- int EmuOpt;
- int s_PicoOpt;
- int s_PsndRate;
- int s_PicoRegion;
- int s_PicoAutoRgnOrder;
- int s_PicoCDBuffers;
- int Frameskip;
- int confirm_save;
- int CPUclock;
- int volume;
- int gamma;
- int scaling; // gp2x: EOPT_SCALE_*; psp: bilinear filtering
- int vscaling;
- int rotation; // for UIQ
- float scale; // psp: screen scale
- float hscale32, hscale40; // psp: horizontal scale
- int gamma2; // psp: black level
- int turbo_rate;
- int renderer;
- int renderer32x;
- int filter; // pandora
- int analog_deadzone;
-} currentConfig_t;
-
-extern currentConfig_t currentConfig, defaultConfig;
-extern char *PicoConfigFile;
-extern int rom_loaded;
-extern int state_slot;
-extern int config_slot, config_slot_current;
-extern unsigned char *movie_data;
-extern int reset_timing;
-
-#define PICO_PEN_ADJUST_X 4
-#define PICO_PEN_ADJUST_Y 2
-extern int pico_pen_x, pico_pen_y;
-extern int pico_inp_mode;
-
-extern char rom_fname_reload[512]; // ROM to try loading on next PGS_ReloadRom
-extern char rom_fname_loaded[512]; // currently loaded ROM filename
-
-// engine states
-extern int engineState;
-enum TPicoGameState {
- PGS_Paused = 1,
- PGS_Running,
- PGS_Quit,
- PGS_KeyConfig,
- PGS_ReloadRom,
- PGS_Menu,
- PGS_TrayMenu,
- PGS_RestartRun,
- PGS_Suspending, /* PSP */
- PGS_SuspendWake, /* PSP */
-};
-
-// media types
-enum {
- PM_BAD = 0,
- PM_MD_CART, /* also 32x */
- PM_MARK3,
- PM_CD,
-};
-
-void emu_init(void);
-void emu_finish(void);
-void emu_loop(void);
-
-int emu_reload_rom(char *rom_fname);
-int emu_swap_cd(const char *fname);
-int emu_save_load_game(int load, int sram);
-void emu_reset_game(void);
-
-void emu_prep_defconfig(void);
-void emu_set_defconfig(void);
-int emu_read_config(const char *rom_fname, int no_defaults);
-int emu_write_config(int game);
-
-char *emu_get_save_fname(int load, int is_sram, int slot);
-int emu_check_save_file(int slot, int *time);
-
-void emu_text_out8 (int x, int y, const char *text);
-void emu_text_out16(int x, int y, const char *text);
-void emu_text_out8_rot (int x, int y, const char *text);
-void emu_text_out16_rot(int x, int y, const char *text);
-
-void emu_make_path(char *buff, const char *end, int size);
-void emu_update_input(void);
-void emu_get_game_name(char *str150);
-void emu_set_fastforward(int set_on);
-void emu_status_msg(const char *format, ...);
-
-/* used by some (but not all) platforms */
-void emu_cmn_forced_frame(int no_scale, int do_emu);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
+++ /dev/null
-// (c) Copyright 2006-2009 notaz, All rights reserved.\r
-// Free for non-commercial use.\r
-\r
-// For commercial use, separate licencing terms must be obtained.\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <strings.h>\r
-\r
-#include "menu.h"\r
-#include "emu.h"\r
-#include "config.h"\r
-#include "input.h"\r
-#include "plat.h"\r
-#include <cpu/debug.h>\r
-#include <version.h>\r
-\r
-\r
-extern char *PicoConfigFile;\r
-static int load_state_slot = -1;\r
-char **g_argv;\r
-\r
-void parse_cmd_line(int argc, char *argv[])\r
-{\r
- int x, unrecognized = 0;\r
-\r
- for (x = 1; x < argc; x++)\r
- {\r
- if (argv[x][0] == '-')\r
- {\r
- if (strcasecmp(argv[x], "-config") == 0) {\r
- if (x+1 < argc) { ++x; PicoConfigFile = argv[x]; }\r
- }\r
- else if (strcasecmp(argv[x], "-loadstate") == 0) {\r
- if (x+1 < argc) { ++x; load_state_slot = atoi(argv[x]); }\r
- }\r
- else if (strcasecmp(argv[x], "-pdb") == 0) {\r
- if (x+1 < argc) { ++x; pdb_command(argv[x]); }\r
- }\r
- else if (strcasecmp(argv[x], "-pdb_connect") == 0) {\r
- if (x+2 < argc) { pdb_net_connect(argv[x+1], argv[x+2]); x += 2; }\r
- }\r
- else {\r
- unrecognized = 1;\r
- break;\r
- }\r
- } else {\r
- /* External Frontend: ROM Name */\r
- FILE *f;\r
- strncpy(rom_fname_reload, argv[x], sizeof(rom_fname_reload));\r
- rom_fname_reload[sizeof(rom_fname_reload) - 1] = 0;\r
- f = fopen(rom_fname_reload, "rb");\r
- if (f) fclose(f);\r
- else unrecognized = 1;\r
- engineState = PGS_ReloadRom;\r
- break;\r
- }\r
- }\r
-\r
- if (unrecognized) {\r
- printf("\n\n\nPicoDrive v" VERSION " (c) notaz, 2006-2009\n");\r
- printf("usage: %s [options] [romfile]\n", argv[0]);\r
- printf("options:\n"\r
- " -config <file> use specified config file instead of default 'config.cfg'\n"\r
- " -loadstate <num> if ROM is specified, try loading slot <num>\n");\r
- }\r
-}\r
-\r
-\r
-int main(int argc, char *argv[])\r
-{\r
- g_argv = argv;\r
-\r
- plat_early_init();\r
-\r
- in_init();\r
- in_probe();\r
-\r
- plat_init();\r
-\r
- emu_prep_defconfig(); // depends on input\r
- emu_read_config(NULL, 0);\r
-\r
- emu_init();\r
- menu_init();\r
-\r
- engineState = PGS_Menu;\r
-\r
- if (argc > 1)\r
- parse_cmd_line(argc, argv);\r
-\r
- if (engineState == PGS_ReloadRom)\r
- {\r
- if (emu_reload_rom(rom_fname_reload)) {\r
- engineState = PGS_Running;\r
- if (load_state_slot >= 0) {\r
- state_slot = load_state_slot;\r
- emu_save_load_game(1, 0);\r
- }\r
- }\r
- }\r
-\r
- for (;;)\r
- {\r
- switch (engineState)\r
- {\r
- case PGS_Menu:\r
- menu_loop();\r
- break;\r
-\r
- case PGS_TrayMenu:\r
- menu_loop_tray();\r
- break;\r
-\r
- case PGS_ReloadRom:\r
- if (emu_reload_rom(rom_fname_reload))\r
- engineState = PGS_Running;\r
- else {\r
- printf("PGS_ReloadRom == 0\n");\r
- engineState = PGS_Menu;\r
- }\r
- break;\r
-\r
- case PGS_RestartRun:\r
- engineState = PGS_Running;\r
- /* vvv fallthrough */\r
-\r
- case PGS_Running:\r
- emu_loop();\r
- break;\r
-\r
- case PGS_Quit:\r
- goto endloop;\r
-\r
- default:\r
- printf("engine got into unknown state (%i), exitting\n", engineState);\r
- goto endloop;\r
- }\r
- }\r
-\r
- endloop:\r
-\r
- emu_finish();\r
- plat_finish();\r
-\r
- return 0;\r
-}\r
+++ /dev/null
-#include <string.h>
-
-#include "emu.h"
-#include "menu_pico.h"
-
-#include <version.h>
-#include <revision.h>
-
-#include <pico/pico.h>
-#include <pico/patch.h>
-
-// rrrr rggg gggb bbbb
-static unsigned short fname2color(const char *fname)
-{
- const char *ext = fname + strlen(fname) - 3;
- static const char *rom_exts[] = { "zip", "bin", "smd", "gen", "iso", "cso", "cue" };
- static const char *other_exts[] = { "gmv", "pat" };
- int i;
-
- if (ext < fname) ext = fname;
- for (i = 0; i < array_size(rom_exts); i++)
- if (strcasecmp(ext, rom_exts[i]) == 0) return 0xbdff; // FIXME: mk defines
- for (i = 0; i < array_size(other_exts); i++)
- if (strcasecmp(ext, other_exts[i]) == 0) return 0xaff5;
- return 0xffff;
-}
-
-static const char *filter_exts[] = {
- ".mp3", ".MP3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html",
- ".jpg", ".gpe"
-};
-
-#include "menu.c"
-
-/* platform specific options and handlers */
-#if defined(__GP2X__)
-#include "../gp2x/menu.c"
-#elif defined(PANDORA)
-#include "../pandora/menu.c"
-#else
-#define MENU_OPTIONS_GFX
-#define MENU_OPTIONS_ADV
-#define menu_main_plat_draw NULL
-#endif
-
-static void menu_enter(int is_rom_loaded)
-{
- if (is_rom_loaded)
- {
- // darken the active framebuffer
- menu_darken_bg(g_menubg_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h, 1);
- }
- else
- {
- char buff[256];
-
- // should really only happen once, on startup..
- emu_make_path(buff, "skin/background.png", sizeof(buff));
- if (readpng(g_menubg_ptr, buff, READPNG_BG, g_menuscreen_w, g_menuscreen_h) < 0)
- memset(g_menubg_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
- }
-
- plat_video_menu_enter(is_rom_loaded);
-}
-
-static void draw_savestate_bg(int slot)
-{
- const char *fname;
- void *tmp_state;
-
- fname = emu_get_save_fname(1, 0, slot);
- if (!fname)
- return;
-
- tmp_state = PicoTmpStateSave();
-
- PicoStateLoadGfx(fname);
-
- /* do a frame and fetch menu bg */
- pemu_forced_frame(0, 0);
-
- menu_darken_bg(g_menubg_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h, 1);
-
- PicoTmpStateRestore(tmp_state);
-}
-
-// --------- loading ROM screen ----------
-
-static int cdload_called = 0;
-
-static void load_progress_cb(int percent)
-{
- int ln, len = percent * g_menuscreen_w / 100;
- unsigned short *dst;
-
- if (len > g_menuscreen_w)
- len = g_menuscreen_w;
-
- menu_draw_begin(0);
- dst = (unsigned short *)g_menuscreen_ptr + g_menuscreen_w * me_sfont_h * 2;
- for (ln = me_sfont_h - 2; ln > 0; ln--, dst += g_menuscreen_w)
- memset(dst, 0xff, len * 2);
- menu_draw_end();
-}
-
-static void cdload_progress_cb(const char *fname, int percent)
-{
- int ln, len = percent * g_menuscreen_w / 100;
- unsigned short *dst;
-
- menu_draw_begin(0);
- dst = (unsigned short *)g_menuscreen_ptr + g_menuscreen_w * me_sfont_h * 2;
- memset(dst, 0xff, g_menuscreen_w * (me_sfont_h - 2) * 2);
-
- smalltext_out16(1, 3 * me_sfont_h, "Processing CD image / MP3s", 0xffff);
- smalltext_out16(1, 4 * me_sfont_h, fname, 0xffff);
- dst += g_menuscreen_w * me_sfont_h * 3;
-
- if (len > g_menuscreen_w)
- len = g_menuscreen_w;
-
- for (ln = (me_sfont_h - 2); ln > 0; ln--, dst += g_menuscreen_w)
- memset(dst, 0xff, len * 2);
- menu_draw_end();
-
- cdload_called = 1;
-}
-
-void menu_romload_prepare(const char *rom_name)
-{
- const char *p = rom_name + strlen(rom_name);
- int i;
-
- while (p > rom_name && *p != '/')
- p--;
-
- /* fill all buffers, callbacks won't update in full */
- for (i = 0; i < 3; i++) {
- menu_draw_begin(1);
- smalltext_out16(1, 1, "Loading", 0xffff);
- smalltext_out16(1, me_sfont_h, p, 0xffff);
- menu_draw_end();
- }
-
- PicoCartLoadProgressCB = load_progress_cb;
- PicoCDLoadProgressCB = cdload_progress_cb;
- cdload_called = 0;
-}
-
-void menu_romload_end(void)
-{
- PicoCartLoadProgressCB = NULL;
- PicoCDLoadProgressCB = NULL;
-
- menu_draw_begin(0);
- smalltext_out16(1, (cdload_called ? 6 : 3) * me_sfont_h,
- "Starting emulation...", 0xffff);
- menu_draw_end();
-}
-
-// ------------ patch/gg menu ------------
-
-static void draw_patchlist(int sel)
-{
- int max_cnt, start, i, pos, active;
-
- max_cnt = g_menuscreen_h / me_sfont_h;
- start = max_cnt / 2 - sel;
-
- menu_draw_begin(1);
-
- for (i = 0; i < PicoPatchCount; i++) {
- pos = start + i;
- if (pos < 0) continue;
- if (pos >= max_cnt) break;
- active = PicoPatches[i].active;
- smalltext_out16(14, pos * me_sfont_h, active ? "ON " : "OFF", active ? 0xfff6 : 0xffff);
- smalltext_out16(14 + me_sfont_w*4, pos * me_sfont_h, PicoPatches[i].name, active ? 0xfff6 : 0xffff);
- }
- pos = start + i;
- if (pos < max_cnt)
- smalltext_out16(14, pos * me_sfont_h, "done", 0xffff);
-
- text_out16(5, max_cnt / 2 * me_sfont_h, ">");
- menu_draw_end();
-}
-
-static void menu_loop_patches(void)
-{
- static int menu_sel = 0;
- int inp;
-
- for (;;)
- {
- draw_patchlist(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R
- |PBTN_MOK|PBTN_MBACK, NULL, 33);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = PicoPatchCount; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > PicoPatchCount) menu_sel = 0; }
- if (inp &(PBTN_LEFT|PBTN_L)) { menu_sel-=10; if (menu_sel < 0) menu_sel = 0; }
- if (inp &(PBTN_RIGHT|PBTN_R)) { menu_sel+=10; if (menu_sel > PicoPatchCount) menu_sel = PicoPatchCount; }
- if (inp & PBTN_MOK) { // action
- if (menu_sel < PicoPatchCount)
- PicoPatches[menu_sel].active = !PicoPatches[menu_sel].active;
- else break;
- }
- if (inp & PBTN_MBACK)
- break;
- }
-}
-
-// -------------- key config --------------
-
-// PicoPad[] format: MXYZ SACB RLDU
-me_bind_action me_ctrl_actions[] =
-{
- { "UP ", 0x0001 },
- { "DOWN ", 0x0002 },
- { "LEFT ", 0x0004 },
- { "RIGHT ", 0x0008 },
- { "A ", 0x0040 },
- { "B ", 0x0010 },
- { "C ", 0x0020 },
- { "A turbo", 0x4000 },
- { "B turbo", 0x1000 },
- { "C turbo", 0x2000 },
- { "START ", 0x0080 },
- { "MODE ", 0x0800 },
- { "X ", 0x0400 },
- { "Y ", 0x0200 },
- { "Z ", 0x0100 },
- { NULL, 0 },
-};
-
-me_bind_action emuctrl_actions[] =
-{
- { "Load State ", PEV_STATE_LOAD },
- { "Save State ", PEV_STATE_SAVE },
- { "Prev Save Slot ", PEV_SSLOT_PREV },
- { "Next Save Slot ", PEV_SSLOT_NEXT },
- { "Switch Renderer ", PEV_SWITCH_RND },
- { "Volume Down ", PEV_VOL_DOWN },
- { "Volume Up ", PEV_VOL_UP },
- { "Fast forward ", PEV_FF },
- { "Enter Menu ", PEV_MENU },
- { "Pico Next page ", PEV_PICO_PNEXT },
- { "Pico Prev page ", PEV_PICO_PPREV },
- { "Pico Switch input", PEV_PICO_SWINP },
- { NULL, 0 }
-};
-
-static int key_config_loop_wrap(int id, int keys)
-{
- switch (id) {
- case MA_CTRL_PLAYER1:
- key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 0);
- break;
- case MA_CTRL_PLAYER2:
- key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 1);
- break;
- case MA_CTRL_EMU:
- key_config_loop(emuctrl_actions, array_size(emuctrl_actions) - 1, -1);
- break;
- default:
- break;
- }
- return 0;
-}
-
-static const char *mgn_dev_name(int id, int *offs)
-{
- const char *name = NULL;
- static int it = 0;
-
- if (id == MA_CTRL_DEV_FIRST)
- it = 0;
-
- for (; it < IN_MAX_DEVS; it++) {
- name = in_get_dev_name(it, 1, 1);
- if (name != NULL)
- break;
- }
-
- it++;
- return name;
-}
-
-static int mh_saveloadcfg(int id, int keys);
-static const char *mgn_saveloadcfg(int id, int *offs);
-
-static menu_entry e_menu_keyconfig[] =
-{
- mee_handler_id("Player 1", MA_CTRL_PLAYER1, key_config_loop_wrap),
- mee_handler_id("Player 2", MA_CTRL_PLAYER2, key_config_loop_wrap),
- mee_handler_id("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap),
- mee_onoff ("6 button pad", MA_OPT_6BUTTON_PAD, PicoOpt, POPT_6BTN_PAD),
- mee_range ("Turbo rate", MA_CTRL_TURBO_RATE, currentConfig.turbo_rate, 1, 30),
- mee_range ("Analog deadzone", MA_CTRL_DEADZONE, currentConfig.analog_deadzone, 1, 99),
- mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_saveloadcfg, mgn_saveloadcfg),
- mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_saveloadcfg, mgn_saveloadcfg),
- mee_label (""),
- mee_label ("Input devices:"),
- mee_label_mk (MA_CTRL_DEV_FIRST, mgn_dev_name),
- mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
- mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
- mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
- mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
- mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
- mee_label_mk (MA_CTRL_DEV_NEXT, mgn_dev_name),
- mee_end,
-};
-
-static int menu_loop_keyconfig(int id, int keys)
-{
- static int sel = 0;
-
- me_enable(e_menu_keyconfig, MA_OPT_SAVECFG_GAME, rom_loaded);
- me_loop(e_menu_keyconfig, &sel);
- return 0;
-}
-
-// ------------ SCD options menu ------------
-
-static const char *mgn_cdopt_ra(int id, int *offs)
-{
- *offs = -5;
- if (PicoCDBuffers <= 0)
- return " OFF";
- sprintf(static_buff, "%5iK", PicoCDBuffers * 2);
- return static_buff;
-}
-
-static int mh_cdopt_ra(int id, int keys)
-{
- if (keys & PBTN_LEFT) {
- PicoCDBuffers >>= 1;
- if (PicoCDBuffers < 2)
- PicoCDBuffers = 0;
- } else {
- if (PicoCDBuffers <= 0)
- PicoCDBuffers = 1;
- PicoCDBuffers <<= 1;
- if (PicoCDBuffers > 8*1024)
- PicoCDBuffers = 8*1024; // 16M
- }
- return 0;
-}
-
-static const char h_cdleds[] = "Show power/CD LEDs of emulated console";
-static const char h_cdda[] = "Play audio tracks from mp3s/wavs/bins";
-static const char h_cdpcm[] = "Emulate PCM audio chip for effects/voices/music";
-static const char h_srcart[] = "Emulate the save RAM cartridge accessory\n"
- "most games don't need this";
-static const char h_scfx[] = "Emulate scale/rotate ASIC chip for graphics effects\n"
- "disable to improve performance";
-static const char h_bsync[] = "More accurate mode for CPUs (needed for some games)\n"
- "disable to improve performance";
-
-static menu_entry e_menu_cd_options[] =
-{
- mee_onoff_h("CD LEDs", MA_CDOPT_LEDS, currentConfig.EmuOpt, EOPT_EN_CD_LEDS, h_cdleds),
- mee_onoff_h("CDDA audio", MA_CDOPT_CDDA, PicoOpt, POPT_EN_MCD_CDDA, h_cdda),
- mee_onoff_h("PCM audio", MA_CDOPT_PCM, PicoOpt, POPT_EN_MCD_PCM, h_cdpcm),
- mee_cust ("ReadAhead buffer", MA_CDOPT_READAHEAD, mh_cdopt_ra, mgn_cdopt_ra),
- mee_onoff_h("SaveRAM cart", MA_CDOPT_SAVERAM, PicoOpt, POPT_EN_MCD_RAMCART, h_srcart),
- mee_onoff_h("Scale/Rot. fx (slow)", MA_CDOPT_SCALEROT_CHIP, PicoOpt, POPT_EN_MCD_GFX, h_scfx),
- mee_onoff_h("Better sync (slow)", MA_CDOPT_BETTER_SYNC, PicoOpt, POPT_EN_MCD_PSYNC, h_bsync),
- mee_end,
-};
-
-static int menu_loop_cd_options(int id, int keys)
-{
- static int sel = 0;
- me_loop(e_menu_cd_options, &sel);
- return 0;
-}
-
-// ------------ 32X options menu ------------
-
-#ifndef NO_32X
-
-// convert from multiplier of VClk
-static int mh_opt_sh2cycles(int id, int keys)
-{
- int *mul = (id == MA_32XOPT_MSH2_CYCLES) ? &p32x_msh2_multiplier : &p32x_ssh2_multiplier;
-
- if (keys & (PBTN_LEFT|PBTN_RIGHT))
- *mul += (keys & PBTN_LEFT) ? -10 : 10;
- if (keys & (PBTN_L|PBTN_R))
- *mul += (keys & PBTN_L) ? -100 : 100;
-
- if (*mul < 1)
- *mul = 1;
- else if (*mul > (10 << SH2_MULTI_SHIFT))
- *mul = 10 << SH2_MULTI_SHIFT;
-
- return 0;
-}
-
-static const char *mgn_opt_sh2cycles(int id, int *offs)
-{
- int mul = (id == MA_32XOPT_MSH2_CYCLES) ? p32x_msh2_multiplier : p32x_ssh2_multiplier;
-
- sprintf(static_buff, "%d", 7670 * mul >> SH2_MULTI_SHIFT);
- return static_buff;
-}
-
-static const char h_32x_enable[] = "Enable emulation of the 32X addon";
-static const char h_pwm[] = "Disabling may improve performance, but break sound";
-static const char h_sh2cycles[] = "Cycles/millisecond (similar to DOSBox)\n"
- "lower values speed up emulation but break games\n"
- "at least 11000 recommended for compatibility";
-
-static menu_entry e_menu_32x_options[] =
-{
- mee_onoff_h ("32X enabled", MA_32XOPT_ENABLE_32X, PicoOpt, POPT_EN_32X, h_32x_enable),
- mee_enum ("32X renderer", MA_32XOPT_RENDERER, currentConfig.renderer32x, renderer_names32x),
- mee_onoff_h ("PWM sound", MA_32XOPT_PWM, PicoOpt, POPT_EN_PWM, h_pwm),
- mee_cust_h ("Master SH2 cycles", MA_32XOPT_MSH2_CYCLES, mh_opt_sh2cycles, mgn_opt_sh2cycles, h_sh2cycles),
- mee_cust_h ("Slave SH2 cycles", MA_32XOPT_SSH2_CYCLES, mh_opt_sh2cycles, mgn_opt_sh2cycles, h_sh2cycles),
- mee_end,
-};
-
-static int menu_loop_32x_options(int id, int keys)
-{
- static int sel = 0;
-
- me_enable(e_menu_32x_options, MA_32XOPT_RENDERER, renderer_names32x[0] != NULL);
- me_loop(e_menu_32x_options, &sel);
-
- return 0;
-}
-
-#endif
-
-// ------------ adv options menu ------------
-
-static menu_entry e_menu_adv_options[] =
-{
- mee_onoff ("SRAM/BRAM saves", MA_OPT_SRAM_STATES, currentConfig.EmuOpt, EOPT_EN_SRAM),
- mee_onoff ("Disable sprite limit", MA_OPT2_NO_SPRITE_LIM, PicoOpt, POPT_DIS_SPRITE_LIM),
- mee_onoff ("Emulate Z80", MA_OPT2_ENABLE_Z80, PicoOpt, POPT_EN_Z80),
- mee_onoff ("Emulate YM2612 (FM)", MA_OPT2_ENABLE_YM2612, PicoOpt, POPT_EN_FM),
- mee_onoff ("Emulate SN76496 (PSG)", MA_OPT2_ENABLE_SN76496,PicoOpt, POPT_EN_PSG),
- mee_onoff ("gzip savestates", MA_OPT2_GZIP_STATES, currentConfig.EmuOpt, EOPT_GZIP_SAVES),
- mee_onoff ("Don't save last used ROM", MA_OPT2_NO_LAST_ROM, currentConfig.EmuOpt, EOPT_NO_AUTOSVCFG),
- mee_onoff ("Disable idle loop patching",MA_OPT2_NO_IDLE_LOOPS,PicoOpt, POPT_DIS_IDLE_DET),
- mee_onoff ("Disable frame limiter", MA_OPT2_NO_FRAME_LIMIT,currentConfig.EmuOpt, EOPT_NO_FRMLIMIT),
- MENU_OPTIONS_ADV
- mee_end,
-};
-
-static int menu_loop_adv_options(int id, int keys)
-{
- static int sel = 0;
- me_loop(e_menu_adv_options, &sel);
- return 0;
-}
-
-// ------------ gfx options menu ------------
-
-static menu_entry e_menu_gfx_options[] =
-{
- mee_enum("Renderer", MA_OPT_RENDERER, currentConfig.renderer, renderer_names),
- MENU_OPTIONS_GFX
- mee_end,
-};
-
-static int menu_loop_gfx_options(int id, int keys)
-{
- static int sel = 0;
-
- me_enable(e_menu_gfx_options, MA_OPT_RENDERER, renderer_names[0] != NULL);
- me_loop(e_menu_gfx_options, &sel);
-
- return 0;
-}
-
-// ------------ options menu ------------
-
-static menu_entry e_menu_options[];
-
-static int sndrate_prevnext(int rate, int dir)
-{
- static const int rates[] = { 8000, 11025, 16000, 22050, 44100 };
- int i;
-
- for (i = 0; i < 5; i++)
- if (rates[i] == rate) break;
-
- i += dir ? 1 : -1;
- if (i > 4) {
- if (!(PicoOpt & POPT_EN_STEREO)) {
- PicoOpt |= POPT_EN_STEREO;
- return rates[0];
- }
- return rates[4];
- }
- if (i < 0) {
- if (PicoOpt & POPT_EN_STEREO) {
- PicoOpt &= ~POPT_EN_STEREO;
- return rates[4];
- }
- return rates[0];
- }
- return rates[i];
-}
-
-static void region_prevnext(int right)
-{
- // jp_ntsc=1, jp_pal=2, usa=4, eu=8
- static const int rgn_orders[] = { 0x148, 0x184, 0x814, 0x418, 0x841, 0x481 };
- int i;
-
- if (right) {
- if (!PicoRegionOverride) {
- for (i = 0; i < 6; i++)
- if (rgn_orders[i] == PicoAutoRgnOrder) break;
- if (i < 5) PicoAutoRgnOrder = rgn_orders[i+1];
- else PicoRegionOverride=1;
- }
- else
- PicoRegionOverride <<= 1;
- if (PicoRegionOverride > 8)
- PicoRegionOverride = 8;
- } else {
- if (!PicoRegionOverride) {
- for (i = 0; i < 6; i++)
- if (rgn_orders[i] == PicoAutoRgnOrder) break;
- if (i > 0) PicoAutoRgnOrder = rgn_orders[i-1];
- }
- else
- PicoRegionOverride >>= 1;
- }
-}
-
-static int mh_opt_misc(int id, int keys)
-{
- switch (id) {
- case MA_OPT_SOUND_QUALITY:
- PsndRate = sndrate_prevnext(PsndRate, keys & PBTN_RIGHT);
- break;
- case MA_OPT_REGION:
- region_prevnext(keys & PBTN_RIGHT);
- break;
- default:
- break;
- }
- return 0;
-}
-
-static int mh_saveloadcfg(int id, int keys)
-{
- int ret;
-
- if (keys & (PBTN_LEFT|PBTN_RIGHT)) { // multi choice
- config_slot += (keys & PBTN_LEFT) ? -1 : 1;
- if (config_slot < 0) config_slot = 9;
- else if (config_slot > 9) config_slot = 0;
- me_enable(e_menu_options, MA_OPT_LOADCFG, config_slot != config_slot_current);
- return 0;
- }
-
- switch (id) {
- case MA_OPT_SAVECFG:
- case MA_OPT_SAVECFG_GAME:
- if (emu_write_config(id == MA_OPT_SAVECFG_GAME ? 1 : 0))
- me_update_msg("config saved");
- else
- me_update_msg("failed to write config");
- break;
- case MA_OPT_LOADCFG:
- ret = emu_read_config(rom_fname_loaded, 1);
- if (!ret) ret = emu_read_config(NULL, 1);
- if (ret) me_update_msg("config loaded");
- else me_update_msg("failed to load config");
- break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-static int mh_restore_defaults(int id, int keys)
-{
- emu_set_defconfig();
- me_update_msg("defaults restored");
- return 1;
-}
-
-static const char *mgn_opt_fskip(int id, int *offs)
-{
- if (currentConfig.Frameskip < 0)
- return "Auto";
- sprintf(static_buff, "%d", currentConfig.Frameskip);
- return static_buff;
-}
-
-static const char *mgn_opt_sound(int id, int *offs)
-{
- const char *str2;
- *offs = -8;
- str2 = (PicoOpt & POPT_EN_STEREO) ? "stereo" : "mono";
- sprintf(static_buff, "%5iHz %s", PsndRate, str2);
- return static_buff;
-}
-
-static const char *mgn_opt_region(int id, int *offs)
-{
- static const char *names[] = { "Auto", " Japan NTSC", " Japan PAL", " USA", " Europe" };
- static const char *names_short[] = { "", " JP", " JP", " US", " EU" };
- int code = PicoRegionOverride;
- int u, i = 0;
-
- *offs = -6;
- if (code) {
- code <<= 1;
- while ((code >>= 1)) i++;
- if (i > 4)
- return "unknown";
- return names[i];
- } else {
- strcpy(static_buff, "Auto:");
- for (u = 0; u < 3; u++) {
- code = (PicoAutoRgnOrder >> u*4) & 0xf;
- for (i = 0; code; code >>= 1, i++)
- ;
- strcat(static_buff, names_short[i]);
- }
- return static_buff;
- }
-}
-
-static const char *mgn_saveloadcfg(int id, int *offs)
-{
- static_buff[0] = 0;
- if (config_slot != 0)
- sprintf(static_buff, "[%i]", config_slot);
- return static_buff;
-}
-
-static const char *men_confirm_save[] = { "OFF", "writes", "loads", "both", NULL };
-static const char h_confirm_save[] = "Ask for confirmation when overwriting save,\n"
- "loading state or both";
-
-static menu_entry e_menu_options[] =
-{
- mee_range ("Save slot", MA_OPT_SAVE_SLOT, state_slot, 0, 9),
- mee_range_cust("Frameskip", MA_OPT_FRAMESKIP, currentConfig.Frameskip, -1, 16, mgn_opt_fskip),
- mee_cust ("Region", MA_OPT_REGION, mh_opt_misc, mgn_opt_region),
- mee_onoff ("Show FPS", MA_OPT_SHOW_FPS, currentConfig.EmuOpt, EOPT_SHOW_FPS),
- mee_onoff ("Enable sound", MA_OPT_ENABLE_SOUND, currentConfig.EmuOpt, EOPT_EN_SOUND),
- mee_cust ("Sound Quality", MA_OPT_SOUND_QUALITY, mh_opt_misc, mgn_opt_sound),
- mee_enum_h ("Confirm savestate", MA_OPT_CONFIRM_STATES,currentConfig.confirm_save, men_confirm_save, h_confirm_save),
- mee_range ("", MA_OPT_CPU_CLOCKS, currentConfig.CPUclock, 20, 1200),
- mee_handler ("[Display options]", menu_loop_gfx_options),
- mee_handler ("[Sega/Mega CD options]", menu_loop_cd_options),
-#ifndef NO_32X
- mee_handler ("[32X options]", menu_loop_32x_options),
-#endif
- mee_handler ("[Advanced options]", menu_loop_adv_options),
- mee_cust_nosave("Save global config", MA_OPT_SAVECFG, mh_saveloadcfg, mgn_saveloadcfg),
- mee_cust_nosave("Save cfg for loaded game",MA_OPT_SAVECFG_GAME, mh_saveloadcfg, mgn_saveloadcfg),
- mee_cust_nosave("Load cfg from profile", MA_OPT_LOADCFG, mh_saveloadcfg, mgn_saveloadcfg),
- mee_handler ("Restore defaults", mh_restore_defaults),
- mee_end,
-};
-
-static int menu_loop_options(int id, int keys)
-{
- static int sel = 0;
- int i;
-
- i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);
- e_menu_options[i].enabled = e_menu_options[i].name[0] ? 1 : 0;
- me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, rom_loaded);
- me_enable(e_menu_options, MA_OPT_LOADCFG, config_slot != config_slot_current);
-
- me_loop(e_menu_options, &sel);
-
- return 0;
-}
-
-// ------------ debug menu ------------
-
-#include <pico/debug.h>
-
-extern void SekStepM68k(void);
-
-static void mplayer_loop(void)
-{
- pemu_sound_start();
-
- while (1)
- {
- PDebugZ80Frame();
- if (in_menu_wait_any(NULL, 0) & PBTN_MA3)
- break;
- pemu_sound_wait();
- }
-
- pemu_sound_stop();
-}
-
-static void draw_text_debug(const char *str, int skip, int from)
-{
- const char *p;
- int line;
-
- p = str;
- while (skip-- > 0)
- {
- while (*p && *p != '\n')
- p++;
- if (*p == 0 || p[1] == 0)
- return;
- p++;
- }
-
- str = p;
- for (line = from; line < g_menuscreen_h / me_sfont_h; line++)
- {
- smalltext_out16(1, line * me_sfont_h, str, 0xffff);
- while (*p && *p != '\n')
- p++;
- if (*p == 0)
- break;
- p++; str = p;
- }
-}
-
-#ifdef __GNUC__
-#define COMPILER "gcc " __VERSION__
-#else
-#define COMPILER
-#endif
-
-static void draw_frame_debug(void)
-{
- char layer_str[48] = "layers: ";
- if (PicoDrawMask & PDRAW_LAYERB_ON) memcpy(layer_str + 8, "B", 1);
- if (PicoDrawMask & PDRAW_LAYERA_ON) memcpy(layer_str + 10, "A", 1);
- if (PicoDrawMask & PDRAW_SPRITES_LOW_ON) memcpy(layer_str + 12, "spr_lo", 6);
- if (PicoDrawMask & PDRAW_SPRITES_HI_ON) memcpy(layer_str + 19, "spr_hi", 6);
- if (PicoDrawMask & PDRAW_32X_ON) memcpy(layer_str + 26, "32x", 4);
-
- pemu_forced_frame(1, 0);
- memcpy(g_menuscreen_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h * 2);
- smalltext_out16(4, 1, "build: r" REVISION " "__DATE__ " " __TIME__ " " COMPILER, 0xffff);
- smalltext_out16(4, g_menuscreen_h - me_sfont_h, layer_str, 0xffff);
-}
-
-static void debug_menu_loop(void)
-{
- int inp, mode = 0;
- int spr_offs = 0, dumped = 0;
- char *tmp;
-
- while (1)
- {
- menu_draw_begin(1);
- switch (mode)
- {
- case 0: tmp = PDebugMain();
- plat_debug_cat(tmp);
- draw_text_debug(tmp, 0, 0);
- if (dumped) {
- smalltext_out16(g_menuscreen_w - 6 * me_sfont_h,
- g_menuscreen_h - me_mfont_h, "dumped", 0xffff);
- dumped = 0;
- }
- break;
- case 1: draw_frame_debug();
- break;
- case 2: pemu_forced_frame(1, 0);
- menu_darken_bg(g_menuscreen_ptr, g_menubg_src_ptr, g_menuscreen_w * g_menuscreen_h, 0);
- PDebugShowSpriteStats((unsigned short *)g_menuscreen_ptr + (g_menuscreen_h/2 - 240/2)*g_menuscreen_w +
- g_menuscreen_w/2 - 320/2, g_menuscreen_w);
- break;
- case 3: memset(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
- PDebugShowPalette(g_menuscreen_ptr, g_menuscreen_w);
- PDebugShowSprite((unsigned short *)g_menuscreen_ptr + g_menuscreen_w*120 + g_menuscreen_w/2 + 16,
- g_menuscreen_w, spr_offs);
- draw_text_debug(PDebugSpriteList(), spr_offs, 6);
- break;
- case 4: tmp = PDebug32x();
- draw_text_debug(tmp, 0, 0);
- break;
- }
- menu_draw_end();
-
- inp = in_menu_wait(PBTN_MOK|PBTN_MBACK|PBTN_MA2|PBTN_MA3|PBTN_L|PBTN_R |
- PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT, NULL, 70);
- if (inp & PBTN_MBACK) return;
- if (inp & PBTN_L) { mode--; if (mode < 0) mode = 4; }
- if (inp & PBTN_R) { mode++; if (mode > 4) mode = 0; }
- switch (mode)
- {
- case 0:
- if (inp & PBTN_MOK)
- PDebugCPUStep();
- if (inp & PBTN_MA3) {
- while (inp & PBTN_MA3)
- inp = in_menu_wait_any(NULL, -1);
- mplayer_loop();
- }
- if ((inp & (PBTN_MA2|PBTN_LEFT)) == (PBTN_MA2|PBTN_LEFT)) {
- mkdir("dumps", 0777);
- PDebugDumpMem();
- while (inp & PBTN_MA2) inp = in_menu_wait_any(NULL, -1);
- dumped = 1;
- }
- break;
- case 1:
- if (inp & PBTN_LEFT) PicoDrawMask ^= PDRAW_LAYERB_ON;
- if (inp & PBTN_RIGHT) PicoDrawMask ^= PDRAW_LAYERA_ON;
- if (inp & PBTN_DOWN) PicoDrawMask ^= PDRAW_SPRITES_LOW_ON;
- if (inp & PBTN_UP) PicoDrawMask ^= PDRAW_SPRITES_HI_ON;
- if (inp & PBTN_MA2) PicoDrawMask ^= PDRAW_32X_ON;
- if (inp & PBTN_MOK) {
- PsndOut = NULL; // just in case
- PicoSkipFrame = 1;
- PicoFrame();
- PicoSkipFrame = 0;
- while (inp & PBTN_MOK) inp = in_menu_wait_any(NULL, -1);
- }
- break;
- case 3:
- if (inp & PBTN_DOWN) spr_offs++;
- if (inp & PBTN_UP) spr_offs--;
- if (spr_offs < 0) spr_offs = 0;
- break;
- }
- }
-}
-
-// ------------ main menu ------------
-
-static const char credits[] =
- "PicoDrive v" VERSION " (c) notaz, 2006-2011\n\n\n"
- "Credits:\n"
- "fDave: Cyclone 68000 core,\n"
- " base code of PicoDrive\n"
- "Reesy & FluBBa: DrZ80 core\n"
- "MAME devs: YM2612 and SN76496 cores\n"
- "Inder, ketchupgun: graphics\n"
-#ifdef __GP2X__
- "rlyeh and others: minimal SDK\n"
- "Squidge: mmuhack\n"
- "Dzz: ARM940 sample\n"
-#endif
- "\n"
- "special thanks (for docs, ideas):\n"
- " Charles MacDonald, Haze,\n"
- " Stephane Dallongeville,\n"
- " Lordus, Exophase, Rokas,\n"
- " Nemesis, Tasco Deluxe";
-
-static char *romsel_run(void)
-{
- char *ret, *sel_name;
-
- sel_name = malloc(sizeof(rom_fname_loaded));
- if (sel_name == NULL)
- return NULL;
- strcpy(sel_name, rom_fname_loaded);
-
- ret = menu_loop_romsel(sel_name, sizeof(rom_fname_loaded));
- free(sel_name);
- return ret;
-}
-
-static int main_menu_handler(int id, int keys)
-{
- char *ret_name;
-
- switch (id)
- {
- case MA_MAIN_RESUME_GAME:
- if (rom_loaded)
- return 1;
- break;
- case MA_MAIN_SAVE_STATE:
- if (rom_loaded)
- return menu_loop_savestate(0);
- break;
- case MA_MAIN_LOAD_STATE:
- if (rom_loaded)
- return menu_loop_savestate(1);
- break;
- case MA_MAIN_RESET_GAME:
- if (rom_loaded) {
- emu_reset_game();
- return 1;
- }
- break;
- case MA_MAIN_LOAD_ROM:
- ret_name = romsel_run();
- if (ret_name != NULL) {
- lprintf("selected file: %s\n", ret_name);
- engineState = PGS_ReloadRom;
- return 1;
- }
- break;
- case MA_MAIN_CREDITS:
- draw_menu_message(credits, NULL);
- in_menu_wait(PBTN_MOK|PBTN_MBACK, NULL, 70);
- break;
- case MA_MAIN_EXIT:
- engineState = PGS_Quit;
- return 1;
- case MA_MAIN_PATCHES:
- if (rom_loaded && PicoPatches) {
- menu_loop_patches();
- PicoPatchApply();
- me_update_msg("Patches applied");
- }
- break;
- default:
- lprintf("%s: something unknown selected\n", __FUNCTION__);
- break;
- }
-
- return 0;
-}
-
-static menu_entry e_menu_main[] =
-{
- mee_label ("PicoDrive " VERSION),
- mee_label (""),
- mee_label (""),
- mee_label (""),
- mee_handler_id("Resume game", MA_MAIN_RESUME_GAME, main_menu_handler),
- mee_handler_id("Save State", MA_MAIN_SAVE_STATE, main_menu_handler),
- mee_handler_id("Load State", MA_MAIN_LOAD_STATE, main_menu_handler),
- mee_handler_id("Reset game", MA_MAIN_RESET_GAME, main_menu_handler),
- mee_handler_id("Load new ROM/ISO", MA_MAIN_LOAD_ROM, main_menu_handler),
- mee_handler ("Change options", menu_loop_options),
- mee_handler ("Configure controls", menu_loop_keyconfig),
- mee_handler_id("Credits", MA_MAIN_CREDITS, main_menu_handler),
- mee_handler_id("Patches / GameGenie",MA_MAIN_PATCHES, main_menu_handler),
- mee_handler_id("Exit", MA_MAIN_EXIT, main_menu_handler),
- mee_end,
-};
-
-void menu_loop(void)
-{
- static int sel = 0;
-
- me_enable(e_menu_main, MA_MAIN_RESUME_GAME, rom_loaded);
- me_enable(e_menu_main, MA_MAIN_SAVE_STATE, rom_loaded);
- me_enable(e_menu_main, MA_MAIN_LOAD_STATE, rom_loaded);
- me_enable(e_menu_main, MA_MAIN_RESET_GAME, rom_loaded);
- me_enable(e_menu_main, MA_MAIN_PATCHES, PicoPatches != NULL);
-
- menu_enter(rom_loaded);
- in_set_config_int(0, IN_CFG_BLOCKING, 1);
- me_loop_d(e_menu_main, &sel, NULL, menu_main_plat_draw);
-
- if (rom_loaded) {
- if (engineState == PGS_Menu)
- engineState = PGS_Running;
- /* wait until menu, ok, back is released */
- while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
- ;
- }
-
- in_set_config_int(0, IN_CFG_BLOCKING, 0);
-}
-
-// --------- CD tray close menu ----------
-
-static int mh_tray_load_cd(int id, int keys)
-{
- char *ret_name;
-
- ret_name = romsel_run();
- if (ret_name == NULL)
- return 0;
-
- engineState = PGS_RestartRun;
- return emu_swap_cd(ret_name);
-}
-
-static int mh_tray_nothing(int id, int keys)
-{
- return 1;
-}
-
-static menu_entry e_menu_tray[] =
-{
- mee_label ("The CD tray has opened."),
- mee_label (""),
- mee_label (""),
- mee_handler("Load CD image", mh_tray_load_cd),
- mee_handler("Insert nothing", mh_tray_nothing),
- mee_end,
-};
-
-int menu_loop_tray(void)
-{
- int ret = 1, sel = 0;
-
- menu_enter(rom_loaded);
-
- in_set_config_int(0, IN_CFG_BLOCKING, 1);
- me_loop(e_menu_tray, &sel);
-
- if (engineState != PGS_RestartRun) {
- engineState = PGS_RestartRun;
- ret = 0; /* no CD inserted */
- }
-
- while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK));
- in_set_config_int(0, IN_CFG_BLOCKING, 0);
-
- return ret;
-}
-
-void me_update_msg(const char *msg)
-{
- strncpy(menu_error_msg, msg, sizeof(menu_error_msg));
- menu_error_msg[sizeof(menu_error_msg) - 1] = 0;
-
- menu_error_time = plat_get_ticks_ms();
- lprintf("msg: %s\n", menu_error_msg);
-}
-
-// ------------ util ------------
-
-/* hidden options for config engine only */
-static menu_entry e_menu_hidden[] =
-{
- mee_onoff("Accurate sprites", MA_OPT_ACC_SPRITES, PicoOpt, 0x080),
- mee_end,
-};
-
-static menu_entry *e_menu_table[] =
-{
- e_menu_options,
- e_menu_gfx_options,
- e_menu_adv_options,
- e_menu_cd_options,
-#ifndef NO_32X
- e_menu_32x_options,
-#endif
- e_menu_keyconfig,
- e_menu_hidden,
-};
-
-static menu_entry *me_list_table = NULL;
-static menu_entry *me_list_i = NULL;
-
-menu_entry *me_list_get_first(void)
-{
- me_list_table = me_list_i = e_menu_table[0];
- return me_list_i;
-}
-
-menu_entry *me_list_get_next(void)
-{
- int i;
-
- me_list_i++;
- if (me_list_i->name != NULL)
- return me_list_i;
-
- for (i = 0; i < array_size(e_menu_table); i++)
- if (me_list_table == e_menu_table[i])
- break;
-
- if (i + 1 < array_size(e_menu_table))
- me_list_table = me_list_i = e_menu_table[i + 1];
- else
- me_list_table = me_list_i = NULL;
-
- return me_list_i;
-}
-
+++ /dev/null
-typedef enum
-{
- MA_NONE = 1,
- MA_MAIN_RESUME_GAME,
- MA_MAIN_SAVE_STATE,
- MA_MAIN_LOAD_STATE,
- MA_MAIN_RESET_GAME,
- MA_MAIN_LOAD_ROM,
- MA_MAIN_CONTROLS,
- MA_MAIN_CREDITS,
- MA_MAIN_PATCHES,
- MA_MAIN_EXIT,
- MA_OPT_RENDERER,
- MA_OPT_SCALING,
- MA_OPT_VSCALING,
- MA_OPT_ACC_SPRITES,
- MA_OPT_SHOW_FPS,
- MA_OPT_FRAMESKIP,
- MA_OPT_ENABLE_SOUND,
- MA_OPT_SOUND_QUALITY,
- MA_OPT_ARM940_SOUND,
- MA_OPT_6BUTTON_PAD,
- MA_OPT_REGION,
- MA_OPT_SRAM_STATES,
- MA_OPT_CONFIRM_STATES,
- MA_OPT_SAVE_SLOT,
- MA_OPT_CPU_CLOCKS,
- MA_OPT_SCD_OPTS,
- MA_OPT_ADV_OPTS,
- MA_OPT_DISP_OPTS, /* psp */
- MA_OPT_SAVECFG,
- MA_OPT_SAVECFG_GAME,
- MA_OPT_LOADCFG,
- MA_OPT_INTERLACED, /* giz */
- MA_OPT_ROTATION, /* uiq */
- MA_OPT_TEARING_FIX, /* wiz */
- MA_OPT2_GAMMA,
- MA_OPT2_A_SN_GAMMA,
- MA_OPT2_DBLBUFF, /* giz */
- MA_OPT2_VSYNC,
- MA_OPT2_ENABLE_Z80,
- MA_OPT2_ENABLE_YM2612,
- MA_OPT2_ENABLE_SN76496,
- MA_OPT2_GZIP_STATES,
- MA_OPT2_NO_LAST_ROM,
- MA_OPT2_RAMTIMINGS, /* gp2x */
- MA_OPT2_SQUIDGEHACK, /* gp2x */
- MA_OPT2_STATUS_LINE, /* psp */
- MA_OPT2_NO_FRAME_LIMIT, /* psp */
- MA_OPT2_SVP_DYNAREC,
- MA_OPT2_NO_SPRITE_LIM,
- MA_OPT2_NO_IDLE_LOOPS,
- MA_OPT2_DONE,
- MA_OPT3_SCALE, /* psp (all OPT3) */
- MA_OPT3_HSCALE32,
- MA_OPT3_HSCALE40,
- MA_OPT3_PRES_NOSCALE,
- MA_OPT3_PRES_SCALE43,
- MA_OPT3_PRES_FULLSCR,
- MA_OPT3_FILTERING,
- MA_OPT3_VSYNC,
- MA_OPT3_GAMMAA,
- MA_OPT3_BLACKLVL,
- MA_OPT3_LAYER_X,
- MA_OPT3_LAYER_Y,
- MA_OPT3_LAYER_W,
- MA_OPT3_LAYER_H,
- MA_OPT3_DONE,
- MA_CDOPT_TESTBIOS_USA,
- MA_CDOPT_TESTBIOS_EUR,
- MA_CDOPT_TESTBIOS_JAP,
- MA_CDOPT_LEDS,
- MA_CDOPT_CDDA,
- MA_CDOPT_PCM,
- MA_CDOPT_READAHEAD,
- MA_CDOPT_SAVERAM,
- MA_CDOPT_SCALEROT_CHIP,
- MA_CDOPT_BETTER_SYNC,
- MA_CDOPT_DONE,
- MA_32XOPT_ENABLE_32X,
- MA_32XOPT_RENDERER,
- MA_32XOPT_PWM,
- MA_32XOPT_MSH2_CYCLES,
- MA_32XOPT_SSH2_CYCLES,
- MA_CTRL_PLAYER1,
- MA_CTRL_PLAYER2,
- MA_CTRL_EMU,
- MA_CTRL_TURBO_RATE,
- MA_CTRL_DEADZONE,
- MA_CTRL_DEV_FIRST,
- MA_CTRL_DEV_NEXT,
- MA_CTRL_DONE,
-} menu_id;
-
+++ /dev/null
-#include "mp3.h"
-
-int mp3_find_sync_word(const unsigned char *buf, int size)
-{
- const unsigned char *p, *pe;
-
- /* find byte-aligned syncword - need 12 (MPEG 1,2) or 11 (MPEG 2.5) matching bits */
- for (p = buf, pe = buf + size - 3; p <= pe; p++)
- {
- int pn;
- if (p[0] != 0xff)
- continue;
- pn = p[1];
- if ((pn & 0xf8) != 0xf8 || // currently must be MPEG1
- (pn & 6) == 0) { // invalid layer
- p++; continue;
- }
- pn = p[2];
- if ((pn & 0xf0) < 0x20 || (pn & 0xf0) == 0xf0 || // bitrates
- (pn & 0x0c) != 0) { // not 44kHz
- continue;
- }
-
- return p - buf;
- }
-
- return -1;
-}
-
+++ /dev/null
-
-int mp3_find_sync_word(const unsigned char *buf, int size);
-
-#ifdef __GP2X__
-void mp3_update_local(int *buffer, int length, int stereo);
-void mp3_start_play_local(void *f, int pos);
-#endif
-
+++ /dev/null
-// Some mp3 related code for Sega/Mega CD.
-// Uses the Helix Fixed-point MP3 decoder
-
-// (c) Copyright 2007, Grazvydas "notaz" Ignotas
-
-#include <stdio.h>
-#include <string.h>
-
-#include <pico/pico_int.h>
-#include <pico/sound/mix.h>
-#include "helix/pub/mp3dec.h"
-#include "mp3.h"
-#include "lprintf.h"
-
-static HMP3Decoder mp3dec = 0;
-static FILE *mp3_current_file = NULL;
-static int mp3_file_len = 0, mp3_file_pos = 0;
-static int mp3_buffer_offs = 0;
-static unsigned char mp3_input_buffer[2*1024];
-
-#ifdef __GP2X__
-#define mp3_update mp3_update_local
-#define mp3_start_play mp3_start_play_local
-#endif
-
-static int try_get_header(unsigned char *buff, MP3FrameInfo *fi)
-{
- int ret, offs1, offs = 0;
-
- while (1)
- {
- offs1 = mp3_find_sync_word(buff + offs, 2048 - offs);
- if (offs1 < 0) return -2;
- offs += offs1;
- if (2048 - offs < 4) return -3;
-
- // printf("trying header %08x\n", *(int *)(buff + offs));
-
- ret = MP3GetNextFrameInfo(mp3dec, fi, buff + offs);
- if (ret == 0 && fi->bitrate != 0) break;
- offs++;
- }
-
- return ret;
-}
-
-int mp3_get_bitrate(void *f_, int len)
-{
- unsigned char buff[2048];
- MP3FrameInfo fi;
- FILE *f = f_;
- int ret;
-
- memset(buff, 0, sizeof(buff));
-
- if (mp3dec)
- MP3FreeDecoder(mp3dec);
- mp3dec = MP3InitDecoder();
-
- fseek(f, 0, SEEK_SET);
- ret = fread(buff, 1, sizeof(buff), f);
- fseek(f, 0, SEEK_SET);
- if (ret <= 0)
- return -1;
-
- ret = try_get_header(buff, &fi);
- if (ret != 0 || fi.bitrate == 0) {
- // try to read somewhere around the middle
- fseek(f, len>>1, SEEK_SET);
- fread(buff, 1, 2048, f);
- fseek(f, 0, SEEK_SET);
- ret = try_get_header(buff, &fi);
- }
- if (ret != 0)
- return ret;
-
- // printf("bitrate: %i\n", fi.bitrate / 1000);
-
- return fi.bitrate / 1000;
-}
-
-static int mp3_decode(void)
-{
- unsigned char *readPtr;
- int bytesLeft;
- int offset; // mp3 frame offset from readPtr
- int had_err;
- int err = 0;
-
- do
- {
- if (mp3_file_pos >= mp3_file_len)
- return 1; /* EOF, nothing to do */
-
- fseek(mp3_current_file, mp3_file_pos, SEEK_SET);
- bytesLeft = fread(mp3_input_buffer, 1, sizeof(mp3_input_buffer), mp3_current_file);
-
- offset = mp3_find_sync_word(mp3_input_buffer, bytesLeft);
- if (offset < 0) {
- lprintf("find_sync_word (%i/%i) err %i\n", mp3_file_pos, mp3_file_len, offset);
- mp3_file_pos = mp3_file_len;
- return 1; // EOF
- }
- readPtr = mp3_input_buffer + offset;
- bytesLeft -= offset;
-
- had_err = err;
- err = MP3Decode(mp3dec, &readPtr, &bytesLeft, cdda_out_buffer, 0);
- if (err) {
- if (err == ERR_MP3_MAINDATA_UNDERFLOW && !had_err) {
- // just need another frame
- mp3_file_pos += readPtr - mp3_input_buffer;
- continue;
- }
- if (err == ERR_MP3_INDATA_UNDERFLOW && !had_err) {
- if (offset == 0)
- // something's really wrong here, frame had to fit
- mp3_file_pos = mp3_file_len;
- else
- mp3_file_pos += offset;
- continue;
- }
- if (-12 <= err && err <= -6) {
- // ERR_MP3_INVALID_FRAMEHEADER, ERR_MP3_INVALID_*
- // just try to skip the offending frame..
- mp3_file_pos += offset + 1;
- continue;
- }
- lprintf("MP3Decode err (%i/%i) %i\n", mp3_file_pos, mp3_file_len, err);
- mp3_file_pos = mp3_file_len;
- return 1;
- }
- mp3_file_pos += readPtr - mp3_input_buffer;
- }
- while (0);
-
- return 0;
-}
-
-void mp3_start_play(void *f_, int pos)
-{
- FILE *f = f_;
-
- mp3_file_len = mp3_file_pos = 0;
- mp3_current_file = NULL;
- mp3_buffer_offs = 0;
-
- if (!(PicoOpt & POPT_EN_MCD_CDDA) || f == NULL) // cdda disabled or no file?
- return;
-
- // must re-init decoder for new track
- if (mp3dec)
- MP3FreeDecoder(mp3dec);
- mp3dec = MP3InitDecoder();
-
- mp3_current_file = f;
- fseek(f, 0, SEEK_END);
- mp3_file_len = ftell(f);
-
- // search for first sync word, skipping stuff like ID3 tags
- while (mp3_file_pos < 128*1024) {
- int offs, bytes;
-
- fseek(f, mp3_file_pos, SEEK_SET);
- bytes = fread(mp3_input_buffer, 1, sizeof(mp3_input_buffer), f);
- if (bytes < 4)
- break;
- offs = mp3_find_sync_word(mp3_input_buffer, bytes);
- if (offs >= 0) {
- mp3_file_pos += offs;
- break;
- }
- mp3_file_pos += bytes - 2;
- }
-
- // seek..
- if (pos) {
- unsigned long long pos64 = mp3_file_len - mp3_file_pos;
- pos64 *= pos;
- mp3_file_pos += pos64 >> 10;
- }
-
- mp3_decode();
-}
-
-void mp3_update(int *buffer, int length, int stereo)
-{
- int length_mp3, shr = 0;
- void (*mix_samples)(int *dest_buf, short *mp3_buf, int count) = mix_16h_to_32;
-
- if (mp3_current_file == NULL || mp3_file_pos >= mp3_file_len)
- return; /* no file / EOF */
-
- length_mp3 = length;
- if (PsndRate <= 11025 + 100) {
- mix_samples = mix_16h_to_32_s2;
- length_mp3 <<= 2; shr = 2;
- }
- else if (PsndRate <= 22050 + 100) {
- mix_samples = mix_16h_to_32_s1;
- length_mp3 <<= 1; shr = 1;
- }
-
- if (1152 - mp3_buffer_offs >= length_mp3) {
- mix_samples(buffer, cdda_out_buffer + mp3_buffer_offs*2, length<<1);
-
- mp3_buffer_offs += length_mp3;
- } else {
- int ret, left = 1152 - mp3_buffer_offs;
-
- mix_samples(buffer, cdda_out_buffer + mp3_buffer_offs*2, (left>>shr)<<1);
- ret = mp3_decode();
- if (ret == 0) {
- mp3_buffer_offs = length_mp3 - left;
- mix_samples(buffer + ((left>>shr)<<1), cdda_out_buffer, (mp3_buffer_offs>>shr)<<1);
- } else
- mp3_buffer_offs = 0;
- }
-}
-
+++ /dev/null
-platform/common/menu.o : revision.h
-
-revision.h: FORCE
-ifndef NOREVISION
- @echo "#define REVISION \"`svn info -r HEAD | grep Revision | cut -c 11-`\"" > /tmp/r.tmp
-else
- @echo "#define REVISION \"0\"" > /tmp/r.tmp
-endif
- @diff -q $@ /tmp/r.tmp > /dev/null 2>&1 || mv -f /tmp/r.tmp $@
-
-FORCE:
-
+++ /dev/null
-#\r
-# Sega/Mega CD games\r
-#\r
-\r
-[CD|GM MK-4432 -00|U|ADVENTURES OF BA]\r
-Scale/Rot. fx (slow) = 1\r
-Better sync (slow) = 1\r
-\r
-[CD|GM T-60055-00|U|AH3-THUNDERSTRIKE]\r
-Scale/Rot. fx (slow) = 1\r
-\r
-[CD|GM MK-4401 -00|U|BATMAN RETURNS]\r
-Scale/Rot. fx (slow) = 1\r
-\r
-[CD|GM T-115075-00|U|BCRACERS]\r
-Scale/Rot. fx (slow) = 1\r
-\r
-[CD|GM MK-4402|U|COBRA COMMAND]\r
-Better sync (slow) = 1\r
-\r
-[CD|GM T-121015-00|U|DRAGONS LAIR]\r
-Renderer = 16bit accurate\r
-\r
-[CD|GM T-60094|J|JAGUAR XJ220]\r
-Renderer = 16bit accurate\r
-\r
-[CD|GM T-127015-00|U|LUNAR]\r
-Scale/Rot. fx (slow) = 1\r
-\r
-[CD|GM T-111065 -0|U|MAD DOG II THE LOST GOLD]\r
-Renderer = 16bit accurate\r
-\r
-[CD|GM T-11105 -00|U|MAD DOG MCCREE]\r
-Renderer = 16bit accurate\r
-\r
-[CD|GM T-81025-00|U|MORTAL KOMBAT]\r
-Renderer = 16bit accurate\r
-Better sync (slow) = 1\r
-\r
-[CD|GM T-04903-01|U|NIGHT TRAP]\r
-Renderer = 16bit accurate\r
-\r
-[CD|GM T-113025-00|U|NOVASTORM]\r
-Better sync (slow) = 1\r
-\r
-[CD|GM T-127035-00|U|Popful MAIL]\r
-Better sync (slow) = 1\r
-\r
-[CD|MK 4603-50|JUE|ROAD AVENGER]\r
-Renderer = 16bit accurate\r
-Better sync (slow) = 1\r
-\r
-[CD|GM T-50085|U|ROAD RASH]\r
-Renderer = 16bit accurate\r
-Better sync (slow) = 1\r
-\r
-[CD|GM MK-4416 -00|E|ROBO ALESTE]\r
-Renderer = 16bit accurate\r
-\r
-[CD|GM T-06201-03|U|SEWER SHARK]\r
-Renderer = 16bit accurate\r
-\r
-[CD|GM T-113045-00|E|SHADOW OF THE BEAST TWO]\r
-Renderer = 16bit accurate\r
-\r
-[CD|GM MK-4404|U|SOL-FEACE]\r
-Better sync (slow) = 1\r
-\r
-[CD|GM MK-4407-00|E|SONIC THE HEDGEHOG-CD]\r
-Scale/Rot. fx (slow) = 1\r
-\r
-[CD|GM MK-4407 -00|U|SONIC THE HEDGEHOG-CD]\r
-Scale/Rot. fx (slow) = 1\r
-\r
-[CD|GM T-22025-00|U|THE 3RD WORLD WAR]\r
-Better sync (slow) = 1\r
-\r
-[CD|GM MK- 4430 -|E|YUMEMI MISTERY MANSION]\r
-Renderer = 16bit accurate\r
-\r
-#\r
-# Virtua Racing\r
-#\r
-[MD|GM MK-1229 -00|U|Virtua Racing]\r
-Renderer = 8bit fast\r
-Show FPS = 1\r
-GP2X CPU clocks = 235\r
-\r
-[MD|GM G-7001 -00|J|Virtua Racing]\r
-Renderer = 8bit fast\r
-Show FPS = 1\r
-GP2X CPU clocks = 235\r
-\r
-[MD|GM MK-1229 -00|E|Virtua Racing]\r
-Renderer = 8bit fast\r
-Show FPS = 1\r
-GP2X CPU clocks = 235\r
-\r
-[MD|GM MK-1229 -00|E|VIRTUA RACING \00\00\00\00\00\00\00\00\00]\r
-Renderer = 8bit fast\r
-Show FPS = 1\r
-GP2X CPU clocks = 235\r
-\r
-#\r
-# Genesis/MegaDrive games\r
-#\r
-[MD|GM MK-1029-00|E| BURNING FORCE]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-14023 -00|J| BURNING FORCE]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-14026 -00|U| BURNING FORCE]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-95076-00|U|CASTLEVANIA BLOODLINES]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-95076-00|E|CASTLEVANIA THE NEW GENERATION]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM MK-1569 -50|A|COMIX ZONE]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM G-4132 -00|1|]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM MK-1569 -00|4|COMIX ZONE]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-097116 00|4|MORTAL KOMBAT 3]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM G-4119-00|J| OUT_RUNNERS 1994/03/03 Ver.FINAL!!]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-13096-00|U| OUT_RUNNERS]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-48376 00|JUE|RED-ZONE]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-177016-00|F|STREET RACER]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-95043-00|J|]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-25036 -00|U| SHOVE IT!]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM MK-1104 -00|U|AFTER BURNERII]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-32053 -00|U|ARCUS ODYSSEY]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM 00054010-00|JUE|RAMBO \87V]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM 00054010-01|JUE|RAMBO \87V]\r
-Renderer = 16bit accurate\r
-\r
-[MD|GM T-50406 -01|U|GALAHAD]\r
-Renderer = 16bit accurate\r
-\r
+++ /dev/null
-// Code for communication with ARM940 and control of it.\r
-// (c) Copyright 2007, Grazvydas "notaz" Ignotas\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <unistd.h>\r
-#include <sys/mman.h>\r
-#include <sys/ioctl.h>\r
-#include <fcntl.h>\r
-#include <errno.h>\r
-\r
-#include "code940/940shared.h"\r
-#include "soc_mmsp2.h"\r
-#include "soc.h"\r
-#include "../common/mp3.h"\r
-#include "../common/arm_utils.h"\r
-#include "../common/menu.h"\r
-#include "../common/emu.h"\r
-#include "../common/input.h"\r
-#include "../../pico/pico_int.h"\r
-#include "../../pico/sound/ym2612.h"\r
-#include "../../pico/sound/mix.h"\r
-\r
-static unsigned char *shared_mem = 0;\r
-static _940_data_t *shared_data = 0;\r
-_940_ctl_t *shared_ctl = 0;\r
-unsigned char *mp3_mem = 0;\r
-\r
-#define MP3_SIZE_MAX (0x400000 + 0x800000) // 12M\r
-#define CODE940_FILE "pico940_v3.bin"\r
-\r
-int crashed_940 = 0;\r
-\r
-static FILE *loaded_mp3 = 0;\r
-\r
-/***********************************************************/\r
-\r
-#define MAXOUT (+32767)\r
-#define MINOUT (-32768)\r
-\r
-/* limitter */\r
-#define Limit(val, max,min) { \\r
- if ( val > max ) val = max; \\r
- else if ( val < min ) val = min; \\r
-}\r
-\r
-/* these will be managed locally on our side */\r
-static UINT8 ST_address; /* address register */\r
-static INT32 addr_A1; /* address line A1 */\r
-\r
-static int writebuff_ptr = 0;\r
-\r
-\r
-/* YM2612 write */\r
-/* a = address */\r
-/* v = value */\r
-/* returns 1 if sample affecting state changed */\r
-int YM2612Write_940(unsigned int a, unsigned int v, int scanline)\r
-{\r
- int upd = 1; /* the write affects sample generation */\r
-\r
- a &= 3;\r
-\r
- //printf("%05i:%03i: ym w ([%i] %02x)\n", Pico.m.frame_count, Pico.m.scanline, a, v);\r
-\r
- switch (a)\r
- {\r
- case 0: /* address port 0 */\r
- if (addr_A1 == 0 && ST_address == v)\r
- return 0; /* address already selected, don't send this command to 940 */\r
- ST_address = v;\r
- addr_A1 = 0;\r
- /* don't send DAC or timer related address changes to 940 */\r
- if (v == 0x24 || v == 0x25 || v == 0x26 || v == 0x2a)\r
- return 0;\r
- upd = 0;\r
- break;\r
-\r
- case 2: /* address port 1 */\r
- if (addr_A1 == 1 && ST_address == v)\r
- return 0;\r
- ST_address = v;\r
- addr_A1 = 1;\r
- upd = 0;\r
- break;\r
- }\r
-\r
- //printf("ym pass\n");\r
-\r
- if (currentConfig.EmuOpt & 4)\r
- {\r
- UINT16 *writebuff = shared_ctl->writebuffsel ? shared_ctl->writebuff0 : shared_ctl->writebuff1;\r
-\r
- /* detect rapid ym updates */\r
- if (upd && !(writebuff_ptr & 0x80000000) && scanline < 224)\r
- {\r
- int mid = Pico.m.pal ? 68 : 93;\r
- if (scanline > mid) {\r
- //printf("%05i:%03i: rapid ym\n", Pico.m.frame_count, scanline);\r
- writebuff[writebuff_ptr++ & 0xffff] = 0xfffe;\r
- writebuff_ptr |= 0x80000000;\r
- //printf("%05i:%03i: ym w ([%02x] %02x, upd=%i)\n", Pico.m.frame_count, scanline, addr, v, upd);\r
- }\r
- }\r
-\r
- /* queue this write for 940 */\r
- if ((writebuff_ptr&0xffff) < 2047) {\r
- writebuff[writebuff_ptr++ & 0xffff] = (a<<8)|v;\r
- } else {\r
- printf("warning: writebuff_ptr > 2047 ([%i] %02x)\n", a, v);\r
- }\r
- }\r
-\r
- return 0; // cause the engine to do updates once per frame only\r
-}\r
-\r
-\r
-#define CHECK_BUSY(job) \\r
- (gp2x_memregs[0x3b46>>1] & (1<<(job-1)))\r
-\r
-static void wait_busy_940(int job)\r
-{\r
- int i;\r
-\r
- job--;\r
- for (i = 0; (gp2x_memregs[0x3b46>>1] & (1<<job)) && i < 0x10000; i++)\r
- spend_cycles(8*1024); // tested to be best for mp3 dec\r
- if (i < 0x10000) return;\r
-\r
- /* 940 crashed */\r
- printf("940 crashed (cnt: %i, ve: ", shared_ctl->loopc);\r
- for (i = 0; i < 8; i++)\r
- printf("%i ", shared_ctl->vstarts[i]);\r
- printf(")\n");\r
- printf("irq pending flags: DUALCPU %04x, SRCPND %08lx (see 26), INTPND %08lx\n",\r
- gp2x_memregs[0x3b46>>1], gp2x_memregl[0x4500>>2], gp2x_memregl[0x4510>>2]);\r
- printf("last lr: %08x, lastjob: %i\n", shared_ctl->last_lr, shared_ctl->lastjob);\r
- printf("trying to interrupt..\n");\r
- gp2x_memregs[0x3B3E>>1] = 0xffff;\r
- for (i = 0; gp2x_memregs[0x3b46>>1] && i < 0x10000; i++)\r
- spend_cycles(8*1024);\r
- printf("i = 0x%x\n", i);\r
- printf("irq pending flags: DUALCPU %04x, SRCPND %08lx (see 26), INTPND %08lx\n",\r
- gp2x_memregs[0x3b46>>1], gp2x_memregl[0x4500>>2], gp2x_memregl[0x4510>>2]);\r
- printf("last lr: %08x, lastjob: %i\n", shared_ctl->last_lr, shared_ctl->lastjob);\r
-\r
- me_update_msg("940 crashed, too much overclock?");\r
- engineState = PGS_Menu;\r
- crashed_940 = 1;\r
-}\r
-\r
-\r
-static void add_job_940(int job)\r
-{\r
- if (job <= 0 || job > 16) {\r
- printf("add_job_940: bad job: %i\n", job);\r
- return;\r
- }\r
-\r
- // generate interrupt for this job\r
- job--;\r
- gp2x_memregs[(0x3B20+job*2)>>1] = 1;\r
-\r
-// printf("added %i, pending %04x\n", job+1, gp2x_memregs[0x3b46>>1]);\r
-}\r
-\r
-\r
-void YM2612PicoStateLoad_940(void)\r
-{\r
- UINT8 *REGS = YM2612GetRegs();\r
-\r
- /* make sure JOB940_PICOSTATELOAD gets done before next JOB940_YM2612UPDATEONE */\r
- add_job_940(JOB940_PICOSTATELOAD);\r
- if (CHECK_BUSY(JOB940_PICOSTATELOAD)) wait_busy_940(JOB940_PICOSTATELOAD);\r
-\r
- writebuff_ptr = 0;\r
- addr_A1 = *(INT32 *) (REGS + 0x200);\r
-}\r
-\r
-void YM2612PicoStateSave2_940(int tat, int tbt)\r
-{\r
- UINT8 *ym_remote_regs, *ym_local_regs;\r
- add_job_940(JOB940_PICOSTATESAVE2);\r
- if (CHECK_BUSY(JOB940_PICOSTATESAVE2)) wait_busy_940(JOB940_PICOSTATESAVE2);\r
-\r
- ym_remote_regs = (UINT8 *) shared_ctl->writebuff0;\r
- ym_local_regs = YM2612GetRegs();\r
- if (*(UINT32 *)(ym_remote_regs + 0x100) != 0x41534d59) {\r
- printf("code940 didn't return valid save data\n");\r
- return;\r
- }\r
-\r
- /* copy addin data only */\r
- memcpy(ym_local_regs, ym_remote_regs, 0x20);\r
- memcpy(ym_local_regs + 0x100, ym_remote_regs + 0x100, 0x30);\r
- memcpy(ym_local_regs + 0x0b8, ym_remote_regs + 0x0b8, 0x48);\r
- memcpy(ym_local_regs + 0x1b8, ym_remote_regs + 0x1b8, 0x48);\r
- *(INT32 *)(ym_local_regs + 0x108) = tat;\r
- *(INT32 *)(ym_local_regs + 0x10c) = tbt;\r
-}\r
-\r
-int YM2612PicoStateLoad2_940(int *tat, int *tbt)\r
-{\r
- UINT8 *ym_remote_regs, *ym_local_regs;\r
- ym_local_regs = YM2612GetRegs();\r
- ym_remote_regs = (UINT8 *) shared_ctl->writebuff0;\r
-\r
- if (*(UINT32 *)(ym_local_regs + 0x100) != 0x41534d59)\r
- return -1;\r
-\r
- *tat = *(INT32 *)(ym_local_regs + 0x108);\r
- *tbt = *(INT32 *)(ym_local_regs + 0x10c);\r
-\r
- if (CHECK_BUSY(JOB940_YM2612UPDATEONE)) wait_busy_940(JOB940_YM2612UPDATEONE);\r
-\r
- /* flush writes */\r
- if (shared_ctl->writebuffsel == 1) {\r
- shared_ctl->writebuff0[writebuff_ptr & 0xffff] = 0xffff;\r
- } else {\r
- shared_ctl->writebuff1[writebuff_ptr & 0xffff] = 0xffff;\r
- }\r
- shared_ctl->writebuffsel ^= 1;\r
- writebuff_ptr = 0;\r
- add_job_940(JOB940_PICOSTATELOAD2_PREP);\r
- if (CHECK_BUSY(JOB940_PICOSTATELOAD2_PREP)) wait_busy_940(JOB940_PICOSTATELOAD2_PREP);\r
-\r
- memcpy(ym_remote_regs, ym_local_regs, 0x200);\r
-\r
- add_job_940(JOB940_PICOSTATELOAD2);\r
- if (CHECK_BUSY(JOB940_PICOSTATELOAD2)) wait_busy_940(JOB940_PICOSTATELOAD2);\r
-\r
- return 0;\r
-}\r
-\r
-\r
-static void internal_reset(void)\r
-{\r
- writebuff_ptr = 0;\r
- ST_address = addr_A1 = -1;\r
-}\r
-\r
-\r
-/* this must be called after mmu hack, the allocated regions must not get cached */\r
-void sharedmem940_init(void)\r
-{\r
- if (shared_mem != NULL) return;\r
-\r
- shared_mem = (unsigned char *) mmap(0, 0x210000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0x2000000);\r
- if (shared_mem == MAP_FAILED)\r
- {\r
- printf("mmap(shared_data) failed with %i\n", errno);\r
- exit(1);\r
- }\r
- shared_data = (_940_data_t *) (shared_mem+0x100000);\r
- /* this area must not get buffered on either side */\r
- shared_ctl = (_940_ctl_t *) (shared_mem+0x200000);\r
- mp3_mem = (unsigned char *) mmap(0, MP3_SIZE_MAX, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0x2400000);\r
- if (mp3_mem == MAP_FAILED)\r
- {\r
- printf("mmap(mp3_mem) failed with %i\n", errno);\r
- exit(1);\r
- }\r
- crashed_940 = 1;\r
-}\r
-\r
-\r
-void sharedmem940_finish(void)\r
-{\r
- munmap(shared_mem, 0x210000);\r
- munmap(mp3_mem, MP3_SIZE_MAX);\r
- shared_mem = mp3_mem = NULL;\r
- shared_data = NULL;\r
- shared_ctl = NULL;\r
-}\r
-\r
-\r
-void YM2612Init_940(int baseclock, int rate)\r
-{\r
- printf("YM2612Init_940()\n");\r
- printf("Mem usage: shared_data: %i, shared_ctl: %i\n", sizeof(*shared_data), sizeof(*shared_ctl));\r
-\r
- reset940(1, 2);\r
- pause940(1);\r
-\r
- gp2x_memregs[0x3B40>>1] = 0; // disable DUALCPU interrupts for 920\r
- gp2x_memregs[0x3B42>>1] = 1; // enable DUALCPU interrupts for 940\r
-\r
- gp2x_memregl[0x4504>>2] = 0; // make sure no FIQs will be generated\r
- gp2x_memregl[0x4508>>2] = ~(1<<26); // unmask DUALCPU ints in the undocumented 940's interrupt controller\r
-\r
-\r
- if (crashed_940)\r
- {\r
- unsigned char ucData[1024];\r
- int nRead, nLen = 0;\r
- char binpath[512];\r
- FILE *fp;\r
-\r
- emu_make_path(binpath, CODE940_FILE, sizeof(binpath));\r
- fp = fopen(binpath, "rb");\r
- if(!fp)\r
- {\r
- memset(g_screen_ptr, 0, 320*240*2);\r
- text_out16(10, 100, "failed to open required file:");\r
- text_out16(10, 110, CODE940_FILE);\r
- gp2x_video_flip2();\r
- in_menu_wait(PBTN_MOK|PBTN_MBACK, 100);\r
- printf("failed to open %s\n", binpath);\r
- exit(1);\r
- }\r
-\r
- while(1)\r
- {\r
- nRead = fread(ucData, 1, 1024, fp);\r
- if(nRead <= 0)\r
- break;\r
- memcpy(shared_mem + nLen, ucData, nRead);\r
- nLen += nRead;\r
- }\r
- fclose(fp);\r
- crashed_940 = 0;\r
- }\r
-\r
- memset(shared_data, 0, sizeof(*shared_data));\r
- memset(shared_ctl, 0, sizeof(*shared_ctl));\r
-\r
- /* cause local ym2612 to init REGS */\r
- YM2612Init_(baseclock, rate);\r
-\r
- internal_reset();\r
-\r
- loaded_mp3 = 0;\r
-\r
- gp2x_memregs[0x3B46>>1] = 0xffff; // clear pending DUALCPU interrupts for 940\r
- gp2x_memregl[0x4500>>2] = 0xffffffff; // clear pending IRQs in SRCPND\r
- gp2x_memregl[0x4510>>2] = 0xffffffff; // clear pending IRQs in INTPND\r
-\r
- /* start the 940 */\r
- reset940(0, 2);\r
- pause940(0);\r
-\r
- // YM2612ResetChip_940(); // will be done on JOB940_YM2612INIT\r
-\r
- /* now cause 940 to init it's ym2612 stuff */\r
- shared_ctl->baseclock = baseclock;\r
- shared_ctl->rate = rate;\r
- add_job_940(JOB940_INITALL);\r
-}\r
-\r
-\r
-void YM2612ResetChip_940(void)\r
-{\r
- //printf("YM2612ResetChip_940()\n");\r
- if (shared_data == NULL) {\r
- printf("YM2612ResetChip_940: reset before init?\n");\r
- return;\r
- }\r
-\r
- YM2612ResetChip_();\r
- internal_reset();\r
-\r
- add_job_940(JOB940_YM2612RESETCHIP);\r
-}\r
-\r
-\r
-int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty)\r
-{\r
- int *ym_buf = shared_data->ym_buffer;\r
- int ym_active_chs;\r
-\r
- //printf("YM2612UpdateOne_940()\n");\r
-\r
- if (CHECK_BUSY(JOB940_YM2612UPDATEONE)) wait_busy_940(JOB940_YM2612UPDATEONE);\r
-\r
- ym_active_chs = shared_ctl->ym_active_chs;\r
-\r
- // mix in ym buffer. is_buf_empty means nobody mixed there anything yet and it may contain trash\r
- if (is_buf_empty && ym_active_chs) memcpy32(buffer, ym_buf, length<<stereo);\r
- else memset32(buffer, 0, length<<stereo);\r
-\r
- if (shared_ctl->writebuffsel == 1) {\r
- shared_ctl->writebuff0[writebuff_ptr & 0xffff] = 0xffff;\r
- } else {\r
- shared_ctl->writebuff1[writebuff_ptr & 0xffff] = 0xffff;\r
- }\r
- writebuff_ptr = 0;\r
-\r
- /* predict sample counter for next frame */\r
- if (PsndLen_exc_add) {\r
- length = PsndLen;\r
- if (PsndLen_exc_cnt + PsndLen_exc_add >= 0x10000) length++;\r
- }\r
-\r
- /* give 940 ym job */\r
- shared_ctl->writebuffsel ^= 1;\r
- shared_ctl->length = length;\r
- shared_ctl->stereo = stereo;\r
-\r
- add_job_940(JOB940_YM2612UPDATEONE);\r
-\r
- return ym_active_chs;\r
-}\r
-\r
-\r
-/***********************************************************/\r
-\r
-static int mp3_samples_ready = 0, mp3_buffer_offs = 0;\r
-static int mp3_play_bufsel = 0, mp3_job_started = 0;\r
-\r
-void mp3_update(int *buffer, int length, int stereo)\r
-{\r
- int length_mp3;\r
-\r
- if (!(PicoOpt & POPT_EXT_FM)) {\r
- mp3_update_local(buffer, length, stereo);\r
- return;\r
- }\r
-\r
- // check if playback was started, track not ended\r
- if (loaded_mp3 == NULL || shared_ctl->mp3_offs >= shared_ctl->mp3_len)\r
- return;\r
-\r
- length_mp3 = length;\r
- if (PsndRate == 22050) length_mp3 <<= 1; // mp3s are locked to 44100Hz stereo\r
- else if (PsndRate == 11025) length_mp3 <<= 2; // so make length 44100ish\r
-\r
- /* do we have to wait? */\r
- if (mp3_job_started && mp3_samples_ready < length_mp3) {\r
- if (CHECK_BUSY(JOB940_MP3DECODE)) wait_busy_940(JOB940_MP3DECODE);\r
- mp3_job_started = 0;\r
- mp3_samples_ready += 1152;\r
- }\r
-\r
- /* mix mp3 data, only stereo */\r
- if (mp3_samples_ready >= length_mp3)\r
- {\r
- int shr = 0;\r
- void (*mix_samples)(int *dest_buf, short *mp3_buf, int count) = mix_16h_to_32;\r
- if (PsndRate == 22050) { mix_samples = mix_16h_to_32_s1; shr = 1; }\r
- else if (PsndRate == 11025) { mix_samples = mix_16h_to_32_s2; shr = 2; }\r
-\r
- if (1152 - mp3_buffer_offs >= length_mp3) {\r
- mix_samples(buffer, shared_data->mp3_buffer[mp3_play_bufsel] + mp3_buffer_offs*2, length<<1);\r
-\r
- mp3_buffer_offs += length_mp3;\r
- } else {\r
- // collect samples from both buffers..\r
- int left = 1152 - mp3_buffer_offs;\r
- if (mp3_play_bufsel == 0)\r
- {\r
- mix_samples(buffer, shared_data->mp3_buffer[0] + mp3_buffer_offs*2, length<<1);\r
- mp3_buffer_offs = length_mp3 - left;\r
- mp3_play_bufsel = 1;\r
- } else {\r
- mix_samples(buffer, shared_data->mp3_buffer[1] + mp3_buffer_offs*2, (left>>shr)<<1);\r
- mp3_buffer_offs = length_mp3 - left;\r
- mix_samples(buffer + ((left>>shr)<<1),\r
- shared_data->mp3_buffer[0], (mp3_buffer_offs>>shr)<<1);\r
- mp3_play_bufsel = 0;\r
- }\r
- }\r
- mp3_samples_ready -= length_mp3;\r
- }\r
-\r
- // ask to decode more if we already can\r
- if (!mp3_job_started)\r
- {\r
- mp3_job_started = 1;\r
- shared_ctl->mp3_buffsel ^= 1;\r
- add_job_940(JOB940_MP3DECODE);\r
- }\r
-}\r
-\r
-\r
-void mp3_start_play(void *f_, int pos) // pos is 0-1023\r
-{\r
- int byte_offs = 0;\r
- FILE *f = f_;\r
-\r
- if (!(PicoOpt & POPT_EN_MCD_CDDA) || f == NULL)\r
- return;\r
-\r
- if (!(PicoOpt & POPT_EXT_FM)) {\r
- mp3_start_play_local(f, pos);\r
- return;\r
- }\r
-\r
- if (loaded_mp3 != f)\r
- {\r
- if (PicoMessage != NULL)\r
- {\r
- fseek(f, 0, SEEK_END);\r
- if (ftell(f) > 2*1024*1024)\r
- PicoMessage("Loading MP3...");\r
- }\r
- fseek(f, 0, SEEK_SET);\r
- fread(mp3_mem, 1, MP3_SIZE_MAX, f);\r
- if (!feof(f)) printf("Warning: mp3 was too large, not all data loaded.\n");\r
- shared_ctl->mp3_len = ftell(f);\r
- loaded_mp3 = f;\r
-\r
- if (PicoOpt & POPT_EXT_FM) {\r
- // as we are going to change 940's cacheable area, we must invalidate it's cache..\r
- if (CHECK_BUSY(JOB940_MP3DECODE)) wait_busy_940(JOB940_MP3DECODE);\r
- add_job_940(JOB940_INVALIDATE_DCACHE);\r
- }\r
- reset_timing = 1;\r
- }\r
-\r
- // seek..\r
- if (pos) {\r
- byte_offs = (shared_ctl->mp3_len << 6) >> 10;\r
- byte_offs *= pos;\r
- byte_offs >>= 6;\r
- }\r
- printf(" mp3 pos1024: %i, byte_offs %i/%i\n", pos, byte_offs, shared_ctl->mp3_len);\r
-\r
- shared_ctl->mp3_offs = byte_offs;\r
-\r
- // reset buffer pointers and stuff..\r
- mp3_samples_ready = mp3_buffer_offs = mp3_play_bufsel = 0;\r
- mp3_job_started = 0;\r
- shared_ctl->mp3_buffsel = 1; // will change to 0 on first decode\r
-\r
- add_job_940(JOB940_MP3RESET);\r
- if (CHECK_BUSY(JOB940_MP3RESET)) wait_busy_940(JOB940_MP3RESET);\r
-}\r
-\r
+++ /dev/null
-void sharedmem940_init(void);\r
-void sharedmem940_finish(void);\r
-\r
-void YM2612Init_940(int baseclock, int rate);\r
-void YM2612ResetChip_940(void);\r
-int YM2612UpdateOne_940(int *buffer, int length, int stereo, int is_buf_empty);\r
-\r
-int YM2612Write_940(unsigned int a, unsigned int v, int scanline);\r
-\r
-int YM2612PicoTick_940(int n);\r
-void YM2612PicoStateLoad_940(void);\r
-void YM2612PicoStateSave2_940(int tat, int tbt);\r
-int YM2612PicoStateLoad2_940(int *tat, int *tbt);\r
+++ /dev/null
-CROSS ?= arm-linux-\r
-\r
-# settings\r
-use_cyclone = 1\r
-#use_musashi = 1\r
-use_drz80 = 1\r
-use_sh2drc = 1\r
-#use_sh2mame = 1\r
-\r
-asm_memory = 1\r
-asm_render = 1\r
-asm_ym2612 = 1\r
-asm_misc = 1\r
-asm_cdpico = 1\r
-asm_cdmemory = 1\r
-asm_32xdraw = 1\r
-#profile = 1\r
-#drc_debug = 3\r
-\r
--include Makefile.local\r
-\r
-ifeq "$(debug_cyclone)" "1"\r
-use_cyclone = 1\r
-use_musashi = 1\r
-endif\r
-ifeq "$(use_musashi)" "1"\r
-# due to CPU stop flag acces\r
-asm_cdpico = 0\r
-asm_cdmemory = 0\r
-endif\r
-\r
-ARCH = arm\r
-DEFINES += ARM __GP2X__ IN_GP2X IN_EVDEV # BENCHMARK\r
-CFLAGS += -Wall -Winline -I../.. -I.\r
-ifeq ($(DEBUG),)\r
-CFLAGS += -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math\r
-endif\r
-CFLAGS += -mcpu=arm920t -mtune=arm920t\r
-ASFLAGS = -mcpu=arm920t -mfloat-abi=soft\r
-LDFLAGS += -lm -lpng\r
-\r
-CC = $(CROSS)gcc\r
-STRIP = $(CROSS)strip\r
-AS = $(CROSS)as\r
-LD = $(CROSS)ld\r
-OBJCOPY = $(CROSS)objcopy\r
-\r
-# frontend\r
-OBJS += plat.o warm.o pollux_set.o soc.o soc_mmsp2.o soc_pollux.o soc_dummy.o emu.o in_gp2x.o\r
-# 940 core control\r
-OBJS += 940ctl.o\r
-\r
-# ARM stuff\r
-OBJS += pico/carthw/svp/compiler.o pico/carthw/svp/stub_arm.o\r
-OBJS += pico/sound/mix_arm.o\r
-\r
-# common\r
-OBJS += platform/common/emu.o platform/common/menu_pico.o platform/common/fonts.o platform/common/config.o \\r
- platform/common/arm_utils.o platform/common/arm_linux.o platform/common/readpng.o \\r
- platform/common/mp3_helix.o platform/common/input.o platform/common/main.o platform/common/mp3.o \\r
- platform/linux/sndout_oss.o platform/linux/plat.o platform/linux/in_evdev.o\r
-\r
-# unzip\r
-OBJS += unzip/unzip.o unzip/unzip_stream.o\r
-# zlib\r
-OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \\r
- zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o\r
-\r
-vpath %.c = ../..\r
-vpath %.s = ../..\r
-vpath %.S = ../..\r
-\r
-DIRS += platform/gp2x platform/linux zlib unzip \r
-\r
-\r
-all: mkdirs PicoDrive\r
-\r
-include ../common/common.mak\r
-include ../common/common_arm.mak\r
-include ../common/revision.mak\r
-\r
-CFLAGS += $(addprefix -D,$(DEFINES))\r
-\r
-# partial linking helps profiled builds due to section merging\r
-PicoDrive.o : $(OBJS) ../common/helix/$(CROSS)helix-mp3.a\r
- $(LD) -r -o $@ $^\r
-\r
-# still using static, dynamic linking slows Wiz 1-10%\r
-# also libm on F100 is not compatible\r
-PicoDrive : PicoDrive.o\r
- @echo ">>>" $@\r
- $(CC) -static -o $@ $(CFLAGS) $^ $(LDFLAGS) -Wl,-Map=$@.map\r
-ifeq ($(DEBUG),)\r
- $(STRIP) $@\r
-endif\r
-\r
-up: PicoDrive\r
- @cp -v PicoDrive /mnt/gp2x/mnt/sd/emus/PicoDrive/\r
-\r
-clean: tidy\r
- $(RM) PicoDrive\r
-tidy:\r
- $(RM) $(OBJS)\r
-\r
-readme.txt: ../../tools/textfilter ../base_readme.txt\r
- ../../tools/textfilter ../base_readme.txt $@ GP2X\r
-\r
-# ----------- release -----------\r
-VER ?= $(shell head -n 1 version.h | sed 's/.*"\(.*\)\.\(.*\)".*/\1\2/g')\r
-CODE940 = code940/pico940_v3.bin\r
-\r
-rel: PicoDrive PicoDrive.gpe $(CODE940) readme.txt ../game_def.cfg \\r
- PicoDrive.png PicoDrive_s.png PicoDrive_t.png \\r
- warm_2.4.25.o warm_2.4.26-open2x.o warm_2.6.24.ko \\r
- ../../pico/carthw.cfg\r
- mkdir -p out/PicoDrive/skin/\r
- cp $^ out/PicoDrive/\r
- cp PicoDrive.ini out/\r
- cp skin/*.png out/PicoDrive/skin/\r
- cp skin/*.txt out/PicoDrive/skin/\r
- mkdir out/bin_to_cso_mp3\r
- cp ../../tools/bin_to_cso_mp3/* out/bin_to_cso_mp3/\r
- cd out && zip -9 -r ../../../PicoDrive_$(VER).zip *\r
- rm -rf out\r
-\r
-$(CODE940):\r
- make -C code940/\r
-\r
+++ /dev/null
-/*\r
- * (c) Copyright 2006-2010 notaz, All rights reserved.\r
- *\r
- * For performance reasons 3 renderers are exported for both MD and 32x modes:\r
- * - 16bpp line renderer\r
- * - 8bpp line renderer (slightly faster)\r
- * - 8bpp tile renderer\r
- * In 32x mode:\r
- * - 32x layer is overlayed on top of 16bpp one\r
- * - line internal one done on PicoDraw2FB, then mixed with 32x\r
- * - tile internal one done on PicoDraw2FB, then mixed with 32x\r
- */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <unistd.h>\r
-\r
-#include "plat_gp2x.h"\r
-#include "soc.h"\r
-#include "soc_pollux.h"\r
-#include "../common/plat.h"\r
-#include "../common/menu.h"\r
-#include "../common/arm_utils.h"\r
-#include "../common/fonts.h"\r
-#include "../common/emu.h"\r
-#include "../common/config.h"\r
-#include "../common/input.h"\r
-#include "../linux/sndout_oss.h"\r
-#include "version.h"\r
-\r
-#include <pico/pico_int.h>\r
-#include <pico/patch.h>\r
-#include <pico/sound/mix.h>\r
-#include <zlib/zlib.h>\r
-\r
-#ifdef BENCHMARK\r
-#define OSD_FPS_X 220\r
-#else\r
-#define OSD_FPS_X 260\r
-#endif\r
-\r
-\r
-extern int crashed_940;\r
-\r
-static short __attribute__((aligned(4))) sndBuffer[2*(44100+100)/50];\r
-static unsigned char PicoDraw2FB_[(8+320) * (8+240+8)];\r
-unsigned char *PicoDraw2FB = PicoDraw2FB_;\r
-static int osd_fps_x, osd_y, doing_bg_frame;\r
-const char *renderer_names[] = { "16bit accurate", " 8bit accurate", " 8bit fast", NULL };\r
-const char *renderer_names32x[] = { "accurate", "faster", "fastest", NULL };\r
-enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT };\r
-\r
-static int (*emu_scan_begin)(unsigned int num) = NULL;\r
-static int (*emu_scan_end)(unsigned int num) = NULL;\r
-\r
-extern void *gp2x_screens[4];\r
-\r
-\r
-void pemu_prep_defconfig(void)\r
-{\r
- gp2x_soc_t soc;\r
-\r
- defaultConfig.CPUclock = default_cpu_clock;\r
- defaultConfig.renderer32x = RT_8BIT_FAST;\r
- defaultConfig.analog_deadzone = 50;\r
-\r
- soc = soc_detect();\r
- if (soc == SOCID_MMSP2)\r
- defaultConfig.s_PicoOpt |= POPT_EXT_FM;\r
- else if (soc == SOCID_POLLUX) {\r
- defaultConfig.EmuOpt |= EOPT_WIZ_TEAR_FIX|EOPT_SHOW_RTC;\r
- defaultConfig.s_PicoOpt |= POPT_EN_MCD_GFX;\r
- }\r
-}\r
-\r
-void pemu_validate_config(void)\r
-{\r
- if (gp2x_dev_id != GP2X_DEV_GP2X)\r
- PicoOpt &= ~POPT_EXT_FM;\r
- if (gp2x_dev_id != GP2X_DEV_WIZ)\r
- currentConfig.EmuOpt &= ~EOPT_WIZ_TEAR_FIX;\r
-\r
- if (currentConfig.gamma < 10 || currentConfig.gamma > 300)\r
- currentConfig.gamma = 100;\r
-\r
- if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 1024)\r
- currentConfig.CPUclock = default_cpu_clock;\r
-}\r
-\r
-static int get_renderer(void)\r
-{\r
- if (PicoAHW & PAHW_32X)\r
- return currentConfig.renderer32x;\r
- else\r
- return currentConfig.renderer;\r
-}\r
-\r
-static void change_renderer(int diff)\r
-{\r
- int *r;\r
- if (PicoAHW & PAHW_32X)\r
- r = ¤tConfig.renderer32x;\r
- else\r
- r = ¤tConfig.renderer;\r
- *r += diff;\r
-\r
- // 8bpp fast is not there (yet?)\r
- if ((PicoAHW & PAHW_SMS) && *r == RT_8BIT_FAST)\r
- (*r)++;\r
-\r
- if (*r >= RT_COUNT)\r
- *r = 0;\r
- else if (*r < 0)\r
- *r = RT_COUNT - 1;\r
-}\r
-\r
-#define is_16bit_mode() \\r
- (get_renderer() == RT_16BIT || (PicoAHW & PAHW_32X))\r
-\r
-static void (*osd_text)(int x, int y, const char *text);\r
-\r
-static void osd_text8(int x, int y, const char *text)\r
-{\r
- int len = strlen(text)*8;\r
- int *p, i, h, offs;\r
-\r
- len = (len+3) >> 2;\r
- for (h = 0; h < 8; h++) {\r
- offs = (x + g_screen_width * (y+h)) & ~3;\r
- p = (int *) ((char *)g_screen_ptr + offs);\r
- for (i = len; i; i--, p++)\r
- *p = 0xe0e0e0e0;\r
- }\r
- emu_text_out8(x, y, text);\r
-}\r
-\r
-static void osd_text16(int x, int y, const char *text)\r
-{\r
- int len = strlen(text)*8;\r
- int *p, i, h, offs;\r
-\r
- len = (len+1) >> 1;\r
- for (h = 0; h < 8; h++) {\r
- offs = (x + g_screen_width * (y+h)) & ~1;\r
- p = (int *) ((short *)g_screen_ptr + offs);\r
- for (i = len; i; i--, p++)\r
- *p = (*p >> 2) & 0x39e7;\r
- }\r
- emu_text_out16(x, y, text);\r
-}\r
-\r
-static void osd_text8_rot(int x, int y, const char *text)\r
-{\r
- int len = strlen(text) * 8;\r
- char *p = (char *)g_screen_ptr + 240*(320-x) + y;\r
-\r
- while (len--) {\r
- memset(p, 0xe0, 8);\r
- p -= 240;\r
- }\r
-\r
- emu_text_out8_rot(x, y, text);\r
-}\r
-\r
-static void osd_text16_rot(int x, int y, const char *text)\r
-{\r
- int len = strlen(text) * 8;\r
- short *p = (short *)g_screen_ptr + 240*(320-x) + y;\r
-\r
- while (len--) {\r
- memset(p, 0, 8*2);\r
- p -= 240;\r
- }\r
-\r
- emu_text_out16_rot(x, y, text);\r
-}\r
-\r
-static void draw_cd_leds(void)\r
-{\r
- int led_reg, pitch, scr_offs, led_offs;\r
- led_reg = Pico_mcd->s68k_regs[0];\r
-\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
- pitch = 240;\r
- led_offs = -pitch * 6;\r
- scr_offs = pitch * (320 - 4);\r
- } else {\r
- pitch = 320;\r
- led_offs = 4;\r
- scr_offs = pitch * 2 + 4;\r
- }\r
-\r
- if (!is_16bit_mode()) {\r
- #define p(x) px[(x) >> 2]\r
- // 8-bit modes\r
- unsigned int *px = (unsigned int *)((char *)g_screen_ptr + scr_offs);\r
- unsigned int col_g = (led_reg & 2) ? 0xc0c0c0c0 : 0xe0e0e0e0;\r
- unsigned int col_r = (led_reg & 1) ? 0xd0d0d0d0 : 0xe0e0e0e0;\r
- p(pitch*0) = p(pitch*1) = p(pitch*2) = col_g;\r
- p(pitch*0 + led_offs) = p(pitch*1 + led_offs) = p(pitch*2 + led_offs) = col_r;\r
- #undef p\r
- } else {\r
- #define p(x) px[(x)*2 >> 2] = px[((x)*2 >> 2) + 1]\r
- // 16-bit modes\r
- unsigned int *px = (unsigned int *)((short *)g_screen_ptr + scr_offs);\r
- unsigned int col_g = (led_reg & 2) ? 0x06000600 : 0;\r
- unsigned int col_r = (led_reg & 1) ? 0xc000c000 : 0;\r
- p(pitch*0) = p(pitch*1) = p(pitch*2) = col_g;\r
- p(pitch*0 + led_offs) = p(pitch*1 + led_offs) = p(pitch*2 + led_offs) = col_r;\r
- #undef p\r
- }\r
-}\r
-\r
-static void draw_pico_ptr(void)\r
-{\r
- unsigned short *p = (unsigned short *)g_screen_ptr;\r
- int x, y, pitch = 320;\r
-\r
- // only if pen enabled and for 16bit modes\r
- if (pico_inp_mode == 0 || currentConfig.EmuOpt != RT_16BIT)\r
- return;\r
-\r
- x = pico_pen_x + PICO_PEN_ADJUST_X;\r
- y = pico_pen_y + PICO_PEN_ADJUST_Y;\r
- if (!(Pico.video.reg[12]&1) && !(PicoOpt & POPT_DIS_32C_BORDER))\r
- x += 32;\r
-\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
- pitch = 240;\r
- p += (319 - x) * pitch + y;\r
- } else\r
- p += x + y * pitch;\r
-\r
- p[0] ^= 0xffff;\r
- p[pitch-1] ^= 0xffff;\r
- p[pitch] ^= 0xffff;\r
- p[pitch+1] ^= 0xffff;\r
- p[pitch*2] ^= 0xffff;\r
-}\r
-\r
-/* rot thing for Wiz */\r
-static unsigned char __attribute__((aligned(4))) rot_buff[320*4*2];\r
-\r
-static int EmuScanBegin16_rot(unsigned int num)\r
-{\r
- DrawLineDest = rot_buff + (num & 3) * 320 * 2;\r
- return 0;\r
-}\r
-\r
-static int EmuScanEnd16_rot(unsigned int num)\r
-{\r
- if ((num & 3) != 3)\r
- return 0;\r
- rotated_blit16(g_screen_ptr, rot_buff, num + 1,\r
- !(Pico.video.reg[12] & 1) && !(PicoOpt & POPT_EN_SOFTSCALE));\r
- return 0;\r
-}\r
-\r
-static int EmuScanBegin8_rot(unsigned int num)\r
-{\r
- DrawLineDest = rot_buff + (num & 3) * 320;\r
- return 0;\r
-}\r
-\r
-static int EmuScanEnd8_rot(unsigned int num)\r
-{\r
- if ((num & 3) != 3)\r
- return 0;\r
- rotated_blit8(g_screen_ptr, rot_buff, num + 1,\r
- !(Pico.video.reg[12] & 1));\r
- return 0;\r
-}\r
-\r
-/* line doublers */\r
-static unsigned int ld_counter;\r
-static int ld_left, ld_lines;\r
-\r
-static int EmuScanBegin16_ld(unsigned int num)\r
-{\r
- if ((signed int)(ld_counter - num) > 100)\r
- ld_counter = 0;\r
-\r
- if (emu_scan_begin)\r
- return emu_scan_begin(ld_counter);\r
- else\r
- DrawLineDest = (char *)g_screen_ptr + 320 * ld_counter * gp2x_current_bpp / 8;\r
-\r
- return 0;\r
-}\r
-\r
-static int EmuScanEnd16_ld(unsigned int num)\r
-{\r
- void *oldline = DrawLineDest;\r
-\r
- if (emu_scan_end)\r
- emu_scan_end(ld_counter);\r
-\r
- ld_counter++;\r
- ld_left--;\r
- if (ld_left <= 0) {\r
- ld_left = ld_lines;\r
-\r
- EmuScanBegin16_ld(num);\r
- memcpy32(DrawLineDest, oldline, 320 * gp2x_current_bpp / 8 / 4);\r
- if (emu_scan_end)\r
- emu_scan_end(ld_counter);\r
-\r
- ld_counter++;\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-static int localPal[0x100];\r
-static void (*vidcpyM2)(void *dest, void *src, int m32col, int with_32c_border);\r
-static int (*make_local_pal)(int fast_mode);\r
-\r
-static int make_local_pal_md(int fast_mode)\r
-{\r
- int pallen = 0xc0;\r
-\r
- bgr444_to_rgb32(localPal, Pico.cram);\r
- if (fast_mode)\r
- return 0x40;\r
-\r
- if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode\r
- bgr444_to_rgb32_sh(localPal, Pico.cram);\r
- localPal[0xc0] = 0x0000c000;\r
- localPal[0xd0] = 0x00c00000;\r
- localPal[0xe0] = 0x00000000; // reserved pixels for OSD\r
- localPal[0xf0] = 0x00ffffff;\r
- pallen = 0x100;\r
- }\r
- else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes\r
- bgr444_to_rgb32(localPal+0x40, HighPal);\r
- bgr444_to_rgb32(localPal+0x80, HighPal+0x40);\r
- }\r
- else\r
- memcpy32(localPal+0x80, localPal, 0x40); // for spr prio mess\r
-\r
- return pallen;\r
-}\r
-\r
-static int make_local_pal_sms(int fast_mode)\r
-{\r
- unsigned short *spal = Pico.cram;\r
- unsigned int *dpal = (void *)localPal;\r
- unsigned int i, t;\r
-\r
- for (i = 0x40; i > 0; i--) {\r
- t = *spal++;\r
- t = ((t & 0x0003) << 22) | ((t & 0x000c) << 12) | ((t & 0x0030) << 2);\r
- t |= t >> 2;\r
- t |= t >> 4;\r
- *dpal++ = t;\r
- }\r
-\r
- return 0x40;\r
-}\r
-\r
-void pemu_finalize_frame(const char *fps, const char *notice)\r
-{\r
- int emu_opt = currentConfig.EmuOpt;\r
- int ret;\r
-\r
- if (PicoAHW & PAHW_32X)\r
- ; // nothing to do\r
- else if (get_renderer() == RT_8BIT_FAST)\r
- {\r
- // 8bit fast renderer\r
- if (Pico.m.dirtyPal) {\r
- Pico.m.dirtyPal = 0;\r
- ret = make_local_pal(1);\r
- // feed new palette to our device\r
- gp2x_video_setpalette(localPal, ret);\r
- }\r
- // a hack for VR\r
- if (PicoAHW & PAHW_SVP)\r
- memset32((int *)(PicoDraw2FB+328*8+328*223), 0xe0e0e0e0, 328);\r
- // do actual copy\r
- vidcpyM2(g_screen_ptr, PicoDraw2FB+328*8,\r
- !(Pico.video.reg[12] & 1), !(PicoOpt & POPT_DIS_32C_BORDER));\r
- }\r
- else if (get_renderer() == RT_8BIT_ACC)\r
- {\r
- // 8bit accurate renderer\r
- if (Pico.m.dirtyPal)\r
- {\r
- Pico.m.dirtyPal = 0;\r
- ret = make_local_pal(0);\r
- gp2x_video_setpalette(localPal, ret);\r
- }\r
- }\r
-\r
- if (notice)\r
- osd_text(4, osd_y, notice);\r
- if (emu_opt & EOPT_SHOW_FPS)\r
- osd_text(osd_fps_x, osd_y, fps);\r
- if ((PicoAHW & PAHW_MCD) && (emu_opt & EOPT_EN_CD_LEDS))\r
- draw_cd_leds();\r
- if (PicoAHW & PAHW_PICO)\r
- draw_pico_ptr();\r
-}\r
-\r
-void plat_video_flip(void)\r
-{\r
- int stride = g_screen_width;\r
- gp2x_video_flip();\r
-\r
- if (is_16bit_mode())\r
- stride *= 2;\r
- PicoDrawSetOutBuf(g_screen_ptr, stride);\r
-}\r
-\r
-/* XXX */\r
-#ifdef __GP2X__\r
-unsigned int plat_get_ticks_ms(void)\r
-{\r
- return gp2x_get_ticks_ms();\r
-}\r
-\r
-unsigned int plat_get_ticks_us(void)\r
-{\r
- return gp2x_get_ticks_us();\r
-}\r
-#endif\r
-\r
-void plat_wait_till_us(unsigned int us_to)\r
-{\r
- unsigned int now;\r
-\r
- spend_cycles(1024);\r
- now = plat_get_ticks_us();\r
-\r
- while ((signed int)(us_to - now) > 512)\r
- {\r
- spend_cycles(1024);\r
- now = plat_get_ticks_us();\r
- }\r
-}\r
-\r
-void plat_video_wait_vsync(void)\r
-{\r
- gp2x_video_wait_vsync();\r
-}\r
-\r
-void plat_status_msg_clear(void)\r
-{\r
- int is_8bit = !is_16bit_mode();\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
- /* ugh.. */\r
- int i, u, *p;\r
- if (is_8bit) {\r
- for (i = 0; i < 4; i++) {\r
- p = (int *)gp2x_screens[i] + (240-8) / 4;\r
- for (u = 320; u > 0; u--, p += 240/4)\r
- p[0] = p[1] = 0xe0e0e0e0;\r
- }\r
- } else {\r
- for (i = 0; i < 4; i++) {\r
- p = (int *)gp2x_screens[i] + (240-8)*2 / 4;\r
- for (u = 320; u > 0; u--, p += 240*2/4)\r
- p[0] = p[1] = p[2] = p[3] = 0;\r
- }\r
- }\r
- return;\r
- }\r
-\r
- if (is_8bit)\r
- gp2x_memset_all_buffers(320*232, 0xe0, 320*8);\r
- else\r
- gp2x_memset_all_buffers(320*232*2, 0, 320*8*2);\r
-}\r
-\r
-void plat_status_msg_busy_next(const char *msg)\r
-{\r
- plat_status_msg_clear();\r
- pemu_finalize_frame("", msg);\r
- plat_video_flip();\r
- emu_status_msg("");\r
-\r
- /* assumption: msg_busy_next gets called only when\r
- * something slow is about to happen */\r
- reset_timing = 1;\r
-}\r
-\r
-void plat_status_msg_busy_first(const char *msg)\r
-{\r
- gp2x_memcpy_all_buffers(g_screen_ptr, 0, 320*240*2);\r
- plat_status_msg_busy_next(msg);\r
-}\r
-\r
-static void vid_reset_mode(void)\r
-{\r
- int gp2x_mode = 16;\r
- int renderer = get_renderer();\r
-\r
- PicoOpt &= ~POPT_ALT_RENDERER;\r
- emu_scan_begin = NULL;\r
- emu_scan_end = NULL;\r
-\r
- switch (renderer) {\r
- case RT_16BIT:\r
- PicoDrawSetOutFormat(PDF_RGB555, 0);\r
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- break;\r
- case RT_8BIT_ACC:\r
- PicoDrawSetOutFormat(PDF_8BIT, 0);\r
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width);\r
- gp2x_mode = 8;\r
- break;\r
- case RT_8BIT_FAST:\r
- PicoOpt |= POPT_ALT_RENDERER;\r
- PicoDrawSetOutFormat(PDF_NONE, 0);\r
- vidcpyM2 = vidcpy_m2;\r
- gp2x_mode = 8;\r
- break;\r
- default:\r
- printf("bad renderer\n");\r
- break;\r
- }\r
-\r
- if (PicoAHW & PAHW_32X) {\r
- // Wiz 16bit is an exception, uses line rendering due to rotation mess\r
- if (renderer == RT_16BIT && (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)) {\r
- PicoDrawSetOutFormat(PDF_RGB555, 1);\r
- PicoDraw32xSetFrameMode(0, 0);\r
- }\r
- else {\r
- PicoDrawSetOutFormat(PDF_NONE, 0);\r
- PicoDraw32xSetFrameMode(1, 0);\r
- }\r
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- gp2x_mode = 16;\r
- }\r
-\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
- if ((PicoAHW & PAHW_32X) || renderer == RT_16BIT) {\r
- emu_scan_begin = EmuScanBegin16_rot;\r
- emu_scan_end = EmuScanEnd16_rot;\r
- }\r
- else if (renderer == RT_8BIT_ACC) {\r
- emu_scan_begin = EmuScanBegin8_rot;\r
- emu_scan_end = EmuScanEnd8_rot;\r
- }\r
- else if (renderer == RT_8BIT_FAST)\r
- vidcpyM2 = vidcpy_m2_rot;\r
- }\r
-\r
- PicoDrawSetCallbacks(emu_scan_begin, emu_scan_end);\r
-\r
- if (is_16bit_mode())\r
- osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text16_rot : osd_text16;\r
- else\r
- osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text8_rot : osd_text8;\r
-\r
- gp2x_video_wait_vsync();\r
- if (!is_16bit_mode()) {\r
- // setup pal for 8-bit modes\r
- localPal[0xc0] = 0x0000c000; // MCD LEDs\r
- localPal[0xd0] = 0x00c00000;\r
- localPal[0xe0] = 0x00000000; // reserved pixels for OSD\r
- localPal[0xf0] = 0x00ffffff;\r
- gp2x_video_setpalette(localPal, 0x100);\r
- gp2x_memset_all_buffers(0, 0xe0, 320*240);\r
- }\r
- else\r
- gp2x_memset_all_buffers(0, 0, 320*240*2);\r
-\r
- if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)\r
- gp2x_mode = -gp2x_mode;\r
-\r
- gp2x_video_changemode(gp2x_mode);\r
-\r
- Pico.m.dirtyPal = 1;\r
-\r
- PicoOpt &= ~POPT_EN_SOFTSCALE;\r
- if (currentConfig.scaling == EOPT_SCALE_SW)\r
- PicoOpt |= POPT_EN_SOFTSCALE;\r
-\r
- // palette converters for 8bit modes\r
- make_local_pal = (PicoAHW & PAHW_SMS) ? make_local_pal_sms : make_local_pal_md;\r
-}\r
-\r
-void emu_video_mode_change(int start_line, int line_count, int is_32cols)\r
-{\r
- int scalex = 320, scaley = 240;\r
- int ln_offs = 0;\r
-\r
- if (doing_bg_frame)\r
- return;\r
-\r
- osd_fps_x = OSD_FPS_X;\r
- osd_y = 232;\r
-\r
- /* set up hwscaling here */\r
- PicoOpt &= ~POPT_DIS_32C_BORDER;\r
- if (is_32cols && currentConfig.scaling == EOPT_SCALE_HW) {\r
- scalex = 256;\r
- PicoOpt |= POPT_DIS_32C_BORDER;\r
- osd_fps_x = OSD_FPS_X - 64;\r
- }\r
-\r
- if (currentConfig.vscaling == EOPT_SCALE_HW) {\r
- ln_offs = start_line;\r
- scaley = line_count;\r
- osd_y = start_line + line_count - 8;\r
- }\r
-\r
- gp2x_video_RGB_setscaling(ln_offs, scalex, scaley);\r
-\r
- /* line doubling */\r
- if (currentConfig.vscaling == EOPT_SCALE_SW && line_count < 240) {\r
- ld_lines = ld_left = line_count / (240 - line_count);\r
- PicoDrawSetCallbacks(EmuScanBegin16_ld, EmuScanEnd16_ld);\r
- }\r
-\r
- // clear whole screen in all buffers\r
- if (!is_16bit_mode())\r
- gp2x_memset_all_buffers(0, 0xe0, 320*240);\r
- else\r
- gp2x_memset_all_buffers(0, 0, 320*240*2);\r
-}\r
-\r
-void plat_video_toggle_renderer(int change, int is_menu_call)\r
-{\r
- change_renderer(change);\r
-\r
- if (is_menu_call)\r
- return;\r
-\r
- vid_reset_mode();\r
- rendstatus_old = -1;\r
-\r
- if (PicoAHW & PAHW_32X)\r
- emu_status_msg(renderer_names32x[get_renderer()]);\r
- else\r
- emu_status_msg(renderer_names[get_renderer()]);\r
-}\r
-\r
-#if 0 // TODO\r
-static void RunEventsPico(unsigned int events)\r
-{\r
- int ret, px, py, lim_x;\r
- static int pdown_frames = 0;\r
-\r
- // for F200\r
- ret = gp2x_touchpad_read(&px, &py);\r
- if (ret >= 0)\r
- {\r
- if (ret > 35000)\r
- {\r
- if (pdown_frames++ > 5)\r
- PicoPad[0] |= 0x20;\r
-\r
- pico_pen_x = px;\r
- pico_pen_y = py;\r
- if (!(Pico.video.reg[12]&1)) {\r
- pico_pen_x -= 32;\r
- if (pico_pen_x < 0) pico_pen_x = 0;\r
- if (pico_pen_x > 248) pico_pen_x = 248;\r
- }\r
- if (pico_pen_y > 224) pico_pen_y = 224;\r
- }\r
- else\r
- pdown_frames = 0;\r
-\r
- //if (ret == 0)\r
- // PicoPicohw.pen_pos[0] = PicoPicohw.pen_pos[1] = 0x8000;\r
- }\r
-}\r
-#endif\r
-\r
-void plat_update_volume(int has_changed, int is_up)\r
-{\r
- static int prev_frame = 0, wait_frames = 0;\r
- int vol = currentConfig.volume;\r
- int need_low_volume = 0;\r
- gp2x_soc_t soc;\r
-\r
- soc = soc_detect();\r
- if ((PicoOpt & POPT_EN_STEREO) && soc == SOCID_MMSP2)\r
- need_low_volume = 1;\r
-\r
- if (has_changed)\r
- {\r
- if (need_low_volume && vol < 5 && prev_frame == Pico.m.frame_count - 1 && wait_frames < 12)\r
- wait_frames++;\r
- else {\r
- if (is_up) {\r
- if (vol < 99) vol++;\r
- } else {\r
- if (vol > 0) vol--;\r
- }\r
- wait_frames = 0;\r
- sndout_oss_setvol(vol, vol);\r
- currentConfig.volume = vol;\r
- }\r
- emu_status_msg("VOL: %02i", vol);\r
- prev_frame = Pico.m.frame_count;\r
- }\r
-\r
- if (!need_low_volume)\r
- return;\r
-\r
- /* set the right mixer func */\r
- if (vol >= 5)\r
- PsndMix_32_to_16l = mix_32_to_16l_stereo;\r
- else {\r
- mix_32_to_16l_level = 5 - vol;\r
- PsndMix_32_to_16l = mix_32_to_16l_stereo_lvl;\r
- }\r
-}\r
-\r
-static void oss_write_nonblocking(int len)\r
-{\r
- // sndout_oss_can_write() is not reliable, only use with no_frmlimit\r
- if ((currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) && !sndout_oss_can_write(len))\r
- return;\r
-\r
- sndout_oss_write_nb(PsndOut, len);\r
-}\r
-\r
-void pemu_sound_start(void)\r
-{\r
- static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0;\r
-\r
- PsndOut = NULL;\r
-\r
- // prepare sound stuff\r
- if (currentConfig.EmuOpt & EOPT_EN_SOUND)\r
- {\r
- int is_stereo = (PicoOpt & POPT_EN_STEREO) ? 1 : 0;\r
- int snd_rate_oss = PsndRate;\r
- gp2x_soc_t soc;\r
-\r
- memset(sndBuffer, 0, sizeof(sndBuffer));\r
- PsndOut = sndBuffer;\r
- PicoWriteSound = oss_write_nonblocking;\r
- plat_update_volume(0, 0);\r
-\r
- printf("starting audio: %i len: %i stereo: %i, pal: %i\n",\r
- PsndRate, PsndLen, is_stereo, Pico.m.pal);\r
- sndout_oss_start(snd_rate_oss, is_stereo, 1);\r
- sndout_oss_setvol(currentConfig.volume, currentConfig.volume);\r
-\r
- soc = soc_detect();\r
- if (soc == SOCID_POLLUX)\r
- PsndRate = pollux_get_real_snd_rate(PsndRate);\r
-\r
- #define SOUND_RERATE_FLAGS (POPT_EN_FM|POPT_EN_PSG|POPT_EN_STEREO|POPT_EXT_FM|POPT_EN_MCD_CDDA)\r
- if (PsndRate != PsndRate_old || Pico.m.pal != pal_old || ((PicoOpt & POPT_EXT_FM) && crashed_940) ||\r
- ((PicoOpt ^ PicoOpt_old) & SOUND_RERATE_FLAGS)) {\r
- PsndRerate(Pico.m.frame_count ? 1 : 0);\r
- }\r
-\r
- PsndRate_old = PsndRate;\r
- PicoOpt_old = PicoOpt;\r
- pal_old = Pico.m.pal;\r
- }\r
-}\r
-\r
-static const int sound_rates[] = { 44100, 32000, 22050, 16000, 11025, 8000 };\r
-\r
-void pemu_sound_stop(void)\r
-{\r
- int i;\r
-\r
- /* get back from Pollux pain */\r
- PsndRate += 1000;\r
- for (i = 0; i < ARRAY_SIZE(sound_rates); i++) {\r
- if (PsndRate >= sound_rates[i]) {\r
- PsndRate = sound_rates[i];\r
- break;\r
- }\r
- }\r
-}\r
-\r
-void pemu_sound_wait(void)\r
-{\r
- // don't need to do anything, writes will block by themselves\r
-}\r
-\r
-void pemu_forced_frame(int no_scale, int do_emu)\r
-{\r
- doing_bg_frame = 1;\r
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- PicoDraw32xSetFrameMode(0, 0);\r
- PicoDrawSetCallbacks(NULL, NULL);\r
- Pico.m.dirtyPal = 1;\r
-\r
- emu_cmn_forced_frame(no_scale, do_emu);\r
-\r
- g_menubg_src_ptr = g_screen_ptr;\r
- doing_bg_frame = 0;\r
-}\r
-\r
-void plat_debug_cat(char *str)\r
-{\r
-}\r
-\r
-#if 0\r
-static void tga_dump(void)\r
-{\r
-#define BYTE unsigned char\r
-#define WORD unsigned short\r
- struct\r
- {\r
- BYTE IDLength; /* 00h Size of Image ID field */\r
- BYTE ColorMapType; /* 01h Color map type */\r
- BYTE ImageType; /* 02h Image type code */\r
- WORD CMapStart; /* 03h Color map origin */\r
- WORD CMapLength; /* 05h Color map length */\r
- BYTE CMapDepth; /* 07h Depth of color map entries */\r
- WORD XOffset; /* 08h X origin of image */\r
- WORD YOffset; /* 0Ah Y origin of image */\r
- WORD Width; /* 0Ch Width of image */\r
- WORD Height; /* 0Eh Height of image */\r
- BYTE PixelDepth; /* 10h Image pixel size */\r
- BYTE ImageDescriptor; /* 11h Image descriptor byte */\r
- } __attribute__((packed)) TGAHEAD;\r
- static unsigned short oldscr[320*240];\r
- FILE *f; char name[128]; int i;\r
-\r
- memset(&TGAHEAD, 0, sizeof(TGAHEAD));\r
- TGAHEAD.ImageType = 2;\r
- TGAHEAD.Width = 320;\r
- TGAHEAD.Height = 240;\r
- TGAHEAD.PixelDepth = 16;\r
- TGAHEAD.ImageDescriptor = 2<<4; // image starts at top-left\r
-\r
-#define CONV(X) (((X>>1)&0x7fe0)|(X&0x1f)) // 555?\r
-\r
- for (i = 0; i < 320*240; i++)\r
- if(oldscr[i] != CONV(((unsigned short *)g_screen_ptr)[i])) break;\r
- if (i < 320*240)\r
- {\r
- for (i = 0; i < 320*240; i++)\r
- oldscr[i] = CONV(((unsigned short *)g_screen_ptr)[i]);\r
- sprintf(name, "%05i.tga", Pico.m.frame_count);\r
- f = fopen(name, "wb");\r
- if (!f) { printf("!f\n"); exit(1); }\r
- fwrite(&TGAHEAD, 1, sizeof(TGAHEAD), f);\r
- fwrite(oldscr, 1, 320*240*2, f);\r
- fclose(f);\r
- }\r
-}\r
-#endif\r
-\r
-void pemu_loop_prep(void)\r
-{\r
- static int gp2x_old_clock = -1, EmuOpt_old = 0, pal_old = 0;\r
- static int gp2x_old_gamma = 100;\r
- gp2x_soc_t soc;\r
-\r
- soc = soc_detect();\r
-\r
- if ((EmuOpt_old ^ currentConfig.EmuOpt) & EOPT_RAM_TIMINGS) {\r
- if (currentConfig.EmuOpt & EOPT_RAM_TIMINGS)\r
- set_ram_timings();\r
- else\r
- unset_ram_timings();\r
- }\r
-\r
- if (gp2x_old_clock < 0)\r
- gp2x_old_clock = default_cpu_clock;\r
- if (gp2x_old_clock != currentConfig.CPUclock && gp2x_set_cpuclk != NULL) {\r
- printf("changing clock to %i...", currentConfig.CPUclock); fflush(stdout);\r
- gp2x_set_cpuclk(currentConfig.CPUclock);\r
- gp2x_old_clock = currentConfig.CPUclock;\r
- printf(" done\n");\r
- }\r
-\r
- if (gp2x_old_gamma != currentConfig.gamma || ((EmuOpt_old ^ currentConfig.EmuOpt) & EOPT_A_SN_GAMMA)) {\r
- set_lcd_gamma(currentConfig.gamma, !!(currentConfig.EmuOpt & EOPT_A_SN_GAMMA));\r
- gp2x_old_gamma = currentConfig.gamma;\r
- printf("updated gamma to %i, A_SN's curve: %i\n", currentConfig.gamma, !!(currentConfig.EmuOpt&0x1000));\r
- }\r
-\r
- if (((EmuOpt_old ^ currentConfig.EmuOpt) & EOPT_VSYNC) || Pico.m.pal != pal_old) {\r
- if ((currentConfig.EmuOpt & EOPT_VSYNC) || soc == SOCID_POLLUX)\r
- set_lcd_custom_rate(Pico.m.pal);\r
- else if (EmuOpt_old & EOPT_VSYNC)\r
- unset_lcd_custom_rate();\r
- }\r
-\r
- if (gp2x_dev_id == GP2X_DEV_CAANOO)\r
- in_set_config_int(in_name_to_id("evdev:pollux-analog"), IN_CFG_ABS_DEAD_ZONE,\r
- currentConfig.analog_deadzone);\r
-\r
- if ((EmuOpt_old ^ currentConfig.EmuOpt) & EOPT_MMUHACK)\r
- gp2x_make_fb_bufferable(currentConfig.EmuOpt & EOPT_MMUHACK);\r
-\r
- EmuOpt_old = currentConfig.EmuOpt;\r
- pal_old = Pico.m.pal;\r
-\r
- // make sure we are in correct mode\r
- change_renderer(0);\r
- vid_reset_mode();\r
-\r
- // dirty buffers better go now than during gameplay\r
- sync();\r
- sleep(0);\r
-\r
- pemu_sound_start();\r
-}\r
-\r
-void pemu_loop_end(void)\r
-{\r
- pemu_sound_stop();\r
-\r
- /* do one more frame for menu bg */\r
- pemu_forced_frame(0, 1);\r
-}\r
-\r
+++ /dev/null
-#include <time.h>
-#include "soc.h"
-#include "plat_gp2x.h"
-
-static void menu_main_plat_draw(void)
-{
- static time_t last_bat_read = 0;
- static int last_bat_val = -1;
- unsigned short *bp = g_screen_ptr;
- int bat_h = me_mfont_h * 2 / 3;
- int i, u, w, wfill, batt_val;
- struct tm *tmp;
- time_t ltime;
- char time_s[16];
-
- if (!(currentConfig.EmuOpt & EOPT_SHOW_RTC))
- return;
-
- ltime = time(NULL);
- tmp = gmtime(<ime);
- strftime(time_s, sizeof(time_s), "%H:%M", tmp);
-
- text_out16(g_screen_width - me_mfont_w * 6, me_mfont_h + 2, time_s);
-
- if (ltime - last_bat_read > 10) {
- last_bat_read = ltime;
- last_bat_val = batt_val = gp2x_read_battery();
- }
- else
- batt_val = last_bat_val;
-
- if (batt_val < 0 || batt_val > 100)
- return;
-
- /* battery info */
- bp += (me_mfont_h * 2 + 2) * g_screen_width + g_screen_width - me_mfont_w * 3 - 3;
- for (i = 0; i < me_mfont_w * 2; i++)
- bp[i] = menu_text_color;
- for (i = 0; i < me_mfont_w * 2; i++)
- bp[i + g_screen_width * bat_h] = menu_text_color;
- for (i = 0; i <= bat_h; i++)
- bp[i * g_screen_width] =
- bp[i * g_screen_width + me_mfont_w * 2] = menu_text_color;
- for (i = 2; i < bat_h - 1; i++)
- bp[i * g_screen_width - 1] =
- bp[i * g_screen_width - 2] = menu_text_color;
-
- w = me_mfont_w * 2 - 1;
- wfill = batt_val * w / 100;
- for (u = 1; u < bat_h; u++)
- for (i = 0; i < wfill; i++)
- bp[(w - i) + g_screen_width * u] = menu_text_color;
-}
-
-// ------------ gfx options menu ------------
-
-static const char *mgn_aopt_gamma(int id, int *offs)
-{
- sprintf(static_buff, "%i.%02i", currentConfig.gamma / 100, currentConfig.gamma % 100);
- return static_buff;
-}
-
-
-const char *men_scaling_opts[] = { "OFF", "software", "hardware", NULL };
-
-#define MENU_OPTIONS_GFX \
- mee_enum ("Horizontal scaling", MA_OPT_SCALING, currentConfig.scaling, men_scaling_opts), \
- mee_enum ("Vertical scaling", MA_OPT_VSCALING, currentConfig.vscaling, men_scaling_opts), \
- mee_onoff ("Tearing Fix", MA_OPT_TEARING_FIX, currentConfig.EmuOpt, EOPT_WIZ_TEAR_FIX), \
- mee_range_cust("Gamma correction", MA_OPT2_GAMMA, currentConfig.gamma, 1, 300, mgn_aopt_gamma), \
- mee_onoff ("A_SN's gamma curve", MA_OPT2_A_SN_GAMMA, currentConfig.EmuOpt, EOPT_A_SN_GAMMA), \
- mee_onoff ("Vsync", MA_OPT2_VSYNC, currentConfig.EmuOpt, EOPT_VSYNC),
-
-#define MENU_OPTIONS_ADV \
- mee_onoff ("Use second CPU for sound", MA_OPT_ARM940_SOUND, PicoOpt, POPT_EXT_FM), \
- mee_onoff ("RAM overclock", MA_OPT2_RAMTIMINGS, currentConfig.EmuOpt, EOPT_RAM_TIMINGS), \
- mee_onoff ("MMU hack", MA_OPT2_SQUIDGEHACK, currentConfig.EmuOpt, EOPT_MMUHACK), \
- mee_onoff ("SVP dynarec", MA_OPT2_SVP_DYNAREC, PicoOpt, POPT_EN_SVP_DRC), \
- mee_onoff ("Status line in main menu", MA_OPT2_STATUS_LINE, currentConfig.EmuOpt, EOPT_SHOW_RTC),
-
-
-static menu_entry e_menu_adv_options[];
-static menu_entry e_menu_gfx_options[];
-static menu_entry e_menu_options[];
-static menu_entry e_menu_keyconfig[];
-
-void gp2x_menu_init(void)
-{
- static menu_entry *cpu_clk_ent;
- int i;
-
- i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);
- cpu_clk_ent = &e_menu_options[i];
-
- /* disable by default.. */
- me_enable(e_menu_adv_options, MA_OPT_ARM940_SOUND, 0);
- me_enable(e_menu_gfx_options, MA_OPT_TEARING_FIX, 0);
- me_enable(e_menu_gfx_options, MA_OPT2_GAMMA, 0);
- me_enable(e_menu_gfx_options, MA_OPT2_A_SN_GAMMA, 0);
-
- switch (gp2x_dev_id) {
- case GP2X_DEV_GP2X:
- me_enable(e_menu_adv_options, MA_OPT_ARM940_SOUND, 1);
- me_enable(e_menu_gfx_options, MA_OPT2_GAMMA, 1);
- me_enable(e_menu_gfx_options, MA_OPT2_A_SN_GAMMA, 1);
- cpu_clk_ent->name = "GP2X CPU clocks";
- break;
- case GP2X_DEV_WIZ:
- me_enable(e_menu_gfx_options, MA_OPT_TEARING_FIX, 1);
- cpu_clk_ent->name = "Wiz/Caanoo CPU clock";
- break;
- case GP2X_DEV_CAANOO:
- cpu_clk_ent->name = "Wiz/Caanoo CPU clock";
- break;
- default:
- break;
- }
-
- if (gp2x_set_cpuclk == NULL)
- cpu_clk_ent->name = "";
-
- if (gp2x_dev_id != GP2X_DEV_GP2X)
- men_scaling_opts[2] = NULL; /* leave only off and sw */
-
- if (gp2x_dev_id != GP2X_DEV_CAANOO)
- me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, 0);
-}
-
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "plat_gp2x.h"
-#include "soc.h"
-#include "warm.h"
-#include "../common/plat.h"
-#include "../common/readpng.h"
-#include "../common/menu.h"
-#include "../common/emu.h"
-#include "../common/input.h"
-#include "../linux/sndout_oss.h"
-
-#include <pico/pico.h>
-
-/* GP2X local */
-int default_cpu_clock;
-int gp2x_dev_id;
-int gp2x_current_bpp;
-void *gp2x_screens[4];
-
-#include <linux/input.h>
-
-static const char * const caanoo_keys[KEY_MAX + 1] = {
- [0 ... KEY_MAX] = NULL,
- [KEY_UP] = "Up",
- [KEY_LEFT] = "Left",
- [KEY_RIGHT] = "Right",
- [KEY_DOWN] = "Down",
- [BTN_TRIGGER] = "A",
- [BTN_THUMB] = "X",
- [BTN_THUMB2] = "B",
- [BTN_TOP] = "Y",
- [BTN_TOP2] = "L",
- [BTN_PINKIE] = "R",
- [BTN_BASE] = "Home",
- [BTN_BASE2] = "Lock",
- [BTN_BASE3] = "I",
- [BTN_BASE4] = "II",
- [BTN_BASE5] = "Push",
-};
-
-struct in_default_bind in_evdev_defbinds[] =
-{
- /* MXYZ SACB RLDU */
- { KEY_UP, IN_BINDTYPE_PLAYER12, 0 },
- { KEY_DOWN, IN_BINDTYPE_PLAYER12, 1 },
- { KEY_LEFT, IN_BINDTYPE_PLAYER12, 2 },
- { KEY_RIGHT, IN_BINDTYPE_PLAYER12, 3 },
- { KEY_S, IN_BINDTYPE_PLAYER12, 4 }, /* B */
- { KEY_D, IN_BINDTYPE_PLAYER12, 5 }, /* C */
- { KEY_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */
- { KEY_ENTER, IN_BINDTYPE_PLAYER12, 7 },
- { KEY_BACKSLASH, IN_BINDTYPE_EMU, PEVB_MENU },
- /* Caanoo */
- { BTN_THUMB, IN_BINDTYPE_PLAYER12, 4 }, /* B */
- { BTN_THUMB2, IN_BINDTYPE_PLAYER12, 5 }, /* C */
- { BTN_TRIGGER, IN_BINDTYPE_PLAYER12, 6 }, /* A */
- { BTN_BASE3, IN_BINDTYPE_PLAYER12, 7 },
- { BTN_TOP2, IN_BINDTYPE_EMU, PEVB_STATE_SAVE },
- { BTN_PINKIE, IN_BINDTYPE_EMU, PEVB_STATE_LOAD },
- { BTN_BASE, IN_BINDTYPE_EMU, PEVB_MENU },
- { 0, 0, 0 }
-};
-
-void gp2x_video_changemode(int bpp)
-{
- gp2x_video_changemode_ll(bpp);
-
- gp2x_current_bpp = bpp < 0 ? -bpp : bpp;
-}
-
-static void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len)
-{
- char *dst;
- if (buffers & (1<<0)) { dst = (char *)gp2x_screens[0] + offset; if (dst != data) memcpy(dst, data, len); }
- if (buffers & (1<<1)) { dst = (char *)gp2x_screens[1] + offset; if (dst != data) memcpy(dst, data, len); }
- if (buffers & (1<<2)) { dst = (char *)gp2x_screens[2] + offset; if (dst != data) memcpy(dst, data, len); }
- if (buffers & (1<<3)) { dst = (char *)gp2x_screens[3] + offset; if (dst != data) memcpy(dst, data, len); }
-}
-
-void gp2x_memcpy_all_buffers(void *data, int offset, int len)
-{
- gp2x_memcpy_buffers(0xf, data, offset, len);
-}
-
-void gp2x_memset_all_buffers(int offset, int byte, int len)
-{
- memset((char *)gp2x_screens[0] + offset, byte, len);
- memset((char *)gp2x_screens[1] + offset, byte, len);
- memset((char *)gp2x_screens[2] + offset, byte, len);
- memset((char *)gp2x_screens[3] + offset, byte, len);
-}
-
-void gp2x_make_fb_bufferable(int yes)
-{
- int ret = 0;
-
- yes = yes ? 1 : 0;
- ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[0], 320*240*2);
- ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[1], 320*240*2);
- ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[2], 320*240*2);
- ret |= warm_change_cb_range(WCB_B_BIT, yes, gp2x_screens[3], 320*240*2);
-
- if (ret)
- fprintf(stderr, "could not make fb buferable.\n");
- else
- printf("made fb buferable.\n");
-}
-
-/* common */
-void plat_video_menu_enter(int is_rom_loaded)
-{
- if (gp2x_current_bpp != 16 || gp2x_dev_id == GP2X_DEV_WIZ) {
- /* try to switch nicely avoiding glitches */
- gp2x_video_wait_vsync();
- memset(gp2x_screens[0], 0, 320*240*2);
- memset(gp2x_screens[1], 0, 320*240*2);
- gp2x_video_flip2(); // might flip to fb2/3
- gp2x_video_flip2(); // ..so we do it again
- }
- else
- gp2x_video_flip2();
-
- // switch to 16bpp
- gp2x_video_changemode_ll(16);
- gp2x_video_RGB_setscaling(0, 320, 240);
-}
-
-void plat_video_menu_begin(void)
-{
- g_menuscreen_ptr = g_screen_ptr;
-}
-
-void plat_video_menu_end(void)
-{
- gp2x_video_flip2();
-}
-
-void plat_early_init(void)
-{
- gp2x_soc_t soc;
- FILE *f;
-
- soc = soc_detect();
- switch (soc)
- {
- case SOCID_MMSP2:
- default_cpu_clock = 200;
- gp2x_dev_id = GP2X_DEV_GP2X;
- break;
- case SOCID_POLLUX:
- default_cpu_clock = 533;
- f = fopen("/dev/accel", "rb");
- if (f) {
- printf("detected Caanoo\n");
- gp2x_dev_id = GP2X_DEV_CAANOO;
- fclose(f);
- }
- else {
- printf("detected Wiz\n");
- gp2x_dev_id = GP2X_DEV_WIZ;
- }
- break;
- default:
- printf("could not recognize SoC, running in dummy mode.\n");
- break;
- }
-
- // just use gettimeofday until plat_init()
- gp2x_get_ticks_ms = plat_get_ticks_ms_good;
- gp2x_get_ticks_us = plat_get_ticks_us_good;
-}
-
-void plat_init(void)
-{
- gp2x_soc_t soc;
-
- soc = soc_detect();
- switch (soc)
- {
- case SOCID_MMSP2:
- mmsp2_init();
- break;
- case SOCID_POLLUX:
- pollux_init();
- break;
- default:
- dummy_init();
- break;
- }
-
- warm_init();
-
- gp2x_memset_all_buffers(0, 0, 320*240*2);
-
- // use buffer2 for menubg to save mem (using only buffers 0, 1 in menu)
- g_menubg_ptr = gp2x_screens[2];
-
- // snd
- sndout_oss_init();
-
- if (gp2x_dev_id == GP2X_DEV_CAANOO)
- in_set_config(in_name_to_id("evdev:pollux-analog"), IN_CFG_KEY_NAMES,
- caanoo_keys, sizeof(caanoo_keys));
-
- gp2x_menu_init();
-}
-
-void plat_finish(void)
-{
- gp2x_soc_t soc;
-
- warm_finish();
-
- soc = soc_detect();
- switch (soc)
- {
- case SOCID_MMSP2:
- mmsp2_finish();
- break;
- case SOCID_POLLUX:
- pollux_finish();
- break;
- default:
- dummy_finish();
- break;
- }
-
- sndout_oss_exit();
-}
-
+++ /dev/null
-// port specific settings\r
-\r
-#ifndef PORT_CONFIG_H\r
-#define PORT_CONFIG_H\r
-\r
-#define CASE_SENSITIVE_FS 1 // CS filesystem\r
-#define DONT_OPEN_MANY_FILES 0\r
-#define REDUCE_IO_CALLS 0\r
-#define SIMPLE_WRITE_SOUND 0\r
-\r
-#define SCREEN_SIZE_FIXED 1\r
-#define SCREEN_WIDTH 320\r
-#define SCREEN_HEIGHT 240\r
-#define MSCREEN_SIZE_FIXED 1\r
-#define MSCREEN_WIDTH SCREEN_WIDTH\r
-#define MSCREEN_HEIGHT SCREEN_HEIGHT\r
-\r
-// draw2.c\r
-#define START_ROW 0 // which row of tiles to start rendering at?\r
-#define END_ROW 28 // ..end\r
-\r
-// pico.c\r
-#define CAN_HANDLE_240_LINES 1\r
-\r
-// logging emu events\r
-#define EL_LOGMASK (EL_STATUS)\r
-// (EL_STATUS|EL_ANOMALY|EL_UIO|EL_SRAMIO|EL_INTS|EL_CDPOLL|EL_IDLE)\r
-\r
-//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)\r
-#define dprintf(x...)\r
-\r
-// platform\r
-#define PATH_SEP "/"\r
-#define PATH_SEP_C '/'\r
-#define MENU_X2 0\r
-\r
-#endif //PORT_CONFIG_H\r
+++ /dev/null
-@ vim:filetype=armasm\r
-\r
-@ .equiv START_ROW, 1\r
-@ .equiv END_ROW, 27\r
-@ one row means 8 pixels. If above example was used, (27-1)*8=208 lines would be rendered.\r
-.equiv START_ROW, 0\r
-.equiv END_ROW, 28\r
-\r
-.equiv UNALIGNED_DRAWLINEDEST, 0\r
-\r
-@ this should be set to one only for GP2X port\r
-.equiv EXTERNAL_YM2612, 1\r
-\r
+++ /dev/null
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <unistd.h>\r
-#include <sys/time.h>\r
-#include "gp2x.h"\r
-\r
-void spend_cycles(int c);\r
-\r
-int main(void)\r
-{\r
- struct timeval tval; // timing\r
- int thissec = 0, frames_done = 0;\r
-\r
- gp2x_init();\r
-\r
- for (;;)\r
- {\r
- gettimeofday(&tval, 0);\r
-\r
- if(thissec != tval.tv_sec)\r
- {\r
- thissec = tval.tv_sec;\r
-\r
- printf("frames_done: %i\n", frames_done);\r
- frames_done = 0;\r
- }\r
-\r
-\r
- //gp2x_video_wait_vsync();\r
- //usleep(1); // sleeps a minimum of ~20ms\r
- //gp2x_video_flip(); // can be called ~430000 times/sec\r
- spend_cycles(1000);\r
- frames_done++;\r
- }\r
-\r
-}\r
-\r
+++ /dev/null
-#define VERSION "1.80"\r
-\r
+++ /dev/null
-/*
- * wARM - exporting ARM processor specific privileged services to userspace
- * userspace part
- *
- * Copyright (c) Gražvydas "notaz" Ignotas, 2009
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the organization nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <sys/syscall.h>
-#include <errno.h>
-
-#define WARM_CODE
-#include "warm.h"
-
-/* provided by glibc */
-extern long init_module(void *, unsigned long, const char *);
-extern long delete_module(const char *, unsigned int);
-
-static int warm_fd = -1;
-static int kernel_version;
-
-static void sys_cacheflush(void *start, void *end)
-{
-#ifdef __ARM_EABI__
- /* EABI version */
- int num = __ARM_NR_cacheflush;
- __asm__("mov r0, %0 ;"
- "mov r1, %1 ;"
- "mov r2, #0 ;"
- "mov r7, %2 ;"
- "swi 0" : : "r" (start), "r" (end), "r" (num)
- : "r0", "r1", "r2", "r3", "r7");
-#else
- /* OABI */
- __asm__("mov r0, %0 ;"
- "mov r1, %1 ;"
- "mov r2, #0 ;"
- "swi %2" : : "r" (start), "r" (end), "i" __ARM_NR_cacheflush
- : "r0", "r1", "r2", "r3");
-#endif
-}
-
-/* Those are here because system() occasionaly fails on Wiz
- * with errno 12 for some unknown reason */
-static int manual_insmod_26(const char *fname, const char *opts)
-{
- unsigned long len, read_len;
- int ret = -1;
- void *buff;
- FILE *f;
-
- f = fopen(fname, "rb");
- if (f == NULL)
- return -1;
-
- fseek(f, 0, SEEK_END);
- len = ftell(f);
- fseek(f, 0, SEEK_SET);
-
- buff = malloc(len);
- if (buff == NULL)
- goto fail0;
-
- read_len = fread(buff, 1, len, f);
- if (read_len != len) {
- fprintf(stderr, "failed to read module\n");
- goto fail1;
- }
-
- ret = init_module(buff, len, opts);
-
-fail1:
- free(buff);
-fail0:
- fclose(f);
- return ret;
-}
-
-static int manual_rmmod(const char *name)
-{
- return delete_module(name, O_NONBLOCK|O_EXCL);
-}
-
-int warm_init(void)
-{
- struct utsname unm;
- char buff1[32], buff2[128];
- int ret;
-
- memset(&unm, 0, sizeof(unm));
- uname(&unm);
-
- if (strlen(unm.release) < 3 || unm.release[1] != '.') {
- fprintf(stderr, "unexpected version string: %s\n", unm.release);
- goto fail;
- }
- kernel_version = ((unm.release[0] - '0') << 4) | (unm.release[2] - '0');
-
- warm_fd = open("/proc/warm", O_RDWR);
- if (warm_fd >= 0)
- return 0;
-
- snprintf(buff1, sizeof(buff1), "warm_%s.%s", unm.release, kernel_version >= 0x26 ? "ko" : "o");
- snprintf(buff2, sizeof(buff2), "/sbin/insmod %s verbose=1", buff1);
-
- /* try to insmod */
- ret = system(buff2);
- if (ret != 0) {
- fprintf(stderr, "system/insmod failed: %d %d\n", ret, errno);
- if (kernel_version >= 0x26) {
- ret = manual_insmod_26(buff1, "verbose=1");
- if (ret != 0)
- fprintf(stderr, "manual insmod also failed: %d\n", ret);
- }
- }
-
- warm_fd = open("/proc/warm", O_RDWR);
- if (warm_fd >= 0)
- return 0;
-
-fail:
- fprintf(stderr, "wARM: can't init, acting as sys_cacheflush wrapper\n");
- return -1;
-}
-
-void warm_finish(void)
-{
- char name[32], cmd[64];
- int ret;
-
- if (warm_fd < 0)
- return;
-
- close(warm_fd);
- warm_fd = -1;
-
- if (kernel_version < 0x26) {
- struct utsname unm;
- memset(&unm, 0, sizeof(unm));
- uname(&unm);
- snprintf(name, sizeof(name), "warm_%s", unm.release);
- }
- else
- strcpy(name, "warm");
-
- snprintf(cmd, sizeof(cmd), "/sbin/rmmod %s", name);
- ret = system(cmd);
- if (ret != 0) {
- fprintf(stderr, "system/rmmod failed: %d %d\n", ret, errno);
- manual_rmmod(name);
- }
-}
-
-int warm_cache_op_range(int op, void *addr, unsigned long size)
-{
- struct warm_cache_op wop;
- int ret;
-
- if (warm_fd < 0) {
- /* note that this won't work for warm_cache_op_all */
- sys_cacheflush(addr, (char *)addr + size);
- return -1;
- }
-
- wop.ops = op;
- wop.addr = (unsigned long)addr;
- wop.size = size;
-
- ret = ioctl(warm_fd, WARMC_CACHE_OP, &wop);
- if (ret != 0) {
- perror("WARMC_CACHE_OP failed");
- return -1;
- }
-
- return 0;
-}
-
-int warm_cache_op_all(int op)
-{
- return warm_cache_op_range(op, NULL, (unsigned long)-1);
-}
-
-int warm_change_cb_range(int cb, int is_set, void *addr, unsigned long size)
-{
- struct warm_change_cb ccb;
- int ret;
-
- if (warm_fd < 0)
- return -1;
-
- ccb.addr = (unsigned long)addr;
- ccb.size = size;
- ccb.cb = cb;
- ccb.is_set = is_set;
-
- ret = ioctl(warm_fd, WARMC_CHANGE_CB, &ccb);
- if (ret != 0) {
- perror("WARMC_CHANGE_CB failed");
- return -1;
- }
-
- return 0;
-}
-
-int warm_change_cb_upper(int cb, int is_set)
-{
- return warm_change_cb_range(cb, is_set, 0, 0);
-}
-
-unsigned long warm_virt2phys(const void *ptr)
-{
- unsigned long ptrio;
- int ret;
-
- ptrio = (unsigned long)ptr;
- ret = ioctl(warm_fd, WARMC_VIRT2PHYS, &ptrio);
- if (ret != 0) {
- perror("WARMC_VIRT2PHYS failed");
- return (unsigned long)-1;
- }
-
- return ptrio;
-}
-
+++ /dev/null
-/*
- * wARM - exporting ARM processor specific privileged services to userspace
- * library functions
- *
- * Copyright (c) Gražvydas "notaz" Ignotas, 2009
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the organization nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef __WARM_H__
-#define __WARM_H__ 1
-
-/* cache operations (warm_cache_op_*):
- * o clean - write dirty data to memory, but also leave in cache.
- * o invalidate - throw away everything in cache, losing dirty data.
- *
- * Write buffer is always drained, no ops will only drain WB
- */
-#define WOP_D_CLEAN (1 << 0)
-#define WOP_D_INVALIDATE (1 << 1)
-#define WOP_I_INVALIDATE (1 << 2)
-
-/* change C and B bits (warm_change_cb_*)
- * if is_set in not zero, bits are set, else cleared.
- * the address for range function is virtual address.
- */
-#define WCB_C_BIT (1 << 0)
-#define WCB_B_BIT (1 << 1)
-
-#ifndef __ASSEMBLER__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-int warm_init(void);
-
-int warm_cache_op_range(int ops, void *virt_addr, unsigned long size);
-int warm_cache_op_all(int ops);
-
-int warm_change_cb_upper(int cb, int is_set);
-int warm_change_cb_range(int cb, int is_set, void *virt_addr, unsigned long size);
-
-unsigned long warm_virt2phys(const void *ptr);
-
-void warm_finish(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-/* internal */
-#ifdef WARM_CODE
-
-#include <linux/ioctl.h>
-
-#define WARM_IOCTL_BASE 'A'
-
-struct warm_cache_op
-{
- unsigned long addr;
- unsigned long size;
- int ops;
-};
-
-struct warm_change_cb
-{
- unsigned long addr;
- unsigned long size;
- int cb;
- int is_set;
-};
-
-#define WARMC_CACHE_OP _IOW(WARM_IOCTL_BASE, 0, struct warm_cache_op)
-#define WARMC_CHANGE_CB _IOW(WARM_IOCTL_BASE, 1, struct warm_change_cb)
-#define WARMC_VIRT2PHYS _IOWR(WARM_IOCTL_BASE, 2, unsigned long)
-
-#endif /* WARM_CODE */
-#endif /* !__ASSEMBLER__ */
-#endif /* __WARM_H__ */
+++ /dev/null
-# settings
-#use_fbdev = 1
-#fake_in_gp2x = 1
-
-use_musashi = 1
-#use_fame = 1
-use_cz80 = 1
-use_sh2drc = 1
-#use_sh2mame = 1
-
-#drc_debug = 3
-#drc_debug_interp = 1
-#profile = 1
-
-all: mkdirs PicoDrive
-
--include Makefile.local
-
-ifndef ARCH
-ARCH = x86
-endif
-
-DEFINES = _UNZIP_SUPPORT IO_STATS IN_EVDEV
-CFLAGS += -ggdb -Wall -falign-functions=2
-CFLAGS += -I../.. -I.
-LDFLAGS += -lm -lpng
-ifeq "$(ARCH)" "arm"
-CFLAGS += -mcpu=arm920t
-DEFINES += ARM
-endif
-
-CC ?= $(CROSS)gcc
-
-# frontend
-OBJS += io.o emu.o blit.o in_evdev.o plat.o sndout_oss.o log_io.o
-
-# common
-OBJS += platform/common/main.o platform/common/emu.o platform/common/menu_pico.o \
- platform/common/config.o platform/common/fonts.o platform/common/readpng.o \
- platform/common/input.o
-
-ifeq "$(use_fbdev)" "1"
-DEFINES += FBDEV
-OBJS += fbdev.o
-else
-LDFLAGS += -lpthread
-LDFLAGS += -lX11
-endif
-
-ifeq "$(fake_in_gp2x)" "1"
-DEFINES += IN_GP2X FAKE_IN_GP2X
-OBJS += platform/gp2x/in_gp2x.o
-DIRS += platform/gp2x
-endif
-
-ifeq "$(ARCH)" "arm"
-OBJS += pico/carthw/svp/stub_arm.o
-endif
-OBJS += pico/sound/mix.o
-OBJS += pico/carthw/svp/compiler.o
-
-# zlib
-OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \
- zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o zlib/uncompr.o
-# unzip
-OBJS += unzip/unzip.o unzip/unzip_stream.o
-
-vpath %.c = ../..
-vpath %.s = ../..
-vpath %.S = ../..
-vpath %.asm = ../..
-
-DIRS += platform/linux zlib unzip
-
-include ../common/common.mak
-include ../common/revision.mak
-
-CFLAGS += $(addprefix -D,$(DEFINES))
-
-clean: tidy
- @$(RM) PicoDrive
-tidy:
- $(RM) $(OBJS)
- rm -rf $(DIRS)
- @make -C ../../cpu/mz80/ clean
-
-PicoDrive : $(OBJS)
- @echo ">>>" $@
- $(CC) $(CFLAGS) $^ $(LDFLAGS) -Wl,-Map=PicoDrive.map -o $@
-
-pprof: pprof.c
- $(CROSS)gcc -O2 -ggdb -DPPROF -DPPROF_TOOL -I../../ -I. $^ -o $@
-
-%.o : %.asm
- @echo ">>>" $<
- nasm -f elf $< -o $@
-
+++ /dev/null
-This port tries to emulate gp2x environment on a standard linux box for testing
-(i.e. to be able to use things like valgrind and efence, gcc runtime
-optimizations, etc.).
-
+++ /dev/null
-
-// Convert 0000bbb0 ggg0rrr0 0000bbb0 ggg0rrr0
-// to 00000000 rrr00000 ggg00000 bbb00000 ...
-// TODO: rm when gp2x/emu.c is no longer used
-
-void bgr444_to_rgb32(void *to, void *from)
-{
- unsigned short *ps = from;
- unsigned int *pd = to;
- int pixels;
-
- for (pixels = 0x40; pixels; pixels--, ps++, pd++)
- {
- *pd = ((*ps<<20)&0xe00000) | ((*ps<<8)&0xe000) | ((*ps>>4)&0xe0);
- *pd |= *pd >> 3;
- }
-}
-
-void bgr444_to_rgb32_sh(void *to, void *from)
-{
- unsigned short *ps = from;
- unsigned int *pd = to;
- int pixels;
-
- pd += 0x40;
- for (pixels = 0x40; pixels; pixels--, ps++, pd++)
- {
- *pd = ((*ps<<20)&0xe00000) | ((*ps<<8)&0xe000) | ((*ps>>4)&0xe0);
- *pd >>= 1;
- *pd |= *pd >> 3;
- pd[0x40*2] = *pd;
- }
-
- ps -= 0x40;
- for (pixels = 0x40; pixels; pixels--, ps++, pd++)
- {
- *pd = ((*ps<<20)&0xe00000) | ((*ps<<8)&0xe000) | ((*ps>>4)&0xe0);
- continue;
- *pd += 0x00404040;
- if (*pd & 0x01000000) *pd |= 0x00e00000;
- if (*pd & 0x00010000) *pd |= 0x0000e000;
- if (*pd & 0x00000100) *pd |= 0x000000e0;
- *pd &= 0x00e0e0e0;
- *pd |= *pd >> 3;
- }
-}
-
-void vidcpy_m2(void *dest, void *src, int m32col, int with_32c_border)
-{
- unsigned char *pd = dest, *ps = src;
- int i, u;
-
- if (m32col) {
- for (i = 0; i < 224; i++)
- {
- ps += 8;
- pd += 32;
- for (u = 0; u < 256; u++)
- *pd++ = *ps++;
- ps += 64;
- pd += 32;
- }
- } else {
- for (i = 0; i < 224; i++)
- {
- ps += 8;
- for (u = 0; u < 320; u++)
- *pd++ = *ps++;
- }
- }
-}
-
-void vidcpy_m2_rot(void *dest, void *src, int m32col, int with_32c_border)
-{
-}
-
-void rotated_blit8 (void *dst, void *linesx4, int y, int is_32col)
-{
-}
-
-void rotated_blit16(void *dst, void *linesx4, int y, int is_32col)
-{
-}
+++ /dev/null
-// (c) Copyright 2006-2009 notaz, All rights reserved.\r
-// Free for non-commercial use.\r
-\r
-// For commercial use, separate licencing terms must be obtained.\r
-\r
-#include <stdio.h>\r
-#include <unistd.h>\r
-\r
-#include "../common/emu.h"\r
-#include "../common/menu.h"\r
-#include "../common/plat.h"\r
-#include "../common/arm_utils.h"\r
-#include "../linux/sndout_oss.h"\r
-#include "version.h"\r
-\r
-#include <pico/pico_int.h>\r
-\r
-\r
-static short __attribute__((aligned(4))) sndBuffer[2*44100/50];\r
-const char *renderer_names[] = { "16bit accurate", " 8bit accurate", " 8bit fast", NULL };\r
-const char *renderer_names32x[] = { "accurate", "faster", "fastest", NULL };\r
-enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT };\r
-\r
-\r
-void pemu_prep_defconfig(void)\r
-{\r
-}\r
-\r
-void pemu_validate_config(void)\r
-{\r
- extern int PicoOpt;\r
-// PicoOpt &= ~POPT_EXT_FM;\r
- PicoOpt &= ~POPT_EN_SVP_DRC;\r
-}\r
-\r
-// FIXME: dupes from GP2X, need cleanup\r
-static void (*osd_text)(int x, int y, const char *text);\r
-\r
-/*\r
-static void osd_text8(int x, int y, const char *text)\r
-{\r
- int len = strlen(text)*8;\r
- int *p, i, h, offs;\r
-\r
- len = (len+3) >> 2;\r
- for (h = 0; h < 8; h++) {\r
- offs = (x + g_screen_width * (y+h)) & ~3;\r
- p = (int *) ((char *)g_screen_ptr + offs);\r
- for (i = len; i; i--, p++)\r
- *p = 0xe0e0e0e0;\r
- }\r
- emu_text_out8(x, y, text);\r
-}\r
-*/\r
-\r
-static void osd_text16(int x, int y, const char *text)\r
-{\r
- int len = strlen(text)*8;\r
- int *p, i, h, offs;\r
-\r
- len = (len+1) >> 1;\r
- for (h = 0; h < 8; h++) {\r
- offs = (x + g_screen_width * (y+h)) & ~1;\r
- p = (int *) ((short *)g_screen_ptr + offs);\r
- for (i = len; i; i--, p++)\r
- *p = (*p >> 2) & 0x39e7;\r
- }\r
- emu_text_out16(x, y, text);\r
-}\r
-\r
-static void draw_cd_leds(void)\r
-{\r
- int led_reg, pitch, scr_offs, led_offs;\r
- led_reg = Pico_mcd->s68k_regs[0];\r
-\r
- pitch = 320;\r
- led_offs = 4;\r
- scr_offs = pitch * 2 + 4;\r
-\r
- if (currentConfig.renderer != RT_16BIT) {\r
- #define p(x) px[(x) >> 2]\r
- // 8-bit modes\r
- unsigned int *px = (unsigned int *)((char *)g_screen_ptr + scr_offs);\r
- unsigned int col_g = (led_reg & 2) ? 0xc0c0c0c0 : 0xe0e0e0e0;\r
- unsigned int col_r = (led_reg & 1) ? 0xd0d0d0d0 : 0xe0e0e0e0;\r
- p(pitch*0) = p(pitch*1) = p(pitch*2) = col_g;\r
- p(pitch*0 + led_offs) = p(pitch*1 + led_offs) = p(pitch*2 + led_offs) = col_r;\r
- #undef p\r
- } else {\r
- #define p(x) px[(x)*2 >> 2] = px[((x)*2 >> 2) + 1]\r
- // 16-bit modes\r
- unsigned int *px = (unsigned int *)((short *)g_screen_ptr + scr_offs);\r
- unsigned int col_g = (led_reg & 2) ? 0x06000600 : 0;\r
- unsigned int col_r = (led_reg & 1) ? 0xc000c000 : 0;\r
- p(pitch*0) = p(pitch*1) = p(pitch*2) = col_g;\r
- p(pitch*0 + led_offs) = p(pitch*1 + led_offs) = p(pitch*2 + led_offs) = col_r;\r
- #undef p\r
- }\r
-}\r
-\r
-void pemu_finalize_frame(const char *fps, const char *notice)\r
-{\r
- if (currentConfig.renderer != RT_16BIT && !(PicoAHW & PAHW_32X)) {\r
- unsigned short *pd = (unsigned short *)g_screen_ptr + 8 * g_screen_width;\r
- unsigned char *ps = PicoDraw2FB + 328*8 + 8;\r
- unsigned short *pal = HighPal;\r
- int i, x;\r
- if (Pico.m.dirtyPal)\r
- PicoDrawUpdateHighPal();\r
- for (i = 0; i < 224; i++, ps += 8)\r
- for (x = 0; x < 320; x++)\r
- *pd++ = pal[*ps++];\r
- }\r
-\r
- if (notice || (currentConfig.EmuOpt & EOPT_SHOW_FPS)) {\r
- if (notice)\r
- osd_text(4, g_screen_height - 8, notice);\r
- if (currentConfig.EmuOpt & EOPT_SHOW_FPS)\r
- osd_text(g_screen_width - 60, g_screen_height - 8, fps);\r
- }\r
- if ((PicoAHW & PAHW_MCD) && (currentConfig.EmuOpt & EOPT_EN_CD_LEDS))\r
- draw_cd_leds();\r
-}\r
-\r
-static void apply_renderer(void)\r
-{\r
- switch (currentConfig.renderer) {\r
- case RT_16BIT:\r
- PicoOpt &= ~POPT_ALT_RENDERER;\r
- PicoDrawSetOutFormat(PDF_RGB555, 0);\r
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- break;\r
- case RT_8BIT_ACC:\r
- PicoOpt &= ~POPT_ALT_RENDERER;\r
- PicoDrawSetOutFormat(PDF_8BIT, 0);\r
- PicoDrawSetOutBuf(PicoDraw2FB + 8, 328);\r
- break;\r
- case RT_8BIT_FAST:\r
- PicoOpt |= POPT_ALT_RENDERER;\r
- PicoDrawSetOutFormat(PDF_NONE, 0);\r
- break;\r
- }\r
-\r
- if (PicoAHW & PAHW_32X) {\r
- int only_32x = 0;\r
- if (currentConfig.renderer == RT_16BIT)\r
- only_32x = 1;\r
- else\r
- PicoDrawSetOutFormat(PDF_NONE, 0);\r
- PicoDraw32xSetFrameMode(1, only_32x);\r
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- }\r
- //PicoDraw32xSetFrameMode(0, 0);\r
- //PicoDrawSetOutFormat(PDF_RGB555, 1);\r
-}\r
-\r
-void plat_video_toggle_renderer(int change, int is_menu)\r
-{\r
- currentConfig.renderer += change;\r
- if (currentConfig.renderer >= RT_COUNT)\r
- currentConfig.renderer = 0;\r
- else if (currentConfig.renderer < 0)\r
- currentConfig.renderer = RT_COUNT - 1;\r
-\r
- if (!is_menu)\r
- apply_renderer();\r
-\r
- emu_status_msg(renderer_names[currentConfig.renderer]);\r
-}\r
-\r
-void plat_video_menu_enter(int is_rom_loaded)\r
-{\r
-}\r
-\r
-void plat_video_menu_begin(void)\r
-{\r
- g_menuscreen_ptr = g_screen_ptr;\r
-}\r
-\r
-void plat_video_menu_end(void)\r
-{\r
- plat_video_flip();\r
-}\r
-\r
-void plat_status_msg_clear(void)\r
-{\r
- unsigned short *d = (unsigned short *)g_screen_ptr + g_screen_width * g_screen_height;\r
- int l = g_screen_width * 8;\r
- memset32((int *)(d - l), 0, l * 2 / 4);\r
-}\r
-\r
-void plat_status_msg_busy_next(const char *msg)\r
-{\r
- plat_status_msg_clear();\r
- pemu_finalize_frame("", msg);\r
- plat_video_flip();\r
- emu_status_msg("");\r
- reset_timing = 1;\r
-}\r
-\r
-void plat_status_msg_busy_first(const char *msg)\r
-{\r
-// memset32(g_screen_ptr, 0, g_screen_width * g_screen_height * 2 / 4);\r
- plat_status_msg_busy_next(msg);\r
-}\r
-\r
-void plat_update_volume(int has_changed, int is_up)\r
-{\r
-}\r
-\r
-void pemu_forced_frame(int no_scale, int do_emu)\r
-{\r
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
- PicoDraw32xSetFrameMode(0, 0);\r
- PicoDrawSetCallbacks(NULL, NULL);\r
- Pico.m.dirtyPal = 1;\r
-\r
- emu_cmn_forced_frame(no_scale, do_emu);\r
-\r
- g_menubg_src_ptr = g_screen_ptr;\r
-}\r
-\r
-static void oss_write_nonblocking(int len)\r
-{\r
- // sndout_oss_can_write() is not reliable, only use with no_frmlimit\r
- if ((currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) && !sndout_oss_can_write(len))\r
- return;\r
-\r
- sndout_oss_write_nb(PsndOut, len);\r
-}\r
-\r
-void pemu_sound_start(void)\r
-{\r
- PsndOut = NULL;\r
-\r
- if (currentConfig.EmuOpt & EOPT_EN_SOUND)\r
- {\r
- int is_stereo = (PicoOpt & POPT_EN_STEREO) ? 1 : 0;\r
-\r
- PsndRerate(Pico.m.frame_count ? 1 : 0);\r
-\r
- printf("starting audio: %i len: %i stereo: %i, pal: %i\n",\r
- PsndRate, PsndLen, is_stereo, Pico.m.pal);\r
- sndout_oss_start(PsndRate, is_stereo, 1);\r
- sndout_oss_setvol(currentConfig.volume, currentConfig.volume);\r
- PicoWriteSound = oss_write_nonblocking;\r
- plat_update_volume(0, 0);\r
- memset(sndBuffer, 0, sizeof(sndBuffer));\r
- PsndOut = sndBuffer;\r
- }\r
-}\r
-\r
-void pemu_sound_stop(void)\r
-{\r
-}\r
-\r
-void pemu_sound_wait(void)\r
-{\r
- // don't need to do anything, writes will block by themselves\r
-}\r
-\r
-void plat_debug_cat(char *str)\r
-{\r
-}\r
-\r
-void emu_video_mode_change(int start_line, int line_count, int is_32cols)\r
-{\r
- // clear whole screen in all buffers\r
- memset32(g_screen_ptr, 0, g_screen_width * g_screen_height * 2 / 4);\r
-}\r
-\r
-void pemu_loop_prep(void)\r
-{\r
- apply_renderer();\r
- osd_text = osd_text16;\r
-\r
- pemu_sound_start();\r
-}\r
-\r
-void pemu_loop_end(void)\r
-{\r
- pemu_sound_stop();\r
-\r
- /* do one more frame for menu bg */\r
- pemu_forced_frame(0, 1);\r
-}\r
-\r
-void plat_wait_till_us(unsigned int us_to)\r
-{\r
- unsigned int now;\r
-\r
- now = plat_get_ticks_us();\r
-\r
- while ((signed int)(us_to - now) > 512)\r
- {\r
- usleep(1024);\r
- now = plat_get_ticks_us();\r
- }\r
-}\r
-\r
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../common/emu.h"
-#include "../common/menu.h"
-#include "../common/plat.h"
-#include "../common/input.h"
-#include "sndout_oss.h"
-#include "version.h"
-
-#include "log_io.h"
-
-int current_keys;
-unsigned char *PicoDraw2FB;
-
-#ifdef FBDEV
-
-#include "fbdev.h"
-
-#else
-
-#include <pthread.h>
-#include <semaphore.h>
-
-static int current_bpp = 16;
-static int current_pal[256];
-static const char *verstring = "PicoDrive " VERSION;
-static int scr_changed = 0, scr_w = SCREEN_WIDTH, scr_h = SCREEN_HEIGHT;
-
-/* faking GP2X pad */
-enum { GP2X_UP=0x1, GP2X_LEFT=0x4, GP2X_DOWN=0x10, GP2X_RIGHT=0x40,
- GP2X_START=1<<8, GP2X_SELECT=1<<9, GP2X_L=1<<10, GP2X_R=1<<11,
- GP2X_A=1<<12, GP2X_B=1<<13, GP2X_X=1<<14, GP2X_Y=1<<15,
- GP2X_VOL_UP=1<<23, GP2X_VOL_DOWN=1<<22, GP2X_PUSH=1<<27 };
-
-static void key_press_event(int keycode)
-{
- switch (keycode)
- {
- case 111:
- case 0x62: current_keys |= GP2X_UP; break;
- case 116:
- case 0x68: current_keys |= GP2X_DOWN; break;
- case 113:
- case 0x64: current_keys |= GP2X_LEFT; break;
- case 114:
- case 0x66: current_keys |= GP2X_RIGHT; break;
- case 0x24: current_keys |= GP2X_START; break; // enter
- case 0x23: current_keys |= GP2X_SELECT;break; // ]
- case 0x34: current_keys |= GP2X_A; break; // z
- case 0x35: current_keys |= GP2X_X; break; // x
- case 0x36: current_keys |= GP2X_B; break; // c
- case 0x37: current_keys |= GP2X_Y; break; // v
- case 0x27: current_keys |= GP2X_L; break; // s
- case 0x28: current_keys |= GP2X_R; break; // d
- case 0x29: current_keys |= GP2X_PUSH; break; // f
- case 0x18: current_keys |= GP2X_VOL_DOWN;break; // q
- case 0x19: current_keys |= GP2X_VOL_UP;break; // w
- case 0x2d: log_io_clear(); break; // k
- case 0x2e: log_io_dump(); break; // l
- case 0x17: { // tab
- extern int PicoReset(void);
- PicoReset();
- break;
- }
- }
-}
-
-static void key_release_event(int keycode)
-{
- switch (keycode)
- {
- case 111:
- case 0x62: current_keys &= ~GP2X_UP; break;
- case 116:
- case 0x68: current_keys &= ~GP2X_DOWN; break;
- case 113:
- case 0x64: current_keys &= ~GP2X_LEFT; break;
- case 114:
- case 0x66: current_keys &= ~GP2X_RIGHT; break;
- case 0x24: current_keys &= ~GP2X_START; break; // enter
- case 0x23: current_keys &= ~GP2X_SELECT;break; // ]
- case 0x34: current_keys &= ~GP2X_A; break; // z
- case 0x35: current_keys &= ~GP2X_X; break; // x
- case 0x36: current_keys &= ~GP2X_B; break; // c
- case 0x37: current_keys &= ~GP2X_Y; break; // v
- case 0x27: current_keys &= ~GP2X_L; break; // s
- case 0x28: current_keys &= ~GP2X_R; break; // d
- case 0x29: current_keys &= ~GP2X_PUSH; break; // f
- case 0x18: current_keys &= ~GP2X_VOL_DOWN;break; // q
- case 0x19: current_keys &= ~GP2X_VOL_UP;break; // w
- }
-}
-
-/* --- */
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-static Display *xlib_display;
-static Window xlib_window;
-static XImage *ximage;
-
-static void ximage_realloc(Display *display, Visual *visual)
-{
- void *xlib_screen;
-
- XLockDisplay(xlib_display);
-
- if (ximage != NULL)
- XDestroyImage(ximage);
- ximage = NULL;
-
- xlib_screen = calloc(scr_w * scr_h, 4);
- if (xlib_screen != NULL)
- ximage = XCreateImage(display, visual, 24, ZPixmap, 0,
- xlib_screen, scr_w, scr_h, 32, 0);
- if (ximage == NULL)
- fprintf(stderr, "failed to alloc ximage\n");
-
- XUnlockDisplay(xlib_display);
-}
-
-static void xlib_update(void)
-{
- Status xstatus;
-
- XLockDisplay(xlib_display);
-
- xstatus = XPutImage(xlib_display, xlib_window, DefaultGC(xlib_display, 0), ximage,
- 0, 0, 0, 0, g_screen_width, g_screen_height);
- if (xstatus != 0)
- fprintf(stderr, "XPutImage %d\n", xstatus);
-
- XUnlockDisplay(xlib_display);
-}
-
-static void *xlib_threadf(void *targ)
-{
- unsigned int width, height, display_width, display_height;
- sem_t *sem = targ;
- XTextProperty windowName;
- Window win;
- XEvent report;
- Display *display;
- Visual *visual;
- int screen;
-
- XInitThreads();
-
- xlib_display = display = XOpenDisplay(NULL);
- if (display == NULL)
- {
- fprintf(stderr, "cannot connect to X server %s\n",
- XDisplayName(NULL));
- sem_post(sem);
- return NULL;
- }
-
- visual = DefaultVisual(display, 0);
- if (visual->class != TrueColor)
- {
- fprintf(stderr, "cannot handle non true color visual\n");
- XCloseDisplay(display);
- sem_post(sem);
- return NULL;
- }
-
- printf("X vendor: %s, rel: %d, display: %s, protocol ver: %d.%d\n", ServerVendor(display),
- VendorRelease(display), DisplayString(display), ProtocolVersion(display),
- ProtocolRevision(display));
-
- screen = DefaultScreen(display);
-
- ximage_realloc(display, visual);
- sem_post(sem);
-
- display_width = DisplayWidth(display, screen);
- display_height = DisplayHeight(display, screen);
-
- xlib_window = win = XCreateSimpleWindow(display,
- RootWindow(display, screen),
- display_width / 2 - scr_w / 2,
- display_height / 2 - scr_h / 2,
- scr_w + 2, scr_h + 2, 1,
- BlackPixel(display, screen),
- BlackPixel(display, screen));
-
- XStringListToTextProperty((char **)&verstring, 1, &windowName);
- XSetWMName(display, win, &windowName);
-
- XSelectInput(display, win, ExposureMask |
- KeyPressMask | KeyReleaseMask |
- StructureNotifyMask);
-
- XMapWindow(display, win);
-
- while (1)
- {
- XNextEvent(display, &report);
- switch (report.type)
- {
- case Expose:
- while (XCheckTypedEvent(display, Expose, &report))
- ;
- xlib_update();
- break;
-
- case ConfigureNotify:
- width = report.xconfigure.width;
- height = report.xconfigure.height;
- if (scr_w != width - 2 || scr_h != height - 2) {
- scr_w = width - 2;
- scr_h = height - 2;
- scr_changed = 1;
- }
- break;
-
- case ButtonPress:
- break;
-
- case KeyPress:
- key_press_event(report.xkey.keycode);
- break;
-
- case KeyRelease:
- key_release_event(report.xkey.keycode);
- break;
-
- default:
- break;
- }
- }
-}
-
-static void xlib_init(void)
-{
- pthread_t x_thread;
- sem_t xlib_sem;
-
- sem_init(&xlib_sem, 0, 0);
-
- pthread_create(&x_thread, NULL, xlib_threadf, &xlib_sem);
- pthread_detach(x_thread);
-
- sem_wait(&xlib_sem);
- sem_destroy(&xlib_sem);
-}
-
-/* --- */
-
-static void realloc_screen(void)
-{
- int size = scr_w * scr_h * 2;
- g_screen_width = g_menuscreen_w = scr_w;
- g_screen_height = g_menuscreen_h = scr_h;
- g_screen_ptr = realloc(g_screen_ptr, size);
- g_menubg_ptr = realloc(g_menubg_ptr, size);
- memset(g_screen_ptr, 0, size);
- memset(g_menubg_ptr, 0, size);
- PicoDraw2FB = g_menubg_ptr;
- scr_changed = 0;
-}
-
-void plat_video_flip(void)
-{
- unsigned int *image;
- int pixel_count, i;
-
- if (ximage == NULL)
- return;
-
- pixel_count = g_screen_width * g_screen_height;
- image = (void *)ximage->data;
-
- if (current_bpp == 8)
- {
- unsigned char *pixels = g_screen_ptr;
- int pix;
-
- for (i = 0; i < pixel_count; i++)
- {
- pix = current_pal[pixels[i]];
- image[i] = pix;
- }
- }
- else
- {
- unsigned short *pixels = g_screen_ptr;
-
- for (i = 0; i < pixel_count; i++)
- {
- /* in: rrrr rggg gggb bbbb */
- /* out: rrrr r000 gggg gg00 bbbb b000 */
- image[i] = (pixels[i] << 8) & 0xf80000;
- image[i] |= (pixels[i] << 5) & 0x00fc00;
- image[i] |= (pixels[i] << 3) & 0x0000f8;
- }
- }
- xlib_update();
-
- if (scr_changed) {
- realloc_screen();
- ximage_realloc(xlib_display, DefaultVisual(xlib_display, 0));
-
- // propagate new ponters to renderers
- plat_video_toggle_renderer(0, 0);
- }
-}
-
-void plat_video_wait_vsync(void)
-{
-}
-
-#endif // !FBDEV
-
-void plat_early_init(void)
-{
-}
-
-void plat_init(void)
-{
-#ifdef FBDEV
- int ret, w, h;
- ret = vout_fbdev_init(&w, &h);
- if (ret != 0)
- exit(1);
- g_screen_width = g_menuscreen_w = w;
- g_screen_height = g_menuscreen_h = h;
- g_menubg_ptr = realloc(g_menubg_ptr, w * g_screen_height * 2);
- PicoDraw2FB = g_menubg_ptr;
-#else
- realloc_screen();
- memset(g_screen_ptr, 0, g_screen_width * g_screen_height * 2);
- xlib_init();
-#endif
-
- // snd
- sndout_oss_init();
-}
-
-void plat_finish(void)
-{
-#ifdef FBDEV
- vout_fbdev_finish();
-#else
- free(g_screen_ptr);
-#endif
- sndout_oss_exit();
-}
-
-/* misc */
-int mp3_get_bitrate(void *f, int size)
-{
- return 128;
-}
-
-void mp3_start_play(void *f, int pos)
-{
-}
-
-void mp3_update(int *buffer, int length, int stereo)
-{
-}
-
-#include <linux/input.h>
-
-struct in_default_bind in_evdev_defbinds[] =
-{
- /* MXYZ SACB RLDU */
- { KEY_UP, IN_BINDTYPE_PLAYER12, 0 },
- { KEY_DOWN, IN_BINDTYPE_PLAYER12, 1 },
- { KEY_LEFT, IN_BINDTYPE_PLAYER12, 2 },
- { KEY_RIGHT, IN_BINDTYPE_PLAYER12, 3 },
- { KEY_S, IN_BINDTYPE_PLAYER12, 4 }, /* B */
- { KEY_D, IN_BINDTYPE_PLAYER12, 5 }, /* C */
- { KEY_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */
- { KEY_ENTER, IN_BINDTYPE_PLAYER12, 7 },
- { KEY_BACKSLASH, IN_BINDTYPE_EMU, PEVB_MENU },
- { 0, 0, 0 }
-};
-
+++ /dev/null
-#include <stdio.h>
-
-typedef struct
-{
- unsigned int addr_min, addr_max;
- int r8, r16, r32, w8, w16, w32;
-} io_log_location;
-
-static io_log_location io_locations[] =
-{
- { 0x400000, 0x9FFFFF, 0, }, // unused
- { 0xa00000, 0xa03fff, 0, }, // z80 RAM
- { 0xa04000, 0xa05fff, 0, }, // ym2612
- { 0xa06000, 0xa060ff, 0, }, // bank reg
- { 0xa06100, 0xa07eff, 0, }, // unused
- { 0xa07f00, 0xa07fff, 0, }, // vdp
- { 0xa08000, 0xa0ffff, 0, }, // 0xa00000-0xa07fff mirror
- { 0xa10000, 0xa1001f, 0, }, // i/o
- { 0xa10020, 0xa10fff, 0, }, // expansion
- { 0xa11000, 0xa110ff, 0, }, // expansion
- { 0xa11100, 0xa11101, 0, }, // z80 busreq
- { 0xa11102, 0xa111ff, 0, }, // expansion
- { 0xa11200, 0xa11201, 0, }, // z80 reset
- { 0xa11202, 0xbfffff, 0, }, // expansion
- { 0xc00000, 0xc00003, 0, }, // vdp data port
- { 0xc00004, 0xc00007, 0, }, // vdp control
- { 0xc00009, 0xc0000f, 0, }, // hv counter
- { 0xc00010, 0xc00017, 0, }, // PSG
- { 0xc00018, 0xc0001f, 0, }, // unused
- { 0xc00020, 0xdfffff, 0, } // vdp mirrors
-};
-
-
-void log_io(unsigned int a, int bits, int is_write)
-{
- int i;
- a &= 0x00ffffff;
- if (bits > 8) a&=~1;
-
- for (i = 0; i < sizeof(io_locations)/sizeof(io_locations[0]); i++)
- {
- if (a >= io_locations[i].addr_min && a <= io_locations[i].addr_max)
- {
- switch (bits|(is_write<<8)) {
- case 0x008: io_locations[i].r8 ++; break;
- case 0x010: io_locations[i].r16++; break;
- case 0x020: io_locations[i].r32++; break;
- case 0x108: io_locations[i].w8 ++; break;
- case 0x110: io_locations[i].w16++; break;
- case 0x120: io_locations[i].w32++; break;
- default: printf("%06x %i %i\n", a, bits, is_write); break;
- }
- }
- }
-}
-
-void log_io_clear(void)
-{
- int i;
- for (i = 0; i < sizeof(io_locations)/sizeof(io_locations[0]); i++)
- {
- io_log_location *iol = &io_locations[i];
- iol->r8 = iol->r16 = iol->r32 = iol->w8 = iol->w16 = iol->w32 = 0;
- }
-}
-
-void log_io_dump(void)
-{
- int i;
- printf(" range : r8 r16 r32 w8 w16 w32\n");
- for (i = 0; i < sizeof(io_locations)/sizeof(io_locations[0]); i++)
- {
- io_log_location *iol = &io_locations[i];
- if (iol->r8 == 0 && iol->r16 == 0 && iol->r32 == 0 && iol->w8 == 0 && iol->w16 == 0 && iol->w32 == 0)
- continue;
- printf("%06x - %06x : %8i %8i %8i %8i %8i %8i\n", iol->addr_min, iol->addr_max,
- iol->r8, iol->r16, iol->r32, iol->w8, iol->w16, iol->w32);
- }
- printf("\n");
-}
-
+++ /dev/null
-void log_io_clear(void);
-void log_io_dump(void);
-
+++ /dev/null
-// port specific settings
-
-#ifndef PORT_CONFIG_H
-#define PORT_CONFIG_H
-
-#define NO_SYNC
-
-#define CASE_SENSITIVE_FS 1 // CS filesystem
-#define DONT_OPEN_MANY_FILES 0
-#define REDUCE_IO_CALLS 0
-
-#define SCREEN_SIZE_FIXED 0
-#define SCREEN_WIDTH 320
-#define SCREEN_HEIGHT 240
-#define MSCREEN_SIZE_FIXED 0
-#define MSCREEN_WIDTH SCREEN_WIDTH
-#define MSCREEN_HEIGHT SCREEN_HEIGHT
-
-// draw2.c
-#define START_ROW 0 // which row of tiles to start rendering at?
-#define END_ROW 28 // ..end
-
-// pico.c
-#define CAN_HANDLE_240_LINES 1
-
-#define SIMPLE_WRITE_SOUND 0
-#define mix_32_to_16l_stereo_lvl mix_32_to_16l_stereo
-
-#define EL_LOGMASK (EL_STATUS|EL_ANOMALY|EL_UIO)
-// EL_VDPDMA|EL_ASVDP|EL_SR | EL_IDLE | EL_BUSREQ|EL_Z80BNK | EL_32X)
-
-//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
-#define dprintf(x...)
-
-// platform
-#define PATH_SEP "/"
-#define PATH_SEP_C '/'
-#define MENU_X2 0
-
-#endif //PORT_CONFIG_H
-
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-#include <pico/pico_int.h>
-
-struct pp_counters *pp_counters;
-static int shmemid;
-
-void pprof_init(void)
-{
- int this_is_new_shmem = 1;
- key_t shmemkey;
- void *shmem;
-
-#ifndef PPROF_TOOL
- unsigned int tmp = pprof_get_one();
- printf("pprof: measured diff is %u\n", pprof_get_one() - tmp);
-#endif
-
- shmemkey = ftok(".", 0x02ABC32E);
- if (shmemkey == -1)
- {
- perror("pprof: ftok failed");
- return;
- }
-
-#ifndef PPROF_TOOL
- shmemid = shmget(shmemkey, sizeof(*pp_counters),
- IPC_CREAT | IPC_EXCL | 0644);
- if (shmemid == -1)
-#endif
- {
- shmemid = shmget(shmemkey, sizeof(*pp_counters),
- 0644);
- if (shmemid == -1)
- {
- perror("pprof: shmget failed");
- return;
- }
- this_is_new_shmem = 0;
- }
-
- shmem = shmat(shmemid, NULL, 0);
- if (shmem == (void *)-1)
- {
- perror("pprof: shmat failed");
- return;
- }
-
- pp_counters = shmem;
- if (this_is_new_shmem) {
- memset(pp_counters, 0, sizeof(*pp_counters));
- printf("pprof: pp_counters cleared.\n");
- }
-}
-
-void pprof_finish(void)
-{
- shmdt(pp_counters);
- shmctl(shmemid, IPC_RMID, NULL);
-}
-
-#ifdef PPROF_TOOL
-
-#define IT(n) { pp_##n, #n }
-static const struct {
- enum pprof_points pp;
- const char *name;
-} pp_tab[] = {
- IT(main),
- IT(frame),
- IT(draw),
- IT(sound),
- IT(m68k),
- IT(z80),
- IT(msh2),
- IT(ssh2),
- IT(dummy),
-};
-
-int main(int argc, char *argv[])
-{
- unsigned long long old[pp_total_points], new[pp_total_points];
- int base = 0;
- int l, i;
-
- pprof_init();
- if (pp_counters == NULL)
- return 1;
-
- if (argc >= 2)
- base = atoi(argv[1]);
-
- memset(old, 0, sizeof(old));
- for (l = 0; ; l++)
- {
- if ((l & 0x1f) == 0) {
- for (i = 0; i < ARRAY_SIZE(pp_tab); i++)
- printf("%6s ", pp_tab[i].name);
- printf("\n");
- }
-
- memcpy(new, pp_counters->counter, sizeof(new));
- for (i = 0; i < ARRAY_SIZE(pp_tab); i++)
- {
- unsigned long long idiff = new[i] - old[i];
- unsigned long long bdiff = (new[base] - old[base]) | 1;
- printf("%6.2f ", (double)idiff * 100.0 / bdiff);
- }
- printf("\n");
- memcpy(old, new, sizeof(old));
-
- if (argc < 3)
- break;
- usleep(atoi(argv[2]));
- }
-
- return 0;
-}
-
-#endif // PPROF_TOOL
-
+++ /dev/null
-#ifndef __PPROF_H__
-#define __PPROF_H__
-
-enum pprof_points {
- pp_main,
- pp_frame,
- pp_draw,
- pp_sound,
- pp_m68k,
- pp_z80,
- pp_msh2,
- pp_ssh2,
- pp_dummy,
- pp_total_points
-};
-
-struct pp_counters
-{
- unsigned long long counter[pp_total_points];
-};
-
-extern struct pp_counters *pp_counters;
-
-#ifdef __i386__
-static __attribute__((always_inline)) inline unsigned int pprof_get_one(void)
-{
- unsigned long long ret;
- __asm__ __volatile__ ("rdtsc" : "=A" (ret));
- return (unsigned int)ret;
-}
-#define unglitch_timer(x)
-
-#elif defined(__GP2X__)
-// XXX: MMSP2 only, timer sometimes seems to return lower vals?
-extern volatile unsigned long *gp2x_memregl;
-#define pprof_get_one() (unsigned int)gp2x_memregl[0x0a00 >> 2]
-#define unglitch_timer(di) \
- if ((signed int)(di) < 0) di = 0
-
-#else
-#error no timer
-#endif
-
-#define pprof_start(point) { \
- unsigned int pp_start_##point = pprof_get_one()
-
-#define pprof_end(point) \
- { \
- unsigned int di = pprof_get_one() - pp_start_##point; \
- unglitch_timer(di); \
- pp_counters->counter[pp_##point] += di; \
- } \
- }
-
-// subtract for recursive stuff
-#define pprof_end_sub(point) \
- { \
- unsigned int di = pprof_get_one() - pp_start_##point; \
- unglitch_timer(di); \
- pp_counters->counter[pp_##point] -= di; \
- } \
- }
-
-extern void pprof_init(void);
-extern void pprof_finish(void);
-
-#endif // __PPROF_H__
+++ /dev/null
-#include "../gp2x/version.h"
-
+++ /dev/null
-#export CROSS = arm-none-linux-gnueabi-\r
-CROSS ?= $(CROSS_COMPILE)\r
-LIBROOT = /home/notaz/dev/pnd/libroot\r
-PND_MAKE ?= $(HOME)/dev/pnd/src/pandora-libraries/testdata/scripts/pnd_make.sh\r
-\r
-# settings\r
-use_cyclone = 1\r
-#use_musashi = 1\r
-use_drz80 = 1\r
-use_sh2drc = 1\r
-#use_sh2mame = 1\r
-\r
-asm_memory = 1\r
-asm_render = 1\r
-asm_ym2612 = 1\r
-asm_misc = 1\r
-asm_cdpico = 1\r
-asm_cdmemory = 1\r
-#profile = 1\r
-#drc_debug = 3\r
-\r
--include Makefile.local\r
-\r
-ifeq "$(use_musashi)" "1"\r
-# due to CPU stop flag acces\r
-asm_cdpico = 0\r
-asm_cdmemory = 0\r
-endif\r
-\r
-ARCH = arm\r
-DEFINES += ARM PANDORA IN_EVDEV\r
-CFLAGS += -I../.. -I. -I$(LIBROOT)/include\r
-CFLAGS += -Wall -Winline -mcpu=cortex-a8 -mtune=cortex-a8 -march=armv7-a\r
-ifeq ($(DEBUG),)\r
-CFLAGS += -O2 -fomit-frame-pointer -fstrict-aliasing -ffast-math\r
-endif\r
-LDFLAGS += -L$(LIBROOT)/lib -Wl,-Bstatic -lpng -Wl,-Bdynamic -lm -lpthread -ldl\r
-ASFLAGS = -mcpu=cortex-a8\r
-CC = $(CROSS)gcc\r
-STRIP = $(CROSS)strip\r
-AS = $(CROSS)as\r
-LD = $(CROSS)ld\r
-OBJCOPY = $(CROSS)objcopy\r
-\r
-# frontend\r
-OBJS += plat.o asm_utils.o\r
-\r
-# common\r
-OBJS += platform/common/emu.o platform/common/menu_pico.o platform/common/fonts.o platform/common/config.o \\r
- platform/common/arm_utils.o platform/common/mp3_helix.o platform/common/arm_linux.o \\r
- platform/common/readpng.o platform/common/input.o platform/common/main.o platform/common/mp3.o \\r
- platform/linux/fbdev.o platform/linux/in_evdev.o platform/linux/sndout_oss.o \\r
- platform/linux/plat.o platform/linux/xenv.o\r
-\r
-# ARM stuff\r
-OBJS += pico/carthw/svp/compiler.o pico/carthw/svp/stub_arm.o\r
-OBJS += pico/sound/mix_arm.o\r
-\r
-# zlib\r
-OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \\r
- zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o\r
-# unzip\r
-OBJS += unzip/unzip.o unzip/unzip_stream.o\r
-\r
-vpath %.c = ../..\r
-vpath %.s = ../..\r
-vpath %.S = ../..\r
-DIRS += platform/linux zlib unzip\r
-\r
-all: mkdirs PicoDrive picorestore\r
-\r
-include ../common/common.mak\r
-include ../common/common_arm.mak\r
-include ../common/revision.mak\r
-\r
-CFLAGS += $(addprefix -D,$(DEFINES))\r
-\r
-PicoDrive : $(OBJS) ../common/helix/$(CROSS)helix-mp3.a\r
- @echo ">>>" $@\r
- $(CC) -o $@ $(CFLAGS) $^ $(LDFLAGS) -Wl,-Map=PicoDrive.map\r
-ifeq ($(DEBUG),)\r
- $(STRIP) $@\r
-endif\r
-\r
-clean: tidy\r
- $(RM) PicoDrive\r
-tidy:\r
- $(RM) $(OBJS)\r
-\r
-readme.txt: ../../tools/textfilter ../base_readme.txt\r
- ../../tools/textfilter ../base_readme.txt $@ PANDORA\r
-\r
-PicoDrive.pxml: PicoDrive.pxml.template\r
- ./make_pxml.sh PicoDrive.pxml.template PicoDrive.pxml\r
-\r
-platform/common/menu_pico.o: platform/common/menu.c menu.c\r
-\r
-# ----------- release -----------\r
-\r
-VER ?= $(shell head -n 1 version.h | sed 's/.*"\(.*\)\.\(.*\)".*/\1\2/g')\r
-\r
-rel: PicoDrive PicoDrive.run picorestore ../../pico/carthw.cfg readme.txt \\r
- skin PicoDrive.png PicoDrive_p.png PicoDrive.pxml\r
- rm -rf out\r
- mkdir out\r
- cp -r $^ out/\r
- $(PND_MAKE) -p PicoDrive_$(VER).pnd -d out -x PicoDrive.pxml -i PicoDrive.png -c\r
+++ /dev/null
-
-void clut_line2x2(void *dest, const void *src, const unsigned short *pal, int pixels_mask);
-void clut_line3x2(void *dest, const void *src, const unsigned short *pal, int pixels_mask);
+++ /dev/null
-@ vim:filetype=armasm
-
-
-@ FIXME: handle dual issue
-.global clut_line2x2 @ void *dest, void *src, unsigned short *pal, int pixels_mask
-
-clut_line2x2:
- stmfd sp!, {r4-r11,lr}
-
- and lr, r3, #0xff0000
- mov lr, lr, lsr #15 @ mask
- mov r3, r3, lsr #3
- and r3, r3, #0xff @ counter
- add r11,r0, #800*2
-
-clut_line_2x2_loop:
- ldmia r1!, {r10,r12}
-
- and r4, lr, r10, lsl #1
- ldrh r4, [r2, r4]
- and r5, lr, r10, lsr #7
- ldrh r5, [r2, r5]
- orr r4, r4, r4, lsl #16
-
- and r6, lr, r10, lsr #15
- ldrh r6, [r2, r6]
- orr r5, r5, r5, lsl #16
-
- and r7, lr, r10, lsr #23
- ldrh r7, [r2, r7]
- orr r6, r6, r6, lsl #16
-
- and r8, lr, r12, lsl #1
- ldrh r8, [r2, r8]
- orr r7, r7, r7, lsl #16
-
- and r9, lr, r12, lsr #7
- ldrh r9, [r2, r9]
- orr r8, r8, r8, lsl #16
-
- and r10,lr, r12, lsr #15
- ldrh r10,[r2, r10]
- orr r9, r9, r9, lsl #16
-
- and r12,lr, r12, lsr #23
- ldrh r12,[r2, r12]
- orr r10,r10,r10, lsl #16
-
- subs r3, r3, #1
- orr r12,r12,r12, lsl #16
-
- stmia r0!, {r4-r10,r12}
- stmia r11!,{r4-r10,r12}
- bne clut_line_2x2_loop
-
- ldmfd sp!, {r4-r11,pc}
-
-
-@ 00 01 11 22 23 33
-@ r4 r5 r6 r7 r8 r9
-
-.macro do_4_to_12 rs
- and r4, lr, \rs, lsl #1
- and r6, lr, \rs, lsr #7
- and r7, lr, \rs, lsr #15
- and r9, lr, \rs, lsr #23
- ldrh r4, [r2, r4]
- ldrh r6, [r2, r6]
- ldrh r7, [r2, r7]
- ldrh r9, [r2, r9]
-
- orr r5, r4, r6, lsl #16
- orr r4, r4, r4, lsl #16
- orr r6, r6, r6, lsl #16
-
- orr r8, r7, r9, lsl #16
- orr r7, r7, r7, lsl #16
- orr r9, r9, r9, lsl #16
-.endm
-
-
-.global clut_line3x2 @ void *dest, void *src, unsigned short *pal, int pixels_mask
-
-clut_line3x2:
- stmfd sp!, {r4-r11,lr}
-
- and lr, r3, #0xff0000
- mov lr, lr, lsr #15 @ mask
- mov r3, r3, lsr #3
- and r3, r3, #0xff @ counter
- add r11,r0, #800*2
-
-clut_line3x2_loop:
- ldmia r1!, {r10,r12}
-
- do_4_to_12 r10
- stmia r0!, {r4-r9}
- stmia r11!,{r4-r9}
-
- do_4_to_12 r12
- subs r3, r3, #1
- stmia r0!, {r4-r9}
- stmia r11!,{r4-r9}
-
- bne clut_line3x2_loop
-
- ldmfd sp!, {r4-r11,pc}
-
+++ /dev/null
-#!/bin/sh
-sed -i
-
-major=`head -n 1 version.h | sed 's/.*"\([0-9]*\)\.\([0-9]*\).*/\1/g'`
-minor=`head -n 1 version.h | sed 's/.*"\([0-9]*\)\.\([0-9]*\).*/\2/g'`
-revision=`head -n 1 revision.h | sed 's/.*"\([0-9]*\)".*/\1/g'`
-
-sed 's/@major@/'$major'/' "$1" > "$2"
-sed -i 's/@minor@/'$minor'/' "$2"
-sed -i 's/@revision@/'$revision'/' "$2"
+++ /dev/null
-#include "plat.h"
-
-static const char *men_scaler[] = { "1x1, 1x1", "2x2, 3x2", "2x2, 2x2", "fullscreen", "custom", NULL };
-static const char h_scaler[] = "Scalers for 40 and 32 column modes\n"
- "(320 and 256 pixel wide horizontal)";
-static const char h_cscaler[] = "Displays the scaler layer, you can resize it\n"
- "using d-pad or move it using R+d-pad";
-static const char *men_dummy[] = { NULL };
-char **pnd_filter_list;
-
-static int menu_loop_cscaler(int id, int keys)
-{
- unsigned int inp;
-
- currentConfig.scaling = SCALE_CUSTOM;
-
- pnd_setup_layer(1, g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
- pnd_restore_layer_data();
-
- for (;;)
- {
- menu_draw_begin(0);
- memset(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
- text_out16(2, 480 - 18, "%dx%d | d-pad to resize, R+d-pad to move", g_layer_cw, g_layer_ch);
- menu_draw_end();
-
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_R|PBTN_MOK|PBTN_MBACK, 40);
- if (inp & PBTN_UP) g_layer_cy--;
- if (inp & PBTN_DOWN) g_layer_cy++;
- if (inp & PBTN_LEFT) g_layer_cx--;
- if (inp & PBTN_RIGHT) g_layer_cx++;
- if (!(inp & PBTN_R)) {
- if (inp & PBTN_UP) g_layer_ch += 2;
- if (inp & PBTN_DOWN) g_layer_ch -= 2;
- if (inp & PBTN_LEFT) g_layer_cw += 2;
- if (inp & PBTN_RIGHT) g_layer_cw -= 2;
- }
- if (inp & (PBTN_MOK|PBTN_MBACK))
- break;
-
- if (inp & (PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT)) {
- if (g_layer_cx < 0) g_layer_cx = 0;
- if (g_layer_cx > 640) g_layer_cx = 640;
- if (g_layer_cy < 0) g_layer_cy = 0;
- if (g_layer_cy > 420) g_layer_cy = 420;
- if (g_layer_cw < 160) g_layer_cw = 160;
- if (g_layer_ch < 60) g_layer_ch = 60;
- if (g_layer_cx + g_layer_cw > 800)
- g_layer_cw = 800 - g_layer_cx;
- if (g_layer_cy + g_layer_ch > 480)
- g_layer_ch = 480 - g_layer_cy;
- pnd_setup_layer(1, g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
- }
- }
-
- pnd_setup_layer(0, g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
-
- return 0;
-}
-
-#define MENU_OPTIONS_GFX \
- mee_enum_h ("Scaler", MA_OPT_SCALING, currentConfig.scaling, \
- men_scaler, h_scaler), \
- mee_enum ("Filter", MA_OPT3_FILTERING, currentConfig.filter, men_dummy), \
- mee_onoff ("Vsync", MA_OPT2_VSYNC, currentConfig.EmuOpt, EOPT_VSYNC), \
- mee_cust_h ("Setup custom scaler", MA_NONE, menu_loop_cscaler, NULL, h_cscaler), \
- mee_range_hide("layer_x", MA_OPT3_LAYER_X, g_layer_cx, 0, 640), \
- mee_range_hide("layer_y", MA_OPT3_LAYER_Y, g_layer_cy, 0, 420), \
- mee_range_hide("layer_w", MA_OPT3_LAYER_W, g_layer_cw, 160, 800), \
- mee_range_hide("layer_h", MA_OPT3_LAYER_H, g_layer_ch, 60, 480), \
-
-#define MENU_OPTIONS_ADV \
- mee_onoff ("SVP dynarec", MA_OPT2_SVP_DYNAREC, PicoOpt, POPT_EN_SVP_DRC), \
- mee_onoff ("Status line in main menu", MA_OPT2_STATUS_LINE, currentConfig.EmuOpt, EOPT_SHOW_RTC),
-
-#define menu_main_plat_draw NULL
-
-#include <dirent.h>
-#include <errno.h>
-
-static menu_entry e_menu_gfx_options[];
-static menu_entry e_menu_options[];
-static menu_entry e_menu_keyconfig[];
-
-void pnd_menu_init(void)
-{
- struct dirent *ent;
- int i, count = 0;
- char **mfilters;
- char buff[64], *p;
- DIR *dir;
-
- dir = opendir("/etc/pandora/conf/dss_fir");
- if (dir == NULL) {
- perror("filter opendir");
- return;
- }
-
- while (1) {
- errno = 0;
- ent = readdir(dir);
- if (ent == NULL) {
- if (errno != 0)
- perror("readdir");
- break;
- }
- p = strstr(ent->d_name, "_up");
- if (p != NULL && (p[3] == 0 || !strcmp(p + 3, "_h")))
- count++;
- }
-
- if (count == 0)
- return;
-
- mfilters = calloc(count + 1, sizeof(mfilters[0]));
- if (mfilters == NULL)
- return;
-
- rewinddir(dir);
- for (i = 0; (ent = readdir(dir)); ) {
- size_t len;
-
- p = strstr(ent->d_name, "_up");
- if (p == NULL || (p[3] != 0 && strcmp(p + 3, "_h")))
- continue;
-
- len = p - ent->d_name;
- if (len > sizeof(buff) - 1)
- continue;
-
- strncpy(buff, ent->d_name, len);
- buff[len] = 0;
- mfilters[i] = strdup(buff);
- if (mfilters[i] != NULL)
- i++;
- }
- closedir(dir);
-
- i = me_id2offset(e_menu_gfx_options, MA_OPT3_FILTERING);
- e_menu_gfx_options[i].data = (void *)mfilters;
- pnd_filter_list = mfilters;
-
- i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);
- e_menu_options[i].name = "Max CPU clock";
-
- me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, 0);
-}
-
+++ /dev/null
-// (c) Copyright 2006-2009 notaz, All rights reserved.\r
-// Free for non-commercial use.\r
-\r
-// For commercial use, separate licencing terms must be obtained.\r
-\r
-#include <stdio.h>\r
-#include <unistd.h>\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <fcntl.h>\r
-#include <sys/ioctl.h>\r
-#include <unistd.h>\r
-#include <linux/fb.h>\r
-#include <linux/omapfb.h>\r
-\r
-#include "../common/emu.h"\r
-#include "../common/menu.h"\r
-#include "../common/plat.h"\r
-#include "../common/arm_utils.h"\r
-#include "../common/input.h"\r
-#include "../linux/sndout_oss.h"\r
-#include "../linux/fbdev.h"\r
-#include "../linux/xenv.h"\r
-#include "plat.h"\r
-#include "asm_utils.h"\r
-#include "version.h"\r
-\r
-#include <pico/pico_int.h>\r
-\r
-#include <linux/input.h>\r
-\r
-static struct vout_fbdev *main_fb, *layer_fb;\r
-// g_layer_* - in use, g_layer_c* - configured custom\r
-int g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch;\r
-static int g_layer_x, g_layer_y;\r
-static int g_layer_w = 320, g_layer_h = 240;\r
-static int g_osd_fps_x, g_osd_y, doing_bg_frame;\r
-\r
-static const char pnd_script_base[] = "sudo -n /usr/pandora/scripts";\r
-static short __attribute__((aligned(4))) sndBuffer[2*44100/50];\r
-static unsigned char __attribute__((aligned(4))) fb_copy[g_screen_width * g_screen_height * 2];\r
-static void *temp_frame;\r
-unsigned char *PicoDraw2FB;\r
-const char *renderer_names[] = { NULL };\r
-const char *renderer_names32x[] = { NULL };\r
-\r
-static const char * const pandora_gpio_keys[KEY_MAX + 1] = {\r
- [0 ... KEY_MAX] = NULL,\r
- [KEY_UP] = "Up",\r
- [KEY_LEFT] = "Left",\r
- [KEY_RIGHT] = "Right",\r
- [KEY_DOWN] = "Down",\r
- [KEY_HOME] = "A",\r
- [KEY_PAGEDOWN] = "X",\r
- [KEY_END] = "B",\r
- [KEY_PAGEUP] = "Y",\r
- [KEY_RIGHTSHIFT]= "L",\r
- [KEY_RIGHTCTRL] = "R",\r
- [KEY_LEFTALT] = "Start",\r
- [KEY_LEFTCTRL] = "Select",\r
- [KEY_MENU] = "Pandora",\r
-};\r
-\r
-struct in_default_bind in_evdev_defbinds[] =\r
-{\r
- /* MXYZ SACB RLDU */\r
- { KEY_UP, IN_BINDTYPE_PLAYER12, 0 },\r
- { KEY_DOWN, IN_BINDTYPE_PLAYER12, 1 },\r
- { KEY_LEFT, IN_BINDTYPE_PLAYER12, 2 },\r
- { KEY_RIGHT, IN_BINDTYPE_PLAYER12, 3 },\r
- { KEY_S, IN_BINDTYPE_PLAYER12, 4 }, /* B */\r
- { KEY_D, IN_BINDTYPE_PLAYER12, 5 }, /* C */\r
- { KEY_A, IN_BINDTYPE_PLAYER12, 6 }, /* A */\r
- { KEY_ENTER, IN_BINDTYPE_PLAYER12, 7 },\r
- { KEY_BACKSLASH, IN_BINDTYPE_EMU, PEVB_MENU },\r
- { KEY_SPACE, IN_BINDTYPE_EMU, PEVB_MENU },\r
- /* Pandora */\r
- { KEY_PAGEDOWN, IN_BINDTYPE_PLAYER12, 4 },\r
- { KEY_END, IN_BINDTYPE_PLAYER12, 5 },\r
- { KEY_HOME, IN_BINDTYPE_PLAYER12, 6 },\r
- { KEY_LEFTALT, IN_BINDTYPE_PLAYER12, 7 },\r
- { KEY_RIGHTSHIFT,IN_BINDTYPE_EMU, PEVB_STATE_SAVE },\r
- { KEY_RIGHTCTRL, IN_BINDTYPE_EMU, PEVB_STATE_LOAD },\r
- { KEY_LEFTCTRL, IN_BINDTYPE_EMU, PEVB_MENU },\r
- { 0, 0, 0 }\r
-};\r
-\r
-static int get_cpu_clock(void)\r
-{\r
- FILE *f;\r
- int ret = 0;\r
- f = fopen("/proc/pandora/cpu_mhz_max", "r");\r
- if (f) {\r
- fscanf(f, "%d", &ret);\r
- fclose(f);\r
- }\r
- return ret;\r
-}\r
-\r
-void pemu_prep_defconfig(void)\r
-{\r
- defaultConfig.EmuOpt |= EOPT_VSYNC|EOPT_16BPP;\r
- defaultConfig.s_PicoOpt |= POPT_EN_MCD_GFX|POPT_EN_MCD_PSYNC;\r
- defaultConfig.scaling = SCALE_2x2_3x2;\r
-}\r
-\r
-void pemu_validate_config(void)\r
-{\r
- currentConfig.CPUclock = get_cpu_clock();\r
-}\r
-\r
-static void osd_text(int x, int y, const char *text)\r
-{\r
- int len = strlen(text)*8;\r
- int i, h;\r
-\r
- len++;\r
- for (h = 0; h < 8; h++) {\r
- unsigned short *p;\r
- p = (unsigned short *)g_screen_ptr + x + g_screen_width*(y + h);\r
- for (i = len; i; i--, p++)\r
- *p = (*p>>2) & 0x39e7;\r
- }\r
- emu_text_out16(x, y, text);\r
-}\r
-\r
-static void draw_cd_leds(void)\r
-{\r
- int old_reg;\r
- old_reg = Pico_mcd->s68k_regs[0];\r
-\r
- if (0) {\r
- // 8-bit modes\r
- unsigned int col_g = (old_reg & 2) ? 0xc0c0c0c0 : 0xe0e0e0e0;\r
- unsigned int col_r = (old_reg & 1) ? 0xd0d0d0d0 : 0xe0e0e0e0;\r
- *(unsigned int *)((char *)g_screen_ptr + g_screen_width*2+ 4) =\r
- *(unsigned int *)((char *)g_screen_ptr + g_screen_width*3+ 4) =\r
- *(unsigned int *)((char *)g_screen_ptr + g_screen_width*4+ 4) = col_g;\r
- *(unsigned int *)((char *)g_screen_ptr + g_screen_width*2+12) =\r
- *(unsigned int *)((char *)g_screen_ptr + g_screen_width*3+12) =\r
- *(unsigned int *)((char *)g_screen_ptr + g_screen_width*4+12) = col_r;\r
- } else {\r
- // 16-bit modes\r
- unsigned int *p = (unsigned int *)((short *)g_screen_ptr + g_screen_width*2+4);\r
- unsigned int col_g = (old_reg & 2) ? 0x06000600 : 0;\r
- unsigned int col_r = (old_reg & 1) ? 0xc000c000 : 0;\r
- *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += g_screen_width/2 - 12/2;\r
- *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += g_screen_width/2 - 12/2;\r
- *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r;\r
- }\r
-}\r
-\r
-static int emuscan(unsigned int num)\r
-{\r
- DrawLineDest = (unsigned short *)g_screen_ptr + num * g_screen_width;\r
-\r
- return 0;\r
-}\r
-\r
-void pemu_finalize_frame(const char *fps, const char *notice)\r
-{\r
- if (notice && notice[0])\r
- osd_text(2, g_osd_y, notice);\r
- if (fps && fps[0] && (currentConfig.EmuOpt & EOPT_SHOW_FPS))\r
- osd_text(g_osd_fps_x, g_osd_y, fps);\r
- if ((PicoAHW & PAHW_MCD) && (currentConfig.EmuOpt & EOPT_EN_CD_LEDS))\r
- draw_cd_leds();\r
-}\r
-\r
-void plat_video_flip(void)\r
-{\r
- g_screen_ptr = vout_fbdev_flip(layer_fb);\r
-\r
- // XXX: drain OS event queue here, maybe we'll actually use it someday..\r
- int dummy;\r
- xenv_update(&dummy);\r
-}\r
-\r
-void plat_video_toggle_renderer(int change, int is_menu)\r
-{\r
-}\r
-\r
-void plat_video_menu_enter(int is_rom_loaded)\r
-{\r
-}\r
-\r
-void plat_video_menu_begin(void)\r
-{\r
-}\r
-\r
-void plat_video_menu_end(void)\r
-{\r
- g_menuscreen_ptr = vout_fbdev_flip(main_fb);\r
-}\r
-\r
-void plat_video_wait_vsync(void)\r
-{\r
- vout_fbdev_wait_vsync(main_fb);\r
-}\r
-\r
-void plat_status_msg_clear(void)\r
-{\r
- vout_fbdev_clear_lines(layer_fb, g_osd_y, 8);\r
-}\r
-\r
-void plat_status_msg_busy_next(const char *msg)\r
-{\r
- plat_status_msg_clear();\r
- pemu_finalize_frame("", msg);\r
- plat_video_flip();\r
- emu_status_msg("");\r
- reset_timing = 1;\r
-}\r
-\r
-void plat_status_msg_busy_first(const char *msg)\r
-{\r
- plat_status_msg_busy_next(msg);\r
-}\r
-\r
-void plat_update_volume(int has_changed, int is_up)\r
-{\r
- static int prev_frame = 0, wait_frames = 0;\r
- int vol = currentConfig.volume;\r
-\r
- if (has_changed)\r
- {\r
- if (is_up) {\r
- if (vol < 99) vol++;\r
- } else {\r
- if (vol > 0) vol--;\r
- }\r
- wait_frames = 0;\r
- sndout_oss_setvol(vol, vol);\r
- currentConfig.volume = vol;\r
- emu_status_msg("VOL: %02i", vol);\r
- prev_frame = Pico.m.frame_count;\r
- }\r
-}\r
-\r
-static void make_bg(int no_scale)\r
-{\r
- unsigned short *s = (void *)fb_copy;\r
- int x, y;\r
-\r
- memset32(g_menubg_src_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2 / 4);\r
-\r
- if (!no_scale && g_menuscreen_w >= 640 && g_menuscreen_h >= 480) {\r
- unsigned int t, *d = g_menubg_src_ptr;\r
- d += (g_menuscreen_h / 2 - 480 / 2) * g_menuscreen_w / 2;\r
- d += (g_menuscreen_w / 2 - 640 / 2) / 2;\r
- for (y = 0; y < 240; y++, s += 320, d += g_menuscreen_w*2/2) {\r
- for (x = 0; x < 320; x++) {\r
- t = s[x];\r
- t |= t << 16;\r
- d[x] = d[x + g_menuscreen_w / 2] = t;\r
- }\r
- }\r
- return;\r
- }\r
-\r
- if (g_menuscreen_w >= 320 && g_menuscreen_h >= 240) {\r
- unsigned short *d = g_menubg_src_ptr;\r
- d += (g_menuscreen_h / 2 - 240 / 2) * g_menuscreen_w;\r
- d += (g_menuscreen_w / 2 - 320 / 2);\r
- for (y = 0; y < 240; y++, s += 320, d += g_menuscreen_w)\r
- memcpy(d, s, 320*2);\r
- return;\r
- }\r
-}\r
-\r
-void pemu_forced_frame(int no_scale, int do_emu)\r
-{\r
- doing_bg_frame = 1;\r
- emu_cmn_forced_frame(no_scale, do_emu);\r
- doing_bg_frame = 0;\r
-\r
- // making a copy because enabling the layer clears it's mem\r
- memcpy32((void *)fb_copy, g_screen_ptr, sizeof(fb_copy) / 4);\r
- make_bg(no_scale);\r
-}\r
-\r
-static void oss_write_nonblocking(int len)\r
-{\r
- // sndout_oss_can_write() is not reliable, only use with no_frmlimit\r
- if ((currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) && !sndout_oss_can_write(len))\r
- return;\r
-\r
- sndout_oss_write_nb(PsndOut, len);\r
-}\r
-\r
-void pemu_sound_start(void)\r
-{\r
- PsndOut = NULL;\r
-\r
- if (currentConfig.EmuOpt & EOPT_EN_SOUND)\r
- {\r
- int is_stereo = (PicoOpt & POPT_EN_STEREO) ? 1 : 0;\r
-\r
- PsndRerate(Pico.m.frame_count ? 1 : 0);\r
-\r
- /*\r
- * for 44k stereo, we do 1470 samples/emu_frame\r
- * OMAP driver does power of 2 buffers, so we need at least 4K buffer.\r
- * The most we can lag is 1K samples, size of OMAP's McBSP FIFO,\r
- * with 2K sample buffer we might sometimes lag more than that,\r
- * thus causing underflows.\r
- */\r
- printf("starting audio: %i len: %i stereo: %i, pal: %i\n",\r
- PsndRate, PsndLen, is_stereo, Pico.m.pal);\r
- sndout_oss_start(PsndRate, is_stereo, 2);\r
- //sndout_oss_setvol(currentConfig.volume, currentConfig.volume);\r
- PicoWriteSound = oss_write_nonblocking;\r
- plat_update_volume(0, 0);\r
- memset(sndBuffer, 0, sizeof(sndBuffer));\r
- PsndOut = sndBuffer;\r
- }\r
-}\r
-\r
-void pemu_sound_stop(void)\r
-{\r
- sndout_oss_stop();\r
-}\r
-\r
-void pemu_sound_wait(void)\r
-{\r
- // don't need to do anything, writes will block by themselves\r
-}\r
-\r
-void plat_debug_cat(char *str)\r
-{\r
-}\r
-\r
-static int pnd_setup_layer_(int fd, int enabled, int x, int y, int w, int h)\r
-{\r
- struct omapfb_plane_info pi;\r
- struct omapfb_mem_info mi;\r
- int ret;\r
-\r
- ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi);\r
- if (ret != 0) {\r
- perror("QUERY_PLANE");\r
- return -1;\r
- }\r
-\r
- ret = ioctl(fd, OMAPFB_QUERY_MEM, &mi);\r
- if (ret != 0) {\r
- perror("QUERY_MEM");\r
- return -1;\r
- }\r
-\r
- /* must disable when changing stuff */\r
- if (pi.enabled) {\r
- pi.enabled = 0;\r
- ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);\r
- if (ret != 0)\r
- perror("SETUP_PLANE");\r
- }\r
-\r
- mi.size = 320*240*2*4;\r
- ret = ioctl(fd, OMAPFB_SETUP_MEM, &mi);\r
- if (ret != 0) {\r
- perror("SETUP_MEM");\r
- return -1;\r
- }\r
-\r
- pi.pos_x = x;\r
- pi.pos_y = y;\r
- pi.out_width = w;\r
- pi.out_height = h;\r
- pi.enabled = enabled;\r
-\r
- ret = ioctl(fd, OMAPFB_SETUP_PLANE, &pi);\r
- if (ret != 0) {\r
- perror("SETUP_PLANE");\r
- return -1;\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-int pnd_setup_layer(int enabled, int x, int y, int w, int h)\r
-{\r
- return pnd_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled, x, y, w, h);\r
-}\r
-\r
-void pnd_restore_layer_data(void)\r
-{\r
- short *t = (short *)fb_copy + 320*240 / 2 + 160;\r
-\r
- // right now this is used by menu, which wants to preview something\r
- // so try to get something on the layer.\r
- if ((t[0] | t[5] | t[13]) == 0)\r
- memset32((void *)fb_copy, 0x07000700, sizeof(fb_copy) / 4);\r
-\r
- memcpy32(g_screen_ptr, (void *)fb_copy, 320*240*2 / 4);\r
- plat_video_flip();\r
-}\r
-\r
-static void apply_filter(int which)\r
-{\r
- char buf[128];\r
- int i;\r
-\r
- if (pnd_filter_list == NULL)\r
- return;\r
-\r
- for (i = 0; i < which; i++)\r
- if (pnd_filter_list[i] == NULL)\r
- return;\r
-\r
- if (pnd_filter_list[i] == NULL)\r
- return;\r
-\r
- snprintf(buf, sizeof(buf), "%s/op_videofir.sh %s", pnd_script_base, pnd_filter_list[i]);\r
- system(buf);\r
-}\r
-\r
-void emu_video_mode_change(int start_line, int line_count, int is_32cols)\r
-{\r
- int fb_w = 320, fb_h = 240, fb_left = 0, fb_right = 0, fb_top = 0, fb_bottom = 0;\r
-\r
- if (doing_bg_frame)\r
- return;\r
-\r
- PicoDrawSetOutFormat(PDF_RGB555, 1);\r
- PicoDrawSetCallbacks(emuscan, NULL);\r
-\r
- if (is_32cols) {\r
- fb_w = 256;\r
- fb_left = fb_right = 32;\r
- }\r
-\r
- switch (currentConfig.scaling) {\r
- case SCALE_1x1:\r
- g_layer_w = fb_w;\r
- g_layer_h = fb_h;\r
- break;\r
- case SCALE_2x2_3x2:\r
- g_layer_w = fb_w * (is_32cols ? 3 : 2);\r
- g_layer_h = fb_h * 2;\r
- break;\r
- case SCALE_2x2_2x2:\r
- g_layer_w = fb_w * 2;\r
- g_layer_h = fb_h * 2;\r
- break;\r
- case SCALE_FULLSCREEN:\r
- g_layer_w = 800;\r
- g_layer_h = 480;\r
- break;\r
- case SCALE_CUSTOM:\r
- g_layer_x = g_layer_cx;\r
- g_layer_y = g_layer_cy;\r
- g_layer_w = g_layer_cw;\r
- g_layer_h = g_layer_ch;\r
- break;\r
- }\r
-\r
- if (currentConfig.scaling != SCALE_CUSTOM) {\r
- // center the layer\r
- g_layer_x = 800 / 2 - g_layer_w / 2;\r
- g_layer_y = 480 / 2 - g_layer_h / 2;\r
- }\r
-\r
- switch (currentConfig.scaling) {\r
- case SCALE_FULLSCREEN:\r
- case SCALE_CUSTOM:\r
- fb_top = start_line;\r
- fb_h = line_count;\r
- break;\r
- }\r
- g_osd_fps_x = is_32cols ? 232 : 264;\r
- g_osd_y = fb_top + fb_h - 8;\r
-\r
- pnd_setup_layer(1, g_layer_x, g_layer_y, g_layer_w, g_layer_h);\r
- vout_fbdev_clear(layer_fb);\r
- vout_fbdev_resize(layer_fb, fb_w, fb_h, 16, fb_left, fb_right, fb_top, fb_bottom, 3);\r
- plat_video_flip();\r
-}\r
-\r
-void pemu_loop_prep(void)\r
-{\r
- static int pal_old = -1;\r
- static int filter_old = -1;\r
- char buf[128];\r
-\r
- if (currentConfig.CPUclock != get_cpu_clock()) {\r
- snprintf(buf, sizeof(buf), "unset DISPLAY; echo y | %s/op_cpuspeed.sh %d",\r
- pnd_script_base, currentConfig.CPUclock);\r
- system(buf);\r
- }\r
-\r
- if (Pico.m.pal != pal_old) {\r
- snprintf(buf, sizeof(buf), "%s/op_lcdrate.sh %d",\r
- pnd_script_base, Pico.m.pal ? 50 : 60);\r
- system(buf);\r
- pal_old = Pico.m.pal;\r
- }\r
-\r
- if (currentConfig.filter != filter_old) {\r
- apply_filter(currentConfig.filter);\r
- filter_old = currentConfig.filter;\r
- }\r
-\r
- // make sure there is no junk left behind the layer\r
- memset32(g_menuscreen_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2 / 4);\r
- g_menuscreen_ptr = vout_fbdev_flip(main_fb);\r
-\r
- // emu_video_mode_change will call pnd_setup_layer()\r
-\r
- // dirty buffers better go now than during gameplay\r
- sync();\r
- sleep(0);\r
-\r
- pemu_sound_start();\r
-}\r
-\r
-void pemu_loop_end(void)\r
-{\r
- pemu_sound_stop();\r
-\r
- /* do one more frame for menu bg */\r
- pemu_forced_frame(0, 1);\r
-\r
- pnd_setup_layer(0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);\r
-}\r
-\r
-void plat_wait_till_us(unsigned int us_to)\r
-{\r
- unsigned int now;\r
- signed int diff;\r
-\r
- now = plat_get_ticks_us();\r
-\r
- // XXX: need to check NOHZ\r
- diff = (signed int)(us_to - now);\r
- if (diff > 10000) {\r
- //printf("sleep %d\n", us_to - now);\r
- usleep(diff * 15 / 16);\r
- now = plat_get_ticks_us();\r
- //printf(" wake %d\n", (signed)(us_to - now));\r
- }\r
-/*\r
- while ((signed int)(us_to - now) > 512) {\r
- spend_cycles(1024);\r
- now = plat_get_ticks_us();\r
- }\r
-*/\r
-}\r
-\r
-void plat_early_init(void)\r
-{\r
-}\r
-\r
-void plat_init(void)\r
-{\r
- const char *main_fb_name, *layer_fb_name;\r
- int fd, ret, w, h;\r
-\r
- main_fb_name = getenv("FBDEV_MAIN");\r
- if (main_fb_name == NULL)\r
- main_fb_name = "/dev/fb0";\r
-\r
- layer_fb_name = getenv("FBDEV_LAYER");\r
- if (layer_fb_name == NULL)\r
- layer_fb_name = "/dev/fb1";\r
-\r
- // must set the layer up first to be able to use it\r
- fd = open(layer_fb_name, O_RDWR);\r
- if (fd == -1) {\r
- fprintf(stderr, "%s: ", layer_fb_name);\r
- perror("open");\r
- exit(1);\r
- }\r
-\r
- ret = pnd_setup_layer_(fd, 0, g_layer_x, g_layer_y, g_layer_w, g_layer_h);\r
- close(fd);\r
- if (ret != 0) {\r
- fprintf(stderr, "failed to set up layer, exiting.\n");\r
- exit(1);\r
- }\r
-\r
- xenv_init();\r
-\r
- w = h = 0;\r
- main_fb = vout_fbdev_init(main_fb_name, &w, &h, 16, 2);\r
- if (main_fb == NULL) {\r
- fprintf(stderr, "couldn't init fb: %s\n", main_fb_name);\r
- exit(1);\r
- }\r
-\r
- g_menuscreen_w = w;\r
- g_menuscreen_h = h;\r
- g_menuscreen_ptr = vout_fbdev_flip(main_fb);\r
-\r
- w = 320; h = 240;\r
- layer_fb = vout_fbdev_init(layer_fb_name, &w, &h, 16, 3);\r
- if (layer_fb == NULL) {\r
- fprintf(stderr, "couldn't init fb: %s\n", layer_fb_name);\r
- goto fail0;\r
- }\r
-\r
- if (w != g_screen_width || h != g_screen_height) {\r
- fprintf(stderr, "%dx%d not supported on %s\n", w, h, layer_fb_name);\r
- goto fail1;\r
- }\r
- g_screen_ptr = vout_fbdev_flip(layer_fb);\r
-\r
- temp_frame = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1);\r
- if (temp_frame == NULL) {\r
- fprintf(stderr, "OOM\n");\r
- goto fail1;\r
- }\r
- g_menubg_ptr = temp_frame;\r
- g_menubg_src_ptr = temp_frame;\r
- PicoDraw2FB = temp_frame;\r
-\r
- sndout_oss_init();\r
- pnd_menu_init();\r
-\r
- in_set_config(in_name_to_id("evdev:gpio-keys"), IN_CFG_KEY_NAMES,\r
- pandora_gpio_keys, sizeof(pandora_gpio_keys));\r
- return;\r
-\r
-fail1:\r
- vout_fbdev_finish(layer_fb);\r
-fail0:\r
- vout_fbdev_finish(main_fb);\r
- exit(1);\r
-}\r
-\r
-void plat_finish(void)\r
-{\r
- sndout_oss_exit();\r
- vout_fbdev_finish(main_fb);\r
- xenv_finish();\r
-\r
- printf("all done\n");\r
-}\r
-\r
+++ /dev/null
-
-extern char **pnd_filter_list;
-extern int g_layer_cx, g_layer_cy;
-extern int g_layer_cw, g_layer_ch;
-
-void pnd_menu_init(void);
-int pnd_setup_layer(int enabled, int x, int y, int w, int h);
-void pnd_restore_layer_data(void);
-
-enum {
- SCALE_1x1,
- SCALE_2x2_3x2,
- SCALE_2x2_2x2,
- SCALE_FULLSCREEN,
- SCALE_CUSTOM,
-};
-
+++ /dev/null
-// port specific settings\r
-\r
-#ifndef PORT_CONFIG_H\r
-#define PORT_CONFIG_H\r
-\r
-#define CASE_SENSITIVE_FS 1 // CS filesystem\r
-#define DONT_OPEN_MANY_FILES 0\r
-#define REDUCE_IO_CALLS 0\r
-\r
-#define SCREEN_SIZE_FIXED 1\r
-#define SCREEN_WIDTH 320\r
-#define SCREEN_HEIGHT 240\r
-#define MSCREEN_SIZE_FIXED 0\r
-#define MSCREEN_WIDTH SCREEN_WIDTH\r
-#define MSCREEN_HEIGHT SCREEN_HEIGHT\r
-\r
-// draw2.c\r
-#define START_ROW 0 // which row of tiles to start rendering at?\r
-#define END_ROW 28 // ..end\r
-\r
-// pico.c\r
-#define CAN_HANDLE_240_LINES 1\r
-\r
-#define SIMPLE_WRITE_SOUND 0\r
-\r
-// logging emu events\r
-#define EL_LOGMASK (EL_STATUS|EL_IDLE) // (EL_STATUS|EL_ANOMALY|EL_UIO|EL_SRAMIO|EL_INTS|EL_CDPOLL) // xffff\r
-\r
-//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)\r
-#define dprintf(x...)\r
-\r
-// platform\r
-#define PATH_SEP "/"\r
-#define PATH_SEP_C '/'\r
-#define MENU_X2 1\r
-\r
-#endif //PORT_CONFIG_H\r
+++ /dev/null
-@ vim:filetype=armasm\r
-\r
-@ .equiv START_ROW, 1\r
-@ .equiv END_ROW, 27\r
-@ one row means 8 pixels. If above example was used, (27-1)*8=208 lines would be rendered.\r
-.equiv START_ROW, 0\r
-.equiv END_ROW, 28\r
-\r
-.equiv UNALIGNED_DRAWLINEDEST, 0\r
-\r
-@ this should be set to one only for GP2X port\r
-.equiv EXTERNAL_YM2612, 1\r
-\r
+++ /dev/null
-#define VERSION "1.80"\r
-\r
+++ /dev/null
-\r
-# pspdev is expected to be in path\r
-PSPSDK = $(shell psp-config --pspsdk-path)\r
-\r
-# settings\r
-#use_musashi = 1\r
-#use_mz80 = 1\r
-amalgamate = 0\r
-for_15fw = 1\r
-# :!touch platform/psp/psp.c\r
-\r
-\r
-CFLAGS += -I../.. -I. -DNO_SYNC -D_ASM_DRAW_C_AMIPS\r
-CFLAGS += -Wall -Winline -G0\r
-#CFLAGS += -DLPRINTF_STDIO\r
-#CFLAGS += -pg\r
-ifeq ($(DEBUG),)\r
-CFLAGS += -O2 -ftracer -fstrength-reduce -ffast-math\r
-else\r
-CFLAGS += -ggdb\r
-endif\r
-ifeq "$(for_15fw)" "1"\r
-CFLAGS += -DFW15\r
-endif\r
-\r
-\r
-# frontend and stuff\r
-OBJS += main.o emu.o mp3.o menu.o psp.o asm_utils.o\r
-\r
-# common\r
-OBJS += platform/common/emu.o platform/common/menu.o platform/common/fonts.o platform/common/config.o platform/common/readpng.o\r
-\r
-# Pico\r
-ifeq "$(amalgamate)" "1"\r
-OBJS += ../../picoAll.o\r
-else\r
-OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o pico/videoport.o \\r
- pico/draw2.o pico/draw.o pico/z80if.o pico/patch.o pico/draw_amips.o pico/memory_amips.o \\r
- pico/misc_amips.o pico/debug.o\r
-# Pico - CD\r
-OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \\r
- pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \\r
- pico/cd/area.o pico/cd/misc.o pico/cd/pcm.o pico/cd/buffering.o\r
-# Pico - carthw\r
-OBJS += pico/carthw/carthw.o pico/carthw/svp/svp.o pico/carthw/svp/memory.o \\r
- pico/carthw/svp/ssp16.o\r
-# Pico - Pico\r
-OBJS += pico/pico/pico.o pico/pico/memory.o pico/pico/xpcm.o\r
-endif\r
-\r
-# Pico - sound\r
-ifneq "$(amalgamate)" "1"\r
-OBJS += pico/sound/sound.o\r
-endif\r
-OBJS += pico/sound/mix.o\r
-OBJS += pico/sound/sn76496.o pico/sound/ym2612.o\r
-# zlib (hacked)\r
-OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \\r
- zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o \\r
- zlib/uncompr.o\r
-# unzip\r
-OBJS += unzip/unzip.o unzip/unzip_stream.o\r
-# CPU cores\r
-ifeq "$(use_musashi)" "1"\r
-CFLAGS += -DEMU_M68K\r
-OBJS += cpu/musashi/m68kops.o cpu/musashi/m68kcpu.o\r
-else\r
-CFLAGS += -DEMU_F68K\r
-OBJS += cpu/fame/famec.o\r
-endif\r
-# z80\r
-ifeq "$(use_mz80)" "1"\r
-CFLAGS += -D_USE_MZ80\r
-OBJS += cpu/mz80/mz80.o\r
-else\r
-CFLAGS += -D_USE_CZ80\r
-OBJS += cpu/cz80/cz80.o\r
-endif\r
-# bg images\r
-OBJS += data/bg32.o data/bg40.o\r
-\r
-vpath %.c = ../..\r
-vpath %.s = ../..\r
-DIRS = platform platform/psp platform/common pico pico/cd pico/pico pico/sound pico/carthw/svp \\r
- zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80\r
-\r
-\r
-LIBS += -lpng -lm -lpspgu -lpsppower -lpspaudio -lpsprtc -lpspaudiocodec -lpspkubridge\r
-#LIBS += -lpspprof\r
-LDFLAGS += -Wl,-Map=PicoDrive.map\r
-\r
-\r
-# target\r
-TARGET = PicoDrive\r
-EXTRA_TARGETS = mkdirs EBOOT.PBP\r
-PSP_EBOOT_TITLE = PicoDrive\r
-PSP_EBOOT_ICON = data/icon.png\r
-#PSP_EBOOT_PIC1 = .png\r
-ifneq "$(for_15fw)" "1"\r
-BUILD_PRX = 1\r
-endif\r
-\r
-CUSTOM_CLEAN = myclean\r
-\r
-include $(PSPSDK)/lib/build.mak\r
-\r
-# some additional rules\r
-mkdirs:\r
- mkdir -p $(DIRS)\r
-\r
-.c.o:\r
- @echo ">>>" $<\r
- $(CC) $(CFLAGS) -c $< -o $@\r
-\r
-AS := psp-as\r
-\r
-.s.o:\r
- @echo ">>>" $<\r
- $(AS) -march=allegrex -mtune=allegrex $< -o $@\r
-\r
-../../cpu/musashi/m68kops.c :\r
- make -C ../../cpu/musashi\r
-\r
-cpu/fame/famec.o : ../../cpu/fame/famec.c\r
- @echo ">>>" $<\r
- $(CC) $(CFLAGS) -Wno-unused -c $< -o $@\r
-\r
-pico/misc.o : ../../pico/misc.c\r
- @echo ">>>" $<\r
- $(CC) $(CFLAGS) -c $< -o $@ -D_ASM_MISC_C_AMIPS\r
-\r
-pico/memory.o : ../../pico/memory.c\r
- @echo ">>>" $<\r
- $(CC) $(CFLAGS) -O2 -c $< -o $@ -D_ASM_MEMORY_C -D_ASM_MEMORY_C_AMIPS\r
-\r
-pico/cd/memory.o : ../../pico/cd/memory.c\r
- @echo ">>>" $<\r
- $(CC) $(CFLAGS) -O2 -c $< -o $@\r
-\r
-pico/cd/gfx_cd.o : ../../pico/cd/gfx_cd.c\r
- @echo ">>>" $<\r
- $(CC) $(CFLAGS) -O2 -c $< -o $@\r
-\r
-readme.txt: ../../tools/textfilter ../base_readme.txt\r
- ../../tools/textfilter ../base_readme.txt $@ PSP\r
-\r
-../../tools/textfilter: ../../tools/textfilter.c\r
- make -C ../../tools/ textfilter\r
-\r
-data/bg32.o: data/bg32.bin\r
- bin2o -i $< $@ bgdatac32\r
-\r
-data/bg40.o: data/bg40.bin\r
- bin2o -i $< $@ bgdatac40\r
-\r
-#\r
-ifndef UPDIR\r
-UPDIR = /media/disk/PSP/GAME/PicoDrive/\r
-endif\r
-up: EBOOT.PBP\r
- @cp -v $^ $(UPDIR)\r
-\r
-\r
-# cleanup\r
-\r
-myclean:\r
- #rm -rf $(DIRS)\r
- $(RM) PicoDrive.map\r
- make -C ../../cpu/musashi clean\r
-\r
-\r
-clean_prof:\r
- find ../.. -name '*.gcno' -delete\r
- find ../.. -name '*.gcda' -delete\r
-\r
-# ----------- release -----------\r
-ifneq ($(findstring rel,$(MAKECMDGOALS)),)\r
-ifeq ($(VER),)\r
-$(error need VER)\r
-endif\r
-endif\r
-\r
-# ?\r
-rel: EBOOT.PBP readme.txt ../game_def.cfg\r
- mkdir -p PicoDrive/skin/\r
- cp $^ PicoDrive/\r
- cp skin/* PicoDrive/skin/\r
- zip -9 -r ../../PicoDrive_psp_$(VER).zip PicoDrive\r
- rm -rf PicoDrive\r
- mkdir bin_to_cso_mp3\r
- cp ../../tools/bin_to_cso_mp3/* bin_to_cso_mp3/\r
- zip -9 -r ../../PicoDrive_psp_$(VER).zip bin_to_cso_mp3\r
- rm -rf bin_to_cso_mp3\r
-\r
-rel_kxploit: readme.txt ../game_def.cfg\r
- mkdir -p PicoDrive/skin/\r
- cp $^ PicoDrive/\r
- cp skin/* PicoDrive/skin/\r
- zip -9 -r ../../PicoDrive_psp_$(VER)_kxploit.zip PicoDrive\r
- zip -9 -r ../../PicoDrive_psp_$(VER)_kxploit.zip PicoDrive%\r
- mkdir bin_to_cso_mp3\r
- cp ../../tools/bin_to_cso_mp3/* bin_to_cso_mp3/\r
- zip -9 -r ../../PicoDrive_psp_$(VER)_kxploit.zip bin_to_cso_mp3\r
- rm -rf bin_to_cso_mp3\r
-\r
+++ /dev/null
-// pointers must be word aligned, gammaa_val = -4..16, black_lvl = {0,1,2}
-void do_pal_convert(unsigned short *dest, unsigned short *src, int gammaa_val, int black_lvl);
+++ /dev/null
-# vim:filetype=mips
-
-# some asm utils
-# (c) Copyright 2007, Grazvydas "notaz" Ignotas
-# All Rights Reserved
-
-.set noreorder
-.set noat
-
-.data
-.align 4
-
-.byte 0, 1, 6, 11, 16, 21, 26, 31 # -4
-.byte 0, 2, 7, 12, 16, 21, 26, 31 # -3
-.byte 0, 3, 7, 12, 17, 22, 26, 31 # -2
-.byte 0, 4, 8, 13, 17, 22, 26, 31 # -1
-pal_gmtab:
-.byte 0, 5, 10, 15, 16, 21, 26, 31 # 0
-.byte 0, 6, 10, 15, 19, 23, 27, 31
-.byte 0, 7, 11, 15, 19, 23, 27, 31
-.byte 0, 8, 12, 16, 19, 23, 27, 31
-.byte 0, 9, 12, 16, 20, 24, 27, 31
-.byte 0, 10, 13, 17, 20, 24, 27, 31
-.byte 0, 10, 14, 17, 21, 24, 28, 31
-.byte 0, 11, 15, 18, 21, 24, 28, 31
-.byte 0, 12, 15, 18, 22, 25, 28, 31
-.byte 0, 13, 16, 19, 22, 25, 28, 31
-.byte 0, 14, 17, 20, 22, 25, 28, 31 # 10
-.byte 0, 15, 17, 20, 23, 26, 28, 31
-.byte 0, 16, 18, 21, 23, 26, 28, 31
-.byte 0, 16, 19, 21, 24, 26, 29, 31
-.byte 0, 17, 20, 22, 24, 26, 29, 31
-.byte 0, 18, 20, 22, 25, 27, 29, 31
-.byte 0, 19, 21, 23, 25, 27, 29, 31 # 16
-
-.text
-.align 4
-
-# bbbb bggg gggr rrrr
-
-#.global pal_gmtab
-.global do_pal_convert # dest, src, gammaa_val, black_lvl
-
-do_pal_convert:
- bnez $a2, dpc_gma
- li $t0, 64/2
- bnez $a3, dpc_gma
- lui $t2, 0x00e
- ori $t2, 0x00e
- lui $t3, 0x006
- ori $t3, 0x006
- lui $t4, 0x0e0
- ori $t4, 0x0e0
- lui $t6, 0xe00
- ori $t6, 0xe00
- lui $t7, 0x600
- ori $t7, 0x600
-
-dpc_loop:
- lw $v0, 0($a1)
- addiu $a1, 4
- and $v1, $v0, $t2 # r
- sll $v1, 1
- and $t9, $v0, $t3
- srl $t9, 1
- or $v1, $t9 # r
- and $t9, $v0, $t4 # g
- sll $t8, $t9, 3
- or $v1, $t8
- or $v1, $t9 # g
- and $t9, $v0, $t6 # b
- sll $t9, 4
- or $v1, $t9
- and $t9, $v0, $t7
- sll $t9, 2
- or $v1, $t9 # b
- sw $v1, 0($a0)
- addiu $t0, -1
- bnez $t0, dpc_loop
- addiu $a0, 4
-
- jr $ra
- nop
-
-# non-zero gamma
-dpc_gma:
- slt $t2, $a2, $0
- sll $a2, 3
- lui $t1, %hi(pal_gmtab)
- addiu $t1, %lo(pal_gmtab)
- addu $a2, $t1
- beqz $a3, dpc_gma_loop
- sb $0, 0($a2) # black level 0
- bnez $t2, dpc_gma_loop # gamma < 0, keep black at 0
- addiu $a3, -2
- slt $t2, $a3, $0 # t2 = a3_orig == 1 ? 1 : 0
- lb $t1, 1($a2)
- addiu $t1, -2
- srlv $t1, $t1, $t2
- sb $t1, 0($a2)
-
-dpc_gma_loop:
- lw $v0, 0($a1)
- addiu $a1, 4
- ext $v1, $v0, 1, 3
- addu $v1, $a2
- lb $v1, 0($v1)
- ext $t1, $v0, 5, 3
- addu $t1, $a2
- lb $t1, 0($t1)
- ext $t2, $v0, 9, 3
- addu $t2, $a2
- lb $t2, 0($t2)
- ext $t3, $v0, 17, 3
- addu $t3, $a2
- lb $t3, 0($t3)
- ext $t4, $v0, 21, 3
- addu $t4, $a2
- lb $t4, 0($t4)
- ext $t5, $v0, 25, 3
- addu $t5, $a2
- lb $t5, 0($t5)
- ins $v1, $t1, 6, 5
- ins $v1, $t2, 11, 5
- ins $v1, $t3, 16, 5
- ins $v1, $t4, 22, 5
- ins $v1, $t5, 27, 5
- sw $v1, 0($a0)
- addiu $t0, -1
- bnez $t0, dpc_gma_loop
- addiu $a0, 4
-
- jr $ra
- nop
-
+++ /dev/null
-// (c) Copyright 2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/syslimits.h> // PATH_MAX
-
-#include <pspthreadman.h>
-#include <pspdisplay.h>
-#include <psputils.h>
-#include <pspgu.h>
-#include <pspaudio.h>
-
-#include "psp.h"
-#include "menu.h"
-#include "emu.h"
-#include "mp3.h"
-#include "asm_utils.h"
-#include "../common/emu.h"
-#include "../common/config.h"
-#include "../common/lprintf.h"
-#include <pico/pico_int.h>
-#include <pico/cd/cue.h>
-
-#define OSD_FPS_X 432
-
-// additional pspaudio imports, credits to crazyc
-int sceAudio_38553111(unsigned short samples, unsigned short freq, char unknown); // play with conversion?
-int sceAudio_5C37C0AE(void); // end play?
-int sceAudio_E0727056(int volume, void *buffer); // blocking output
-int sceAudioOutput2GetRestSample();
-
-
-unsigned char *PicoDraw2FB = (unsigned char *)VRAM_CACHED_STUFF + 8; // +8 to be able to skip border with 1 quadword..
-int engineStateSuspend;
-
-#define PICO_PEN_ADJUST_X 4
-#define PICO_PEN_ADJUST_Y 2
-static int pico_pen_x = 320/2, pico_pen_y = 240/2;
-
-static void sound_init(void);
-static void sound_deinit(void);
-static void blit2(const char *fps, const char *notice, int lagging_behind);
-static void clearArea(int full);
-
-int plat_get_root_dir(char *dst, int len)
-{
- if (len > 0) *dst = 0;
- return 0;
-}
-
-static void osd_text(int x, const char *text, int is_active, int clear_all)
-{
- unsigned short *screen = is_active ? psp_video_get_active_fb() : psp_screen;
- int len = clear_all ? (480 / 2) : (strlen(text) * 8 / 2);
- int *p, h;
- void *tmp;
- for (h = 0; h < 8; h++) {
- p = (int *) (screen+x+512*(264+h));
- p = (int *) ((int)p & ~3); // align
- memset32_uncached(p, 0, len);
- }
- if (is_active) { tmp = psp_screen; psp_screen = screen; } // nasty pointer tricks
- emu_text_out16(x, 264, text);
- if (is_active) psp_screen = tmp;
-}
-
-void emu_msg_cb(const char *msg)
-{
- osd_text(4, msg, 1, 1);
- noticeMsgTime = sceKernelGetSystemTimeLow() - 2000000;
-
- /* assumption: emu_msg_cb gets called only when something slow is about to happen */
- reset_timing = 1;
-}
-
-/* FIXME: move to plat */
-void emu_Init(void)
-{
- sound_init();
-}
-
-void emu_Deinit(void)
-{
- sound_deinit();
-}
-
-void pemu_prep_defconfig(void)
-{
- defaultConfig.s_PsndRate = 22050;
- defaultConfig.s_PicoCDBuffers = 64;
- defaultConfig.CPUclock = 333;
- defaultConfig.KeyBinds[ 4] = 1<<0; // SACB RLDU
- defaultConfig.KeyBinds[ 6] = 1<<1;
- defaultConfig.KeyBinds[ 7] = 1<<2;
- defaultConfig.KeyBinds[ 5] = 1<<3;
- defaultConfig.KeyBinds[14] = 1<<4;
- defaultConfig.KeyBinds[13] = 1<<5;
- defaultConfig.KeyBinds[15] = 1<<6;
- defaultConfig.KeyBinds[ 3] = 1<<7;
- defaultConfig.KeyBinds[12] = 1<<26; // switch rnd
- defaultConfig.KeyBinds[ 8] = 1<<27; // save state
- defaultConfig.KeyBinds[ 9] = 1<<28; // load state
- defaultConfig.KeyBinds[28] = 1<<0; // num "buttons"
- defaultConfig.KeyBinds[30] = 1<<1;
- defaultConfig.KeyBinds[31] = 1<<2;
- defaultConfig.KeyBinds[29] = 1<<3;
- defaultConfig.scaling = 1; // bilinear filtering for psp
- defaultConfig.scale = 1.20; // fullscreen
- defaultConfig.hscale40 = 1.25;
- defaultConfig.hscale32 = 1.56;
-}
-
-
-extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count);
-extern void amips_clut_6bit(unsigned short *dst, unsigned char *src, unsigned short *pal, int count);
-
-static void (*amips_clut_f)(unsigned short *dst, unsigned char *src, unsigned short *pal, int count) = NULL;
-
-struct Vertex
-{
- short u,v;
- short x,y,z;
-};
-
-static struct Vertex __attribute__((aligned(4))) g_vertices[2];
-static unsigned short __attribute__((aligned(16))) localPal[0x100];
-static int dynamic_palette = 0, need_pal_upload = 0, blit_16bit_mode = 0;
-static int fbimg_offs = 0;
-
-static void set_scaling_params(void)
-{
- int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs, border_hack = 0;
- g_vertices[0].x = g_vertices[0].y =
- g_vertices[0].z = g_vertices[1].z = 0;
-
- fbimg_height = (int)(240.0 * currentConfig.scale + 0.5);
- if (Pico.video.reg[12] & 1) {
- fbimg_width = (int)(320.0 * currentConfig.scale * currentConfig.hscale40 + 0.5);
- src_width = 320;
- } else {
- fbimg_width = (int)(256.0 * currentConfig.scale * currentConfig.hscale32 + 0.5);
- src_width = 256;
- }
-
- if (fbimg_width & 1) fbimg_width++; // make even
- if (fbimg_height & 1) fbimg_height++;
-
- if (fbimg_width >= 480) {
- g_vertices[0].u = (fbimg_width-480)/2;
- g_vertices[1].u = src_width - (fbimg_width-480)/2 - 1;
- fbimg_width = 480;
- fbimg_xoffs = 0;
- } else {
- g_vertices[0].u = 0;
- g_vertices[1].u = src_width;
- fbimg_xoffs = 240 - fbimg_width/2;
- }
- if (fbimg_width > 320 && fbimg_width <= 480) border_hack = 1;
-
- if (fbimg_height >= 272) {
- g_vertices[0].v = (fbimg_height-272)/2;
- g_vertices[1].v = 240 - (fbimg_height-272)/2;
- fbimg_height = 272;
- fbimg_yoffs = 0;
- } else {
- g_vertices[0].v = 0;
- g_vertices[1].v = 240;
- fbimg_yoffs = 136 - fbimg_height/2;
- }
-
- g_vertices[1].x = fbimg_width;
- g_vertices[1].y = fbimg_height;
- if (fbimg_xoffs < 0) fbimg_xoffs = 0;
- if (fbimg_yoffs < 0) fbimg_yoffs = 0;
- if (border_hack) {
- g_vertices[0].u++;
- g_vertices[0].x++;
- g_vertices[1].u--;
- g_vertices[1].x--;
- }
- fbimg_offs = (fbimg_yoffs*512 + fbimg_xoffs) * 2; // dst is always 16bit
-
- /*
- lprintf("set_scaling_params:\n");
- lprintf("offs: %i, %i\n", fbimg_xoffs, fbimg_yoffs);
- lprintf("xy0, xy1: %i, %i; %i, %i\n", g_vertices[0].x, g_vertices[0].y, g_vertices[1].x, g_vertices[1].y);
- lprintf("uv0, uv1: %i, %i; %i, %i\n", g_vertices[0].u, g_vertices[0].v, g_vertices[1].u, g_vertices[1].v);
- */
-}
-
-static void do_pal_update(int allow_sh, int allow_as)
-{
- unsigned int *dpal=(void *)localPal;
- int i;
-
- //for (i = 0x3f/2; i >= 0; i--)
- // dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4);
- do_pal_convert(localPal, Pico.cram, currentConfig.gamma, currentConfig.gamma2);
-
- Pico.m.dirtyPal = 0;
- need_pal_upload = 1;
-
- if (allow_sh && (Pico.video.reg[0xC]&8)) // shadow/hilight?
- {
- // shadowed pixels
- for (i = 0x3f/2; i >= 0; i--)
- dpal[0x20|i] = dpal[0x60|i] = (dpal[i]>>1)&0x7bcf7bcf;
- // hilighted pixels
- for (i = 0x3f; i >= 0; i--) {
- int t=localPal[i]&0xf79e;t+=0x4208;
- if (t&0x20) t|=0x1e;
- if (t&0x800) t|=0x780;
- if (t&0x10000) t|=0xf000;
- t&=0xf79e;
- localPal[0x80|i]=(unsigned short)t;
- }
- localPal[0xe0] = 0;
- localPal[0xf0] = 0x001f;
- }
- else if (allow_as && (rendstatus & PDRAW_SPR_LO_ON_HI))
- {
- memcpy32((int *)dpal+0x80/2, (void *)localPal, 0x40*2/4);
- }
-}
-
-static void do_slowmode_lines(int line_to)
-{
- int line = 0, line_len = (Pico.video.reg[12]&1) ? 320 : 256;
- unsigned short *dst = (unsigned short *)VRAM_STUFF + 512*240/2;
- unsigned char *src = (unsigned char *)VRAM_CACHED_STUFF + 16;
- if (!(Pico.video.reg[1]&8)) { line = 8; dst += 512*8; src += 512*8; }
-
- for (; line < line_to; line++, dst+=512, src+=512)
- amips_clut_f(dst, src, localPal, line_len);
-}
-
-static void EmuScanPrepare(void)
-{
- HighCol = (unsigned char *)VRAM_CACHED_STUFF + 8;
- if (!(Pico.video.reg[1]&8)) HighCol += 8*512;
-
- if (dynamic_palette > 0)
- dynamic_palette--;
-
- if (Pico.m.dirtyPal)
- do_pal_update(1, 1);
- if ((rendstatus & PDRAW_SPR_LO_ON_HI) && !(Pico.video.reg[0xC]&8))
- amips_clut_f = amips_clut_6bit;
- else amips_clut_f = amips_clut;
-}
-
-static int EmuScanSlowBegin(unsigned int num)
-{
- if (!dynamic_palette)
- HighCol = (unsigned char *)VRAM_CACHED_STUFF + num * 512 + 8;
-
- return 0;
-}
-
-static int EmuScanSlowEnd(unsigned int num)
-{
- if (Pico.m.dirtyPal) {
- if (!dynamic_palette) {
- do_slowmode_lines(num);
- dynamic_palette = 3; // last for 2 more frames
- }
- do_pal_update(1, 1);
- }
-
- if (dynamic_palette) {
- int line_len = (Pico.video.reg[12]&1) ? 320 : 256;
- void *dst = (char *)VRAM_STUFF + 512*240 + 512*2*num;
- amips_clut_f(dst, HighCol + 8, localPal, line_len);
- }
-
- return 0;
-}
-
-static void blitscreen_clut(void)
-{
- int offs = fbimg_offs;
- offs += (psp_screen == VRAM_FB0) ? VRAMOFFS_FB0 : VRAMOFFS_FB1;
-
- sceGuSync(0,0); // sync with prev
- sceGuStart(GU_DIRECT, guCmdList);
- sceGuDrawBuffer(GU_PSM_5650, (void *)offs, 512); // point to back buffer
-
- if (dynamic_palette)
- {
- if (!blit_16bit_mode) { // the current mode is not 16bit
- sceGuTexMode(GU_PSM_5650, 0, 0, 0);
- sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 512*240);
-
- blit_16bit_mode = 1;
- }
- }
- else
- {
- if (blit_16bit_mode) {
- sceGuClutMode(GU_PSM_5650,0,0xff,0);
- sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image
- sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16);
- blit_16bit_mode = 0;
- }
-
- if ((PicoOpt&0x10) && Pico.m.dirtyPal)
- do_pal_update(0, 0);
-
- sceKernelDcacheWritebackAll();
-
- if (need_pal_upload) {
- need_pal_upload = 0;
- sceGuClutLoad((256/8), localPal); // upload 32*8 entries (256)
- }
- }
-
-#if 1
- if (g_vertices[0].u == 0 && g_vertices[1].u == g_vertices[1].x)
- {
- struct Vertex* vertices;
- int x;
-
- #define SLICE_WIDTH 32
- for (x = 0; x < g_vertices[1].x; x += SLICE_WIDTH)
- {
- // render sprite
- vertices = (struct Vertex*)sceGuGetMemory(2 * sizeof(struct Vertex));
- memcpy(vertices, g_vertices, 2 * sizeof(struct Vertex));
- vertices[0].u = vertices[0].x = x;
- vertices[1].u = vertices[1].x = x + SLICE_WIDTH;
- sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,vertices);
- }
- // lprintf("listlen: %iB\n", sceGuCheckList()); // ~480 only
- }
- else
-#endif
- sceGuDrawArray(GU_SPRITES,GU_TEXTURE_16BIT|GU_VERTEX_16BIT|GU_TRANSFORM_2D,2,0,g_vertices);
-
- sceGuFinish();
-}
-
-
-static void cd_leds(void)
-{
- unsigned int reg, col_g, col_r, *p;
-
- reg = Pico_mcd->s68k_regs[0];
-
- p = (unsigned int *)((short *)psp_screen + 512*2+4+2);
- col_g = (reg & 2) ? 0x06000600 : 0;
- col_r = (reg & 1) ? 0x00180018 : 0;
- *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 512/2 - 12/2;
- *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 512/2 - 12/2;
- *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r;
-}
-
-static void draw_pico_ptr(void)
-{
- unsigned char *p = (unsigned char *)VRAM_STUFF + 16;
-
- // only if pen enabled and for 8bit mode
- if (pico_inp_mode == 0 || blit_16bit_mode) return;
-
- p += 512 * (pico_pen_y + PICO_PEN_ADJUST_Y);
- p += pico_pen_x + PICO_PEN_ADJUST_X;
- p[ -1] = 0xe0; p[ 0] = 0xf0; p[ 1] = 0xe0;
- p[ 511] = 0xf0; p[ 512] = 0xf0; p[ 513] = 0xf0;
- p[1023] = 0xe0; p[1024] = 0xf0; p[1025] = 0xe0;
-}
-
-
-#if 0
-static void dbg_text(void)
-{
- int *p, h, len;
- char text[128];
-
- sprintf(text, "sl: %i, 16b: %i", g_vertices[0].u == 0 && g_vertices[1].u == g_vertices[1].x, blit_16bit_mode);
- len = strlen(text) * 8 / 2;
- for (h = 0; h < 8; h++) {
- p = (int *) ((unsigned short *) psp_screen+2+512*(256+h));
- p = (int *) ((int)p & ~3); // align
- memset32_uncached(p, 0, len);
- }
- emu_text_out16(2, 256, text);
-}
-#endif
-
-/* called after rendering is done, but frame emulation is not finished */
-void blit1(void)
-{
- if (PicoOpt&0x10)
- {
- int i;
- unsigned char *pd;
- // clear top and bottom trash
- for (pd = PicoDraw2FB+8, i = 8; i > 0; i--, pd += 512)
- memset32((int *)pd, 0xe0e0e0e0, 320/4);
- for (pd = PicoDraw2FB+512*232+8, i = 8; i > 0; i--, pd += 512)
- memset32((int *)pd, 0xe0e0e0e0, 320/4);
- }
-
- if (PicoAHW & PAHW_PICO)
- draw_pico_ptr();
-
- blitscreen_clut();
-}
-
-
-static void blit2(const char *fps, const char *notice, int lagging_behind)
-{
- int vsync = 0, emu_opt = currentConfig.EmuOpt;
-
- if (notice || (emu_opt & 2)) {
- if (notice) osd_text(4, notice, 0, 0);
- if (emu_opt & 2) osd_text(OSD_FPS_X, fps, 0, 0);
- }
-
- //dbg_text();
-
- if ((emu_opt & 0x400) && (PicoAHW & PAHW_MCD))
- cd_leds();
-
- if (currentConfig.EmuOpt & 0x2000) { // want vsync
- if (!(currentConfig.EmuOpt & 0x10000) || !lagging_behind) vsync = 1;
- }
-
- psp_video_flip(vsync);
-}
-
-// clears whole screen or just the notice area (in all buffers)
-static void clearArea(int full)
-{
- if (full) {
- memset32_uncached(psp_screen, 0, 512*272*2/4);
- psp_video_flip(0);
- memset32_uncached(psp_screen, 0, 512*272*2/4);
- memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*240/4);
- memset32((int *)VRAM_CACHED_STUFF+512*240/4, 0, 512*240*2/4);
- } else {
- void *fb = psp_video_get_active_fb();
- memset32_uncached((int *)((char *)psp_screen + 512*264*2), 0, 512*8*2/4);
- memset32_uncached((int *)((char *)fb + 512*264*2), 0, 512*8*2/4);
- }
-}
-
-static void vidResetMode(void)
-{
- // setup GU
- sceGuSync(0,0); // sync with prev
- sceGuStart(GU_DIRECT, guCmdList);
-
- sceGuClutMode(GU_PSM_5650,0,0xff,0);
- sceGuTexMode(GU_PSM_T8,0,0,0); // 8-bit image
- sceGuTexFunc(GU_TFX_REPLACE,GU_TCC_RGB);
- if (currentConfig.scaling)
- sceGuTexFilter(GU_LINEAR, GU_LINEAR);
- else sceGuTexFilter(GU_NEAREST, GU_NEAREST);
- sceGuTexScale(1.0f,1.0f);
- sceGuTexOffset(0.0f,0.0f);
-
- sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16);
-
- // slow rend.
- PicoDrawSetOutFormat(PDF_NONE, 0);
- PicoDrawSetCallbacks(EmuScanSlowBegin, EmuScanSlowEnd);
-
- localPal[0xe0] = 0;
- localPal[0xf0] = 0x001f;
- Pico.m.dirtyPal = 1;
- blit_16bit_mode = dynamic_palette = 0;
-
- sceGuFinish();
- set_scaling_params();
- sceGuSync(0,0);
-}
-
-void plat_debug_cat(char *str)
-{
- strcat(str, blit_16bit_mode ? "soft clut\n" : "hard clut\n");
-}
-
-
-/* sound stuff */
-#define SOUND_BLOCK_SIZE_NTSC (1470*2) // 1024 // 1152
-#define SOUND_BLOCK_SIZE_PAL (1764*2)
-#define SOUND_BLOCK_COUNT 8
-
-static short __attribute__((aligned(4))) sndBuffer[SOUND_BLOCK_SIZE_PAL*SOUND_BLOCK_COUNT + 44100/50*2];
-static short *snd_playptr = NULL, *sndBuffer_endptr = NULL;
-static int samples_made = 0, samples_done = 0, samples_block = 0;
-static int sound_thread_exit = 0;
-static SceUID sound_sem = -1;
-
-static void writeSound(int len);
-
-static int sound_thread(SceSize args, void *argp)
-{
- int ret = 0;
-
- lprintf("sthr: started, priority %i\n", sceKernelGetThreadCurrentPriority());
-
- while (!sound_thread_exit)
- {
- if (samples_made - samples_done < samples_block) {
- // wait for data (use at least 2 blocks)
- //lprintf("sthr: wait... (%i)\n", samples_made - samples_done);
- while (samples_made - samples_done <= samples_block*2 && !sound_thread_exit)
- ret = sceKernelWaitSema(sound_sem, 1, 0);
- if (ret < 0) lprintf("sthr: sceKernelWaitSema: %i\n", ret);
- continue;
- }
-
- // lprintf("sthr: got data: %i\n", samples_made - samples_done);
-
- ret = sceAudio_E0727056(PSP_AUDIO_VOLUME_MAX, snd_playptr);
-
- samples_done += samples_block;
- snd_playptr += samples_block;
- if (snd_playptr >= sndBuffer_endptr)
- snd_playptr = sndBuffer;
- // 1.5 kernel returns 0, newer ones return # of samples queued
- if (ret < 0)
- lprintf("sthr: sceAudio_E0727056: %08x; pos %i/%i\n", ret, samples_done, samples_made);
-
- // shouln't happen, but just in case
- if (samples_made - samples_done >= samples_block*3) {
- //lprintf("sthr: block skip (%i)\n", samples_made - samples_done);
- samples_done += samples_block; // skip
- snd_playptr += samples_block;
- }
-
- }
-
- lprintf("sthr: exit\n");
- sceKernelExitDeleteThread(0);
- return 0;
-}
-
-static void sound_init(void)
-{
- SceUID thid;
- int ret;
-
- sound_sem = sceKernelCreateSema("sndsem", 0, 0, 1, NULL);
- if (sound_sem < 0) lprintf("sceKernelCreateSema() failed: %i\n", sound_sem);
-
- samples_made = samples_done = 0;
- samples_block = SOUND_BLOCK_SIZE_NTSC; // make sure it goes to sema
- sound_thread_exit = 0;
- thid = sceKernelCreateThread("sndthread", sound_thread, 0x12, 0x10000, 0, NULL);
- if (thid >= 0)
- {
- ret = sceKernelStartThread(thid, 0, 0);
- if (ret < 0) lprintf("sound_init: sceKernelStartThread returned %08x\n", ret);
- }
- else
- lprintf("sceKernelCreateThread failed: %i\n", thid);
-}
-
-void pemu_sound_start(void)
-{
- static int PsndRate_old = 0, PicoOpt_old = 0, pal_old = 0;
- int ret, stereo;
-
- samples_made = samples_done = 0;
-
- if (PsndRate != PsndRate_old || (PicoOpt&0x0b) != (PicoOpt_old&0x0b) || Pico.m.pal != pal_old) {
- PsndRerate(Pico.m.frame_count ? 1 : 0);
- }
- stereo=(PicoOpt&8)>>3;
-
- samples_block = Pico.m.pal ? SOUND_BLOCK_SIZE_PAL : SOUND_BLOCK_SIZE_NTSC;
- if (PsndRate <= 22050) samples_block /= 2;
- sndBuffer_endptr = &sndBuffer[samples_block*SOUND_BLOCK_COUNT];
-
- lprintf("starting audio: %i, len: %i, stereo: %i, pal: %i, block samples: %i\n",
- PsndRate, PsndLen, stereo, Pico.m.pal, samples_block);
-
- // while (sceAudioOutput2GetRestSample() > 0) psp_msleep(100);
- // sceAudio_5C37C0AE();
- ret = sceAudio_38553111(samples_block/2, PsndRate, 2); // seems to not need that stupid 64byte alignment
- if (ret < 0) {
- lprintf("sceAudio_38553111() failed: %i\n", ret);
- emu_status_msg("sound init failed (%i), snd disabled", ret);
- currentConfig.EmuOpt &= ~EOPT_EN_SOUND;
- } else {
- PicoWriteSound = writeSound;
- memset32((int *)(void *)sndBuffer, 0, sizeof(sndBuffer)/4);
- snd_playptr = sndBuffer_endptr - samples_block;
- samples_made = samples_block; // send 1 empty block first..
- PsndOut = sndBuffer;
- PsndRate_old = PsndRate;
- PicoOpt_old = PicoOpt;
- pal_old = Pico.m.pal;
- }
-}
-
-void pemu_sound_stop(void)
-{
- int i;
- if (samples_done == 0)
- {
- // if no data is written between sceAudio_38553111 and sceAudio_5C37C0AE calls,
- // we get a deadlock on next sceAudio_38553111 call
- // so this is yet another workaround:
- memset32((int *)(void *)sndBuffer, 0, samples_block*4/4);
- samples_made = samples_block * 3;
- sceKernelSignalSema(sound_sem, 1);
- }
- sceKernelDelayThread(100*1000);
- samples_made = samples_done = 0;
- for (i = 0; sceAudioOutput2GetRestSample() > 0 && i < 16; i++)
- psp_msleep(100);
- sceAudio_5C37C0AE();
-}
-
-/* wait until we can write more sound */
-void pemu_sound_wait(void)
-{
- // TODO: test this
- while (!sound_thread_exit && samples_made - samples_done > samples_block * 4)
- psp_msleep(10);
-}
-
-static void sound_deinit(void)
-{
- sound_thread_exit = 1;
- sceKernelSignalSema(sound_sem, 1);
- sceKernelDeleteSema(sound_sem);
- sound_sem = -1;
-}
-
-static void writeSound(int len)
-{
- int ret;
-
- PsndOut += len / 2;
- /*if (PsndOut > sndBuffer_endptr) {
- memcpy32((int *)(void *)sndBuffer, (int *)endptr, (PsndOut - endptr + 1) / 2);
- PsndOut = &sndBuffer[PsndOut - endptr];
- lprintf("mov\n");
- }
- else*/
- if (PsndOut > sndBuffer_endptr) lprintf("snd oflow %i!\n", PsndOut - sndBuffer_endptr);
- if (PsndOut >= sndBuffer_endptr)
- PsndOut = sndBuffer;
-
- // signal the snd thread
- samples_made += len / 2;
- if (samples_made - samples_done > samples_block*2) {
- // lprintf("signal, %i/%i\n", samples_done, samples_made);
- ret = sceKernelSignalSema(sound_sem, 1);
- //if (ret < 0) lprintf("snd signal ret %08x\n", ret);
- }
-}
-
-
-static void SkipFrame(void)
-{
- PicoSkipFrame=1;
- PicoFrame();
- PicoSkipFrame=0;
-}
-
-void pemu_forced_frame(int no_scale, int do_emu)
-{
- int po_old = PicoOpt;
- int eo_old = currentConfig.EmuOpt;
-
- PicoOpt &= ~POPT_ALT_RENDERER;
- PicoOpt |= POPT_ACC_SPRITES;
- if (!no_scale)
- PicoOpt |= POPT_EN_SOFTSCALE;
- currentConfig.EmuOpt |= 0x80;
-
- vidResetMode();
- memset32(VRAM_CACHED_STUFF, 0xe0e0e0e0, 512*8/4); // borders
- memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4);
- memset32_uncached((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
-
- PicoDrawSetOutFormat(PDF_NONE, 0);
- PicoDrawSetCallbacks(EmuScanSlowBegin, EmuScanSlowEnd);
- EmuScanPrepare();
- PicoFrameDrawOnly();
- blit1();
- sceGuSync(0,0);
-
- PicoOpt = po_old;
- currentConfig.EmuOpt = eo_old;
-}
-
-
-static void RunEventsPico(unsigned int events, unsigned int keys)
-{
- emu_RunEventsPico(events);
-
- if (pico_inp_mode != 0)
- {
- PicoPad[0] &= ~0x0f; // release UDLR
- if (keys & PBTN_UP) { pico_pen_y--; if (pico_pen_y < 8) pico_pen_y = 8; }
- if (keys & PBTN_DOWN) { pico_pen_y++; if (pico_pen_y > 224-PICO_PEN_ADJUST_Y) pico_pen_y = 224-PICO_PEN_ADJUST_Y; }
- if (keys & PBTN_LEFT) { pico_pen_x--; if (pico_pen_x < 0) pico_pen_x = 0; }
- if (keys & PBTN_RIGHT) {
- int lim = (Pico.video.reg[12]&1) ? 319 : 255;
- pico_pen_x++;
- if (pico_pen_x > lim-PICO_PEN_ADJUST_X)
- pico_pen_x = lim-PICO_PEN_ADJUST_X;
- }
- PicoPicohw.pen_pos[0] = pico_pen_x;
- if (!(Pico.video.reg[12]&1)) PicoPicohw.pen_pos[0] += pico_pen_x/4;
- PicoPicohw.pen_pos[0] += 0x3c;
- PicoPicohw.pen_pos[1] = pico_inp_mode == 1 ? (0x2f8 + pico_pen_y) : (0x1fc + pico_pen_y);
- }
-}
-
-static void RunEvents(unsigned int which)
-{
- if (which & 0x1800) // save or load (but not both)
- {
- int do_it = 1;
-
- if ( emu_check_save_file(state_slot) &&
- (( (which & 0x1000) && (currentConfig.EmuOpt & 0x800)) || // load
- (!(which & 0x1000) && (currentConfig.EmuOpt & 0x200))) ) // save
- {
- int keys;
- sceGuSync(0,0);
- blit2("", (which & 0x1000) ? "LOAD STATE? (X=yes, O=no)" : "OVERWRITE SAVE? (X=yes, O=no)", 0);
- while( !((keys = psp_pad_read(1)) & (PBTN_X|PBTN_CIRCLE)) )
- psp_msleep(50);
- if (keys & PBTN_CIRCLE) do_it = 0;
- while( ((keys = psp_pad_read(1)) & (PBTN_X|PBTN_CIRCLE)) ) // wait for release
- psp_msleep(50);
- clearArea(0);
- }
-
- if (do_it)
- {
- osd_text(4, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME", 1, 0);
- PicoStateProgressCB = emu_msg_cb;
- emu_save_load_game((which & 0x1000) >> 12, 0);
- PicoStateProgressCB = NULL;
- psp_msleep(0);
- }
-
- reset_timing = 1;
- }
- if (which & 0x0400) // switch renderer
- {
- if (PicoOpt&0x10) { PicoOpt&=~0x10; currentConfig.EmuOpt |= 0x80; }
- else { PicoOpt|= 0x10; currentConfig.EmuOpt &= ~0x80; }
-
- vidResetMode();
-
- if (PicoOpt & POPT_ALT_RENDERER)
- emu_status_msg("fast renderer");
- else if (currentConfig.EmuOpt&0x80)
- emu_status_msg("accurate renderer");
- }
- if (which & 0x0300)
- {
- if(which&0x0200) {
- state_slot -= 1;
- if(state_slot < 0) state_slot = 9;
- } else {
- state_slot += 1;
- if(state_slot > 9) state_slot = 0;
- }
- emu_status_msg("SAVE SLOT %i [%s]", state_slot,
- emu_check_save_file(state_slot) ? "USED" : "FREE");
- }
-}
-
-static void updateKeys(void)
-{
- unsigned int keys, allActions[2] = { 0, 0 }, events;
- static unsigned int prevEvents = 0;
- int i;
-
- /* FIXME: port to input fw, merge with emu.c:emu_update_input() */
- keys = psp_pad_read(0);
- if (keys & PSP_CTRL_HOME)
- sceDisplayWaitVblankStart();
-
- if (keys & PBTN_SELECT)
- engineState = PGS_Menu;
-
- keys &= CONFIGURABLE_KEYS;
-
- PicoPad[0] = allActions[0] & 0xfff;
- PicoPad[1] = allActions[1] & 0xfff;
-
- if (allActions[0] & 0x7000) emu_DoTurbo(&PicoPad[0], allActions[0]);
- if (allActions[1] & 0x7000) emu_DoTurbo(&PicoPad[1], allActions[1]);
-
- events = (allActions[0] | allActions[1]) >> 16;
-
- if ((events ^ prevEvents) & 0x40) {
- emu_set_fastforward(events & 0x40);
- reset_timing = 1;
- }
-
- events &= ~prevEvents;
-
- if (PicoAHW == PAHW_PICO)
- RunEventsPico(events, keys);
- if (events) RunEvents(events);
- if (movie_data) emu_updateMovie();
-
- prevEvents = (allActions[0] | allActions[1]) >> 16;
-}
-
-
-static void simpleWait(unsigned int until)
-{
- unsigned int tval;
- int diff;
-
- tval = sceKernelGetSystemTimeLow();
- diff = (int)until - (int)tval;
- if (diff >= 512 && diff < 100*1024)
- sceKernelDelayThread(diff);
-}
-
-void pemu_loop(void)
-{
- static int mp3_init_done = 0;
- char fpsbuff[24]; // fps count c string
- unsigned int tval, tval_thissec = 0; // timing
- int target_fps, target_frametime, lim_time, tval_diff, i, oldmodes = 0;
- int pframes_done, pframes_shown; // "period" frames, used for sync
- int frames_done, frames_shown, tval_fpsc = 0; // actual frames
- char *notice = NULL;
-
- lprintf("entered emu_Loop()\n");
-
- fpsbuff[0] = 0;
-
- if (currentConfig.CPUclock != psp_get_cpu_clock()) {
- lprintf("setting cpu clock to %iMHz... ", currentConfig.CPUclock);
- i = psp_set_cpu_clock(currentConfig.CPUclock);
- lprintf(i ? "failed\n" : "done\n");
- currentConfig.CPUclock = psp_get_cpu_clock();
- }
-
- // make sure we are in correct mode
- vidResetMode();
- clearArea(1);
- Pico.m.dirtyPal = 1;
- oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc;
-
- // pal/ntsc might have changed, reset related stuff
- target_fps = Pico.m.pal ? 50 : 60;
- target_frametime = Pico.m.pal ? (1000000<<8)/50 : (1000000<<8)/60+1;
- reset_timing = 1;
-
- if (PicoAHW & PAHW_MCD) {
- // prepare CD buffer
- PicoCDBufferInit();
- // mp3...
- if (!mp3_init_done) {
- i = mp3_init();
- mp3_init_done = 1;
- if (i) { engineState = PGS_Menu; return; }
- }
- }
-
- // prepare sound stuff
- PsndOut = NULL;
- if (currentConfig.EmuOpt & EOPT_EN_SOUND)
- {
- pemu_sound_start();
- }
-
- sceDisplayWaitVblankStart();
- pframes_shown = pframes_done =
- frames_shown = frames_done = 0;
-
- tval_fpsc = sceKernelGetSystemTimeLow();
-
- // loop?
- while (engineState == PGS_Running)
- {
- int modes;
-
- tval = sceKernelGetSystemTimeLow();
- if (reset_timing || tval < tval_fpsc) {
- //stdbg("timing reset");
- reset_timing = 0;
- tval_thissec = tval;
- pframes_shown = pframes_done = 0;
- }
-
- // show notice message?
- if (noticeMsgTime) {
- static int noticeMsgSum;
- if (tval - noticeMsgTime > 2000000) { // > 2.0 sec
- noticeMsgTime = 0;
- clearArea(0);
- notice = 0;
- } else {
- int sum = noticeMsg[0]+noticeMsg[1]+noticeMsg[2];
- if (sum != noticeMsgSum) { clearArea(0); noticeMsgSum = sum; }
- notice = noticeMsg;
- }
- }
-
- // check for mode changes
- modes = ((Pico.video.reg[12]&1)<<2)|(Pico.video.reg[1]&8);
- if (modes != oldmodes) {
- oldmodes = modes;
- clearArea(1);
- set_scaling_params();
- }
-
- // second passed?
- if (tval - tval_fpsc >= 1000000)
- {
- if (currentConfig.EmuOpt & 2)
- sprintf(fpsbuff, "%02i/%02i ", frames_shown, frames_done);
- frames_done = frames_shown = 0;
- tval_fpsc += 1000000;
- }
-
- if (tval - tval_thissec >= 1000000)
- {
- // missing 1 frame?
- if (currentConfig.Frameskip < 0 && pframes_done < target_fps) {
- SkipFrame(); pframes_done++; frames_done++;
- }
-
- tval_thissec += 1000000;
-
- if (currentConfig.Frameskip < 0) {
- pframes_done -= target_fps; if (pframes_done < 0) pframes_done = 0;
- pframes_shown -= target_fps; if (pframes_shown < 0) pframes_shown = 0;
- if (pframes_shown > pframes_done) pframes_shown = pframes_done;
- } else {
- pframes_done = pframes_shown = 0;
- }
- }
-#ifdef PFRAMES
- sprintf(fpsbuff, "%i", Pico.m.frame_count);
-#endif
-
- lim_time = (pframes_done+1) * target_frametime;
- if (currentConfig.Frameskip >= 0) // frameskip enabled
- {
- for (i = 0; i < currentConfig.Frameskip; i++) {
- updateKeys();
- SkipFrame(); pframes_done++; frames_done++;
- if (!(currentConfig.EmuOpt&0x40000)) { // do framelimitting if needed
- int tval_diff;
- tval = sceKernelGetSystemTimeLow();
- tval_diff = (int)(tval - tval_thissec) << 8;
- if (tval_diff < lim_time) // we are too fast
- simpleWait(tval + ((lim_time - tval_diff)>>8));
- }
- lim_time += target_frametime;
- }
- }
- else // auto frameskip
- {
- int tval_diff;
- tval = sceKernelGetSystemTimeLow();
- tval_diff = (int)(tval - tval_thissec) << 8;
- if (tval_diff > lim_time && (pframes_done/16 < pframes_shown))
- {
- // no time left for this frame - skip
- if (tval_diff - lim_time >= (300000<<8)) {
- reset_timing = 1;
- continue;
- }
- updateKeys();
- SkipFrame(); pframes_done++; frames_done++;
- continue;
- }
- }
-
- updateKeys();
-
- if (!(PicoOpt&0x10))
- EmuScanPrepare();
-
- PicoFrame();
-
- sceGuSync(0,0);
-
- // check time
- tval = sceKernelGetSystemTimeLow();
- tval_diff = (int)(tval - tval_thissec) << 8;
-
- blit2(fpsbuff, notice, tval_diff > lim_time);
-
- if (currentConfig.Frameskip < 0 && tval_diff - lim_time >= (300000<<8)) { // slowdown detection
- reset_timing = 1;
- }
- else if (!(currentConfig.EmuOpt&0x40000) || currentConfig.Frameskip < 0)
- {
- // sleep if we are still too fast
- if (tval_diff < lim_time)
- {
- // we are too fast
- simpleWait(tval + ((lim_time - tval_diff) >> 8));
- }
- }
-
- pframes_done++; pframes_shown++;
- frames_done++; frames_shown++;
- }
-
-
- emu_set_fastforward(0);
-
- if (PicoAHW & PAHW_MCD) PicoCDBufferFree();
-
- if (PsndOut != NULL) {
- pemu_sound_stop();
- PsndOut = NULL;
- }
-
- // save SRAM
- if ((currentConfig.EmuOpt & 1) && SRam.changed) {
- emu_msg_cb("Writing SRAM/BRAM..");
- emu_save_load_game(0, 1);
- SRam.changed = 0;
- }
-
- // clear fps counters and stuff
- memset32_uncached((int *)psp_video_get_active_fb() + 512*264*2/4, 0, 512*8*2/4);
-}
-
-void emu_HandleResume(void)
-{
- if (!(PicoAHW & PAHW_MCD)) return;
-
- // reopen first CD track
- if (Pico_mcd->TOC.Tracks[0].F != NULL)
- {
- char *fname = rom_fname_reload;
- int len = strlen(rom_fname_reload);
- cue_data_t *cue_data = NULL;
-
- if (len > 4 && strcasecmp(fname + len - 4, ".cue") == 0)
- {
- cue_data = cue_parse(rom_fname_reload);
- if (cue_data != NULL)
- fname = cue_data->tracks[1].fname;
- }
-
- lprintf("emu_HandleResume: reopen %s\n", fname);
- pm_close(Pico_mcd->TOC.Tracks[0].F);
- Pico_mcd->TOC.Tracks[0].F = pm_open(fname);
- lprintf("reopen %s\n", Pico_mcd->TOC.Tracks[0].F != NULL ? "ok" : "failed");
-
- if (cue_data != NULL) cue_destroy(cue_data);
- }
-
- mp3_reopen_file();
-
- if (!(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1))
- cdda_start_play();
-}
-
+++ /dev/null
-// (c) Copyright 2006-2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-
-extern int engineStateSuspend;
-
-void emu_HandleResume(void);
-
-void emu_msg_cb(const char *msg);
-
-// actually comes from Pico/Misc_amips.s
-void memset32_uncached(int *dest, int c, int count);
-
+++ /dev/null
-// (c) Copyright 2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-#include <string.h>
-#include "psp.h"
-#include "emu.h"
-#include "menu.h"
-#include "mp3.h"
-#include "../common/menu.h"
-#include "../common/emu.h"
-#include "../common/config.h"
-#include "../common/lprintf.h"
-
-#ifdef GPROF
-#include <pspprof.h>
-#endif
-
-#ifdef GCOV
-#include <stdio.h>
-#include <stdlib.h>
-
-void dummy(void)
-{
- engineState = atoi(rom_fname_reload);
- setbuf(NULL, NULL);
- getenv(NULL);
-}
-#endif
-
-int pico_main(void)
-{
- psp_init();
-
- emu_prepareDefaultConfig();
- emu_ReadConfig(0, 0);
- config_readlrom(PicoConfigFile);
-
- emu_Init();
- menu_init();
- // moved to emu_Loop(), after CPU clock change..
- //mp3_init();
-
- engineState = PGS_Menu;
-
- for (;;)
- {
- switch (engineState)
- {
- case PGS_Menu:
-#ifndef GPROF
- menu_loop();
-#else
- strcpy(rom_fname_reload, rom_fname_loaded);
- engineState = PGS_ReloadRom;
-#endif
- break;
-
- case PGS_ReloadRom:
- if (emu_reload_rom(rom_fname_reload)) {
- engineState = PGS_Running;
- if (mp3_last_error != 0)
- engineState = PGS_Menu; // send to menu to display mp3 error
- } else {
- lprintf("PGS_ReloadRom == 0\n");
- engineState = PGS_Menu;
- }
- break;
-
- case PGS_Suspending:
- while (engineState == PGS_Suspending)
- psp_wait_suspend();
- break;
-
- case PGS_SuspendWake:
- psp_unhandled_suspend = 0;
- psp_resume_suspend();
- emu_HandleResume();
- engineState = engineStateSuspend;
- break;
-
- case PGS_RestartRun:
- engineState = PGS_Running;
-
- case PGS_Running:
- if (psp_unhandled_suspend) {
- psp_unhandled_suspend = 0;
- psp_resume_suspend();
- emu_HandleResume();
- break;
- }
- pemu_loop();
-#ifdef GPROF
- goto endloop;
-#endif
- break;
-
- case PGS_Quit:
- goto endloop;
-
- default:
- lprintf("engine got into unknown state (%i), exitting\n", engineState);
- goto endloop;
- }
- }
-
- endloop:
-
- mp3_deinit();
- emu_Deinit();
-#ifdef GPROF
- gprof_cleanup();
-#endif
-#ifndef GCOV
- psp_finish();
-#endif
-
- return 0;
-}
-
+++ /dev/null
-// (c) Copyright 2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-// don't like to use loads of #ifdefs, so duplicating GP2X code
-// horribly instead
-
-#include <string.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <unistd.h>
-#include <sys/syslimits.h> // PATH_MAX
-
-#include <pspdisplay.h>
-#include <pspgu.h>
-#include <pspiofilemgr.h>
-#include <psputils.h>
-
-#include "psp.h"
-#include "emu.h"
-#include "menu.h"
-#include "mp3.h"
-#include "../common/menu.h"
-#include "../common/emu.h"
-#include "../common/readpng.h"
-#include "../common/lprintf.h"
-#include "../common/input.h"
-#include "version.h"
-
-#include <pico/pico_int.h>
-#include <pico/patch.h>
-#include <zlib/zlib.h>
-
-
-#define pspKeyUnkn "???"
-const char * const keyNames[] = {
- "SELECT", pspKeyUnkn, pspKeyUnkn, "START", "UP", "RIGHT", "DOWN", "LEFT",
- "L", "R", pspKeyUnkn, pspKeyUnkn, "TRIANGLE", "CIRCLE", "X", "SQUARE",
- "HOME", "HOLD", "WLAN_UP", "REMOTE", "VOLUP", "VOLDOWN", "SCREEN", "NOTE",
- pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, pspKeyUnkn, "NUB UP", "NUB RIGHT", "NUB DOWN", "NUB LEFT" // fake
-};
-
-static unsigned short bg_buffer[480*272] __attribute__((aligned(16)));
-#define menu_screen psp_screen
-
-void menu_darken_bg(void *dst, const void *src, int pixels, int darker);
-static void menu_prepare_bg(int use_game_bg, int use_fg);
-
-
-static unsigned int inp_prev = 0;
-
-void menu_draw_begin(void)
-{
- // short *src = (short *)bg_buffer, *dst = (short *)menu_screen;
- // int i;
-
- // for (i = 272; i >= 0; i--, dst += 512, src += 480)
- // memcpy32((int *)dst, (int *)src, 480*2/4);
-
- sceGuSync(0,0); // sync with prev
- sceGuStart(GU_DIRECT, guCmdList);
- sceGuCopyImage(GU_PSM_5650, 0, 0, 480, 272, 480, bg_buffer, 0, 0, 512, menu_screen);
- sceGuFinish();
- sceGuSync(0,0);
-}
-
-
-void menu_draw_end(void)
-{
- psp_video_flip(1);
-}
-
-
-// --------- loading ROM screen ----------
-
-static int lcdr_line = 0;
-
-static void load_progress_cb(int percent)
-{
- int ln, len = percent * 480 / 100;
- unsigned short *dst;
-
- //sceDisplayWaitVblankStart();
-
- dst = (unsigned short *)menu_screen + 512*10*lcdr_line;
-
- if (len > 480) len = 480;
- for (ln = 8; ln > 0; ln--, dst += 512)
- memset(dst, 0xff, len*2);
-}
-
-static void cdload_progress_cb(int percent)
-{
- int ln, len = percent * 480 / 100;
- unsigned short *dst;
-
- if (lcdr_line <= 2) {
- lcdr_line++;
- smalltext_out16(1, lcdr_line++ * 10, "Processing CD image / MP3s", 0xffff);
- smalltext_out16_lim(1, lcdr_line++ * 10, romFileName, 0xffff, 80);
- }
-
- dst = (unsigned short *)menu_screen + 512*10*lcdr_line;
-
- if (len > 480) len = 480;
- for (ln = 8; ln > 0; ln--, dst += 512)
- memset(dst, 0xff, len*2);
-}
-
-void menu_romload_prepare(const char *rom_name)
-{
- const char *p = rom_name + strlen(rom_name);
- while (p > rom_name && *p != '/') p--;
-
- psp_video_switch_to_single();
- if (rom_loaded) menu_draw_begin();
- else memset32_uncached(psp_screen, 0, 512*272*2/4);
-
- smalltext_out16(1, 1, "Loading", 0xffff);
- smalltext_out16_lim(1, 10, p, 0xffff, 80);
- PicoCartLoadProgressCB = load_progress_cb;
- PicoCDLoadProgressCB = cdload_progress_cb;
- lcdr_line = 2;
-}
-
-void menu_romload_end(void)
-{
- PicoCartLoadProgressCB = PicoCDLoadProgressCB = NULL;
- smalltext_out16(1, ++lcdr_line*10, "Starting emulation...", 0xffff);
-}
-
-// -------------- ROM selector --------------
-
-struct my_dirent
-{
- unsigned int d_type;
- char d_name[255];
-};
-
-// bbbb bggg gggr rrrr
-static unsigned short file2color(const char *fname)
-{
- const char *ext = fname + strlen(fname) - 3;
- static const char *rom_exts[] = { "zip", "bin", "smd", "gen", "iso", "cso", "cue" };
- static const char *other_exts[] = { "gmv", "pat" };
- int i;
-
- if (ext < fname) ext = fname;
- for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++)
- if (strcasecmp(ext, rom_exts[i]) == 0) return 0xfdf7;
- for (i = 0; i < sizeof(other_exts)/sizeof(other_exts[0]); i++)
- if (strcasecmp(ext, other_exts[i]) == 0) return 0xaff5;
- return 0xffff;
-}
-
-static void draw_dirlist(char *curdir, struct my_dirent **namelist, int n, int sel)
-{
- int start, i, pos;
-
- start = 13 - sel;
- n--; // exclude current dir (".")
-
- menu_draw_begin();
-
- if (!rom_loaded) {
-// menu_darken_bg(menu_screen, menu_screen, 321*240, 0);
- }
-
- menu_darken_bg((char *)menu_screen + 512*129*2, (char *)menu_screen + 512*129*2, 512*10, 0);
-
- if (start - 2 >= 0)
- smalltext_out16_lim(14, (start - 2)*10, curdir, 0xffff, 53-2);
- for (i = 0; i < n; i++) {
- pos = start + i;
- if (pos < 0) continue;
- if (pos > 26) break;
- if (namelist[i+1]->d_type & FIO_S_IFDIR) {
- smalltext_out16_lim(14, pos*10, "/", 0xd7ff, 1);
- smalltext_out16_lim(14+6, pos*10, namelist[i+1]->d_name, 0xd7ff, 80-3);
- } else {
- unsigned short color = file2color(namelist[i+1]->d_name);
- smalltext_out16_lim(14, pos*10, namelist[i+1]->d_name, color, 80-2);
- }
- }
- text_out16(5, 130, ">");
- menu_draw_end();
-}
-
-static int scandir_cmp(const void *p1, const void *p2)
-{
- struct my_dirent **d1 = (struct my_dirent **)p1, **d2 = (struct my_dirent **)p2;
- if ((*d1)->d_type & (*d2)->d_type & FIO_S_IFDIR)
- return strcasecmp((*d1)->d_name, (*d2)->d_name);
- if ((*d1)->d_type & FIO_S_IFDIR) return -1; // put before
- if ((*d2)->d_type & FIO_S_IFDIR) return 1;
- return strcasecmp((*d1)->d_name, (*d2)->d_name);
-}
-
-static char *filter_exts[] = {
- ".mp3", ".srm", ".brm", "s.gz", ".mds", "bcfg", ".txt", ".htm", "html",
- ".jpg", ".pbp"
-};
-
-static int scandir_filter(const struct my_dirent *ent)
-{
- const char *p;
- int i;
-
- if (ent == NULL || ent->d_name == NULL) return 0;
- if (strlen(ent->d_name) < 5) return 1;
-
- p = ent->d_name + strlen(ent->d_name) - 4;
-
- for (i = 0; i < sizeof(filter_exts)/sizeof(filter_exts[0]); i++)
- {
- if (strcasecmp(p, filter_exts[i]) == 0) return 0;
- }
-
- return 1;
-}
-
-static int my_scandir(const char *dir, struct my_dirent ***namelist_out,
- int(*filter)(const struct my_dirent *),
- int(*compar)(const void *, const void *))
-{
- int ret = -1, dir_uid = -1, name_alloc = 4, name_count = 0;
- struct my_dirent **namelist = NULL, *ent;
- SceIoDirent sce_ent;
-
- namelist = malloc(sizeof(*namelist) * name_alloc);
- if (namelist == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
-
- // try to read first..
- dir_uid = sceIoDopen(dir);
- if (dir_uid >= 0)
- {
- /* it is very important to clear SceIoDirent to be passed to sceIoDread(), */
- /* or else it may crash, probably misinterpreting something in it. */
- memset(&sce_ent, 0, sizeof(sce_ent));
- ret = sceIoDread(dir_uid, &sce_ent);
- if (ret < 0)
- {
- lprintf("sceIoDread(\"%s\") failed with %i\n", dir, ret);
- goto fail;
- }
- }
- else
- lprintf("sceIoDopen(\"%s\") failed with %i\n", dir, dir_uid);
-
- while (ret > 0)
- {
- ent = malloc(sizeof(*ent));
- if (ent == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
- ent->d_type = sce_ent.d_stat.st_mode;
- strncpy(ent->d_name, sce_ent.d_name, sizeof(ent->d_name));
- ent->d_name[sizeof(ent->d_name)-1] = 0;
- if (filter == NULL || filter(ent))
- namelist[name_count++] = ent;
- else free(ent);
-
- if (name_count >= name_alloc)
- {
- void *tmp;
- name_alloc *= 2;
- tmp = realloc(namelist, sizeof(*namelist) * name_alloc);
- if (tmp == NULL) { lprintf("%s:%i: OOM\n", __FILE__, __LINE__); goto fail; }
- namelist = tmp;
- }
-
- memset(&sce_ent, 0, sizeof(sce_ent));
- ret = sceIoDread(dir_uid, &sce_ent);
- }
-
- // sort
- if (compar != NULL && name_count > 3) qsort(&namelist[2], name_count - 2, sizeof(namelist[0]), compar);
-
- // all done.
- ret = name_count;
- *namelist_out = namelist;
- goto end;
-
-fail:
- if (namelist != NULL)
- {
- while (name_count--)
- free(namelist[name_count]);
- free(namelist);
- }
-end:
- if (dir_uid >= 0) sceIoDclose(dir_uid);
- return ret;
-}
-
-
-static SceIoStat cpstat;
-
-static char *romsel_loop(char *curr_path)
-{
- struct my_dirent **namelist;
- int n, iret, sel = 0;
- unsigned long inp = 0;
- char *ret = NULL, *fname = NULL;
-
- // is this a dir or a full path?
- memset(&cpstat, 0, sizeof(cpstat));
- iret = sceIoGetstat(curr_path, &cpstat);
- if (iret >= 0 && (cpstat.st_mode & FIO_S_IFDIR)); // dir
- else if (iret >= 0 && (cpstat.st_mode & FIO_S_IFREG)) { // file
- char *p;
- for (p = curr_path + strlen(curr_path) - 1; p > curr_path && *p != '/'; p--);
- if (p > curr_path) {
- *p = 0;
- fname = p+1;
- }
- else strcpy(curr_path, "ms0:/");
- }
- else strcpy(curr_path, "ms0:/"); // something else
-
- n = my_scandir(curr_path, &namelist, scandir_filter, scandir_cmp);
- if (n < 0) {
- // try root..
- n = my_scandir("ms0:/", &namelist, scandir_filter, scandir_cmp);
- if (n < 0) {
- // oops, we failed
- lprintf("scandir failed, dir: "); lprintf(curr_path); lprintf("\n");
- return NULL;
- }
- }
-
- // try to find sel
- if (fname != NULL) {
- int i;
- for (i = 1; i < n; i++) {
- if (strcmp(namelist[i]->d_name, fname) == 0) {
- sel = i - 1;
- break;
- }
- }
- }
-
- for (;;)
- {
- draw_dirlist(curr_path, namelist, n, sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R|PBTN_X|PBTN_CIRCLE, 0);
- if(inp & PBTN_UP ) { sel--; if (sel < 0) sel = n-2; }
- if(inp & PBTN_DOWN) { sel++; if (sel > n-2) sel = 0; }
- if(inp & PBTN_LEFT) { sel-=10; if (sel < 0) sel = 0; }
- if(inp & PBTN_L) { sel-=24; if (sel < 0) sel = 0; }
- if(inp & PBTN_RIGHT) { sel+=10; if (sel > n-2) sel = n-2; }
- if(inp & PBTN_R) { sel+=24; if (sel > n-2) sel = n-2; }
- if(inp & PBTN_CIRCLE) // enter dir/select
- {
- if (namelist[sel+1]->d_type & FIO_S_IFDIR)
- {
- int newlen = strlen(curr_path) + strlen(namelist[sel+1]->d_name) + 2;
- char *p, *newdir = malloc(newlen);
- if (strcmp(namelist[sel+1]->d_name, "..") == 0) {
- char *start = curr_path;
- p = start + strlen(start) - 1;
- while (*p == '/' && p > start) p--;
- while (*p != '/' && *p != ':' && p > start) p--;
- if (p <= start || *p == ':') strcpy(newdir, "ms0:/");
- else { strncpy(newdir, start, p-start); newdir[p-start] = 0; }
- } else {
- strcpy(newdir, curr_path);
- p = newdir + strlen(newdir) - 1;
- while (*p == '/' && p >= newdir) *p-- = 0;
- strcat(newdir, "/");
- strcat(newdir, namelist[sel+1]->d_name);
- }
- ret = romsel_loop(newdir);
- free(newdir);
- break;
- }
- else if (namelist[sel+1]->d_type & FIO_S_IFREG)
- {
- strcpy(romFileName, curr_path);
- strcat(romFileName, "/");
- strcat(romFileName, namelist[sel+1]->d_name);
- ret = romFileName;
- break;
- }
- }
- if(inp & PBTN_X) break; // cancel
- }
-
- if (n > 0) {
- while(n--) free(namelist[n]);
- free(namelist);
- }
-
- return ret;
-}
-
-// ------------ patch/gg menu ------------
-
-static void draw_patchlist(int sel)
-{
- int start, i, pos, active;
-
- start = 13 - sel;
-
- menu_draw_begin();
-
- for (i = 0; i < PicoPatchCount; i++) {
- pos = start + i;
- if (pos < 0) continue;
- if (pos > 26) break;
- active = PicoPatches[i].active;
- smalltext_out16_lim(14, pos*10, active ? "ON " : "OFF", active ? 0xfff6 : 0xffff, 3);
- smalltext_out16_lim(14+6*4, pos*10, PicoPatches[i].name, active ? 0xfff6 : 0xffff, 53-6);
- }
- pos = start + i;
- if (pos < 27) smalltext_out16_lim(14, pos*10, "done", 0xffff, 4);
-
- text_out16(5, 130, ">");
- menu_draw_end();
-}
-
-
-static void patches_menu_loop(void)
-{
- int menu_sel = 0;
- unsigned long inp = 0;
-
- for(;;)
- {
- draw_patchlist(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_L|PBTN_R|PBTN_X|PBTN_CIRCLE, 0);
- if(inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = PicoPatchCount; }
- if(inp & PBTN_DOWN) { menu_sel++; if (menu_sel > PicoPatchCount) menu_sel = 0; }
- if(inp &(PBTN_LEFT|PBTN_L)) { menu_sel-=10; if (menu_sel < 0) menu_sel = 0; }
- if(inp &(PBTN_RIGHT|PBTN_R)) { menu_sel+=10; if (menu_sel > PicoPatchCount) menu_sel = PicoPatchCount; }
- if(inp & PBTN_CIRCLE) { // action
- if (menu_sel < PicoPatchCount)
- PicoPatches[menu_sel].active = !PicoPatches[menu_sel].active;
- else return;
- }
- if(inp & PBTN_X) return;
- }
-
-}
-
-// ------------ savestate loader ------------
-
-static int state_slot_flags = 0;
-
-static void state_check_slots(void)
-{
- int slot;
-
- state_slot_flags = 0;
-
- for (slot = 0; slot < 10; slot++)
- {
- if (emu_checkSaveFile(slot))
- {
- state_slot_flags |= 1 << slot;
- }
- }
-}
-
-static void *get_oldstate_for_preview(void)
-{
- unsigned char *ptr = malloc(sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram) + sizeof(Pico.video));
- if (ptr == NULL) return NULL;
-
- memcpy(ptr, Pico.vram, sizeof(Pico.vram));
- memcpy(ptr + sizeof(Pico.vram), Pico.cram, sizeof(Pico.cram));
- memcpy(ptr + sizeof(Pico.vram) + sizeof(Pico.cram), Pico.vsram, sizeof(Pico.vsram));
- memcpy(ptr + sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram), &Pico.video, sizeof(Pico.video));
- return ptr;
-}
-
-static void restore_oldstate(void *ptrx)
-{
- unsigned char *ptr = ptrx;
- memcpy(Pico.vram, ptr, sizeof(Pico.vram));
- memcpy(Pico.cram, ptr + sizeof(Pico.vram), sizeof(Pico.cram));
- memcpy(Pico.vsram, ptr + sizeof(Pico.vram) + sizeof(Pico.cram), sizeof(Pico.vsram));
- memcpy(&Pico.video,ptr + sizeof(Pico.vram) + sizeof(Pico.cram) + sizeof(Pico.vsram), sizeof(Pico.video));
- free(ptrx);
-}
-
-static void draw_savestate_bg(int slot)
-{
- void *file, *oldstate;
- char *fname;
-
- fname = emu_GetSaveFName(1, 0, slot);
- if (!fname) return;
-
- oldstate = get_oldstate_for_preview();
- if (oldstate == NULL) return;
-
- if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) {
- file = gzopen(fname, "rb");
- emu_setSaveStateCbs(1);
- } else {
- file = fopen(fname, "rb");
- emu_setSaveStateCbs(0);
- }
-
- if (file) {
- if (PicoAHW & PAHW_MCD) {
- PicoCdLoadStateGfx(file);
- } else {
- areaSeek(file, 0x10020, SEEK_SET); // skip header and RAM in state file
- areaRead(Pico.vram, 1, sizeof(Pico.vram), file);
- areaSeek(file, 0x2000, SEEK_CUR);
- areaRead(Pico.cram, 1, sizeof(Pico.cram), file);
- areaRead(Pico.vsram, 1, sizeof(Pico.vsram), file);
- areaSeek(file, 0x221a0, SEEK_SET);
- areaRead(&Pico.video, 1, sizeof(Pico.video), file);
- }
- areaClose(file);
- }
-
- emu_forcedFrame(0);
- menu_prepare_bg(1, 0);
-
- restore_oldstate(oldstate);
-}
-
-static void draw_savestate_menu(int menu_sel, int is_loading)
-{
- int tl_x = 80+25, tl_y = 16+60, y, i;
-
- if (state_slot_flags & (1 << menu_sel))
- draw_savestate_bg(menu_sel);
- menu_draw_begin();
-
- text_out16(tl_x, 16+30, is_loading ? "Load state" : "Save state");
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 108);
-
- /* draw all 10 slots */
- y = tl_y;
- for (i = 0; i < 10; i++, y+=10)
- {
- text_out16(tl_x, y, "SLOT %i (%s)", i, (state_slot_flags & (1 << i)) ? "USED" : "free");
- }
- text_out16(tl_x, y, "back");
-
- menu_draw_end();
-}
-
-static int savestate_menu_loop(int is_loading)
-{
- static int menu_sel = 10;
- int menu_sel_max = 10;
- unsigned long inp = 0;
-
- state_check_slots();
-
- for(;;)
- {
- draw_savestate_menu(menu_sel, is_loading);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_X|PBTN_CIRCLE, 0);
- if(inp & PBTN_UP ) {
- do {
- menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max;
- } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
- }
- if(inp & PBTN_DOWN) {
- do {
- menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0;
- } while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
- }
- if(inp & PBTN_CIRCLE) { // save/load
- if (menu_sel < 10) {
- state_slot = menu_sel;
- PicoStateProgressCB = emu_msg_cb; /* also suitable for menu */
- if (emu_SaveLoadGame(is_loading, 0)) {
- strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed");
- return 1;
- }
- return 0;
- } else return 1;
- }
- if(inp & PBTN_X) return 1;
- }
-}
-
-// -------------- key config --------------
-
-static char *action_binds(int player_idx, int action_mask)
-{
- static char strkeys[32*5];
- int i;
-
- strkeys[0] = 0;
- for (i = 0; i < 32; i++) // i is key index
- {
- if (currentConfig.KeyBinds[i] & action_mask)
- {
- if (player_idx >= 0 && ((currentConfig.KeyBinds[i] >> 16) & 3) != player_idx) continue;
- if (strkeys[0]) {
- strcat(strkeys, i >= 28 ? ", " : " + "); // nub "buttons" don't create combos
- strcat(strkeys, keyNames[i]);
- break;
- }
- else strcpy(strkeys, keyNames[i]);
- }
- }
-
- return strkeys;
-}
-
-static void unbind_action(int action)
-{
- int i;
-
- for (i = 0; i < 32; i++)
- currentConfig.KeyBinds[i] &= ~action;
-}
-
-static int count_bound_keys(int action, int pl_idx)
-{
- int i, keys = 0;
-
- for (i = 0; i < 32; i++)
- {
- if (pl_idx >= 0 && (currentConfig.KeyBinds[i]&0x30000) != (pl_idx<<16)) continue;
- if (currentConfig.KeyBinds[i] & action) keys++;
- }
-
- return keys;
-}
-
-static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_idx, int sel)
-{
- int x, y, tl_y = 16+20, i;
-
- menu_draw_begin();
- if (player_idx >= 0) {
- text_out16(80+80, 16, "Player %i controls", player_idx + 1);
- x = 80+80;
- } else {
- text_out16(80+80, 16, "Emulator controls");
- x = 80+40;
- }
-
- menu_draw_selection(x - 16, tl_y + sel*10, (player_idx >= 0) ? 66 : 130);
-
- y = tl_y;
- for (i = 0; i < opt_cnt; i++, y+=10)
- text_out16(x, y, "%s : %s", opts[i].name, action_binds(player_idx, opts[i].mask));
-
- text_out16(x, y, "Done");
-
- if (sel < opt_cnt) {
- text_out16(80+30, 220, "Press a button to bind/unbind");
- text_out16(80+30, 230, "Use SELECT to clear");
- text_out16(80+30, 240, "To bind UP/DOWN, hold SELECT");
- text_out16(80+30, 250, "Select \"Done\" to exit");
- } else {
- text_out16(80+30, 230, "Use Options -> Save cfg");
- text_out16(80+30, 240, "to save controls");
- text_out16(80+30, 250, "Press X or O to exit");
- }
- menu_draw_end();
-}
-
-static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_idx)
-{
- int sel = 0, menu_sel_max = opt_cnt, prev_select = 0, i;
- unsigned long inp = 0;
-
- for (;;)
- {
- draw_key_config(opts, opt_cnt, player_idx, sel);
- inp = in_menu_wait(CONFIGURABLE_KEYS|PBTN_SELECT, 1);
- if (!(inp & PBTN_SELECT)) {
- prev_select = 0;
- if(inp & PBTN_UP ) { sel--; if (sel < 0) sel = menu_sel_max; continue; }
- if(inp & PBTN_DOWN) { sel++; if (sel > menu_sel_max) sel = 0; continue; }
- }
- if (sel >= opt_cnt) {
- if (inp & (PBTN_X|PBTN_CIRCLE)) break;
- else continue;
- }
- // if we are here, we want to bind/unbind something
- if ((inp & PBTN_SELECT) && !prev_select)
- unbind_action(opts[sel].mask);
- prev_select = inp & PBTN_SELECT;
- inp &= CONFIGURABLE_KEYS;
- inp &= ~PBTN_SELECT;
- for (i = 0; i < 32; i++)
- if (inp & (1 << i)) {
- if (count_bound_keys(opts[sel].mask, player_idx) >= 2)
- currentConfig.KeyBinds[i] &= ~opts[sel].mask; // allow to unbind only
- else currentConfig.KeyBinds[i] ^= opts[sel].mask;
- if (player_idx >= 0 && (currentConfig.KeyBinds[i] & opts[sel].mask)) {
- currentConfig.KeyBinds[i] &= ~(3 << 16);
- currentConfig.KeyBinds[i] |= player_idx << 16;
- }
- }
- }
-}
-
-menu_entry ctrlopt_entries[] =
-{
- { "Player 1", MB_NONE, MA_CTRL_PLAYER1, NULL, 0, 0, 0, 1, 0 },
- { "Player 2", MB_NONE, MA_CTRL_PLAYER2, NULL, 0, 0, 0, 1, 0 },
- { "Emulator controls", MB_NONE, MA_CTRL_EMU, NULL, 0, 0, 0, 1, 0 },
- { "6 button pad", MB_ONOFF, MA_OPT_6BUTTON_PAD, &PicoOpt, 0x020, 0, 0, 1, 1 },
- { "Turbo rate", MB_RANGE, MA_CTRL_TURBO_RATE, ¤tConfig.turbo_rate, 0, 1, 30, 1, 1 },
- { "Done", MB_NONE, MA_CTRL_DONE, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define CTRLOPT_ENTRY_COUNT (sizeof(ctrlopt_entries) / sizeof(ctrlopt_entries[0]))
-const int ctrlopt_entry_count = CTRLOPT_ENTRY_COUNT;
-
-static void draw_kc_sel(int menu_sel)
-{
- int tl_x = 80+25+40, tl_y = 16+60, y;
-
- y = tl_y;
- menu_draw_begin();
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 138);
-
- me_draw(ctrlopt_entries, ctrlopt_entry_count, tl_x, tl_y, NULL, NULL);
-
- menu_draw_end();
-}
-
-
-// player2_flag, ?, ?, ?, ?, ?, ?, menu
-// "NEXT SAVE SLOT", "PREV SAVE SLOT", "SWITCH RENDERER", "SAVE STATE",
-// "LOAD STATE", "VOLUME UP", "VOLUME DOWN", "DONE"
-me_bind_action emuctrl_actions[] =
-{
- { "Load State ", 1<<28 },
- { "Save State ", 1<<27 },
- { "Prev Save Slot ", 1<<25 },
- { "Next Save Slot ", 1<<24 },
- { "Switch Renderer ", 1<<26 },
- { "Fast forward ", 1<<22 },
- { "Pico Next page ", 1<<21 },
- { "Pico Prev page ", 1<<20 },
- { "Pico Switch input", 1<<19 },
- { NULL, 0 }
-};
-
-static void kc_sel_loop(void)
-{
- int menu_sel = 5, menu_sel_max = 5;
- unsigned long inp = 0;
- menu_id selected_id;
-
- while (1)
- {
- draw_kc_sel(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
- selected_id = me_index2id(ctrlopt_entries, CTRLOPT_ENTRY_COUNT, menu_sel);
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) // multi choise
- me_process(ctrlopt_entries, CTRLOPT_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- if (inp & PBTN_CIRCLE) {
- int is_6button = PicoOpt & POPT_6BTN_PAD;
- switch (selected_id) {
- case MA_CTRL_PLAYER1: key_config_loop(me_ctrl_actions, is_6button ? 15 : 11, 0); return;
- case MA_CTRL_PLAYER2: key_config_loop(me_ctrl_actions, is_6button ? 15 : 11, 1); return;
- case MA_CTRL_EMU: key_config_loop(emuctrl_actions,
- sizeof(emuctrl_actions)/sizeof(emuctrl_actions[0]) - 1, -1); return;
- case MA_CTRL_DONE: if (!rom_loaded) emu_WriteConfig(0); return;
- default: return;
- }
- }
- if (inp & PBTN_X) return;
- }
-}
-
-
-// --------- sega/mega cd options ----------
-
-menu_entry cdopt_entries[] =
-{
- { NULL, MB_NONE, MA_CDOPT_TESTBIOS_USA, NULL, 0, 0, 0, 1, 0 },
- { NULL, MB_NONE, MA_CDOPT_TESTBIOS_EUR, NULL, 0, 0, 0, 1, 0 },
- { NULL, MB_NONE, MA_CDOPT_TESTBIOS_JAP, NULL, 0, 0, 0, 1, 0 },
- { "CD LEDs", MB_ONOFF, MA_CDOPT_LEDS, ¤tConfig.EmuOpt, 0x0400, 0, 0, 1, 1 },
- { "CDDA audio", MB_ONOFF, MA_CDOPT_CDDA, &PicoOpt, 0x0800, 0, 0, 1, 1 },
- { "PCM audio", MB_ONOFF, MA_CDOPT_PCM, &PicoOpt, 0x0400, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_CDOPT_READAHEAD, NULL, 0, 0, 0, 1, 1 },
- { "SaveRAM cart", MB_ONOFF, MA_CDOPT_SAVERAM, &PicoOpt, 0x8000, 0, 0, 1, 1 },
- { "Scale/Rot. fx (slow)", MB_ONOFF, MA_CDOPT_SCALEROT_CHIP,&PicoOpt, 0x1000, 0, 0, 1, 1 },
- { "Better sync (slow)", MB_ONOFF, MA_CDOPT_BETTER_SYNC, &PicoOpt, 0x2000, 0, 0, 1, 1 },
- { "done", MB_NONE, MA_CDOPT_DONE, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define CDOPT_ENTRY_COUNT (sizeof(cdopt_entries) / sizeof(cdopt_entries[0]))
-const int cdopt_entry_count = CDOPT_ENTRY_COUNT;
-
-
-struct bios_names_t
-{
- char us[32], eu[32], jp[32];
-};
-
-static void menu_cdopt_cust_draw(const menu_entry *entry, int x, int y, void *param)
-{
- struct bios_names_t *bios_names = param;
- char ra_buff[16];
-
- switch (entry->id)
- {
- case MA_CDOPT_TESTBIOS_USA: text_out16(x, y, "USA BIOS: %s", bios_names->us); break;
- case MA_CDOPT_TESTBIOS_EUR: text_out16(x, y, "EUR BIOS: %s", bios_names->eu); break;
- case MA_CDOPT_TESTBIOS_JAP: text_out16(x, y, "JAP BIOS: %s", bios_names->jp); break;
- case MA_CDOPT_READAHEAD:
- if (PicoCDBuffers > 1) sprintf(ra_buff, "%5iK", PicoCDBuffers * 2);
- else strcpy(ra_buff, " OFF");
- text_out16(x, y, "ReadAhead buffer %s", ra_buff);
- break;
- default:break;
- }
-}
-
-static void draw_cd_menu_options(int menu_sel, struct bios_names_t *bios_names)
-{
- int tl_x = 80+25, tl_y = 16+60;
- menu_id selected_id;
- char ra_buff[16];
-
- if (PicoCDBuffers > 1) sprintf(ra_buff, "%5iK", PicoCDBuffers * 2);
- else strcpy(ra_buff, " OFF");
-
- menu_draw_begin();
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 246);
-
- me_draw(cdopt_entries, CDOPT_ENTRY_COUNT, tl_x, tl_y, menu_cdopt_cust_draw, bios_names);
-
- selected_id = me_index2id(cdopt_entries, CDOPT_ENTRY_COUNT, menu_sel);
- if ((selected_id == MA_CDOPT_TESTBIOS_USA && strcmp(bios_names->us, "NOT FOUND")) ||
- (selected_id == MA_CDOPT_TESTBIOS_EUR && strcmp(bios_names->eu, "NOT FOUND")) ||
- (selected_id == MA_CDOPT_TESTBIOS_JAP && strcmp(bios_names->jp, "NOT FOUND")))
- text_out16(tl_x, 250, "Press start to test selected BIOS");
-
- menu_draw_end();
-}
-
-static void cd_menu_loop_options(void)
-{
- static int menu_sel = 0;
- int menu_sel_max = 10;
- unsigned long inp = 0;
- struct bios_names_t bios_names;
- menu_id selected_id;
- char *bios, *p;
-
- if (emu_findBios(4, &bios)) { // US
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
- if (*p == '/') p++;
- strncpy(bios_names.us, p, sizeof(bios_names.us)); bios_names.us[sizeof(bios_names.us)-1] = 0;
- } else strcpy(bios_names.us, "NOT FOUND");
-
- if (emu_findBios(8, &bios)) { // EU
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
- if (*p == '/') p++;
- strncpy(bios_names.eu, p, sizeof(bios_names.eu)); bios_names.eu[sizeof(bios_names.eu)-1] = 0;
- } else strcpy(bios_names.eu, "NOT FOUND");
-
- if (emu_findBios(1, &bios)) { // JP
- for (p = bios+strlen(bios)-1; p > bios && *p != '/'; p--);
- if (*p == '/') p++;
- strncpy(bios_names.jp, p, sizeof(bios_names.jp)); bios_names.jp[sizeof(bios_names.jp)-1] = 0;
- } else strcpy(bios_names.jp, "NOT FOUND");
-
- menuErrorMsg[0] = 0;
-
- for (;;)
- {
- draw_cd_menu_options(menu_sel, &bios_names);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE|PBTN_START, 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- selected_id = me_index2id(cdopt_entries, CDOPT_ENTRY_COUNT, menu_sel);
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) { // multi choise
- if (!me_process(cdopt_entries, CDOPT_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0) &&
- selected_id == MA_CDOPT_READAHEAD) {
- if (inp & PBTN_LEFT) {
- PicoCDBuffers >>= 1;
- if (PicoCDBuffers < 2) PicoCDBuffers = 0;
- } else {
- if (PicoCDBuffers < 2) PicoCDBuffers = 2;
- else PicoCDBuffers <<= 1;
- if (PicoCDBuffers > 8*1024) PicoCDBuffers = 8*1024; // 16M
- }
- }
- }
- if (inp & PBTN_CIRCLE) // toggleable options
- if (!me_process(cdopt_entries, CDOPT_ENTRY_COUNT, selected_id, 1) &&
- selected_id == MA_CDOPT_DONE) {
- return;
- }
- if (inp & PBTN_START) {
- switch (selected_id) { // BIOS testers
- case MA_CDOPT_TESTBIOS_USA:
- if (emu_findBios(4, &bios)) { // test US
- strcpy(romFileName, bios);
- engineState = PGS_ReloadRom;
- return;
- }
- break;
- case MA_CDOPT_TESTBIOS_EUR:
- if (emu_findBios(8, &bios)) { // test EU
- strcpy(romFileName, bios);
- engineState = PGS_ReloadRom;
- return;
- }
- break;
- case MA_CDOPT_TESTBIOS_JAP:
- if (emu_findBios(1, &bios)) { // test JP
- strcpy(romFileName, bios);
- engineState = PGS_ReloadRom;
- return;
- }
- break;
- default:
- break;
- }
- }
- if (inp & PBTN_X) return;
- }
-}
-
-// --------- display options ----------
-
-menu_entry opt3_entries[] =
-{
- { NULL, MB_NONE, MA_OPT3_SCALE, NULL, 0, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT3_HSCALE32, NULL, 0, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT3_HSCALE40, NULL, 0, 0, 0, 1, 1 },
- { NULL, MB_ONOFF, MA_OPT3_FILTERING, ¤tConfig.scaling, 1, 0, 0, 1, 1 },
- { NULL, MB_RANGE, MA_OPT3_GAMMAA, ¤tConfig.gamma, 0, -4, 16, 1, 1 },
- { NULL, MB_RANGE, MA_OPT3_BLACKLVL, ¤tConfig.gamma2, 0, 0, 2, 1, 1 },
- { NULL, MB_NONE, MA_OPT3_VSYNC, NULL, 0, 0, 0, 1, 1 },
- { "Set to unscaled centered", MB_NONE, MA_OPT3_PRES_NOSCALE, NULL, 0, 0, 0, 1, 0 },
- { "Set to 4:3 scaled", MB_NONE, MA_OPT3_PRES_SCALE43, NULL, 0, 0, 0, 1, 0 },
- { "Set to fullscreen", MB_NONE, MA_OPT3_PRES_FULLSCR, NULL, 0, 0, 0, 1, 0 },
- { "done", MB_NONE, MA_OPT3_DONE, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define OPT3_ENTRY_COUNT (sizeof(opt3_entries) / sizeof(opt3_entries[0]))
-const int opt3_entry_count = OPT3_ENTRY_COUNT;
-
-
-static void menu_opt3_cust_draw(const menu_entry *entry, int x, int y, void *param)
-{
- switch (entry->id)
- {
- case MA_OPT3_SCALE:
- text_out16(x, y, "Scale factor: %.2f", currentConfig.scale);
- break;
- case MA_OPT3_HSCALE32:
- text_out16(x, y, "Hor. scale (for low res. games): %.2f", currentConfig.hscale32);
- break;
- case MA_OPT3_HSCALE40:
- text_out16(x, y, "Hor. scale (for hi res. games): %.2f", currentConfig.hscale40);
- break;
- case MA_OPT3_FILTERING:
- text_out16(x, y, "Bilinear filtering %s", currentConfig.scaling?"ON":"OFF");
- break;
- case MA_OPT3_GAMMAA:
- text_out16(x, y, "Gamma adjustment %2i", currentConfig.gamma);
- break;
- case MA_OPT3_BLACKLVL:
- text_out16(x, y, "Black level %2i", currentConfig.gamma2);
- break;
- case MA_OPT3_VSYNC: {
- char *val = " never";
- if (currentConfig.EmuOpt & 0x2000)
- val = (currentConfig.EmuOpt & 0x10000) ? "sometimes" : " always";
- text_out16(x, y, "Wait for vsync (slow) %s", val);
- break;
- }
- default: break;
- }
-}
-
-static void menu_opt3_preview(int is_32col)
-{
- void *oldstate = NULL;
-
- if (!rom_loaded || ((Pico.video.reg[12]&1)^1) != is_32col)
- {
- extern char bgdatac32_start[], bgdatac40_start[];
- extern int bgdatac32_size, bgdatac40_size;
- void *bgdata = is_32col ? bgdatac32_start : bgdatac40_start;
- unsigned long insize = is_32col ? bgdatac32_size : bgdatac40_size, outsize = 65856;
- int ret;
- ret = uncompress((Bytef *)bg_buffer, &outsize, bgdata, insize);
- if (ret == 0)
- {
- if (rom_loaded) oldstate = get_oldstate_for_preview();
- memcpy(Pico.vram, bg_buffer, sizeof(Pico.vram));
- memcpy(Pico.cram, (char *)bg_buffer + 0x10000, 0x40*2);
- memcpy(Pico.vsram, (char *)bg_buffer + 0x10080, 0x40*2);
- memcpy(&Pico.video,(char *)bg_buffer + 0x10100, 0x40);
- }
- else
- lprintf("uncompress returned %i\n", ret);
- }
-
- memset32_uncached(psp_screen, 0, 512*272*2/4);
- emu_forcedFrame(0);
- menu_prepare_bg(1, 0);
-
- if (oldstate) restore_oldstate(oldstate);
-}
-
-static void draw_dispmenu_options(int menu_sel)
-{
- int tl_x = 80, tl_y = 16+50;
-
- menu_draw_begin();
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 316);
-
- me_draw(opt3_entries, OPT3_ENTRY_COUNT, tl_x, tl_y, menu_opt3_cust_draw, NULL);
-
- menu_draw_end();
-}
-
-static void dispmenu_loop_options(void)
-{
- static int menu_sel = 0;
- int menu_sel_max, is_32col = (Pico.video.reg[12]&1)^1;
- unsigned long inp = 0;
- menu_id selected_id;
-
- menu_sel_max = me_count_enabled(opt3_entries, OPT3_ENTRY_COUNT) - 1;
-
- for (;;)
- {
- draw_dispmenu_options(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- selected_id = me_index2id(opt3_entries, OPT3_ENTRY_COUNT, menu_sel);
- if (selected_id == MA_OPT3_HSCALE40 && is_32col) { is_32col = 0; menu_opt3_preview(is_32col); }
- if (selected_id == MA_OPT3_HSCALE32 && !is_32col) { is_32col = 1; menu_opt3_preview(is_32col); }
-
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) // multi choise
- {
- float *setting = NULL;
- int tmp;
- me_process(opt3_entries, OPT3_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0);
- switch (selected_id) {
- case MA_OPT3_SCALE: setting = ¤tConfig.scale; break;
- case MA_OPT3_HSCALE40: setting = ¤tConfig.hscale40; is_32col = 0; break;
- case MA_OPT3_HSCALE32: setting = ¤tConfig.hscale32; is_32col = 1; break;
- case MA_OPT3_FILTERING:
- case MA_OPT3_GAMMAA:
- case MA_OPT3_BLACKLVL: menu_opt3_preview(is_32col); break;
- case MA_OPT3_VSYNC:
- tmp = ((currentConfig.EmuOpt>>13)&1) | ((currentConfig.EmuOpt>>15)&2);
- tmp = (inp & PBTN_LEFT) ? (tmp>>1) : ((tmp<<1)|1);
- if (tmp > 3) tmp = 3;
- currentConfig.EmuOpt &= ~0x12000;
- currentConfig.EmuOpt |= ((tmp&2)<<15) | ((tmp&1)<<13);
- break;
- default: break;
- }
- if (setting != NULL) {
- while ((inp = psp_pad_read(0)) & (PBTN_LEFT|PBTN_RIGHT)) {
- *setting += (inp & PBTN_LEFT) ? -0.01 : 0.01;
- if (*setting <= 0) *setting = 0.01;
- menu_opt3_preview(is_32col);
- draw_dispmenu_options(menu_sel); // will wait vsync
- }
- }
- }
- if (inp & PBTN_CIRCLE) { // toggleable options
- me_process(opt3_entries, OPT3_ENTRY_COUNT, selected_id, 1);
- switch (selected_id) {
- case MA_OPT3_DONE:
- return;
- case MA_OPT3_PRES_NOSCALE:
- currentConfig.scale = currentConfig.hscale40 = currentConfig.hscale32 = 1.0;
- menu_opt3_preview(is_32col);
- break;
- case MA_OPT3_PRES_SCALE43:
- currentConfig.scale = 1.20;
- currentConfig.hscale40 = 1.00;
- currentConfig.hscale32 = 1.25;
- menu_opt3_preview(is_32col);
- break;
- case MA_OPT3_PRES_FULLSCR:
- currentConfig.scale = 1.20;
- currentConfig.hscale40 = 1.25;
- currentConfig.hscale32 = 1.56;
- menu_opt3_preview(is_32col);
- break;
- case MA_OPT3_FILTERING:
- menu_opt3_preview(is_32col);
- break;
- default: break;
- }
- }
- if (inp & PBTN_X) return;
- }
-}
-
-
-// --------- advanced options ----------
-
-menu_entry opt2_entries[] =
-{
- { "Disable sprite limit", MB_ONOFF, MA_OPT2_NO_SPRITE_LIM, &PicoOpt, 0x40000, 0, 0, 1, 1 },
- { "Emulate Z80", MB_ONOFF, MA_OPT2_ENABLE_Z80, &PicoOpt, 0x00004, 0, 0, 1, 1 },
- { "Emulate YM2612 (FM)", MB_ONOFF, MA_OPT2_ENABLE_YM2612, &PicoOpt, 0x00001, 0, 0, 1, 1 },
- { "Emulate SN76496 (PSG)", MB_ONOFF, MA_OPT2_ENABLE_SN76496, &PicoOpt, 0x00002, 0, 0, 1, 1 },
- { "gzip savestates", MB_ONOFF, MA_OPT2_GZIP_STATES, ¤tConfig.EmuOpt, 0x00008, 0, 0, 1, 1 },
- { "Don't save last used ROM", MB_ONOFF, MA_OPT2_NO_LAST_ROM, ¤tConfig.EmuOpt, 0x00020, 0, 0, 1, 1 },
- { "Status line in main menu", MB_ONOFF, MA_OPT2_STATUS_LINE, ¤tConfig.EmuOpt, 0x20000, 0, 0, 1, 1 },
- { "Disable idle loop patching",MB_ONOFF, MA_OPT2_NO_IDLE_LOOPS, &PicoOpt, 0x80000, 0, 0, 1, 1 },
- { "Disable frame limiter", MB_ONOFF, MA_OPT2_NO_FRAME_LIMIT, ¤tConfig.EmuOpt, 0x40000, 0, 0, 1, 1 },
- { "done", MB_NONE, MA_OPT2_DONE, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define OPT2_ENTRY_COUNT (sizeof(opt2_entries) / sizeof(opt2_entries[0]))
-const int opt2_entry_count = OPT2_ENTRY_COUNT;
-
-
-static void draw_amenu_options(int menu_sel)
-{
- int tl_x = 80+25, tl_y = 16+50;
-
- menu_draw_begin();
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 252);
-
- me_draw(opt2_entries, OPT2_ENTRY_COUNT, tl_x, tl_y, NULL, NULL);
-
- menu_draw_end();
-}
-
-static void amenu_loop_options(void)
-{
- static int menu_sel = 0;
- int menu_sel_max;
- unsigned long inp = 0;
- menu_id selected_id;
-
- menu_sel_max = me_count_enabled(opt2_entries, OPT2_ENTRY_COUNT) - 1;
-
- for(;;)
- {
- draw_amenu_options(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- selected_id = me_index2id(opt2_entries, OPT2_ENTRY_COUNT, menu_sel);
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) { // multi choise
- if (!me_process(opt2_entries, OPT2_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0) &&
- selected_id == MA_OPT2_GAMMA) {
- // TODO?
- }
- }
- if (inp & PBTN_CIRCLE) { // toggleable options
- if (!me_process(opt2_entries, OPT2_ENTRY_COUNT, selected_id, 1) &&
- selected_id == MA_OPT2_DONE) {
- return;
- }
- }
- if (inp & PBTN_X) return;
- }
-}
-
-// -------------- options --------------
-
-
-menu_entry opt_entries[] =
-{
- { NULL, MB_NONE, MA_OPT_RENDERER, NULL, 0, 0, 0, 1, 1 },
- { "Accurate sprites", MB_ONOFF, MA_OPT_ACC_SPRITES, &PicoOpt, 0x080, 0, 0, 0, 1 },
- { "Show FPS", MB_ONOFF, MA_OPT_SHOW_FPS, ¤tConfig.EmuOpt, 0x0002, 0, 0, 1, 1 },
- { NULL, MB_RANGE, MA_OPT_FRAMESKIP, ¤tConfig.Frameskip, 0, -1, 16, 1, 1 },
- { "Enable sound", MB_ONOFF, MA_OPT_ENABLE_SOUND, ¤tConfig.EmuOpt, 0x0004, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT_REGION, NULL, 0, 0, 0, 1, 1 },
- { "Use SRAM/BRAM savestates", MB_ONOFF, MA_OPT_SRAM_STATES, ¤tConfig.EmuOpt, 0x0001, 0, 0, 1, 1 },
- { NULL, MB_NONE, MA_OPT_CONFIRM_STATES,NULL, 0, 0, 0, 1, 1 },
- { "Save slot", MB_RANGE, MA_OPT_SAVE_SLOT, &state_slot, 0, 0, 9, 1, 1 },
- { NULL, MB_NONE, MA_OPT_CPU_CLOCKS, NULL, 0, 0, 0, 1, 1 },
- { "[Display options]", MB_NONE, MA_OPT_DISP_OPTS, NULL, 0, 0, 0, 1, 0 },
- { "[Sega/Mega CD options]", MB_NONE, MA_OPT_SCD_OPTS, NULL, 0, 0, 0, 1, 0 },
- { "[Advanced options]", MB_NONE, MA_OPT_ADV_OPTS, NULL, 0, 0, 0, 1, 0 },
- { NULL, MB_NONE, MA_OPT_SAVECFG, NULL, 0, 0, 0, 1, 0 },
- { "Save cfg for current game only",MB_NONE,MA_OPT_SAVECFG_GAME,NULL, 0, 0, 0, 1, 0 },
- { NULL, MB_NONE, MA_OPT_LOADCFG, NULL, 0, 0, 0, 1, 0 },
-};
-
-#define OPT_ENTRY_COUNT (sizeof(opt_entries) / sizeof(opt_entries[0]))
-const int opt_entry_count = OPT_ENTRY_COUNT;
-
-
-static void menu_opt_cust_draw(const menu_entry *entry, int x, int y, void *param)
-{
- char *str, str24[24];
-
- switch (entry->id)
- {
- case MA_OPT_RENDERER:
- if (PicoOpt & 0x10)
- str = "fast";
- else if (currentConfig.EmuOpt & 0x80)
- str = "accurate";
- else
- str = " 8bit accurate"; // n/a
- text_out16(x, y, "Renderer: %s", str);
- break;
- case MA_OPT_FRAMESKIP:
- if (currentConfig.Frameskip < 0)
- strcpy(str24, "Auto");
- else sprintf(str24, "%i", currentConfig.Frameskip);
- text_out16(x, y, "Frameskip %s", str24);
- break;
- case MA_OPT_SOUND_QUALITY:
- str = (PicoOpt&0x08)?"stereo":"mono";
- text_out16(x, y, "Sound Quality: %5iHz %s", PsndRate, str);
- break;
- case MA_OPT_REGION:
- text_out16(x, y, "Region: %s", me_region_name(PicoRegionOverride, PicoAutoRgnOrder));
- break;
- case MA_OPT_CONFIRM_STATES:
- switch ((currentConfig.EmuOpt >> 9) & 5) {
- default: str = "OFF"; break;
- case 1: str = "writes"; break;
- case 4: str = "loads"; break;
- case 5: str = "both"; break;
- }
- text_out16(x, y, "Confirm savestate %s", str);
- break;
- case MA_OPT_CPU_CLOCKS:
- text_out16(x, y, "CPU/bus clock %3i/%3iMHz", currentConfig.CPUclock, currentConfig.CPUclock/2);
- break;
- case MA_OPT_SAVECFG:
- str24[0] = 0;
- if (config_slot != 0) sprintf(str24, " (profile: %i)", config_slot);
- text_out16(x, y, "Save cfg as default%s", str24);
- break;
- case MA_OPT_LOADCFG:
- text_out16(x, y, "Load cfg from profile %i", config_slot);
- break;
- default:
- lprintf("%s: unimplemented (%i)\n", __FUNCTION__, entry->id);
- break;
- }
-}
-
-
-static void draw_menu_options(int menu_sel)
-{
- int tl_x = 80+25, tl_y = 16+24;
-
- menu_draw_begin();
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 284);
-
- me_draw(opt_entries, OPT_ENTRY_COUNT, tl_x, tl_y, menu_opt_cust_draw, NULL);
-
- menu_draw_end();
-}
-
-static int sndrate_prevnext(int rate, int dir)
-{
- int i, rates[] = { 11025, 22050, 44100 };
-
- for (i = 0; i < 5; i++)
- if (rates[i] == rate) break;
-
- i += dir ? 1 : -1;
- if (i > 2) return dir ? 44100 : 22050;
- if (i < 0) return dir ? 22050 : 11025;
- return rates[i];
-}
-
-static void region_prevnext(int right)
-{
- // jp_ntsc=1, jp_pal=2, usa=4, eu=8
- static int rgn_orders[] = { 0x148, 0x184, 0x814, 0x418, 0x841, 0x481 };
- int i;
- if (right) {
- if (!PicoRegionOverride) {
- for (i = 0; i < 6; i++)
- if (rgn_orders[i] == PicoAutoRgnOrder) break;
- if (i < 5) PicoAutoRgnOrder = rgn_orders[i+1];
- else PicoRegionOverride=1;
- }
- else PicoRegionOverride<<=1;
- if (PicoRegionOverride > 8) PicoRegionOverride = 8;
- } else {
- if (!PicoRegionOverride) {
- for (i = 0; i < 6; i++)
- if (rgn_orders[i] == PicoAutoRgnOrder) break;
- if (i > 0) PicoAutoRgnOrder = rgn_orders[i-1];
- }
- else PicoRegionOverride>>=1;
- }
-}
-
-static void menu_options_save(void)
-{
- if (PicoRegionOverride) {
- // force setting possibly changed..
- Pico.m.pal = (PicoRegionOverride == 2 || PicoRegionOverride == 8) ? 1 : 0;
- }
- if (!(PicoOpt & POPT_6BTN_PAD)) {
- // unbind XYZ MODE, just in case
- unbind_action(0xf00);
- }
-}
-
-static int menu_loop_options(void)
-{
- static int menu_sel = 0;
- int menu_sel_max, ret;
- unsigned long inp = 0;
- menu_id selected_id;
-
- me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_SAVECFG_GAME, rom_loaded);
- me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_LOADCFG, config_slot != config_slot_current);
- menu_sel_max = me_count_enabled(opt_entries, OPT_ENTRY_COUNT) - 1;
- if (menu_sel > menu_sel_max) menu_sel = menu_sel_max;
-
- while (1)
- {
- draw_menu_options(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT|PBTN_X|PBTN_CIRCLE, 0);
- if (inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if (inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- selected_id = me_index2id(opt_entries, OPT_ENTRY_COUNT, menu_sel);
- if (inp & (PBTN_LEFT|PBTN_RIGHT)) { // multi choise
- if (!me_process(opt_entries, OPT_ENTRY_COUNT, selected_id, (inp&PBTN_RIGHT) ? 1 : 0)) {
- switch (selected_id) {
- case MA_OPT_RENDERER:
- if ((PicoOpt & 0x10) || !(currentConfig.EmuOpt & 0x80)) {
- PicoOpt &= ~0x10;
- currentConfig.EmuOpt |= 0x80;
- } else {
- PicoOpt |= 0x10;
- currentConfig.EmuOpt &= ~0x80;
- }
- break;
- case MA_OPT_SOUND_QUALITY:
- PsndRate = sndrate_prevnext(PsndRate, inp & PBTN_RIGHT);
- break;
- case MA_OPT_REGION:
- region_prevnext(inp & PBTN_RIGHT);
- break;
- case MA_OPT_CONFIRM_STATES: {
- int n = ((currentConfig.EmuOpt>>9)&1) | ((currentConfig.EmuOpt>>10)&2);
- n += (inp & PBTN_LEFT) ? -1 : 1;
- if (n < 0) n = 0; else if (n > 3) n = 3;
- n |= n << 1; n &= ~2;
- currentConfig.EmuOpt &= ~0xa00;
- currentConfig.EmuOpt |= n << 9;
- break;
- }
- case MA_OPT_SAVE_SLOT:
- if (inp & PBTN_RIGHT) {
- state_slot++; if (state_slot > 9) state_slot = 0;
- } else {state_slot--; if (state_slot < 0) state_slot = 9;
- }
- break;
- case MA_OPT_CPU_CLOCKS:
- while ((inp = psp_pad_read(0)) & (PBTN_LEFT|PBTN_RIGHT)) {
- currentConfig.CPUclock += (inp & PBTN_LEFT) ? -1 : 1;
- if (currentConfig.CPUclock < 19) currentConfig.CPUclock = 19;
- if (currentConfig.CPUclock > 333) currentConfig.CPUclock = 333;
- draw_menu_options(menu_sel); // will wait vsync
- }
- break;
- case MA_OPT_SAVECFG:
- case MA_OPT_SAVECFG_GAME:
- case MA_OPT_LOADCFG:
- config_slot += (inp&PBTN_RIGHT) ? 1 : -1;
- if (config_slot > 9) config_slot = 0;
- if (config_slot < 0) config_slot = 9;
- me_enable(opt_entries, OPT_ENTRY_COUNT, MA_OPT_LOADCFG, config_slot != config_slot_current);
- menu_sel_max = me_count_enabled(opt_entries, OPT_ENTRY_COUNT) - 1;
- if (menu_sel > menu_sel_max) menu_sel = menu_sel_max;
- break;
- default:
- //lprintf("%s: something unknown selected (%i)\n", __FUNCTION__, selected_id);
- break;
- }
- }
- }
- if (inp & PBTN_CIRCLE) {
- if (!me_process(opt_entries, OPT_ENTRY_COUNT, selected_id, 1))
- {
- switch (selected_id)
- {
- case MA_OPT_DISP_OPTS:
- dispmenu_loop_options();
- break;
- case MA_OPT_SCD_OPTS:
- cd_menu_loop_options();
- if (engineState == PGS_ReloadRom)
- return 0; // test BIOS
- break;
- case MA_OPT_ADV_OPTS:
- amenu_loop_options();
- break;
- case MA_OPT_SAVECFG: // done (update and write)
- menu_options_save();
- if (emu_WriteConfig(0)) strcpy(menuErrorMsg, "config saved");
- else strcpy(menuErrorMsg, "failed to write config");
- return 1;
- case MA_OPT_SAVECFG_GAME: // done (update and write for current game)
- menu_options_save();
- if (emu_WriteConfig(1)) strcpy(menuErrorMsg, "config saved");
- else strcpy(menuErrorMsg, "failed to write config");
- return 1;
- case MA_OPT_LOADCFG:
- ret = emu_ReadConfig(1, 1);
- if (!ret) ret = emu_ReadConfig(0, 1);
- if (ret) strcpy(menuErrorMsg, "config loaded");
- else strcpy(menuErrorMsg, "failed to load config");
- return 1;
- default:
- //lprintf("%s: something unknown selected (%i)\n", __FUNCTION__, selected_id);
- break;
- }
- }
- }
- if(inp & PBTN_X) {
- menu_options_save();
- return 0; // done (update, no write)
- }
- }
-}
-
-// -------------- credits --------------
-
-static void draw_menu_credits(void)
-{
- int tl_x = 80+15, tl_y = 16+64, y;
- menu_draw_begin();
-
- text_out16(tl_x, 16+20, "PicoDrive v" VERSION " (c) notaz, 2006-2008");
-
- y = tl_y;
- text_out16(tl_x, y, "Credits:");
- text_out16(tl_x, (y+=10), "fDave: base code of PicoDrive");
- text_out16(tl_x, (y+=10), "Chui: Fame/C");
- text_out16(tl_x, (y+=10), "NJ: CZ80");
- text_out16(tl_x, (y+=10), "MAME devs: YM2612 and SN76496 cores");
- text_out16(tl_x, (y+=10), "ps2dev.org people: PSP SDK/code");
- text_out16(tl_x, (y+=10), "ketchupgun: skin design");
-
- text_out16(tl_x, (y+=20), "special thanks (for docs, ideas):");
- text_out16(tl_x, (y+=10), " Charles MacDonald, Haze,");
- text_out16(tl_x, (y+=10), " Stephane Dallongeville,");
- text_out16(tl_x, (y+=10), " Lordus, Exophase, Rokas,");
- text_out16(tl_x, (y+=10), " Nemesis, Tasco Deluxe");
-
- menu_draw_end();
-}
-
-
-// -------------- root menu --------------
-
-menu_entry main_entries[] =
-{
- { "Resume game", MB_NONE, MA_MAIN_RESUME_GAME, NULL, 0, 0, 0, 0 },
- { "Save State", MB_NONE, MA_MAIN_SAVE_STATE, NULL, 0, 0, 0, 0 },
- { "Load State", MB_NONE, MA_MAIN_LOAD_STATE, NULL, 0, 0, 0, 0 },
- { "Reset game", MB_NONE, MA_MAIN_RESET_GAME, NULL, 0, 0, 0, 0 },
- { "Load new ROM/ISO", MB_NONE, MA_MAIN_LOAD_ROM, NULL, 0, 0, 0, 1 },
- { "Change options", MB_NONE, MA_MAIN_OPTIONS, NULL, 0, 0, 0, 1 },
- { "Configure controls", MB_NONE, MA_MAIN_CONTROLS, NULL, 0, 0, 0, 1 },
- { "Credits", MB_NONE, MA_MAIN_CREDITS, NULL, 0, 0, 0, 1 },
- { "Patches / GameGenie",MB_NONE, MA_MAIN_PATCHES, NULL, 0, 0, 0, 0 },
- { "Exit", MB_NONE, MA_MAIN_EXIT, NULL, 0, 0, 0, 1 }
-};
-
-#define MAIN_ENTRY_COUNT (sizeof(main_entries) / sizeof(main_entries[0]))
-
-static void draw_menu_root(int menu_sel)
-{
- const int tl_x = 86+70, tl_y = 16+70;
- char *stat = NULL;
-
- menu_draw_begin();
-
- if ((currentConfig.EmuOpt&0x20000) && (stat = psp_get_status_line()))
- text_out16(287, 12, "%s", stat);
-
- text_out16(tl_x, 48, "PicoDrive v" VERSION);
-
- menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 146);
-
- me_draw(main_entries, MAIN_ENTRY_COUNT, tl_x, tl_y, NULL, NULL);
-
- // error
- if (menuErrorMsg[0])
- text_out16(10, 252, menuErrorMsg);
- menu_draw_end();
-}
-
-
-static void menu_loop_root(void)
-{
- static int menu_sel = 0;
- int ret, menu_sel_max;
- unsigned long inp = 0;
-
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_RESUME_GAME, rom_loaded);
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_SAVE_STATE, rom_loaded);
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_LOAD_STATE, rom_loaded);
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_RESET_GAME, rom_loaded);
- me_enable(main_entries, MAIN_ENTRY_COUNT, MA_MAIN_PATCHES, PicoPatches != NULL);
-
- menu_sel_max = me_count_enabled(main_entries, MAIN_ENTRY_COUNT) - 1;
- if (menu_sel > menu_sel_max) menu_sel = menu_sel_max;
-
- // mp3 errors?
- if (mp3_last_error != 0) {
- if (mp3_last_error == -1)
- sprintf(menuErrorMsg, "Unsupported mp3 format, use 44kHz stereo");
- else sprintf(menuErrorMsg, "mp3 init failed, code %08x", mp3_last_error);
- mp3_last_error = 0;
- }
-
- /* make sure action buttons are not pressed on entering menu */
- draw_menu_root(menu_sel);
-
- while (psp_pad_read(1) & (PBTN_X|PBTN_CIRCLE|PBTN_SELECT)) psp_msleep(50);
-
- for (;;)
- {
- draw_menu_root(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_X|PBTN_CIRCLE|PBTN_SELECT|PBTN_L|PBTN_R, 0);
- if(inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if(inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- if((inp & (PBTN_L|PBTN_R)) == (PBTN_L|PBTN_R)) debug_menu_loop();
- if( inp & (PBTN_SELECT|PBTN_X)) {
- if (rom_loaded) {
- while (psp_pad_read(1) & (PBTN_SELECT|PBTN_X)) psp_msleep(50); // wait until released
- engineState = PGS_Running;
- break;
- }
- }
- if(inp & PBTN_CIRCLE) {
- menuErrorMsg[0] = 0; // clear error msg
- switch (me_index2id(main_entries, MAIN_ENTRY_COUNT, menu_sel))
- {
- case MA_MAIN_RESUME_GAME:
- if (rom_loaded) {
- while (psp_pad_read(1) & PBTN_CIRCLE) psp_msleep(50);
- engineState = PGS_Running;
- return;
- }
- break;
- case MA_MAIN_SAVE_STATE:
- if (rom_loaded) {
- if(savestate_menu_loop(0))
- continue;
- engineState = PGS_Running;
- return;
- }
- break;
- case MA_MAIN_LOAD_STATE:
- if (rom_loaded) {
- if(savestate_menu_loop(1))
- continue;
- while (psp_pad_read(1) & PBTN_CIRCLE) psp_msleep(50);
- engineState = PGS_Running;
- return;
- }
- break;
- case MA_MAIN_RESET_GAME:
- if (rom_loaded) {
- emu_ResetGame();
- while (psp_pad_read(1) & PBTN_CIRCLE) psp_msleep(50);
- engineState = PGS_Running;
- return;
- }
- break;
- case MA_MAIN_LOAD_ROM:
- {
- char curr_path[PATH_MAX], *selfname;
- FILE *tstf;
- if ( (tstf = fopen(loadedRomFName, "rb")) )
- {
- fclose(tstf);
- strcpy(curr_path, loadedRomFName);
- }
- else
- getcwd(curr_path, PATH_MAX);
- selfname = romsel_loop(curr_path);
- if (selfname) {
- lprintf("selected file: %s\n", selfname);
- engineState = PGS_ReloadRom;
- return;
- }
- break;
- }
- case MA_MAIN_OPTIONS:
- ret = menu_loop_options();
- if (ret == 1) continue; // status update
- if (engineState == PGS_ReloadRom)
- return; // BIOS test
- break;
- case MA_MAIN_CONTROLS:
- kc_sel_loop();
- break;
- case MA_MAIN_CREDITS:
- draw_menu_credits();
- psp_msleep(500);
- inp = 0;
- while (!(inp & (PBTN_X|PBTN_CIRCLE)))
- inp = in_menu_wait(PBTN_X|PBTN_CIRCLE, 0);
- break;
- case MA_MAIN_EXIT:
- engineState = PGS_Quit;
- return;
- case MA_MAIN_PATCHES:
- if (rom_loaded && PicoPatches) {
- patches_menu_loop();
- PicoPatchApply();
- strcpy(menuErrorMsg, "Patches applied");
- continue;
- }
- break;
- default:
- lprintf("%s: something unknown selected\n", __FUNCTION__);
- break;
- }
- }
- }
-}
-
-void menu_darken_bg(void *dst, const void *src, int pixels, int darker)
-{
- unsigned int *dest = dst;
- const unsigned int *srce = src;
- pixels /= 2;
- if (darker)
- {
- while (pixels--)
- {
- unsigned int p = *srce++;
- *dest++ = ((p&0xf79ef79e)>>1) - ((p&0xc618c618)>>3);
- }
- }
- else
- {
- while (pixels--)
- {
- unsigned int p = *srce++;
- *dest++ = (p&0xf79ef79e)>>1;
- }
- }
-}
-
-static void menu_prepare_bg(int use_game_bg, int use_fg)
-{
- if (use_game_bg)
- {
- // darken the active framebuffer
- unsigned short *dst = bg_buffer;
- unsigned short *src = use_fg ? psp_video_get_active_fb() : psp_screen;
- int i;
- for (i = 272; i > 0; i--, dst += 480, src += 512)
- menu_darken_bg(dst, src, 480, 1);
- //memset32_uncached((int *)(bg_buffer + 480*264), 0, 480*8*2/4);
- }
- else
- {
- // should really only happen once, on startup..
- memset32_uncached((int *)(void *)bg_buffer, 0, sizeof(bg_buffer)/4);
- readpng(bg_buffer, "skin/background.png", READPNG_BG);
- }
- sceKernelDcacheWritebackAll();
-}
-
-static void menu_gfx_prepare(void)
-{
- menu_prepare_bg(rom_loaded, 1);
-
- menu_draw_begin();
- menu_draw_end();
-}
-
-
-void menu_loop(void)
-{
- menu_gfx_prepare();
-
- menu_loop_root();
-
- menuErrorMsg[0] = 0;
-}
-
-
-// --------- CD tray close menu ----------
-
-static void draw_menu_tray(int menu_sel)
-{
- int tl_x = 70, tl_y = 90, y;
-
- menu_draw_begin();
-
- text_out16(tl_x, 20, "The unit is about to");
- text_out16(tl_x, 30, "close the CD tray.");
-
- y = tl_y;
- text_out16(tl_x, y, "Load new CD image");
- text_out16(tl_x, (y+=10), "Insert nothing");
-
- // draw cursor
- text_out16(tl_x - 16, tl_y + menu_sel*10, ">");
- // error
- if (menuErrorMsg[0]) text_out16(5, 226, menuErrorMsg);
- menu_draw_end();
-}
-
-
-int menu_loop_tray(void)
-{
- int menu_sel = 0, menu_sel_max = 1;
- unsigned long inp = 0;
- char curr_path[PATH_MAX], *selfname;
- FILE *tstf;
-
- menu_gfx_prepare();
-
- if ( (tstf = fopen(loadedRomFName, "rb")) )
- {
- fclose(tstf);
- strcpy(curr_path, loadedRomFName);
- }
- else
- {
- getcwd(curr_path, PATH_MAX);
- }
-
- /* make sure action buttons are not pressed on entering menu */
- draw_menu_tray(menu_sel);
- while (psp_pad_read(1) & PBTN_CIRCLE) psp_msleep(50);
-
- for (;;)
- {
- draw_menu_tray(menu_sel);
- inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_CIRCLE, 0);
- if(inp & PBTN_UP ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
- if(inp & PBTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
- if(inp & PBTN_CIRCLE) {
- switch (menu_sel) {
- case 0: // select image
- selfname = romsel_loop(curr_path);
- if (selfname) {
- int ret = -1;
- cd_img_type cd_type;
- cd_type = emu_cdCheck(NULL, romFileName);
- if (cd_type != CIT_NOT_CD)
- ret = Insert_CD(romFileName, cd_type);
- if (ret != 0) {
- sprintf(menuErrorMsg, "Load failed, invalid CD image?");
- lprintf("%s\n", menuErrorMsg);
- continue;
- }
- engineState = PGS_RestartRun;
- return 1;
- }
- break;
- case 1: // insert nothing
- engineState = PGS_RestartRun;
- return 0;
- }
- }
- menuErrorMsg[0] = 0; // clear error msg
- }
-}
-
-
+++ /dev/null
-// (c) Copyright 2006,2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-void menu_loop(void);
-int menu_loop_tray(void);
-void menu_romload_prepare(const char *rom_name);
-void menu_romload_end(void);
-
-
-#define CONFIGURABLE_KEYS (PBTN_UP|PBTN_LEFT|PBTN_RIGHT|PBTN_DOWN|PBTN_L|PBTN_R|PBTN_TRIANGLE|PBTN_CIRCLE|PBTN_X|PBTN_SQUARE|PBTN_START| \
- PBTN_NUB_UP|PBTN_NUB_RIGHT|PBTN_NUB_DOWN|PBTN_NUB_LEFT|PBTN_NOTE)
-
+++ /dev/null
-// (c) Copyright 2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-#include <stdio.h>
-#include <string.h>
-
-#include <pspkernel.h>
-#include <pspsdk.h>
-#include <pspaudiocodec.h>
-#include <kubridge.h>
-
-#include "../../pico/pico_int.h"
-#include "../../pico/sound/mix.h"
-#include "../common/lprintf.h"
-
-int mp3_last_error = 0;
-
-static int initialized = 0;
-static SceUID thread_job_sem = -1;
-static SceUID thread_busy_sem = -1;
-static int thread_exit = 0;
-
-// MPEG-1, layer 3
-static int bitrates[] = { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 };
-//static int samplerates[] = { 44100, 48000, 32000, 0 };
-
-#define MIN_INFRAME_SIZE 96
-#define IN_BUFFER_SIZE (2*1024)
-
-static unsigned long mp3_codec_struct[65] __attribute__((aligned(64)));
-
-static unsigned char mp3_src_buffer[2][IN_BUFFER_SIZE] __attribute__((aligned(64)));
-static short mp3_mix_buffer[2][1152*2] __attribute__((aligned(64)));
-static int working_buf = 0;
-
-static const char *mp3_fname = NULL;
-static SceUID mp3_handle = -1;
-static int mp3_src_pos = 0, mp3_src_size = 0;
-
-static int decode_thread(SceSize args, void *argp);
-
-
-static void psp_sem_lock(SceUID sem)
-{
- int ret = sceKernelWaitSema(sem, 1, 0);
- if (ret < 0) lprintf("sceKernelWaitSema(%08x) failed with %08x\n", sem, ret);
-}
-
-static void psp_sem_unlock(SceUID sem)
-{
- int ret = sceKernelSignalSema(sem, 1);
- if (ret < 0) lprintf("sceKernelSignalSema(%08x) failed with %08x\n", sem, ret);
-}
-
-// only accepts MPEG-1, layer3
-static int find_sync_word(unsigned char *data, int len)
-{
- int i;
- for (i = 0; i < len-1; i++)
- {
- if ( data[i+0] != 0xff) continue;
- if ((data[i+1] & 0xfe) == 0xfa) return i;
- i++;
- }
- return -1;
-}
-
-static int read_next_frame(int which_buffer)
-{
- int i, bytes_read, frame_offset;
- int bitrate, padding, frame_size = 0;
-
- for (i = 0; i < 32; i++)
- {
- bytes_read = sceIoRead(mp3_handle, mp3_src_buffer[which_buffer], sizeof(mp3_src_buffer[which_buffer]));
- mp3_src_pos += bytes_read;
- if (bytes_read < MIN_INFRAME_SIZE) {
- mp3_src_pos = mp3_src_size;
- return 0; // EOF/IO failure
- }
- frame_offset = find_sync_word(mp3_src_buffer[which_buffer], bytes_read);
- if (frame_offset < 0) {
- lprintf("missing syncword, foffs=%i\n", mp3_src_pos - bytes_read);
- mp3_src_pos--;
- sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
- continue;
- }
- if (bytes_read - frame_offset < 4) {
- lprintf("syncword @ EOB, foffs=%i\n", mp3_src_pos - bytes_read);
- mp3_src_pos--;
- sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
- continue;
- }
-
- bitrate = mp3_src_buffer[which_buffer][frame_offset+2] >> 4;
- padding = (mp3_src_buffer[which_buffer][frame_offset+2] & 2) >> 1;
-
- frame_size = 144000*bitrates[bitrate]/44100 + padding;
- if (frame_size <= 0) {
- lprintf("bad frame, foffs=%i\n", mp3_src_pos - bytes_read);
- continue; // bad frame
- }
-
- if (bytes_read - frame_offset < frame_size)
- {
- lprintf("unfit, foffs=%i\n", mp3_src_pos - bytes_read);
- mp3_src_pos -= bytes_read - frame_offset;
- if (mp3_src_size - mp3_src_pos < frame_size) {
- mp3_src_pos = mp3_src_size;
- return 0; // EOF
- }
- sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
- continue; // didn't fit, re-read..
- }
-
- if (frame_offset) {
- //lprintf("unaligned, foffs=%i, offs=%i\n", mp3_src_pos - bytes_read, frame_offset);
- memmove(mp3_src_buffer[which_buffer], mp3_src_buffer[which_buffer] + frame_offset, frame_size);
- }
-
- // align for next frame read
- mp3_src_pos -= bytes_read - (frame_offset + frame_size);
- sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
-
- break;
- }
-
- return frame_size > 0 ? frame_size : -1;
-}
-
-
-static SceUID load_start_module(const char *prxname)
-{
- SceUID mod, mod1;
- int status, ret;
-
- mod = pspSdkLoadStartModule(prxname, PSP_MEMORY_PARTITION_KERNEL);
- if (mod < 0) {
- lprintf("failed to load %s (%08x), trying kuKernelLoadModule\n", prxname, mod);
- mod1 = kuKernelLoadModule(prxname, 0, NULL);
- if (mod1 < 0) lprintf("kuKernelLoadModule failed with %08x\n", mod1);
- else {
- ret = sceKernelStartModule(mod1, 0, NULL, &status, 0);
- if (ret < 0) lprintf("sceKernelStartModule failed with %08x\n", ret);
- else mod = mod1;
- }
- }
- return mod;
-}
-
-
-int mp3_init(void)
-{
- SceUID thid, mod;
- int ret;
-
- /* load modules */
- /* <= 1.5 (and probably some other, not sure which) fw need this to for audiocodec to work,
- * so if it fails, assume we are just on new enough firmware and continue.. */
- load_start_module("flash0:/kd/me_for_vsh.prx");
-
- if (sceKernelDevkitVersion() < 0x02070010)
- mod = load_start_module("flash0:/kd/audiocodec.prx");
- else mod = load_start_module("flash0:/kd/avcodec.prx");
- if (mod < 0) {
- ret = mod;
- mod = load_start_module("flash0:/kd/audiocodec_260.prx"); // last chance..
- if (mod < 0) goto fail;
- }
-
- /* audiocodec init */
- memset(mp3_codec_struct, 0, sizeof(mp3_codec_struct));
- ret = sceAudiocodecCheckNeedMem(mp3_codec_struct, 0x1002);
- if (ret < 0) {
- lprintf("sceAudiocodecCheckNeedMem failed with %08x\n", ret);
- goto fail;
- }
-
- ret = sceAudiocodecGetEDRAM(mp3_codec_struct, 0x1002);
- if (ret < 0) {
- lprintf("sceAudiocodecGetEDRAM failed with %08x\n", ret);
- goto fail;
- }
-
- ret = sceAudiocodecInit(mp3_codec_struct, 0x1002);
- if (ret < 0) {
- lprintf("sceAudiocodecInit failed with %08x\n", ret);
- goto fail1;
- }
-
- /* thread and stuff */
- thread_job_sem = sceKernelCreateSema("p_mp3job_sem", 0, 0, 1, NULL);
- if (thread_job_sem < 0) {
- lprintf("sceKernelCreateSema() failed: %08x\n", thread_job_sem);
- ret = thread_job_sem;
- goto fail1;
- }
-
- thread_busy_sem = sceKernelCreateSema("p_mp3busy_sem", 0, 1, 1, NULL);
- if (thread_busy_sem < 0) {
- lprintf("sceKernelCreateSema() failed: %08x\n", thread_busy_sem);
- ret = thread_busy_sem;
- goto fail2;
- }
-
- /* use slightly higher prio then main */
- thread_exit = 0;
- thid = sceKernelCreateThread("mp3decode_thread", decode_thread, 30, 0x2000, 0, NULL);
- if (thid < 0) {
- lprintf("failed to create decode thread: %08x\n", thid);
- ret = thid;
- goto fail3;
- }
- ret = sceKernelStartThread(thid, 0, 0);
- if (ret < 0) {
- lprintf("failed to start decode thread: %08x\n", ret);
- goto fail3;
- }
-
- mp3_last_error = 0;
- initialized = 1;
- return 0;
-
-fail3:
- sceKernelDeleteSema(thread_busy_sem);
- thread_busy_sem = -1;
-fail2:
- sceKernelDeleteSema(thread_job_sem);
- thread_job_sem = -1;
-fail1:
- sceAudiocodecReleaseEDRAM(mp3_codec_struct);
-fail:
- mp3_last_error = ret;
- initialized = 0;
- return 1;
-}
-
-void mp3_deinit(void)
-{
- lprintf("mp3_deinit, initialized=%i\n", initialized);
-
- if (!initialized) return;
- thread_exit = 1;
- psp_sem_lock(thread_busy_sem);
- psp_sem_unlock(thread_busy_sem);
-
- sceKernelSignalSema(thread_job_sem, 1);
- sceKernelDelayThread(100*1000);
-
- if (mp3_handle >= 0) sceIoClose(mp3_handle);
- mp3_handle = -1;
- mp3_fname = NULL;
-
- sceKernelDeleteSema(thread_busy_sem);
- thread_busy_sem = -1;
- sceKernelDeleteSema(thread_job_sem);
- thread_job_sem = -1;
- sceAudiocodecReleaseEDRAM(mp3_codec_struct);
- initialized = 0;
-}
-
-// may overflow stack?
-static int decode_thread(SceSize args, void *argp)
-{
- int ret, frame_size;
-
- lprintf("decode_thread started with id %08x, priority %i\n",
- sceKernelGetThreadId(), sceKernelGetThreadCurrentPriority());
-
- while (!thread_exit)
- {
- psp_sem_lock(thread_job_sem);
- if (thread_exit) break;
-
- psp_sem_lock(thread_busy_sem);
- //lprintf("{ job\n");
-
- frame_size = read_next_frame(working_buf);
- if (frame_size > 0)
- {
- mp3_codec_struct[6] = (unsigned long)mp3_src_buffer[working_buf];
- mp3_codec_struct[8] = (unsigned long)mp3_mix_buffer[working_buf];
- mp3_codec_struct[7] = mp3_codec_struct[10] = frame_size;
- mp3_codec_struct[9] = 1152 * 4;
-
- ret = sceAudiocodecDecode(mp3_codec_struct, 0x1002);
- if (ret < 0) lprintf("sceAudiocodecDecode failed with %08x\n", ret);
- }
-
- //lprintf("} job\n");
- psp_sem_unlock(thread_busy_sem);
- }
-
- lprintf("leaving decode thread\n");
- sceKernelExitDeleteThread(0);
- return 0;
-}
-
-
-// might be called before initialization
-int mp3_get_bitrate(void *f, int size)
-{
- int ret, retval = -1, sample_rate, bitrate;
- // filenames are stored instead handles in PSP, due to stupid max open file limit
- char *fname = f;
-
- /* make sure thread is not busy.. */
- if (thread_busy_sem >= 0)
- psp_sem_lock(thread_busy_sem);
-
- if (mp3_handle >= 0) sceIoClose(mp3_handle);
- mp3_handle = sceIoOpen(fname, PSP_O_RDONLY, 0777);
- if (mp3_handle < 0) {
- lprintf("sceIoOpen(%s) failed\n", fname);
- goto end;
- }
-
- mp3_src_pos = 0;
- ret = read_next_frame(0);
- if (ret <= 0) {
- lprintf("read_next_frame() failed (%s)\n", fname);
- goto end;
- }
- sample_rate = (mp3_src_buffer[0][2] & 0x0c) >> 2;
- bitrate = mp3_src_buffer[0][2] >> 4;
-
- if (sample_rate != 0) {
- lprintf("unsupported samplerate (%s)\n", fname);
- goto end; // only 44kHz supported..
- }
- bitrate = bitrates[bitrate];
- if (bitrate == 0) {
- lprintf("unsupported bitrate (%s)\n", fname);
- goto end;
- }
-
- /* looking good.. */
- retval = bitrate;
-end:
- if (mp3_handle >= 0) sceIoClose(mp3_handle);
- mp3_handle = -1;
- mp3_fname = NULL;
- if (thread_busy_sem >= 0)
- psp_sem_unlock(thread_busy_sem);
- if (retval < 0) mp3_last_error = -1; // remember we had a problem..
- return retval;
-}
-
-
-static int mp3_job_started = 0, mp3_samples_ready = 0, mp3_buffer_offs = 0, mp3_play_bufsel = 0;
-
-void mp3_start_play(void *f, int pos)
-{
- char *fname = f;
-
- if (!initialized) return;
-
- lprintf("mp3_start_play(%s) @ %i\n", fname, pos);
- psp_sem_lock(thread_busy_sem);
-
- if (mp3_fname != fname || mp3_handle < 0)
- {
- if (mp3_handle >= 0) sceIoClose(mp3_handle);
- mp3_handle = sceIoOpen(fname, PSP_O_RDONLY, 0777);
- if (mp3_handle < 0) {
- lprintf("sceIoOpen(%s) failed\n", fname);
- psp_sem_unlock(thread_busy_sem);
- return;
- }
- mp3_src_size = sceIoLseek32(mp3_handle, 0, PSP_SEEK_END);
- mp3_fname = fname;
- }
-
- // clear decoder state
- sceAudiocodecInit(mp3_codec_struct, 0x1002);
-
- // seek..
- mp3_src_pos = (int) (((float)pos / 1023.0f) * (float)mp3_src_size);
- sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
- lprintf("seek %i: %i/%i\n", pos, mp3_src_pos, mp3_src_size);
-
- mp3_job_started = 1;
- mp3_samples_ready = mp3_buffer_offs = mp3_play_bufsel = 0;
- working_buf = 0;
-
- /* send a request to decode first frame */
- psp_sem_unlock(thread_busy_sem);
- psp_sem_unlock(thread_job_sem);
- sceKernelDelayThread(1); // reschedule
-}
-
-
-void mp3_update(int *buffer, int length, int stereo)
-{
- int length_mp3;
-
- // playback was started, track not ended
- if (mp3_handle < 0 || mp3_src_pos >= mp3_src_size) return;
-
- length_mp3 = length;
- if (PsndRate == 22050) length_mp3 <<= 1; // mp3s are locked to 44100Hz stereo
- else if (PsndRate == 11025) length_mp3 <<= 2; // so make length 44100ish
-
- /* do we have to wait? */
- if (mp3_job_started && mp3_samples_ready < length_mp3)
- {
- psp_sem_lock(thread_busy_sem);
- psp_sem_unlock(thread_busy_sem);
- mp3_job_started = 0;
- mp3_samples_ready += 1152;
- }
-
- /* mix mp3 data, only stereo */
- if (mp3_samples_ready >= length_mp3)
- {
- int shr = 0;
- void (*mix_samples)(int *dest_buf, short *mp3_buf, int count) = mix_16h_to_32;
- if (PsndRate == 22050) { mix_samples = mix_16h_to_32_s1; shr = 1; }
- else if (PsndRate == 11025) { mix_samples = mix_16h_to_32_s2; shr = 2; }
-
- if (1152 - mp3_buffer_offs >= length_mp3) {
- mix_samples(buffer, mp3_mix_buffer[mp3_play_bufsel] + mp3_buffer_offs*2, length<<1);
-
- mp3_buffer_offs += length_mp3;
- } else {
- // collect samples from both buffers..
- int left = 1152 - mp3_buffer_offs;
- if (mp3_play_bufsel == 0)
- {
- mix_samples(buffer, mp3_mix_buffer[0] + mp3_buffer_offs*2, length<<1);
- mp3_buffer_offs = length_mp3 - left;
- mp3_play_bufsel = 1;
- } else {
- mix_samples(buffer, mp3_mix_buffer[1] + mp3_buffer_offs*2, (left>>shr)<<1);
- mp3_buffer_offs = length_mp3 - left;
- mix_samples(buffer + ((left>>shr)<<1),
- mp3_mix_buffer[0], (mp3_buffer_offs>>shr)<<1);
- mp3_play_bufsel = 0;
- }
- }
- mp3_samples_ready -= length_mp3;
- }
-
- // ask to decode more if we already can
- if (!mp3_job_started)
- {
- mp3_job_started = 1;
- working_buf ^= 1;
-
- /* next job.. */
- psp_sem_lock(thread_busy_sem); // just in case
- psp_sem_unlock(thread_busy_sem);
- psp_sem_unlock(thread_job_sem);
- sceKernelDelayThread(1);
- }
-}
-
-
-int mp3_get_offset(void) // 0-1023
-{
- unsigned int offs1024 = 0;
- int cdda_on;
-
- cdda_on = (PicoAHW & PAHW_MCD) && (PicoOpt&0x800) && !(Pico_mcd->s68k_regs[0x36] & 1) &&
- (Pico_mcd->scd.Status_CDC & 1) && mp3_handle >= 0;
-
- if (cdda_on) {
- offs1024 = mp3_src_pos << 7;
- offs1024 /= mp3_src_size >> 3;
- }
- lprintf("offs1024=%u (%i/%i)\n", offs1024, mp3_src_pos, mp3_src_size);
-
- return offs1024;
-}
-
-
-void mp3_reopen_file(void)
-{
- if (mp3_fname == NULL) return;
- lprintf("mp3_reopen_file(%s)\n", mp3_fname);
-
- // try closing, just in case
- if (mp3_handle >= 0) sceIoClose(mp3_handle);
-
- mp3_handle = sceIoOpen(mp3_fname, PSP_O_RDONLY, 0777);
- if (mp3_handle >= 0)
- sceIoLseek32(mp3_handle, mp3_src_pos, PSP_SEEK_SET);
- lprintf("mp3_reopen_file %s\n", mp3_handle >= 0 ? "ok" : "failed");
-}
-
+++ /dev/null
-
-// additional stuff for PSP mp3 decoder implementation
-extern int mp3_last_error;
-
-int mp3_init(void);
-void mp3_deinit(void);
-void mp3_reopen_file(void);
-
+++ /dev/null
-// port specific settings\r
-\r
-#ifndef PORT_CONFIG_H\r
-#define PORT_CONFIG_H\r
-\r
-#define CASE_SENSITIVE_FS 0\r
-#define DONT_OPEN_MANY_FILES 1 // work around the stupid PSP ~10 open file limit\r
-#define REDUCE_IO_CALLS 1 // another workaround\r
-#define SIMPLE_WRITE_SOUND 0\r
-\r
-#define SCREEN_SIZE_FIXED 1\r
-#define SCREEN_WIDTH 512\r
-#define SCREEN_HEIGHT 272\r
-#define MSCREEN_SIZE_FIXED 1\r
-#define MSCREEN_WIDTH SCREEN_WIDTH\r
-#define MSCREEN_HEIGHT SCREEN_HEIGHT\r
-\r
-// draw.c\r
-#define USE_BGR555 1\r
-\r
-// draw2.c\r
-#define START_ROW 0 // which row of tiles to start rendering at?\r
-#define END_ROW 28 // ..end\r
-#define DRAW2_OVERRIDE_LINE_WIDTH 512\r
-\r
-// pico.c\r
-extern void blit1(void);\r
-#define DRAW_FINISH_FUNC blit1\r
-#define CAN_HANDLE_240_LINES 1\r
-\r
-// logging emu events\r
-#define EL_LOGMASK (EL_STATUS|EL_IDLE) // (EL_STATUS|EL_ANOMALY|EL_UIO|EL_SRAMIO) // xffff\r
-\r
-//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)\r
-#define dprintf(x...)\r
-\r
-// platform\r
-#define PATH_SEP "/"\r
-#define PATH_SEP_C '/'\r
-#define MENU_X2 0\r
-\r
-#endif //PORT_CONFIG_H\r
+++ /dev/null
-// (c) Copyright 2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <pspkernel.h>
-#include <pspiofilemgr.h>
-#include <pspdisplay.h>
-#include <psppower.h>
-#include <psprtc.h>
-#include <pspgu.h>
-#include <pspsdk.h>
-
-#include "psp.h"
-#include "emu.h"
-#include "../common/lprintf.h"
-#include "version.h"
-
-extern int pico_main(void);
-
-#ifndef FW15
-
-PSP_MODULE_INFO("PicoDrive", 0, 1, 51);
-PSP_HEAP_SIZE_MAX();
-
-int main() { return pico_main(); } /* just a wrapper */
-
-#else
-
-PSP_MODULE_INFO("PicoDrive", 0x1000, 1, 51);
-PSP_MAIN_THREAD_ATTR(0);
-
-int main()
-{
- SceUID thid;
-
- /* this is the thing we need the kernel mode for */
- pspSdkInstallNoDeviceCheckPatch();
-
- thid = sceKernelCreateThread("pico_main", (SceKernelThreadEntry) pico_main, 32, 0x2000, PSP_THREAD_ATTR_USER, NULL);
- if (thid >= 0)
- sceKernelStartThread(thid, 0, 0);
-#ifndef GCOV
- sceKernelExitDeleteThread(0);
-#else
- while (engineState != PGS_Quit)
- sceKernelDelayThread(1024 * 1024);
-#endif
-
- return 0;
-}
-
-#endif
-
-int psp_unhandled_suspend = 0;
-
-unsigned int __attribute__((aligned(16))) guCmdList[GU_CMDLIST_SIZE];
-
-void *psp_screen = VRAM_FB0;
-
-static int current_screen = 0; /* front bufer */
-
-static SceUID main_thread_id = -1;
-
-#define ANALOG_DEADZONE 80
-
-/* Exit callback */
-static int exit_callback(int arg1, int arg2, void *common)
-{
- sceKernelExitGame();
- return 0;
-}
-
-/* Power Callback */
-static int power_callback(int unknown, int pwrflags, void *common)
-{
- lprintf("power_callback: flags: 0x%08X\n", pwrflags);
-
- /* check for power switch and suspending as one is manual and the other automatic */
- if (pwrflags & PSP_POWER_CB_POWER_SWITCH || pwrflags & PSP_POWER_CB_SUSPENDING || pwrflags & PSP_POWER_CB_STANDBY)
- {
- psp_unhandled_suspend = 1;
- if (engineState != PGS_Suspending)
- engineStateSuspend = engineState;
- sceKernelDelayThread(100000); // ??
- }
- else if (pwrflags & PSP_POWER_CB_RESUME_COMPLETE)
- {
- engineState = PGS_SuspendWake;
- }
-
- //sceDisplayWaitVblankStart();
- return 0;
-}
-
-/* Callback thread */
-static int callback_thread(SceSize args, void *argp)
-{
- int cbid;
-
- lprintf("callback_thread started with id %08x, priority %i\n",
- sceKernelGetThreadId(), sceKernelGetThreadCurrentPriority());
-
- cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
- sceKernelRegisterExitCallback(cbid);
- cbid = sceKernelCreateCallback("Power Callback", power_callback, NULL);
- scePowerRegisterCallback(0, cbid);
-
- sceKernelSleepThreadCB();
-
- return 0;
-}
-
-void psp_init(void)
-{
- SceUID thid;
- char buff[128], *r;
-
- /* fw 1.5 sometimes returns 8002032c, although getcwd works */
- r = getcwd(buff, sizeof(buff));
- if (r) sceIoChdir(buff);
-
- main_thread_id = sceKernelGetThreadId();
-
- lprintf("\n%s\n", "PicoDrive v" VERSION " " __DATE__ " " __TIME__);
- lprintf("running on %08x kernel\n", sceKernelDevkitVersion()),
- lprintf("entered psp_init, threadId %08x, priority %i\n", main_thread_id,
- sceKernelGetThreadCurrentPriority());
-
- thid = sceKernelCreateThread("update_thread", callback_thread, 0x11, 0xFA0, 0, NULL);
- if (thid >= 0)
- {
- sceKernelStartThread(thid, 0, 0);
- }
-
- /* video */
- sceDisplaySetMode(0, 480, 272);
- sceDisplaySetFrameBuf(VRAM_FB1, 512, PSP_DISPLAY_PIXEL_FORMAT_565, PSP_DISPLAY_SETBUF_NEXTFRAME);
- current_screen = 1;
- psp_screen = VRAM_FB0;
-
- /* gu */
- sceGuInit();
-
- sceGuStart(GU_DIRECT, guCmdList);
- sceGuDrawBuffer(GU_PSM_5650, (void *)VRAMOFFS_FB0, 512);
- sceGuDispBuffer(480, 272, (void *)VRAMOFFS_FB1, 512); // don't care
- sceGuClear(GU_COLOR_BUFFER_BIT | GU_DEPTH_BUFFER_BIT);
- sceGuDepthBuffer((void *)VRAMOFFS_DEPTH, 512);
- sceGuOffset(2048 - (480 / 2), 2048 - (272 / 2));
- sceGuViewport(2048, 2048, 480, 272);
- sceGuDepthRange(0xc350, 0x2710);
- sceGuScissor(0, 0, 480, 272);
- sceGuEnable(GU_SCISSOR_TEST);
-
- sceGuDepthMask(0xffff);
- sceGuDisable(GU_DEPTH_TEST);
-
- sceGuFrontFace(GU_CW);
- sceGuEnable(GU_TEXTURE_2D);
- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
- sceGuAmbientColor(0xffffffff);
- sceGuColor(0xffffffff);
- sceGuFinish();
- sceGuSync(0, 0);
-
- sceDisplayWaitVblankStart();
- sceGuDisplay(GU_TRUE);
-
-
- /* input */
- sceCtrlSetSamplingCycle(0);
- sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
-}
-
-void psp_finish(void)
-{
- lprintf("psp_finish..\n");
- sceGuTerm();
-
- //sceKernelSleepThread();
- sceKernelExitGame();
-}
-
-void psp_video_flip(int wait_vsync)
-{
- if (wait_vsync) sceDisplayWaitVblankStart();
- sceDisplaySetFrameBuf(psp_screen, 512, PSP_DISPLAY_PIXEL_FORMAT_565,
- wait_vsync ? PSP_DISPLAY_SETBUF_IMMEDIATE : PSP_DISPLAY_SETBUF_NEXTFRAME);
- current_screen ^= 1;
- psp_screen = current_screen ? VRAM_FB0 : VRAM_FB1;
-}
-
-void *psp_video_get_active_fb(void)
-{
- return current_screen ? VRAM_FB1 : VRAM_FB0;
-}
-
-void psp_video_switch_to_single(void)
-{
- psp_screen = VRAM_FB0;
- sceDisplaySetFrameBuf(psp_screen, 512, PSP_DISPLAY_PIXEL_FORMAT_565, PSP_DISPLAY_SETBUF_NEXTFRAME);
- current_screen = 0;
-}
-
-void psp_msleep(int ms)
-{
- sceKernelDelayThread(ms * 1000);
-}
-
-unsigned int psp_pad_read(int blocking)
-{
- unsigned int buttons;
- SceCtrlData pad;
- if (blocking)
- sceCtrlReadBufferPositive(&pad, 1);
- else sceCtrlPeekBufferPositive(&pad, 1);
- buttons = pad.Buttons;
-
- // analog..
- buttons &= ~(PBTN_NUB_UP|PBTN_NUB_DOWN|PBTN_NUB_LEFT|PBTN_NUB_RIGHT);
- if (pad.Lx < 128 - ANALOG_DEADZONE) buttons |= PBTN_NUB_LEFT;
- if (pad.Lx > 128 + ANALOG_DEADZONE) buttons |= PBTN_NUB_RIGHT;
- if (pad.Ly < 128 - ANALOG_DEADZONE) buttons |= PBTN_NUB_UP;
- if (pad.Ly > 128 + ANALOG_DEADZONE) buttons |= PBTN_NUB_DOWN;
-
- return buttons;
-}
-
-int psp_get_cpu_clock(void)
-{
- return scePowerGetCpuClockFrequencyInt();
-}
-
-int psp_set_cpu_clock(int clock)
-{
- int ret = scePowerSetClockFrequency(clock, clock, clock/2);
- if (ret != 0) lprintf("failed to set clock: %i\n", ret);
-
- return ret;
-}
-
-char *psp_get_status_line(void)
-{
- static char buff[64];
- int ret, bat_percent, bat_time;
- pspTime time;
-
- ret = sceRtcGetCurrentClockLocalTime(&time);
- bat_percent = scePowerGetBatteryLifePercent();
- bat_time = scePowerGetBatteryLifeTime();
- if (ret < 0 || bat_percent < 0 || bat_time < 0) return NULL;
-
- snprintf(buff, sizeof(buff), "%02i:%02i bat: %3i%%", time.hour, time.minutes, bat_percent);
- if (!scePowerIsPowerOnline())
- snprintf(buff+strlen(buff), sizeof(buff)-strlen(buff), " (%i:%02i)", bat_time/60, bat_time%60);
- return buff;
-}
-
-void psp_wait_suspend(void)
-{
- // probably should do something smarter here?
- sceDisplayWaitVblankStart();
-}
-
-void psp_resume_suspend(void)
-{
- // for some reason file IO doesn't seem to work
- // after resume for some period of time, at least on 1.5
- SceUID fd;
- int i;
- for (i = 0; i < 30; i++) {
- fd = sceIoOpen("EBOOT.PBP", PSP_O_RDONLY, 0777);
- if (fd >= 0) break;
- sceKernelDelayThread(100 * 1024);
- }
- if (fd >= 0) sceIoClose(fd);
- sceDisplayWaitVblankStart();
- if (i < 30)
- lprintf("io resumed after %i tries\n", i);
- else {
- lprintf("io resume failed with %08x\n", fd);
- sceKernelDelayThread(500 * 1024);
- }
-}
-
-/* alt logging */
-#define LOG_FILE "log.txt"
-
-#ifndef LPRINTF_STDIO
-typedef struct _log_entry
-{
- char buff[256];
- struct _log_entry *next;
-} log_entry;
-
-static log_entry *le_root = NULL;
-#endif
-
-/* strange: if this function leaks memory (before psp_init() call?),
- * resume after suspend breaks on 3.90 */
-void lprintf(const char *fmt, ...)
-{
- va_list vl;
-
-#ifdef LPRINTF_STDIO
- va_start(vl, fmt);
- vprintf(fmt, vl);
- va_end(vl);
-#else
- static SceUID logfd = -1;
- static int msg_count = 0;
- char buff[256];
- log_entry *le, *le1;
-
- if (logfd == -2) return; // disabled
-
- va_start(vl, fmt);
- vsnprintf(buff, sizeof(buff), fmt, vl);
- va_end(vl);
-
- // note: this is still unsafe code
- if (main_thread_id != sceKernelGetThreadId())
- {
- le = malloc(sizeof(*le));
- if (le == NULL) return;
- le->next = NULL;
- strcpy(le->buff, buff);
- if (le_root == NULL) le_root = le;
- else {
- for (le1 = le_root; le1->next != NULL; le1 = le1->next);
- le1->next = le;
- }
- return;
- }
-
- logfd = sceIoOpen(LOG_FILE, PSP_O_WRONLY|PSP_O_APPEND, 0777);
- if (logfd < 0) {
- if (msg_count == 0) logfd = -2;
- return;
- }
-
- if (le_root != NULL)
- {
- le1 = le_root;
- le_root = NULL;
- sceKernelDelayThread(1000);
- while (le1 != NULL) {
- le = le1;
- le1 = le->next;
- sceIoWrite(logfd, le->buff, strlen(le->buff));
- free(le);
- msg_count++;
- }
- }
-
- sceIoWrite(logfd, buff, strlen(buff));
- msg_count++;
-
- // make sure it gets flushed
- sceIoClose(logfd);
- logfd = -1;
-#endif
-}
-
-
+++ /dev/null
-// (c) Copyright 2007 notaz, All rights reserved.
-// Free for non-commercial use.
-
-// For commercial use, separate licencing terms must be obtained.
-
-#include <pspctrl.h>
-
-void psp_init(void);
-void psp_finish(void);
-
-void psp_msleep(int ms);
-
-// vram usage map:
-// 000000-044000 fb0
-// 044000-088000 fb1
-// 088000-0cc000 depth (?)
-// 0cc000-126000 emu draw buffers: 512*240 + 512*240*2
-
-#define VRAMOFFS_FB0 0x00000000
-#define VRAMOFFS_FB1 0x00044000
-#define VRAMOFFS_DEPTH 0x00088000
-#define VRAMOFFS_STUFF 0x000cc000
-
-#define VRAM_FB0 ((void *) (0x44000000+VRAMOFFS_FB0))
-#define VRAM_FB1 ((void *) (0x44000000+VRAMOFFS_FB1))
-#define VRAM_STUFF ((void *) (0x44000000+VRAMOFFS_STUFF))
-
-#define VRAM_CACHED_STUFF ((void *) (0x04000000+VRAMOFFS_STUFF))
-
-#define GU_CMDLIST_SIZE (16*1024)
-
-extern unsigned int guCmdList[GU_CMDLIST_SIZE];
-extern int psp_unhandled_suspend;
-
-void *psp_video_get_active_fb(void);
-void psp_video_switch_to_single(void);
-void psp_video_flip(int wait_vsync);
-extern void *psp_screen;
-
-unsigned int psp_pad_read(int blocking);
-
-int psp_get_cpu_clock(void);
-int psp_set_cpu_clock(int clock);
-
-char *psp_get_status_line(void);
-
-void psp_wait_suspend(void);
-void psp_resume_suspend(void);
-
-/* shorter btn names */
-#define PBTN_UP PSP_CTRL_UP
-#define PBTN_LEFT PSP_CTRL_LEFT
-#define PBTN_RIGHT PSP_CTRL_RIGHT
-#define PBTN_DOWN PSP_CTRL_DOWN
-#define PBTN_L PSP_CTRL_LTRIGGER
-#define PBTN_R PSP_CTRL_RTRIGGER
-#define PBTN_TRIANGLE PSP_CTRL_TRIANGLE
-#define PBTN_CIRCLE PSP_CTRL_CIRCLE
-#define PBTN_X PSP_CTRL_CROSS
-#define PBTN_SQUARE PSP_CTRL_SQUARE
-#define PBTN_SELECT PSP_CTRL_SELECT
-#define PBTN_START PSP_CTRL_START
-#define PBTN_NOTE PSP_CTRL_NOTE // doesn't seem to work?
-
-/* fake 'nub' btns */
-#define PBTN_NUB_UP (1 << 28)
-#define PBTN_NUB_RIGHT (1 << 29)
-#define PBTN_NUB_DOWN (1 << 30)
-#define PBTN_NUB_LEFT (1 << 31)
-
+++ /dev/null
-#define VERSION "1.51b"\r
-\r
+++ /dev/null
-# settings
-CROSS=i586-mingw32msvc-
-
-#use_musashi = 1
-use_fame = 1
-use_cz80 = 1
-use_sh2drc = 1
-#use_sh2mame = 1
-
--include Makefile.local
-
-ARCH ?= x86
-CC = $(CROSS)gcc
-CXX = $(CROSS)g++
-LD = $(CROSS)ld
-STRIP = $(CROSS)strip
-
-DEFINES = _UNZIP_SUPPORT IN_VK
-CFLAGS += -O2 -Wall -falign-functions=2 -ffast-math
-CFLAGS += -I../.. -I. -I../../zlib/ -Idirectx/include/
-LDFLAGS += -mwindows -L. -Ldirectx/lib/ -lgdi32 -lcomdlg32 -lddraw -ldsound -ldxguid
-
-# frontend
-OBJS += main.o plat.o direct.o dsnd.o in_vk.o
-
-# common
-OBJS += platform/common/emu.o platform/common/menu.o \
- platform/common/config.o platform/common/fonts.o platform/common/readpng.o \
- platform/common/input.o
-
-OBJS += pico/carthw/svp/compiler.o
-OBJS += pico/sound/mix.o
-# zlib
-OBJS += zlib/gzio.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o \
- zlib/deflate.o zlib/crc32.o zlib/adler32.o zlib/zutil.o zlib/compress.o zlib/uncompr.o
-# unzip
-OBJS += unzip/unzip.o unzip/unzip_stream.o
-
-CFLAGS += $(addprefix -D,$(DEFINES))
-CXXFLAGS = $(CFLAGS)
-
-vpath %.c = ../..
-
-DIRS += zlib unzip
-
-TARGET = PicoDrive.exe
-all: mkdirs $(TARGET)
-
-include ../common/common.mak
-include ../common/revision.mak
-
-clean: tidy
- @$(RM) $(TARGET)
-tidy:
- $(RM) $(OBJS) $(TARGET).map
- rm -rf $(DIRS)
-
-$(TARGET) : $(OBJS)
- @echo ">>>" $@
- $(CC) $(CFLAGS) $^ $(LDFLAGS) -lm -lpng -Wl,-Map=$(TARGET).map -o $@
- $(STRIP) $@
-
-# ----------- release -----------
-ifneq ($(findstring rel,$(MAKECMDGOALS)),)
-ifeq ($(VER),)
-$(error need VER)
-endif
-endif
-
-rel: $(TARGET) readme.txt carthw.cfg
- zip -9 -j ../../PicoDrive_win32_$(VER).zip $^
-
+++ /dev/null
-#include <windows.h>\r
-#include <commdlg.h>\r
-#include <stdio.h>\r
-\r
-#include "../../pico/pico.h"\r
-#include "../common/readpng.h"\r
-#include "../common/config.h"\r
-#include "../common/lprintf.h"\r
-#include "../common/emu.h"\r
-#include "../common/menu.h"\r
-#include "../common/input.h"\r
-#include "../common/plat.h"\r
-#include "version.h"\r
-#include "direct.h"\r
-#include "in_vk.h"\r
-\r
-char *romname=NULL;\r
-HWND FrameWnd=NULL;\r
-RECT FrameRectMy;\r
-RECT EmuScreenRect = { 0, 0, 320, 224 };\r
-int lock_to_1_1 = 1;\r
-static HWND PicoSwWnd=NULL, PicoPadWnd=NULL;\r
-\r
-static HMENU mmain = 0, mdisplay = 0, mpicohw = 0;\r
-static HBITMAP ppad_bmp = 0;\r
-static HBITMAP ppage_bmps[7] = { 0, };\r
-static char rom_name[0x20*3+1];\r
-static int main_wnd_as_pad = 0;\r
-\r
-static HANDLE loop_enter_event, loop_end_event;\r
-\r
-void error(char *text)\r
-{\r
- MessageBox(FrameWnd, text, "Error", 0);\r
-}\r
-\r
-static void UpdateRect(void)\r
-{\r
- WINDOWINFO wi;\r
- memset(&wi, 0, sizeof(wi));\r
- wi.cbSize = sizeof(wi);\r
- GetWindowInfo(FrameWnd, &wi);\r
- FrameRectMy = wi.rcClient;\r
-}\r
-\r
-static int extract_rom_name(char *dest, const unsigned char *src, int len)\r
-{\r
- char *p = dest, s_old = 0x20;\r
- int i;\r
-\r
- for (i = len - 1; i >= 0; i--)\r
- {\r
- if (src[i^1] != ' ') break;\r
- }\r
- len = i + 1;\r
-\r
- for (i = 0; i < len; i++)\r
- {\r
- unsigned char s = src[i^1];\r
- if (s == 0x20 && s_old == 0x20) continue;\r
- else if (s >= 0x20 && s < 0x7f && s != '%')\r
- {\r
- *p++ = s;\r
- }\r
- else\r
- {\r
- sprintf(p, "%%%02x", s);\r
- p += 3;\r
- }\r
- s_old = s;\r
- }\r
- *p = 0;\r
-\r
- return p - dest;\r
-}\r
-\r
-static void check_name_alias(const char *afname)\r
-{\r
- char buff[256], *var, *val;\r
- FILE *f;\r
- int ret;\r
-\r
- f = fopen(afname, "r");\r
- if (f == NULL) return;\r
-\r
- while (1)\r
- {\r
- ret = config_get_var_val(f, buff, sizeof(buff), &var, &val);\r
- if (ret == 0) break;\r
- if (ret == -1) continue;\r
-\r
- if (strcmp(rom_name, var) == 0) {\r
- lprintf("rom aliased: \"%s\" -> \"%s\"\n", rom_name, val);\r
- strncpy(rom_name, val, sizeof(rom_name));\r
- break;\r
- }\r
- }\r
- fclose(f);\r
-}\r
-\r
-static HBITMAP png2hb(const char *fname, int is_480)\r
-{\r
- BITMAPINFOHEADER bih;\r
- HBITMAP bmp;\r
- void *bmem;\r
- int ret;\r
-\r
- bmem = calloc(1, is_480 ? 480*240*3 : 320*240*3);\r
- if (bmem == NULL) return NULL;\r
- ret = readpng(bmem, fname, READPNG_24, is_480 ? 480 : 320, 240);\r
- if (ret != 0) {\r
- free(bmem);\r
- return NULL;\r
- }\r
-\r
- memset(&bih, 0, sizeof(bih));\r
- bih.biSize = sizeof(bih);\r
- bih.biWidth = is_480 ? 480 : 320;\r
- bih.biHeight = -240;\r
- bih.biPlanes = 1;\r
- bih.biBitCount = 24;\r
- bih.biCompression = BI_RGB;\r
- bmp = CreateDIBitmap(GetDC(FrameWnd), &bih, CBM_INIT, bmem, (BITMAPINFO *)&bih, 0);\r
- if (bmp == NULL)\r
- lprintf("CreateDIBitmap failed with %i", GetLastError());\r
-\r
- free(bmem);\r
- return bmp;\r
-}\r
-\r
-static void PrepareForROM(void)\r
-{\r
- unsigned char *rom_data = NULL;\r
- int i, ret, show = PicoAHW & PAHW_PICO;\r
- \r
- PicoGetInternal(PI_ROM, (pint_ret_t *) &rom_data);\r
- EnableMenuItem(mmain, 2, MF_BYPOSITION|(show ? MF_ENABLED : MF_GRAYED));\r
- ShowWindow(PicoPadWnd, show ? SW_SHOWNA : SW_HIDE);\r
- ShowWindow(PicoSwWnd, show ? SW_SHOWNA : SW_HIDE);\r
- CheckMenuItem(mpicohw, 1210, show ? MF_CHECKED : MF_UNCHECKED);\r
- CheckMenuItem(mpicohw, 1211, show ? MF_CHECKED : MF_UNCHECKED);\r
- PostMessage(FrameWnd, WM_COMMAND, 1220 + PicoPicohw.page, 0);\r
- DrawMenuBar(FrameWnd);\r
- InvalidateRect(PicoSwWnd, NULL, 1);\r
-\r
- PicoPicohw.pen_pos[0] =\r
- PicoPicohw.pen_pos[1] = 0x8000;\r
- in_vk_add_pl12 = 0;\r
-\r
- ret = extract_rom_name(rom_name, rom_data + 0x150, 0x20);\r
- if (ret == 0)\r
- extract_rom_name(rom_name, rom_data + 0x130, 0x20);\r
-\r
- if (show)\r
- {\r
- char path[MAX_PATH], *p;\r
- GetModuleFileName(NULL, path, sizeof(path) - 32);\r
- p = strrchr(path, '\\');\r
- if (p == NULL) p = path;\r
- else p++;\r
- if (ppad_bmp == NULL) {\r
- strcpy(p, "pico\\pad.png");\r
- ppad_bmp = png2hb(path, 0);\r
- }\r
-\r
- strcpy(p, "pico\\alias.txt");\r
- check_name_alias(path);\r
-\r
- for (i = 0; i < 7; i++) {\r
- if (ppage_bmps[i] != NULL) DeleteObject(ppage_bmps[i]);\r
- sprintf(p, "pico\\%s_%i.png", rom_name, i);\r
- ppage_bmps[i] = png2hb(path, 1);\r
- }\r
- // games usually don't have page 6, so just duplicate page 5.\r
- if (ppage_bmps[6] == NULL && ppage_bmps[5] != NULL) {\r
- sprintf(p, "pico\\%s_5.png", rom_name);\r
- ppage_bmps[6] = png2hb(path, 1);\r
- }\r
- }\r
-}\r
-\r
-static void LoadROM(const char *cmdpath)\r
-{\r
- char rompath[MAX_PATH];\r
- int ret;\r
-\r
- if (cmdpath != NULL && strlen(cmdpath)) {\r
- strcpy(rompath, cmdpath + (cmdpath[0] == '\"' ? 1 : 0));\r
- if (rompath[strlen(rompath)-1] == '\"')\r
- rompath[strlen(rompath)-1] = 0;\r
- }\r
- else {\r
- OPENFILENAME of; ZeroMemory(&of, sizeof(of));\r
- rompath[sizeof(rompath) - 1] = 0;\r
- strncpy(rompath, rom_fname_loaded, sizeof(rompath) - 1);\r
- of.lStructSize = sizeof(of);\r
- of.lpstrFilter = "ROMs, CD images\0*.smd;*.bin;*.gen;*.zip;*.32x;*.sms;*.iso;*.cso;*.cue\0"\r
- "whatever\0*.*\0";\r
- of.lpstrFile = rompath;\r
- of.nMaxFile = MAX_PATH;\r
- of.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;\r
- of.hwndOwner = FrameWnd;\r
- if (!GetOpenFileName(&of))\r
- return;\r
- }\r
-\r
- if (engineState == PGS_Running) {\r
- engineState = PGS_Paused;\r
- WaitForSingleObject(loop_end_event, 5000);\r
- }\r
-\r
- ret = emu_reload_rom(rompath);\r
- if (ret == 0) {\r
- extern char menu_error_msg[]; // HACK..\r
- error(menu_error_msg);\r
- return;\r
- }\r
-\r
- PrepareForROM();\r
- engineState = PGS_Running;\r
- SetEvent(loop_enter_event);\r
-}\r
-\r
-static const int rect_widths[4] = { 320, 256, 640, 512 };\r
-static const int rect_heights[4] = { 224, 224, 448, 448 };\r
-\r
-// Window proc for the frame window:\r
-static LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)\r
-{\r
- POINT pt;\r
- RECT rc;\r
- int i;\r
- switch (msg)\r
- {\r
- case WM_CLOSE:\r
- PostQuitMessage(0);\r
- return 0;\r
- case WM_DESTROY:\r
- FrameWnd = NULL; // Blank the handle\r
- break;\r
- case WM_SIZE:\r
- case WM_MOVE:\r
- case WM_SIZING:\r
- UpdateRect();\r
- if (lock_to_1_1 && FrameRectMy.right - FrameRectMy.left != 0 &&\r
- (FrameRectMy.right - FrameRectMy.left != EmuScreenRect.right - EmuScreenRect.left ||\r
- FrameRectMy.bottom - FrameRectMy.top != EmuScreenRect.bottom - EmuScreenRect.top)) {\r
- lock_to_1_1 = 0;\r
- CheckMenuItem(mdisplay, 1104, MF_UNCHECKED);\r
- }\r
- break;\r
- case WM_COMMAND:\r
- switch (LOWORD(wparam))\r
- {\r
- case 1000:\r
- LoadROM(NULL);\r
- break;\r
- case 1001:\r
- emu_reset_game();\r
- return 0;\r
- case 1002:\r
- PostQuitMessage(0);\r
- return 0;\r
- case 1100:\r
- case 1101:\r
- case 1102:\r
- case 1103:\r
-// LoopWait=1; // another sync hack\r
-// for (i = 0; !LoopWaiting && i < 10; i++) Sleep(10);\r
- FrameRectMy.right = FrameRectMy.left + rect_widths[wparam&3];\r
- FrameRectMy.bottom = FrameRectMy.top + rect_heights[wparam&3];\r
- AdjustWindowRect(&FrameRectMy, WS_OVERLAPPEDWINDOW, 1);\r
- MoveWindow(hwnd, FrameRectMy.left, FrameRectMy.top,\r
- FrameRectMy.right-FrameRectMy.left, FrameRectMy.bottom-FrameRectMy.top, 1);\r
- UpdateRect();\r
- lock_to_1_1 = 0;\r
- CheckMenuItem(mdisplay, 1104, MF_UNCHECKED);\r
-// if (rom_loaded) LoopWait=0;\r
- return 0;\r
- case 1104:\r
- lock_to_1_1 = !lock_to_1_1;\r
- CheckMenuItem(mdisplay, 1104, lock_to_1_1 ? MF_CHECKED : MF_UNCHECKED);\r
- /* FALLTHROUGH */\r
- case 2000: // EmuScreenRect/FrameRectMy sync request\r
- if (!lock_to_1_1)\r
- return 0;\r
- FrameRectMy.right = FrameRectMy.left + (EmuScreenRect.right - EmuScreenRect.left);\r
- FrameRectMy.bottom = FrameRectMy.top + (EmuScreenRect.bottom - EmuScreenRect.top);\r
- AdjustWindowRect(&FrameRectMy, WS_OVERLAPPEDWINDOW, 1);\r
- MoveWindow(hwnd, FrameRectMy.left, FrameRectMy.top,\r
- FrameRectMy.right-FrameRectMy.left, FrameRectMy.bottom-FrameRectMy.top, 1);\r
- UpdateRect();\r
- return 0;\r
- case 1210:\r
- case 1211:\r
- i = IsWindowVisible((LOWORD(wparam)&1) ? PicoPadWnd : PicoSwWnd);\r
- i = !i;\r
- ShowWindow((LOWORD(wparam)&1) ? PicoPadWnd : PicoSwWnd, i ? SW_SHOWNA : SW_HIDE);\r
- CheckMenuItem(mpicohw, LOWORD(wparam), i ? MF_CHECKED : MF_UNCHECKED);\r
- return 0;\r
- case 1212:\r
- main_wnd_as_pad = !main_wnd_as_pad;\r
- CheckMenuItem(mpicohw, 1212, main_wnd_as_pad ? MF_CHECKED : MF_UNCHECKED);\r
- return 0;\r
- case 1220:\r
- case 1221:\r
- case 1222:\r
- case 1223:\r
- case 1224:\r
- case 1225:\r
- case 1226:\r
- PicoPicohw.page = LOWORD(wparam) % 10;\r
- for (i = 0; i < 7; i++)\r
- CheckMenuItem(mpicohw, 1220 + i, MF_UNCHECKED);\r
- CheckMenuItem(mpicohw, 1220 + PicoPicohw.page, MF_CHECKED);\r
- InvalidateRect(PicoSwWnd, NULL, 1);\r
- return 0;\r
- case 1300:\r
- MessageBox(FrameWnd, plat_get_credits(), "About", 0);\r
- return 0;\r
- }\r
- break;\r
- case WM_TIMER:\r
- GetCursorPos(&pt);\r
- GetWindowRect(PicoSwWnd, &rc);\r
- if (PtInRect(&rc, pt)) break;\r
- GetWindowRect(PicoPadWnd, &rc);\r
- if (PtInRect(&rc, pt)) break;\r
- PicoPicohw.pen_pos[0] |= 0x8000;\r
- PicoPicohw.pen_pos[1] |= 0x8000;\r
- in_vk_add_pl12 = 0;\r
- break;\r
- case WM_LBUTTONDOWN: in_vk_add_pl12 |= 0x20; return 0;\r
- case WM_LBUTTONUP: in_vk_add_pl12 &= ~0x20; return 0;\r
- case WM_MOUSEMOVE:\r
- if (!main_wnd_as_pad) break;\r
- PicoPicohw.pen_pos[0] = 0x03c + (320 * LOWORD(lparam) / (FrameRectMy.right - FrameRectMy.left));\r
- PicoPicohw.pen_pos[1] = 0x1fc + (232 * HIWORD(lparam) / (FrameRectMy.bottom - FrameRectMy.top));\r
- SetTimer(FrameWnd, 100, 1000, NULL);\r
- break;\r
- case WM_KEYDOWN:\r
- if (wparam == VK_TAB) {\r
- emu_reset_game();\r
- break;\r
- }\r
- if (wparam == VK_ESCAPE) {\r
- LoadROM(NULL);\r
- break;\r
- }\r
- in_vk_keydown(wparam);\r
- break;\r
- case WM_KEYUP:\r
- in_vk_keyup(wparam);\r
- break;\r
- }\r
-\r
- return DefWindowProc(hwnd,msg,wparam,lparam);\r
-}\r
-\r
-static LRESULT CALLBACK PicoSwWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)\r
-{\r
- PAINTSTRUCT ps;\r
- HDC hdc, hdc2;\r
-\r
- switch (msg)\r
- {\r
- case WM_DESTROY: PicoSwWnd=NULL; break;\r
- case WM_LBUTTONDOWN: in_vk_add_pl12 |= 0x20; return 0;\r
- case WM_LBUTTONUP: in_vk_add_pl12 &= ~0x20; return 0;\r
- case WM_MOUSEMOVE:\r
- if (HIWORD(lparam) < 0x20) break;\r
- PicoPicohw.pen_pos[0] = 0x03c + LOWORD(lparam) * 2/3;\r
- PicoPicohw.pen_pos[1] = 0x2f8 + HIWORD(lparam) - 0x20;\r
- SetTimer(FrameWnd, 100, 1000, NULL);\r
- break;\r
- case WM_KEYDOWN: in_vk_keydown(wparam); break;\r
- case WM_KEYUP: in_vk_keyup(wparam); break;\r
- case WM_PAINT:\r
- hdc = BeginPaint(hwnd, &ps);\r
- if (ppage_bmps[PicoPicohw.page] == NULL)\r
- {\r
- SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));\r
- SetTextColor(hdc, RGB(255, 255, 255));\r
- SetBkColor(hdc, RGB(0, 0, 0));\r
- TextOut(hdc, 2, 2, "missing PNGs for", 16);\r
- TextOut(hdc, 2, 18, rom_name, strlen(rom_name));\r
- }\r
- else\r
- {\r
- hdc2 = CreateCompatibleDC(GetDC(FrameWnd));\r
- SelectObject(hdc2, ppage_bmps[PicoPicohw.page]);\r
- BitBlt(hdc, 0, 0, 480, 240, hdc2, 0, 0, SRCCOPY);\r
- DeleteDC(hdc2);\r
- }\r
- EndPaint(hwnd, &ps);\r
- return 0;\r
- case WM_CLOSE:\r
- ShowWindow(hwnd, SW_HIDE);\r
- CheckMenuItem(mpicohw, 1210, MF_UNCHECKED);\r
- return 0;\r
- }\r
-\r
- return DefWindowProc(hwnd,msg,wparam,lparam);\r
-}\r
-\r
-static LRESULT CALLBACK PicoPadWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)\r
-{\r
- PAINTSTRUCT ps;\r
- HDC hdc, hdc2;\r
-\r
- switch (msg)\r
- {\r
- case WM_DESTROY: PicoPadWnd=NULL; break;\r
- case WM_LBUTTONDOWN: in_vk_add_pl12 |= 0x20; return 0;\r
- case WM_LBUTTONUP: in_vk_add_pl12 &= ~0x20; return 0;\r
- case WM_MOUSEMOVE:\r
- PicoPicohw.pen_pos[0] = 0x03c + LOWORD(lparam);\r
- PicoPicohw.pen_pos[1] = 0x1fc + HIWORD(lparam);\r
- SetTimer(FrameWnd, 100, 1000, NULL);\r
- break;\r
- case WM_KEYDOWN: in_vk_keydown(wparam); break;\r
- case WM_KEYUP: in_vk_keyup(wparam); break;\r
- case WM_PAINT:\r
- if (ppad_bmp == NULL) break;\r
- hdc = BeginPaint(hwnd, &ps);\r
- hdc2 = CreateCompatibleDC(GetDC(FrameWnd));\r
- SelectObject(hdc2, ppad_bmp);\r
- BitBlt(hdc, 0, 0, 320, 240, hdc2, 0, 0, SRCCOPY);\r
- EndPaint(hwnd, &ps);\r
- DeleteDC(hdc2);\r
- return 0;\r
- case WM_CLOSE:\r
- ShowWindow(hwnd, SW_HIDE);\r
- CheckMenuItem(mpicohw, 1211, MF_UNCHECKED);\r
- return 0;\r
- }\r
-\r
- return DefWindowProc(hwnd,msg,wparam,lparam);\r
-}\r
-\r
-\r
-static int FrameInit()\r
-{\r
- WNDCLASS wc;\r
- RECT rect={0,0,0,0};\r
- HMENU mfile;\r
- int style=0;\r
- int left=0,top=0,width=0,height=0;\r
-\r
- memset(&wc,0,sizeof(wc));\r
-\r
- // Register the window class:\r
- wc.lpfnWndProc=WndProc;\r
- wc.hInstance=GetModuleHandle(NULL);\r
- wc.hCursor=LoadCursor(NULL,IDC_ARROW);\r
- wc.hbrBackground=CreateSolidBrush(0);\r
- wc.lpszClassName="PicoMainFrame";\r
- RegisterClass(&wc);\r
-\r
- wc.lpszClassName="PicoSwWnd";\r
- wc.lpfnWndProc=PicoSwWndProc;\r
- RegisterClass(&wc);\r
-\r
- wc.lpszClassName="PicoPadWnd";\r
- wc.lpfnWndProc=PicoPadWndProc;\r
- RegisterClass(&wc);\r
-\r
- rect.right =320;\r
- rect.bottom=224;\r
-\r
- // Adjust size of windows based on borders:\r
- style=WS_OVERLAPPEDWINDOW;\r
- AdjustWindowRect(&rect,style,1);\r
- width =rect.right-rect.left;\r
- height=rect.bottom-rect.top;\r
-\r
- // Place window in the centre of the screen:\r
- SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);\r
- left=rect.left+rect.right;\r
- top=rect.top+rect.bottom;\r
-\r
- left-=width; left>>=1;\r
- top-=height; top>>=1;\r
-\r
- // Create menu:\r
- mfile = CreateMenu();\r
- InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1000, "&Load ROM");\r
- InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1001, "&Reset");\r
- InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1002, "E&xit");\r
- mdisplay = CreateMenu();\r
- InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1100, "320x224");\r
- InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1101, "256x224");\r
- InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1102, "640x448");\r
- InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1103, "512x448");\r
- InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1104, "Lock to 1:1");\r
- mpicohw = CreateMenu();\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1210, "Show &Storyware");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1211, "Show &Drawing pad");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1212, "&Main window as pad");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1220, "Title page (&0)");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1221, "Page &1");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1222, "Page &2");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1223, "Page &3");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1224, "Page &4");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1225, "Page &5");\r
- InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1226, "Page &6");\r
- mmain = CreateMenu();\r
- InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mfile, "&File");\r
- InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mdisplay, "&Display");\r
- InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mpicohw, "&Pico");\r
- EnableMenuItem(mmain, 2, MF_BYPOSITION|MF_GRAYED);\r
-// InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, 1200, "&Config");\r
- InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING, 1300, "&About");\r
-\r
- // Create the window:\r
- FrameWnd=CreateWindow("PicoMainFrame","PicoDrive " VERSION,style|WS_VISIBLE,\r
- left,top,width,height,NULL,mmain,NULL,NULL);\r
-\r
- CheckMenuItem(mdisplay, 1104, lock_to_1_1 ? MF_CHECKED : MF_UNCHECKED);\r
- ShowWindow(FrameWnd, SW_NORMAL);\r
- UpdateWindow(FrameWnd);\r
- UpdateRect();\r
-\r
- // create Pico windows\r
- style = WS_OVERLAPPED|WS_CAPTION|WS_BORDER|WS_SYSMENU;\r
- rect.left=rect.top=0;\r
- rect.right =320;\r
- rect.bottom=224;\r
-\r
- AdjustWindowRect(&rect,style,1);\r
- width =rect.right-rect.left;\r
- height=rect.bottom-rect.top;\r
-\r
- left += 326;\r
- PicoSwWnd=CreateWindow("PicoSwWnd","Storyware",style,\r
- left,top,width+160,height,FrameWnd,NULL,NULL,NULL);\r
-\r
- top += 266;\r
- PicoPadWnd=CreateWindow("PicoPadWnd","Drawing Pad",style,\r
- left,top,width,height,FrameWnd,NULL,NULL,NULL);\r
-\r
- return 0;\r
-}\r
-\r
-// --------------------\r
-\r
-static DWORD WINAPI work_thread(void *x)\r
-{\r
- while (engineState != PGS_Quit) {\r
- WaitForSingleObject(loop_enter_event, INFINITE);\r
- if (engineState != PGS_Running)\r
- continue;\r
-\r
- printf("loop..\n");\r
- emu_loop();\r
- SetEvent(loop_end_event);\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-// XXX: use main.c\r
-void xxinit(void)\r
-{\r
- /* in_init() must go before config, config accesses in_ fwk */\r
- in_init();\r
- emu_prep_defconfig();\r
- emu_read_config(NULL, 0);\r
- config_readlrom(PicoConfigFile);\r
-\r
- plat_init();\r
- in_probe();\r
-\r
- emu_init();\r
- menu_init();\r
-}\r
-\r
-\r
-int WINAPI WinMain(HINSTANCE p1, HINSTANCE p2, LPSTR cmdline, int p4)\r
-{\r
- MSG msg;\r
- DWORD tid = 0;\r
- HANDLE thread;\r
- int ret;\r
-\r
- xxinit();\r
- FrameInit();\r
- ret = DirectInit();\r
- if (ret)\r
- goto end0;\r
-\r
- loop_enter_event = CreateEvent(NULL, 0, 0, NULL);\r
- if (loop_enter_event == NULL)\r
- goto end0;\r
-\r
- loop_end_event = CreateEvent(NULL, 0, 0, NULL);\r
- if (loop_end_event == NULL)\r
- goto end0;\r
-\r
- thread = CreateThread(NULL, 0, work_thread, NULL, 0, &tid);\r
- if (thread == NULL)\r
- goto end0;\r
-\r
- LoadROM(cmdline);\r
-\r
- // Main window loop:\r
- for (;;)\r
- {\r
- GetMessage(&msg,NULL,0,0);\r
- if (msg.message==WM_QUIT) break;\r
-\r
- TranslateMessage(&msg);\r
- DispatchMessage(&msg);\r
- }\r
-\r
- // Signal thread to quit and wait for it to exit:\r
- if (engineState == PGS_Running) {\r
- engineState = PGS_Quit;\r
- WaitForSingleObject(loop_end_event, 5000);\r
- }\r
- CloseHandle(thread); thread=NULL;\r
-\r
- emu_write_config(0);\r
- emu_finish();\r
- //plat_finish();\r
-\r
-end0:\r
- DirectExit();\r
- DestroyWindow(FrameWnd);\r
-\r
-// _CrtDumpMemoryLeaks();\r
- return 0;\r
-}\r
-\r
+++ /dev/null
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern HWND FrameWnd;
-extern RECT FrameRectMy;
-extern RECT EmuScreenRect;
-
-#ifdef __cplusplus
-}
-#endif
+++ /dev/null
-#include <windows.h>
-#include <stdio.h>
-
-#include "../common/lprintf.h"
-#include "../common/plat.h"
-#include "../common/emu.h"
-#include "../../pico/pico.h"
-#include "version.h"
-#include "direct.h"
-#include "dsnd.h"
-#include "main.h"
-
-static unsigned short screen_buff[320 * 240];
-static unsigned char PicoDraw2FB_[(8+320) * (8+240+8)];
-unsigned char *PicoDraw2FB = PicoDraw2FB_;
-const char *renderer_names[] = { NULL };
-const char *renderer_names32x[] = { NULL };
-
-void plat_init(void)
-{
- g_screen_ptr = (void *)screen_buff;
-}
-
-int plat_is_dir(const char *path)
-{
- return (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
-}
-
-unsigned int plat_get_ticks_ms(void)
-{
- return GetTickCount();
-}
-
-unsigned int plat_get_ticks_us(void)
-{
- // XXX: maybe performance counters?
- return GetTickCount() * 1000;
-}
-
-void plat_wait_till_us(unsigned int us)
-{
- int msdiff = (int)(us - plat_get_ticks_us()) / 1000;
- if (msdiff > 6)
- Sleep(msdiff - 6);
- while (plat_get_ticks_us() < us)
- ;
-}
-
-void plat_sleep_ms(int ms)
-{
- Sleep(ms);
-}
-
-int plat_wait_event(int *fds_hnds, int count, int timeout_ms)
-{
- return -1;
-}
-
-void pemu_prep_defconfig(void)
-{
- memset(&defaultConfig, 0, sizeof(defaultConfig));
- defaultConfig.s_PicoOpt|= POPT_6BTN_PAD; // for xmen proto
- defaultConfig.s_PicoCDBuffers = 0;
- defaultConfig.Frameskip = 0;
-}
-
-void pemu_validate_config(void)
-{
-}
-
-void pemu_loop_prep(void)
-{
- PicoDrawSetOutFormat(PDF_RGB555, 1);
- PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);
- pemu_sound_start();
-}
-
-void pemu_loop_end(void)
-{
- pemu_sound_stop();
-}
-
-void pemu_forced_frame(int no_scale, int do_emu)
-{
-}
-
-void pemu_finalize_frame(const char *fps, const char *notice_msg)
-{
-}
-
-void plat_video_flip(void)
-{
- DirectScreen(g_screen_ptr);
- DirectPresent();
-}
-
-void plat_video_wait_vsync(void)
-{
-}
-
-void plat_video_toggle_renderer(int change, int is_menu)
-{
- // this will auto-select SMS/32X renderers
- PicoDrawSetOutFormat(PDF_RGB555, 1);
-}
-
-void emu_video_mode_change(int start_line, int line_count, int is_32cols)
-{
- EmuScreenRect.left = is_32cols ? 32 : 0;
- EmuScreenRect.right = is_32cols ? 256+32 : 320;
- EmuScreenRect.top = start_line;
- EmuScreenRect.bottom = start_line + line_count;
-
- PostMessage(FrameWnd, WM_COMMAND, 0x20000 | 2000, 0);
-}
-
-static int sndbuff[2*44100/50/2 + 4];
-
-static void update_sound(int len)
-{
- /* avoid writing audio when lagging behind to prevent audio lag */
- if (PicoSkipFrame != 2)
- DSoundUpdate(sndbuff, (currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) ? 0 : 1);
-}
-
-void pemu_sound_start(void)
-{
- int ret;
-
- PsndOut = NULL;
- currentConfig.EmuOpt &= ~EOPT_EXT_FRMLIMIT;
-
- // prepare sound stuff
- if (currentConfig.EmuOpt & EOPT_EN_SOUND)
- {
- PsndRerate(0);
-
- ret = DSoundInit(FrameWnd, PsndRate, (PicoOpt & POPT_EN_STEREO) ? 1 : 0, PsndLen);
- if (ret != 0) {
- lprintf("dsound init failed\n");
- return;
- }
-
- PsndOut = (void *)sndbuff;
- PicoWriteSound = update_sound;
- currentConfig.EmuOpt |= EOPT_EXT_FRMLIMIT;
- }
-}
-
-void pemu_sound_stop(void)
-{
- DSoundExit();
-}
-
-void pemu_sound_wait(void)
-{
-}
-
-int plat_get_root_dir(char *dst, int len)
-{
- int ml;
-
- ml = GetModuleFileName(NULL, dst, len);
- while (ml > 0 && dst[ml] != '\\')
- ml--;
- if (ml != 0)
- ml++;
-
- dst[ml] = 0;
- return ml;
-}
-
-void plat_status_msg_busy_first(const char *msg)
-{
-}
-
-void plat_status_msg_busy_next(const char *msg)
-{
-}
-
-void plat_status_msg_clear(void)
-{
-}
-
-void plat_video_menu_enter(int is_rom_loaded)
-{
-}
-
-void plat_video_menu_begin(void)
-{
-}
-
-void plat_video_menu_end(void)
-{
-}
-
-void plat_update_volume(int has_changed, int is_up)
-{
-}
-
-const char *plat_get_credits(void)
-{
- return "PicoDrive v" VERSION " minibeta (c) notaz, 2006-2009\n\n"
- "Credits:\n"
- "fDave: base code of PicoDrive\n"
- "Chui: Fame/C\n"
- "NJ: CZ80\n"
- "MAME devs: YM2612, SN76496 and SH2 cores\n"
- "Stéphane Dallongeville: base of Fame/C (C68K), CZ80\n\n"
- "Special thanks (ideas, valuable information and stuff):\n"
- "Charles MacDonald, Eke, Exophase, Haze, Lordus, Nemesis,\n"
- "Pierpaolo Prazzoli, Rokas, Steve Snake, Tasco Deluxe.\n";
-}
-
-void plat_debug_cat(char *str)
-{
-}
-
-// required by pico
-int mp3_get_bitrate(void *f, int size)
-{
- return 128;
-}
-
-void mp3_start_play(void *f, int pos)
-{
-}
-
-void mp3_update(int *buffer, int length, int stereo)
-{
-}
-
-// other
-void lprintf(const char *fmt, ...)
-{
- char buf[512];
- va_list val;
-
- va_start(val, fmt);
- vsnprintf(buf, sizeof(buf), fmt, val);
- va_end(val);
- OutputDebugString(buf);
- printf("%s", buf);
-}
-
-// fake
-int alphasort() { return 0; }
-int scandir() { return 0; }
-
+++ /dev/null
-// port specific settings
-
-#ifndef PORT_CONFIG_H
-#define PORT_CONFIG_H
-
-#define NO_SYNC
-
-#define CASE_SENSITIVE_FS 0 // CS filesystem
-#define DONT_OPEN_MANY_FILES 0
-#define REDUCE_IO_CALLS 0
-
-#define SCREEN_SIZE_FIXED 0
-#define SCREEN_WIDTH 320
-#define SCREEN_HEIGHT 240
-#define MSCREEN_SIZE_FIXED 0
-#define MSCREEN_WIDTH SCREEN_WIDTH
-#define MSCREEN_HEIGHT SCREEN_HEIGHT
-
-// draw2.c
-#define START_ROW 0 // which row of tiles to start rendering at?
-#define END_ROW 28 // ..end
-
-// pico.c
-#define CAN_HANDLE_240_LINES 1
-
-#define SIMPLE_WRITE_SOUND 1
-#define mix_32_to_16l_stereo_lvl mix_32_to_16l_stereo
-
-#define EL_LOGMASK (EL_STATUS)
-
-//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
-#define dprintf(x...)
-
-// platform
-#define PATH_SEP "\\"
-#define PATH_SEP_C '\\'
-#define MENU_X2 0
-
-#endif //PORT_CONFIG_H
-
+++ /dev/null
-\r
-About\r
------\r
-\r
-This is a quick windows port of PicoDrive, a Megadrive / Genesis emulator for\r
-handheld devices. It was originally coded having ARM CPU based devices in mind\r
-(most work was done on GP2X version), but there is also a PSP port.\r
-\r
-The reason I'm sometimes doing windows versions is to show certain emulation\r
-possibilities, first release was to demonstrate SVP emulation (Virtua Racing),\r
-later Pico toy and X-Men 32X prototype. It is not to compete with other\r
-emulators like Kega Fusion and the likes.\r
-\r
-For more info, visit http://notaz.gp2x.de/svp.php\r
-\r
-\r
-Releases\r
---------\r
-\r
-1.70 - preliminary 32X emulation, runs X-Men proto.\r
-1.45a - Few bugfixes and additions.\r
-1.45 - Added preliminary Sega Pico emulation.\r
-1.40b - Perspective fix thanks to Pierpaolo Prazzoli's info.\r
-1.40a - Tasco Deluxe's dithering fix.\r
-1.40 - first release.\r
-\r
-\r
-Controls\r
---------\r
-\r
-These are currently hardcoded, keyboard only:\r
-\r
-PC Gen/MD Sega Pico\r
--------+-----------+---------\r
-Enter: Start\r
-A: A\r
-S: B red button\r
-D: C pen push\r
-Q,W,E: X,Y,Z\r
-TAB: (reset)\r
-Esc: (load ROM)\r
-Arrows: D-pad\r
-\r
-It is possible to change some things in config.cfg (it is created on exit),\r
-but possibilities are limited.\r
-\r
-\r
-Credits\r
--------\r
-\r
-Vast majority of code written by notaz (notasasatgmailcom).\r
-\r
-A lot of work on making SVP emulation happen was done by Tasco Deluxe, my\r
-stuff is a continuation of his. Pierpaolo Prazzoli's information and his\r
-SSP1610 disassembler in MAME code helped a lot too.\r
-\r
-The original PicoDrive was written by fDave from finalburn.com\r
-\r
-This PicoDrive version uses bits and pieces of from other projects:\r
-\r
-68k: FAME/C core, by Chui and Stéphane Dallongeville (as C68K).\r
-z80: CZ80 by Stéphane Dallongeville and modified by NJ.\r
-YM2612, SN76496 and SH2 cores: MAME devs.\r
-\r
-Special thanks (ideas, valuable information and stuff):\r
-Charles MacDonald, Eke, Exophase, Haze, Lordus, Nemesis,\r
-Pierpaolo Prazzoli, Rokas, Steve Snake, Tasco Deluxe.\r
-\r
-Greets to all the sceners and emu authors out there!\r
-\r
+++ /dev/null
-#define VERSION "1.70"\r
-\r