forked from sin365/AxibugEmuOnline
Compare commits
8 Commits
e27c970d45
...
e4da00136d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4da00136d | ||
| c7f32874ae | |||
| 16adace210 | |||
| 250b230914 | |||
| bb42d3f3bd | |||
| ba1ac5d5c2 | |||
| dc5f55c003 | |||
| 8b39e9aa02 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -14,3 +14,6 @@
|
||||
/AxibugEmuOnline.Client/ProjectSettings/AutoStreamingSettings.asset
|
||||
/AxibugEmuOnline.Client/Logs
|
||||
/virtuanessrc097-master/save
|
||||
/virtuanessrc097-master/.vs
|
||||
/virtuanessrc097-master/Debug
|
||||
/virtuanessrc097-master/VirtualNES.ini
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,45 +3,50 @@ using System.Diagnostics;
|
||||
using UnityEngine;
|
||||
using VirtualNes.Core;
|
||||
|
||||
public class AudioProvider : MonoBehaviour
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
[SerializeField]
|
||||
private AudioSource m_as;
|
||||
|
||||
private SoundBuffer _buffer = new SoundBuffer(4096);
|
||||
|
||||
public void Initialize()
|
||||
public class AudioProvider : MonoBehaviour
|
||||
{
|
||||
var dummy = AudioClip.Create("dummy", 1, 1, AudioSettings.outputSampleRate, false);
|
||||
[SerializeField]
|
||||
private AudioSource m_as;
|
||||
|
||||
dummy.SetData(new float[] { 1 }, 0);
|
||||
m_as.clip = dummy; //just to let unity play the audiosource
|
||||
m_as.loop = true;
|
||||
m_as.spatialBlend = 1;
|
||||
m_as.Play();
|
||||
}
|
||||
private SoundBuffer _buffer = new SoundBuffer(4096);
|
||||
|
||||
void OnAudioFilterRead(float[] data, int channels)
|
||||
{
|
||||
int step = channels;
|
||||
|
||||
var bufferCount = _buffer.Available();
|
||||
|
||||
for (int i = 0; i < data.Length; i += step)
|
||||
public void Initialize()
|
||||
{
|
||||
float rawFloat = 0;
|
||||
if (_buffer.TryRead(out byte rawData))
|
||||
rawFloat = rawData / 255f;
|
||||
var dummy = AudioClip.Create("dummy", 1, 1, AudioSettings.outputSampleRate, false);
|
||||
|
||||
data[i] = rawFloat;
|
||||
for (int fill = 1; fill < step; fill++)
|
||||
data[i + fill] = rawFloat;
|
||||
dummy.SetData(new float[] { 1 }, 0);
|
||||
m_as.clip = dummy; //just to let unity play the audiosource
|
||||
m_as.loop = true;
|
||||
m_as.spatialBlend = 1;
|
||||
m_as.Play();
|
||||
}
|
||||
|
||||
void OnAudioFilterRead(float[] data, int channels)
|
||||
{
|
||||
int step = channels;
|
||||
|
||||
var bufferCount = _buffer.Available();
|
||||
|
||||
for (int i = 0; i < data.Length; i += step)
|
||||
{
|
||||
float rawFloat = 0;
|
||||
if (_buffer.TryRead(out byte rawData))
|
||||
rawFloat = rawData / 255f;
|
||||
|
||||
data[i] = rawFloat;
|
||||
for (int fill = 1; fill < step; fill++)
|
||||
data[i + fill] = rawFloat;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessSound(NES nes)
|
||||
{
|
||||
nes.apu.Process(_buffer, (uint)(Supporter.Config.sound.nRate * Time.deltaTime));
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessSound(NES nes)
|
||||
{
|
||||
nes.apu.Process(_buffer, (uint)(Supporter.Config.sound.nRate * Time.deltaTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,7 @@ namespace AxibugEmuOnline.Client
|
||||
private void Start()
|
||||
{
|
||||
Application.targetFrameRate = 60;
|
||||
StartGame("tstd2.nes");
|
||||
StartGame("ff1.nes");
|
||||
}
|
||||
|
||||
public void StartGame(string romName)
|
||||
@ -44,7 +44,6 @@ namespace AxibugEmuOnline.Client
|
||||
m_nesIns = null;
|
||||
}
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (m_nesIns != null)
|
||||
|
||||
@ -30,7 +30,7 @@ Transform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4232056521131536011}
|
||||
m_RootOrder: 1
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &9003897287163669553
|
||||
MonoBehaviour:
|
||||
@ -141,6 +141,78 @@ AudioSource:
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
--- !u!1 &3545890545112170401
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1038087993597378172}
|
||||
- component: {fileID: 3032498056073774270}
|
||||
- component: {fileID: 634277252673086327}
|
||||
m_Layer: 5
|
||||
m_Name: Viewer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &1038087993597378172
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3545890545112170401}
|
||||
m_LocalRotation: {x: 1, y: 0, z: 0, w: 0}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4232056520494431727}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 128, y: 256}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!222 &3032498056073774270
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3545890545112170401}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &634277252673086327
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3545890545112170401}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Texture: {fileID: 8400000, guid: ffe34aaf87e4b9942b4c2ac05943d444, type: 2}
|
||||
m_UVRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
--- !u!1 &4232056520112715746
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -168,8 +240,7 @@ Transform:
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4232056520494431727}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4232056521131536011}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
@ -217,8 +288,9 @@ RectTransform:
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 4232056521759880275}
|
||||
m_Father: {fileID: 4232056520112715745}
|
||||
m_RootOrder: 0
|
||||
- {fileID: 1038087993597378172}
|
||||
m_Father: {fileID: 4232056521131536011}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
@ -315,7 +387,9 @@ Transform:
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4232056520112715745}
|
||||
- {fileID: 393435831810118449}
|
||||
- {fileID: 4785916497946256520}
|
||||
- {fileID: 4232056520494431727}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
@ -405,3 +479,47 @@ MonoBehaviour:
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
--- !u!1 &7856060136050839404
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 393435831810118449}
|
||||
- component: {fileID: 499856625911497759}
|
||||
m_Layer: 0
|
||||
m_Name: PatternViewer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &393435831810118449
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7856060136050839404}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4232056521131536011}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &499856625911497759
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7856060136050839404}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: c7a50c189f5be5b4ea54de444f8488a0, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
img: {fileID: 634277252673086327}
|
||||
|
||||
@ -7,10 +7,18 @@ using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using VirtualNes.Core;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public static class PaletteDefine
|
||||
{
|
||||
public struct RGBQUAD
|
||||
{
|
||||
public byte rgbBlue;
|
||||
public byte rgbGreen;
|
||||
public byte rgbRed;
|
||||
public byte rgbReserved;
|
||||
}
|
||||
|
||||
public class PALBUF
|
||||
{
|
||||
public byte r;
|
||||
@ -108,6 +116,33 @@ namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
|
||||
new PALBUF(0x00, 0x00, 0x00),
|
||||
};
|
||||
|
||||
#region 256色モード用
|
||||
// Color
|
||||
public static RGBQUAD[][] m_cpPalette = new RGBQUAD[8][]
|
||||
{
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
};
|
||||
// Monochrome
|
||||
public static RGBQUAD[][] m_mpPalette = new RGBQUAD[8][]
|
||||
{
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
new RGBQUAD[64*2],
|
||||
};
|
||||
#endregion
|
||||
|
||||
#region ピクセルフォーマットに変換したパレット
|
||||
// Color
|
||||
public static uint[][] m_cnPalette = new uint[8][]
|
||||
@ -161,6 +196,18 @@ namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
|
||||
};
|
||||
#endregion
|
||||
|
||||
public static RGBQUAD[] GetPaletteData()
|
||||
{
|
||||
RGBQUAD[] rgb = new RGBQUAD[256];
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
rgb[i] = m_cpPalette[0][i];
|
||||
rgb[i + 0x40] = m_mpPalette[0][i];
|
||||
}
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
static PaletteDefine()
|
||||
{
|
||||
int Rbit = 0, Gbit = 0, Bbit = 0;
|
||||
@ -186,6 +233,13 @@ namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
|
||||
Gs = (uint)(PalConvTbl[j][1] * m_PaletteBuf[i].g * m_nScanlineColor / 100.0f);
|
||||
Bs = (uint)(PalConvTbl[j][2] * m_PaletteBuf[i].b * m_nScanlineColor / 100.0f);
|
||||
|
||||
m_cpPalette[j][i + 0x00].rgbRed = (byte)Rn;
|
||||
m_cpPalette[j][i + 0x00].rgbGreen = (byte)Gn;
|
||||
m_cpPalette[j][i + 0x00].rgbBlue = (byte)Bn;
|
||||
m_cpPalette[j][i + 0x40].rgbRed = (byte)Rs;
|
||||
m_cpPalette[j][i + 0x40].rgbGreen = (byte)Gs;
|
||||
m_cpPalette[j][i + 0x40].rgbBlue = (byte)Bs;
|
||||
|
||||
m_cnPalette[j][i] = ((Rn >> (8 - Rbit)) << Rsft) | ((Gn >> (8 - Gbit)) << Gsft) | ((Bn >> (8 - Bbit)) << Bsft);
|
||||
m_csPalette[j][i] = ((Rs >> (8 - Rbit)) << Rsft) | ((Gs >> (8 - Gbit)) << Gsft) | ((Bs >> (8 - Bbit)) << Bsft);
|
||||
|
||||
@ -216,6 +270,13 @@ namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
|
||||
if (Gs > 0xFF) Gs = 0xFF;
|
||||
if (Bs > 0xFF) Bs = 0xFF;
|
||||
|
||||
m_mpPalette[j][i + 0x00].rgbRed = (byte)Rn;
|
||||
m_mpPalette[j][i + 0x00].rgbGreen = (byte)Gn;
|
||||
m_mpPalette[j][i + 0x00].rgbBlue = (byte)Bn;
|
||||
m_mpPalette[j][i + 0x40].rgbRed = (byte)Rs;
|
||||
m_mpPalette[j][i + 0x40].rgbGreen = (byte)Gs;
|
||||
m_mpPalette[j][i + 0x40].rgbBlue = (byte)Bs;
|
||||
|
||||
m_mnPalette[j][i] = ((Rn >> (8 - Rbit)) << Rsft) | ((Gn >> (8 - Gbit)) << Gsft) | ((Bn >> (8 - Bbit)) << Bsft);
|
||||
m_msPalette[j][i] = ((Rs >> (8 - Rbit)) << Rsft) | ((Gs >> (8 - Gbit)) << Gsft) | ((Bs >> (8 - Bbit)) << Bsft);
|
||||
}
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VirtualNes;
|
||||
using static AxibugEmuOnline.Client.PaletteDefine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class PatternViewer : MonoBehaviour
|
||||
{
|
||||
public RawImage img;
|
||||
|
||||
private Color32[] m_lpPattern = new Color32[128 * 256];
|
||||
private Texture2D m_texture;
|
||||
private Dictionary<byte, RGBQUAD> colors = new Dictionary<byte, RGBQUAD>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_texture = new Texture2D(128, 256);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
Paint();
|
||||
}
|
||||
|
||||
public void Paint()
|
||||
{
|
||||
img.texture = m_texture;
|
||||
|
||||
var pal = MMU.SPPAL;
|
||||
var palette = PaletteDefine.GetPaletteData();
|
||||
colors[0] = palette[pal[0]];
|
||||
colors[1] = palette[pal[1]];
|
||||
colors[2] = palette[pal[2]];
|
||||
colors[3] = palette[pal[3]];
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
var Ptn = MMU.PPU_MEM_BANK[i];
|
||||
int lpPtn = 0;
|
||||
for (int p = 0; p < 64; p++)
|
||||
{
|
||||
int lpScn = i * 32 * 128 + (p & 15) * 8 + (p / 16) * 8 * 128;
|
||||
for (int y = 0; y < 8; y++)
|
||||
{
|
||||
byte chr_l = Ptn[lpPtn + y];
|
||||
byte chr_h = Ptn[lpPtn + y + 8];
|
||||
m_lpPattern[lpScn + 0] = ToColor32(colors, (((chr_h >> 6) & 2) | ((chr_l >> 7) & 1)));
|
||||
m_lpPattern[lpScn + 4] = ToColor32(colors, (((chr_h >> 2) & 2) | ((chr_l >> 3) & 1)));
|
||||
m_lpPattern[lpScn + 1] = ToColor32(colors, (((chr_h >> 5) & 2) | ((chr_l >> 6) & 1)));
|
||||
m_lpPattern[lpScn + 5] = ToColor32(colors, (((chr_h >> 1) & 2) | ((chr_l >> 2) & 1)));
|
||||
m_lpPattern[lpScn + 2] = ToColor32(colors, (((chr_h >> 4) & 2) | ((chr_l >> 5) & 1)));
|
||||
m_lpPattern[lpScn + 6] = ToColor32(colors, (((chr_h >> 0) & 2) | ((chr_l >> 1) & 1)));
|
||||
m_lpPattern[lpScn + 3] = ToColor32(colors, (((chr_h >> 3) & 2) | ((chr_l >> 4) & 1)));
|
||||
m_lpPattern[lpScn + 7] = ToColor32(colors, (((chr_h << 1) & 2) | ((chr_l >> 0) & 1)));
|
||||
// Next line
|
||||
lpScn += 128;
|
||||
}
|
||||
// Next pattern
|
||||
lpPtn += 16;
|
||||
}
|
||||
}
|
||||
|
||||
m_texture.SetPixels32(m_lpPattern);
|
||||
m_texture.Apply();
|
||||
}
|
||||
|
||||
private Color32 ToColor32(Dictionary<byte, RGBQUAD> map, int v)
|
||||
{
|
||||
var raw = map[(byte)v];
|
||||
return new Color32(raw.rgbRed, raw.rgbGreen, raw.rgbBlue, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c7a50c189f5be5b4ea54de444f8488a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,9 +1,7 @@
|
||||
using AxibugEmuOnline.Client.Assets.Script.NesEmulator;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VirtualNes.Core;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
|
||||
@ -34,6 +34,13 @@ namespace VirtualNes.Core
|
||||
m_length = length;
|
||||
}
|
||||
|
||||
public void SetArray(byte[] array, int offset)
|
||||
{
|
||||
m_rawArray = array;
|
||||
m_offset = offset;
|
||||
m_length = array.Length - offset;
|
||||
}
|
||||
|
||||
public byte this[int index]
|
||||
{
|
||||
get
|
||||
|
||||
@ -78,6 +78,13 @@ namespace VirtualNes
|
||||
CPU_MEM_PAGE[page] = 0;
|
||||
}
|
||||
|
||||
internal static void SetPROM_Bank(byte page, ByteArrayRef ptr, byte type)
|
||||
{
|
||||
CPU_MEM_BANK[page] = ptr;
|
||||
CPU_MEM_TYPE[page] = type;
|
||||
CPU_MEM_PAGE[page] = 0;
|
||||
}
|
||||
|
||||
internal static void SetPROM_8K_Bank(byte page, int bank)
|
||||
{
|
||||
bank %= PROM_8K_SIZE;
|
||||
|
||||
@ -81,9 +81,23 @@ namespace VirtualNes.Core
|
||||
{
|
||||
//todo : 实现加载mapper
|
||||
switch (no)
|
||||
{
|
||||
case 4: return new Mapper004(parent);
|
||||
case 16: return new Mapper016(parent);
|
||||
{
|
||||
case 0: return new Mapper000(parent);
|
||||
case 1: return new Mapper001(parent);
|
||||
case 2: return new Mapper002(parent);
|
||||
case 3: return new Mapper003(parent);
|
||||
case 4: return new Mapper004(parent);
|
||||
case 5: return new Mapper005(parent);
|
||||
case 6: return new Mapper006(parent);
|
||||
case 7: return new Mapper007(parent);
|
||||
case 8: return new Mapper008(parent);
|
||||
case 9: return new Mapper009(parent);
|
||||
case 10: return new Mapper010(parent);
|
||||
case 11: return new Mapper011(parent);
|
||||
case 12: return new Mapper012(parent);
|
||||
case 13: return new Mapper013(parent);
|
||||
case 15: return new Mapper015(parent);
|
||||
case 16: return new Mapper016(parent);
|
||||
case 17: return new Mapper017(parent);
|
||||
case 18: return new Mapper018(parent);
|
||||
case 19: return new Mapper019(parent);
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper000 //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper000 : Mapper
|
||||
{
|
||||
|
||||
public Mapper000(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
switch (PROM_16K_SIZE)
|
||||
{
|
||||
default:
|
||||
case 1: // 16K only
|
||||
SetPROM_16K_Bank(4, 0);
|
||||
SetPROM_16K_Bank(6, 0);
|
||||
break;
|
||||
case 2: // 32K
|
||||
SetPROM_32K_Bank(0);
|
||||
break;
|
||||
}
|
||||
|
||||
uint crc = nes.rom.GetPROM_CRC();
|
||||
if (crc == 0x4e7db5af)
|
||||
{ // Circus Charlie(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
|
||||
}
|
||||
if (crc == 0x57970078)
|
||||
{ // F-1 Race(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
|
||||
}
|
||||
if (crc == 0xaf2bbcbc // Mach Rider(JU)
|
||||
|| crc == 0x3acd4bf1)
|
||||
{ // Mach Rider(Alt)(JU)
|
||||
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c57bc13f96a8d064a885b65c6aebc351
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,416 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper001 Nintendo MMC1 //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper001 : Mapper
|
||||
{
|
||||
|
||||
uint last_addr;
|
||||
|
||||
BYTE patch;
|
||||
BYTE wram_patch;
|
||||
BYTE wram_bank;
|
||||
BYTE wram_count;
|
||||
|
||||
BYTE[] reg = new byte[4];
|
||||
BYTE shift, regbuf;
|
||||
|
||||
public Mapper001(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
reg[0] = 0x0C; // D3=1,D2=1
|
||||
reg[1] = reg[2] = reg[3] = 0;
|
||||
shift = regbuf = 0;
|
||||
|
||||
patch = 0;
|
||||
wram_patch = 0;
|
||||
|
||||
if (PROM_16K_SIZE < 32)
|
||||
{
|
||||
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For 512K/1M byte Cartridge
|
||||
SetPROM_16K_Bank(4, 0);
|
||||
SetPROM_16K_Bank(6, 16 - 1);
|
||||
|
||||
patch = 1;
|
||||
}
|
||||
|
||||
if (VROM_8K_SIZE != 0)
|
||||
{
|
||||
// SetVROM_8K_Bank( 0 );
|
||||
}
|
||||
|
||||
uint crc = nes.rom.GetPROM_CRC();
|
||||
|
||||
if (crc == 0xb8e16bd0)
|
||||
{ // Snow Bros.(J)
|
||||
patch = 2;
|
||||
}
|
||||
// if( crc == 0x9b565541 ) { // Triathron, The(J)
|
||||
// nes.SetFrameIRQmode( FALSE );
|
||||
// }
|
||||
if (crc == 0xc96c6f04)
|
||||
{ // Venus Senki(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
|
||||
}
|
||||
// if( crc == 0x5e3f7004 ) { // Softball Tengoku(J)
|
||||
// }
|
||||
|
||||
if (crc == 0x4d2edf70)
|
||||
{ // Night Rider(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||
}
|
||||
if (crc == 0xcd2a73f0)
|
||||
{ // Pirates!(U)
|
||||
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||
patch = 2;
|
||||
}
|
||||
|
||||
// if( crc == 0x09efe54b ) { // Majaventure - Mahjong Senki(J)
|
||||
// nes.SetFrameIRQmode( FALSE );
|
||||
// }
|
||||
|
||||
if (crc == 0x11469ce3)
|
||||
{ // Viva! Las Vegas(J)
|
||||
}
|
||||
if (crc == 0xd878ebf5)
|
||||
{ // Ninja Ryukenden(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
|
||||
}
|
||||
|
||||
// if( crc == 0x7bd7b849 ) { // Nekketsu Koukou - Dodgeball Bu(J)
|
||||
// }
|
||||
|
||||
if (crc == 0x466efdc2)
|
||||
{ // Final Fantasy(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||
nes.ppu.SetExtMonoMode(true);
|
||||
}
|
||||
if (crc == 0xc9556b36)
|
||||
{ // Final Fantasy I&II(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||
nes.ppu.SetExtMonoMode(true);
|
||||
nes.SetSAVERAM_SIZE(16 * 1024);
|
||||
wram_patch = 2;
|
||||
}
|
||||
|
||||
if (crc == 0x717e1169)
|
||||
{ // Cosmic Wars(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
|
||||
}
|
||||
|
||||
if (crc == 0xC05D2034)
|
||||
{ // Snake's Revenge(U)
|
||||
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
|
||||
}
|
||||
|
||||
if (crc == 0xb8747abf // Best Play - Pro Yakyuu Special(J)
|
||||
|| crc == 0x29449ba9 // Nobunaga no Yabou - Zenkoku Ban(J)
|
||||
|| crc == 0x2b11e0b0 // Nobunaga no Yabou - Zenkoku Ban(J)(alt)
|
||||
|| crc == 0x4642dda6 // Nobunaga's Ambition(U)
|
||||
|| crc == 0xfb69743a // Aoki Ookami to Shiroki Mejika - Genghis Khan(J)
|
||||
|| crc == 0x2225c20f // Genghis Khan(U)
|
||||
|| crc == 0xabbf7217 // Sangokushi(J)
|
||||
)
|
||||
{
|
||||
|
||||
nes.SetSAVERAM_SIZE(16 * 1024);
|
||||
wram_patch = 1;
|
||||
wram_bank = 0;
|
||||
wram_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private ByteArrayRef _PROM_BANK = new ByteArrayRef();
|
||||
//void Mapper001::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
// DEBUGOUT( "MMC1 %04X=%02X\n", addr&0xFFFF,data&0xFF );
|
||||
|
||||
if (wram_patch == 1 && addr == 0xBFFF)
|
||||
{
|
||||
wram_count++;
|
||||
wram_bank += (byte)(data & 0x01);
|
||||
if (wram_count == 5)
|
||||
{
|
||||
if (wram_bank != 0)
|
||||
{
|
||||
_PROM_BANK.SetArray(WRAM, 0x2000);
|
||||
SetPROM_Bank(3, _PROM_BANK, BANKTYPE_RAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
_PROM_BANK.SetArray(WRAM, 0x0000);
|
||||
SetPROM_Bank(3, _PROM_BANK, BANKTYPE_RAM);
|
||||
}
|
||||
wram_bank = wram_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (patch != 1)
|
||||
{
|
||||
if ((addr & 0x6000) != (last_addr & 0x6000))
|
||||
{
|
||||
shift = regbuf = 0;
|
||||
}
|
||||
last_addr = addr;
|
||||
}
|
||||
|
||||
if ((data & 0x80) != 0)
|
||||
{
|
||||
shift = regbuf = 0;
|
||||
// reg[0] = 0x0C; // D3=1,D2=1
|
||||
reg[0] |= 0x0C; // D3=1,D2=1 残りはリセットされない
|
||||
return;
|
||||
}
|
||||
|
||||
if ((data & 0x01) != 0) regbuf |= (byte)(1 << shift);
|
||||
if (++shift < 5)
|
||||
return;
|
||||
addr = (ushort)((addr & 0x7FFF) >> 13);
|
||||
reg[addr] = regbuf;
|
||||
|
||||
// DEBUGOUT( "MMC1 %d=%02X\n", addr&0xFFFF,regbuf&0xFF );
|
||||
|
||||
regbuf = 0;
|
||||
shift = 0;
|
||||
|
||||
if (patch != 1)
|
||||
{
|
||||
// For Normal Cartridge
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
if ((reg[0] & 0x02) != 0)
|
||||
{
|
||||
if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
|
||||
else SetVRAM_Mirror(VRAM_MIRROR4L);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// Register #1
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
if ((reg[0] & 0x10) != 0)
|
||||
{
|
||||
// CHR 4K bank lower($0000-$0FFF)
|
||||
SetVROM_4K_Bank(0, reg[1]);
|
||||
// CHR 4K bank higher($1000-$1FFF)
|
||||
SetVROM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// CHR 8K bank($0000-$1FFF)
|
||||
SetVROM_8K_Bank(reg[1] >> 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For Romancia
|
||||
if ((reg[0] & 0x10) != 0)
|
||||
{
|
||||
SetCRAM_4K_Bank(0, reg[1]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// Register #2
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
if ((reg[0] & 0x10) != 0)
|
||||
{
|
||||
// CHR 4K bank lower($0000-$0FFF)
|
||||
SetVROM_4K_Bank(0, reg[1]);
|
||||
// CHR 4K bank higher($1000-$1FFF)
|
||||
SetVROM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// CHR 8K bank($0000-$1FFF)
|
||||
SetVROM_8K_Bank(reg[1] >> 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For Romancia
|
||||
if ((reg[0] & 0x10) != 0)
|
||||
{
|
||||
SetCRAM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (!((reg[0] & 0x08) != 0))
|
||||
{
|
||||
// PRG 32K bank ($8000-$FFFF)
|
||||
SetPROM_32K_Bank(reg[3] >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((reg[0] & 0x04) != 0)
|
||||
{
|
||||
// PRG 16K bank ($8000-$BFFF)
|
||||
SetPROM_16K_Bank(4, reg[3]);
|
||||
SetPROM_16K_Bank(6, PROM_16K_SIZE - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// PRG 16K bank ($C000-$FFFF)
|
||||
SetPROM_16K_Bank(6, reg[3]);
|
||||
SetPROM_16K_Bank(4, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For 512K/1M byte Cartridge
|
||||
INT PROM_BASE = 0;
|
||||
if (PROM_16K_SIZE >= 32)
|
||||
{
|
||||
PROM_BASE = reg[1] & 0x10;
|
||||
}
|
||||
|
||||
// For FinalFantasy I&II
|
||||
if (wram_patch == 2)
|
||||
{
|
||||
if (((reg[1] & 0x18) == 0))
|
||||
{
|
||||
_PROM_BANK.SetArray(WRAM, 0x0000);
|
||||
SetPROM_Bank(3, _PROM_BANK, BANKTYPE_RAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
_PROM_BANK.SetArray(WRAM, 0x2000);
|
||||
SetPROM_Bank(3, _PROM_BANK, BANKTYPE_RAM);
|
||||
}
|
||||
}
|
||||
|
||||
// Register #0
|
||||
if (addr == 0)
|
||||
{
|
||||
if ((reg[0] & 0x02) != 0)
|
||||
{
|
||||
if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((reg[0] & 0x01) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
|
||||
else SetVRAM_Mirror(VRAM_MIRROR4L);
|
||||
}
|
||||
}
|
||||
// Register #1
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
if ((reg[0] & 0x10) != 0)
|
||||
{
|
||||
// CHR 4K bank lower($0000-$0FFF)
|
||||
SetVROM_4K_Bank(0, reg[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// CHR 8K bank($0000-$1FFF)
|
||||
SetVROM_8K_Bank(reg[1] >> 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For Romancia
|
||||
if ((reg[0] & 0x10) != 0)
|
||||
{
|
||||
SetCRAM_4K_Bank(0, reg[1]);
|
||||
}
|
||||
}
|
||||
// Register #2
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
if ((reg[0] & 0x10) != 0)
|
||||
{
|
||||
// CHR 4K bank higher($1000-$1FFF)
|
||||
SetVROM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For Romancia
|
||||
if ((reg[0] & 0x10) != 0)
|
||||
{
|
||||
SetCRAM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
}
|
||||
// Register #3
|
||||
if (((reg[0] & 0x08) == 0))
|
||||
{
|
||||
// PRG 32K bank ($8000-$FFFF)
|
||||
SetPROM_32K_Bank((reg[3] & (0xF + PROM_BASE)) >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((reg[0] & 0x04) != 0)
|
||||
{
|
||||
// PRG 16K bank ($8000-$BFFF)
|
||||
SetPROM_16K_Bank(4, PROM_BASE + (reg[3] & 0x0F));
|
||||
if (PROM_16K_SIZE >= 32) SetPROM_16K_Bank(6, PROM_BASE + 16 - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// PRG 16K bank ($C000-$FFFF)
|
||||
SetPROM_16K_Bank(6, PROM_BASE + (reg[3] & 0x0F));
|
||||
if (PROM_16K_SIZE >= 32) SetPROM_16K_Bank(4, PROM_BASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper001::SaveState(LPBYTE p)
|
||||
public override void SaveState(byte[] p)
|
||||
{
|
||||
p[0] = reg[0];
|
||||
p[1] = reg[1];
|
||||
p[2] = reg[2];
|
||||
p[3] = reg[3];
|
||||
p[4] = shift;
|
||||
p[5] = regbuf;
|
||||
|
||||
p[6] = wram_bank;
|
||||
p[7] = wram_count;
|
||||
}
|
||||
|
||||
//void Mapper001::LoadState(LPBYTE p)
|
||||
public override void LoadState(byte[] p)
|
||||
{
|
||||
reg[0] = p[0];
|
||||
reg[1] = p[1];
|
||||
reg[2] = p[2];
|
||||
reg[3] = p[3];
|
||||
shift = p[4];
|
||||
regbuf = p[5];
|
||||
|
||||
wram_bank = p[6];
|
||||
wram_count = p[7];
|
||||
}
|
||||
|
||||
public override bool IsStateSave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c921e7f594a988845856d30f6a925157
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,72 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper002 UNROM //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper002 : Mapper
|
||||
{
|
||||
|
||||
BYTE patch;
|
||||
public Mapper002(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
|
||||
|
||||
patch = 0;
|
||||
|
||||
uint crc = nes.rom.GetPROM_CRC();
|
||||
// if( crc == 0x322c9b09 ) { // Metal Gear (Alt)(J)
|
||||
//// nes.SetFrameIRQmode( FALSE );
|
||||
// }
|
||||
// if( crc == 0xe7a3867b ) { // Dragon Quest 2(Alt)(J)
|
||||
// nes.SetFrameIRQmode( FALSE );
|
||||
// }
|
||||
//// if( crc == 0x9622fbd9 ) { // Ballblazer(J)
|
||||
//// patch = 0;
|
||||
//// }
|
||||
if (crc == 0x8c3d54e8 // Ikari(J)
|
||||
|| crc == 0x655efeed // Ikari Warriors(U)
|
||||
|| crc == 0x538218b2)
|
||||
{ // Ikari Warriors(E)
|
||||
patch = 1;
|
||||
}
|
||||
|
||||
if (crc == 0xb20c1030)
|
||||
{ // Shanghai(J)(original)
|
||||
patch = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void Mapper002::WriteLow(WORD addr, BYTE data)
|
||||
public override void WriteLow(ushort addr, byte data)
|
||||
{
|
||||
if (!nes.rom.IsSAVERAM())
|
||||
{
|
||||
if (addr >= 0x5000 && patch == 1)
|
||||
SetPROM_16K_Bank(4, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.WriteLow(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper002::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
if (patch != 2)
|
||||
SetPROM_16K_Bank(4, data);
|
||||
else
|
||||
SetPROM_16K_Bank(4, data >> 4);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb072eff593853c41974a6d3b8bc1f93
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,66 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper003 CNROM //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper003 : Mapper
|
||||
{
|
||||
|
||||
public Mapper003(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
switch (PROM_16K_SIZE)
|
||||
{
|
||||
case 1: // 16K only
|
||||
SetPROM_16K_Bank(4, 0);
|
||||
SetPROM_16K_Bank(6, 0);
|
||||
break;
|
||||
case 2: // 32K
|
||||
SetPROM_32K_Bank(0);
|
||||
break;
|
||||
}
|
||||
// nes.SetRenderMethod( NES::TILE_RENDER );
|
||||
uint crc = nes.rom.GetPROM_CRC();
|
||||
|
||||
if (crc == 0x2b72fe7e)
|
||||
{ // Ganso Saiyuuki - Super Monkey Dai Bouken(J)
|
||||
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||
nes.ppu.SetExtNameTableMode(true);
|
||||
}
|
||||
|
||||
// if( crc == 0xE44D95B5 ) { // ひみつw
|
||||
// }
|
||||
}
|
||||
|
||||
#if FALSE//0
|
||||
void Mapper003::WriteLow( WORD addr, BYTE data )
|
||||
{
|
||||
if( patch ) {
|
||||
Mapper::WriteLow( addr, data );
|
||||
} else {
|
||||
if( nes.rom.IsSAVERAM() ) {
|
||||
Mapper::WriteLow( addr, data );
|
||||
} else {
|
||||
if( addr >= 0x4800 ) {
|
||||
SetVROM_8K_Bank( data & 0x03 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//void Mapper003::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
SetVROM_8K_Bank(data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d63147469fd9c5540882a5a89799462b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,846 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper005 Nintendo MMC5 //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using System;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using static VirtualNes.Core.PPU;
|
||||
using static VirtualNes.MMU;
|
||||
using BYTE = System.Byte;
|
||||
using INT = System.Int32;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper005 : Mapper
|
||||
{
|
||||
public const int MMC5_IRQ_METAL = 1 << 0;
|
||||
|
||||
BYTE sram_size;
|
||||
|
||||
BYTE prg_size; // $5100
|
||||
BYTE chr_size; // $5101
|
||||
BYTE sram_we_a, sram_we_b; // $5102-$5103
|
||||
BYTE graphic_mode; // $5104
|
||||
BYTE nametable_mode; // $5105
|
||||
BYTE[] nametable_type = new byte[4]; // $5105 use
|
||||
|
||||
BYTE sram_page; // $5113
|
||||
|
||||
BYTE fill_chr, fill_pal; // $5106-$5107
|
||||
BYTE split_control; // $5200
|
||||
BYTE split_scroll; // $5201
|
||||
BYTE split_page; // $5202
|
||||
|
||||
BYTE split_x;
|
||||
ushort split_addr;
|
||||
ushort split_yofs;
|
||||
|
||||
BYTE chr_type;
|
||||
BYTE chr_mode; // $5120-$512B use
|
||||
//BYTE chr_page[2][8];
|
||||
BYTE[,] chr_page = new byte[2, 8]; // $5120-$512B
|
||||
// BGパターン用バンク
|
||||
ByteArrayRef[] BG_MEM_BANK = new ByteArrayRef[8]{
|
||||
new ByteArrayRef(),
|
||||
new ByteArrayRef(),
|
||||
new ByteArrayRef(),
|
||||
new ByteArrayRef(),
|
||||
new ByteArrayRef(),
|
||||
new ByteArrayRef(),
|
||||
new ByteArrayRef(),
|
||||
new ByteArrayRef(),
|
||||
};
|
||||
BYTE[] BG_MEM_PAGE = new byte[8];
|
||||
|
||||
BYTE irq_status; // $5204(R)
|
||||
BYTE irq_enable; // $5204(W)
|
||||
BYTE irq_line; // $5203
|
||||
BYTE irq_scanline;
|
||||
BYTE irq_clear; // HSyncで使用
|
||||
BYTE irq_type;
|
||||
|
||||
BYTE mult_a, mult_b; // $5205-$5206
|
||||
public Mapper005(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
byte i;
|
||||
|
||||
prg_size = 3;
|
||||
chr_size = 3;
|
||||
|
||||
sram_we_a = 0x00;
|
||||
sram_we_b = 0x00;
|
||||
|
||||
graphic_mode = 0;
|
||||
nametable_mode = 0;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
nametable_type[i] = 0;
|
||||
}
|
||||
|
||||
fill_chr = fill_pal = 0;
|
||||
split_control = split_scroll = split_page = 0;
|
||||
|
||||
irq_enable = 0;
|
||||
irq_status = 0;
|
||||
irq_scanline = 0;
|
||||
irq_line = 0;
|
||||
irq_clear = 0;
|
||||
|
||||
irq_type = 0;
|
||||
|
||||
mult_a = mult_b = 0;
|
||||
|
||||
chr_type = 0;
|
||||
chr_mode = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
chr_page[0, i] = i;
|
||||
chr_page[1, i] = (byte)(4 + (i & 0x03));
|
||||
}
|
||||
|
||||
SetPROM_32K_Bank(PROM_8K_SIZE - 1, PROM_8K_SIZE - 1, PROM_8K_SIZE - 1, PROM_8K_SIZE - 1);
|
||||
SetVROM_8K_Bank(0);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
BG_MEM_BANK[i].SetArray(VROM, 0x0400 * i);
|
||||
BG_MEM_PAGE[i] = i;
|
||||
}
|
||||
|
||||
// SRAM設定
|
||||
SetBank_SRAM(3, 0);
|
||||
|
||||
sram_size = 0;
|
||||
nes.SetSAVERAM_SIZE(16 * 1024);
|
||||
|
||||
uint crc = nes.rom.GetPROM_CRC();
|
||||
|
||||
if (crc == 0x2b548d75 // Bandit Kings of Ancient China(U)
|
||||
|| crc == 0xf4cd4998 // Dai Koukai Jidai(J)
|
||||
|| crc == 0x8fa95456 // Ishin no Arashi(J)
|
||||
|| crc == 0x98c8e090 // Nobunaga no Yabou - Sengoku Gunyuu Den(J)
|
||||
|| crc == 0x8e9a5e2f // L'Empereur(Alt)(U)
|
||||
|| crc == 0x57e3218b // L'Empereur(U)
|
||||
|| crc == 0x2f50bd38 // L'Empereur(J)
|
||||
|| crc == 0xb56958d1 // Nobunaga's Ambition 2(U)
|
||||
|| crc == 0xe6c28c5f // Suikoden - Tenmei no Chikai(J)
|
||||
|| crc == 0xcd35e2e9)
|
||||
{ // Uncharted Waters(U)
|
||||
sram_size = 1;
|
||||
nes.SetSAVERAM_SIZE(32 * 1024);
|
||||
}
|
||||
else
|
||||
if (crc == 0xf4120e58 // Aoki Ookami to Shiroki Mejika - Genchou Hishi(J)
|
||||
|| crc == 0x286613d8 // Nobunaga no Yabou - Bushou Fuuun Roku(J)
|
||||
|| crc == 0x11eaad26 // Romance of the Three Kingdoms 2(U)
|
||||
|| crc == 0x95ba5733)
|
||||
{ // Sangokushi 2(J)
|
||||
sram_size = 2;
|
||||
nes.SetSAVERAM_SIZE(64 * 1024);
|
||||
}
|
||||
|
||||
if (crc == 0x95ca9ec7)
|
||||
{ // Castlevania 3 - Dracula's Curse(U)
|
||||
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||
}
|
||||
|
||||
if (crc == 0xcd9acf43)
|
||||
{ // Metal Slader Glory(J)
|
||||
irq_type = MMC5_IRQ_METAL;
|
||||
}
|
||||
|
||||
if (crc == 0xe91548d8)
|
||||
{ // Shin 4 Nin Uchi Mahjong - Yakuman Tengoku(J)
|
||||
chr_type = 1;
|
||||
}
|
||||
|
||||
nes.ppu.SetExtLatchMode(true);
|
||||
nes.apu.SelectExSound(8);
|
||||
}
|
||||
|
||||
//BYTE Mapper005::ReadLow(WORD addr)
|
||||
public override byte ReadLow(ushort addr)
|
||||
{
|
||||
BYTE data = (BYTE)(addr >> 8);
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x5015:
|
||||
data = nes.apu.ExRead(addr);
|
||||
break;
|
||||
|
||||
case 0x5204:
|
||||
data = irq_status;
|
||||
// irq_status = 0;
|
||||
irq_status = (byte)(irq_status & ~0x80);
|
||||
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0x5205:
|
||||
data = (byte)(mult_a * mult_b);
|
||||
break;
|
||||
case 0x5206:
|
||||
data = (BYTE)((mult_a * mult_b) >> 8);
|
||||
break;
|
||||
}
|
||||
|
||||
if (addr >= 0x5C00 && addr <= 0x5FFF)
|
||||
{
|
||||
if (graphic_mode >= 2)
|
||||
{ // ExRAM mode
|
||||
data = VRAM[0x0800 + (addr & 0x3FF)];
|
||||
}
|
||||
}
|
||||
else if (addr >= 0x6000 && addr <= 0x7FFF)
|
||||
{
|
||||
data = base.ReadLow(addr);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//void Mapper005::WriteLow(WORD addr, BYTE data)
|
||||
public override void WriteLow(ushort addr, byte data)
|
||||
{
|
||||
byte i;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x5100:
|
||||
prg_size = (byte)(data & 0x03);
|
||||
break;
|
||||
case 0x5101:
|
||||
chr_size = (byte)(data & 0x03);
|
||||
break;
|
||||
|
||||
case 0x5102:
|
||||
sram_we_a = (byte)(data & 0x03);
|
||||
break;
|
||||
case 0x5103:
|
||||
sram_we_b = (byte)(data & 0x03);
|
||||
break;
|
||||
|
||||
case 0x5104:
|
||||
graphic_mode = (byte)(data & 0x03);
|
||||
break;
|
||||
case 0x5105:
|
||||
nametable_mode = data;
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
nametable_type[i] = (byte)(data & 0x03);
|
||||
SetVRAM_1K_Bank((byte)(8 + i), nametable_type[i]);
|
||||
data >>= 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5106:
|
||||
fill_chr = data;
|
||||
break;
|
||||
case 0x5107:
|
||||
fill_pal = (byte)(data & 0x03);
|
||||
break;
|
||||
|
||||
case 0x5113:
|
||||
SetBank_SRAM(3, (byte)(data & 0x07));
|
||||
break;
|
||||
|
||||
case 0x5114:
|
||||
case 0x5115:
|
||||
case 0x5116:
|
||||
case 0x5117:
|
||||
SetBank_CPU(addr, data);
|
||||
break;
|
||||
|
||||
case 0x5120:
|
||||
case 0x5121:
|
||||
case 0x5122:
|
||||
case 0x5123:
|
||||
case 0x5124:
|
||||
case 0x5125:
|
||||
case 0x5126:
|
||||
case 0x5127:
|
||||
chr_mode = 0;
|
||||
chr_page[0, addr & 0x07] = data;
|
||||
SetBank_PPU();
|
||||
break;
|
||||
|
||||
case 0x5128:
|
||||
case 0x5129:
|
||||
case 0x512A:
|
||||
case 0x512B:
|
||||
chr_mode = 1;
|
||||
chr_page[1, (addr & 0x03) + 0] = data;
|
||||
chr_page[1, (addr & 0x03) + 4] = data;
|
||||
SetBank_PPU();
|
||||
break;
|
||||
|
||||
case 0x5200:
|
||||
split_control = data;
|
||||
break;
|
||||
case 0x5201:
|
||||
split_scroll = data;
|
||||
break;
|
||||
case 0x5202:
|
||||
split_page = (byte)(data & 0x3F);
|
||||
break;
|
||||
|
||||
case 0x5203:
|
||||
irq_line = data;
|
||||
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0x5204:
|
||||
irq_enable = data;
|
||||
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
|
||||
case 0x5205:
|
||||
mult_a = data;
|
||||
break;
|
||||
case 0x5206:
|
||||
mult_b = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (addr >= 0x5000 && addr <= 0x5015)
|
||||
{
|
||||
nes.apu.ExWrite(addr, data);
|
||||
}
|
||||
else if (addr >= 0x5C00 && addr <= 0x5FFF)
|
||||
{
|
||||
if (graphic_mode == 2)
|
||||
{ // ExRAM
|
||||
VRAM[0x0800 + (addr & 0x3FF)] = data;
|
||||
}
|
||||
else if (graphic_mode != 3)
|
||||
{ // Split,ExGraphic
|
||||
if ((irq_status & 0x40) != 0)
|
||||
{
|
||||
VRAM[0x0800 + (addr & 0x3FF)] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
VRAM[0x0800 + (addr & 0x3FF)] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (addr >= 0x6000 && addr <= 0x7FFF)
|
||||
{
|
||||
if ((sram_we_a == 0x02) && (sram_we_b == 0x01))
|
||||
{
|
||||
if (CPU_MEM_TYPE[3] == BANKTYPE_RAM)
|
||||
{
|
||||
CPU_MEM_BANK[3][addr & 0x1FFF] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper005::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
if (sram_we_a == 0x02 && sram_we_b == 0x01)
|
||||
{
|
||||
if (addr >= 0x8000 && addr < 0xE000)
|
||||
{
|
||||
if (CPU_MEM_TYPE[addr >> 13] == BANKTYPE_RAM)
|
||||
{
|
||||
CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetBank_CPU(uint addr, BYTE data)
|
||||
{
|
||||
if ((data & 0x80) != 0)
|
||||
{
|
||||
// PROM Bank
|
||||
switch (addr & 7)
|
||||
{
|
||||
case 4:
|
||||
if (prg_size == 3)
|
||||
{
|
||||
SetPROM_8K_Bank(4, data & 0x7F);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (prg_size == 1 || prg_size == 2)
|
||||
{
|
||||
SetPROM_16K_Bank(4, (data & 0x7F) >> 1);
|
||||
}
|
||||
else if (prg_size == 3)
|
||||
{
|
||||
SetPROM_8K_Bank(5, (data & 0x7F));
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (prg_size == 2 || prg_size == 3)
|
||||
{
|
||||
SetPROM_8K_Bank(6, (data & 0x7F));
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (prg_size == 0)
|
||||
{
|
||||
SetPROM_32K_Bank((data & 0x7F) >> 2);
|
||||
}
|
||||
else if (prg_size == 1)
|
||||
{
|
||||
SetPROM_16K_Bank(6, (data & 0x7F) >> 1);
|
||||
}
|
||||
else if (prg_size == 2 || prg_size == 3)
|
||||
{
|
||||
SetPROM_8K_Bank(7, (data & 0x7F));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// WRAM Bank
|
||||
switch (addr & 7)
|
||||
{
|
||||
case 4:
|
||||
if (prg_size == 3)
|
||||
{
|
||||
SetBank_SRAM(4, (byte)(data & 0x07));
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (prg_size == 1 || prg_size == 2)
|
||||
{
|
||||
SetBank_SRAM(4, (byte)((data & 0x06) + 0));
|
||||
SetBank_SRAM(5, (byte)((data & 0x06) + 1));
|
||||
}
|
||||
else if (prg_size == 3)
|
||||
{
|
||||
SetBank_SRAM(5, (byte)(data & 0x07));
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (prg_size == 2 || prg_size == 3)
|
||||
{
|
||||
SetBank_SRAM(6, (byte)(data & 0x07));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ByteArrayRef _prom_bank = new ByteArrayRef();
|
||||
void SetBank_SRAM(BYTE page, BYTE data)
|
||||
{
|
||||
if (sram_size == 0) data = (byte)((data > 3) ? 8 : 0);
|
||||
if (sram_size == 1) data = (byte)((data > 3) ? 1 : 0);
|
||||
if (sram_size == 2) data = (byte)((data > 3) ? 8 : data);
|
||||
if (sram_size == 3) data = (byte)((data > 3) ? 4 : data);
|
||||
|
||||
if (data != 8)
|
||||
{
|
||||
int offset = 0x2000 * data;
|
||||
_prom_bank.SetArray(WRAM, offset, WRAM.Length - offset);
|
||||
SetPROM_Bank(page, _prom_bank, BANKTYPE_RAM);
|
||||
CPU_MEM_PAGE[page] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
CPU_MEM_TYPE[page] = BANKTYPE_ROM;
|
||||
}
|
||||
}
|
||||
|
||||
void SetBank_PPU()
|
||||
{
|
||||
INT i;
|
||||
|
||||
if (chr_mode == 0)
|
||||
{
|
||||
// PPU SP Bank
|
||||
switch (chr_size)
|
||||
{
|
||||
case 0:
|
||||
SetVROM_8K_Bank(chr_page[0, 7]);
|
||||
break;
|
||||
case 1:
|
||||
SetVROM_4K_Bank(0, chr_page[0, 3]);
|
||||
SetVROM_4K_Bank(4, chr_page[0, 7]);
|
||||
break;
|
||||
case 2:
|
||||
SetVROM_2K_Bank(0, chr_page[0, 1]);
|
||||
SetVROM_2K_Bank(2, chr_page[0, 3]);
|
||||
SetVROM_2K_Bank(4, chr_page[0, 5]);
|
||||
SetVROM_2K_Bank(6, chr_page[0, 7]);
|
||||
break;
|
||||
case 3:
|
||||
SetVROM_8K_Bank(chr_page[0, 0],
|
||||
chr_page[0, 1],
|
||||
chr_page[0, 2],
|
||||
chr_page[0, 3],
|
||||
chr_page[0, 4],
|
||||
chr_page[0, 5],
|
||||
chr_page[0, 6],
|
||||
chr_page[0, 7]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (chr_mode == 1)
|
||||
{
|
||||
// PPU BG Bank
|
||||
switch (chr_size)
|
||||
{
|
||||
case 0:
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
BG_MEM_BANK[i].SetArray(VROM, 0x2000 * (chr_page[1, 7] % VROM_8K_SIZE) + 0x0400 * i);
|
||||
BG_MEM_PAGE[i] = (byte)((chr_page[1, 7] % VROM_8K_SIZE) * 8 + i);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
BG_MEM_BANK[i + 0].SetArray(VROM, 0x1000 * (chr_page[1, 3] % VROM_4K_SIZE) + 0x0400 * i);
|
||||
BG_MEM_BANK[i + 4].SetArray(VROM, 0x1000 * (chr_page[1, 7] % VROM_4K_SIZE) + 0x0400 * i);
|
||||
BG_MEM_PAGE[i + 0] = (byte)((chr_page[1, 3] % VROM_4K_SIZE) * 4 + i);
|
||||
BG_MEM_PAGE[i + 4] = (byte)((chr_page[1, 7] % VROM_4K_SIZE) * 4 + i);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
BG_MEM_BANK[i + 0].SetArray(VROM, 0x0800 * (chr_page[1, 1] % VROM_2K_SIZE) + 0x0400 * i);
|
||||
BG_MEM_BANK[i + 2].SetArray(VROM, 0x0800 * (chr_page[1, 3] % VROM_2K_SIZE) + 0x0400 * i);
|
||||
BG_MEM_BANK[i + 4].SetArray(VROM, 0x0800 * (chr_page[1, 5] % VROM_2K_SIZE) + 0x0400 * i);
|
||||
BG_MEM_BANK[i + 6].SetArray(VROM, 0x0800 * (chr_page[1, 7] % VROM_2K_SIZE) + 0x0400 * i);
|
||||
BG_MEM_PAGE[i + 0] = (byte)((chr_page[1, 1] % VROM_2K_SIZE) * 2 + i);
|
||||
BG_MEM_PAGE[i + 2] = (byte)((chr_page[1, 3] % VROM_2K_SIZE) * 2 + i);
|
||||
BG_MEM_PAGE[i + 4] = (byte)((chr_page[1, 5] % VROM_2K_SIZE) * 2 + i);
|
||||
BG_MEM_PAGE[i + 6] = (byte)((chr_page[1, 7] % VROM_2K_SIZE) * 2 + i);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
BG_MEM_BANK[i].SetArray(VROM, 0x0400 * (chr_page[1, i] % VROM_1K_SIZE));
|
||||
BG_MEM_PAGE[i] = (byte)((chr_page[1, i] % VROM_1K_SIZE) + i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void HSync(int scanline)
|
||||
{
|
||||
if ((irq_type & MMC5_IRQ_METAL) != 0)
|
||||
{
|
||||
if (irq_scanline == irq_line)
|
||||
{
|
||||
irq_status |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
// if( nes.ppu.IsDispON() && scanline < 239 ) {
|
||||
if (nes.ppu.IsDispON() && scanline < 240)
|
||||
{
|
||||
irq_scanline++;
|
||||
irq_status |= 0x40;
|
||||
irq_clear = 0;
|
||||
}
|
||||
else if ((irq_type & MMC5_IRQ_METAL) != 0)
|
||||
{
|
||||
irq_scanline = 0;
|
||||
irq_status = (byte)(irq_status & ~0x80);
|
||||
irq_status = (byte)(irq_status & ~0x40);
|
||||
}
|
||||
|
||||
if ((irq_type & MMC5_IRQ_METAL) == 0)
|
||||
{
|
||||
if (irq_scanline == irq_line)
|
||||
{
|
||||
irq_status |= 0x80;
|
||||
}
|
||||
|
||||
if (++irq_clear > 2)
|
||||
{
|
||||
irq_scanline = 0;
|
||||
irq_status = (byte)(irq_status & ~0x80);
|
||||
irq_status = (byte)(irq_status & ~0x40);
|
||||
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
}
|
||||
}
|
||||
|
||||
if ((irq_enable & 0x80) != 0 && (irq_status & 0x80) != 0 && (irq_status & 0x40) != 0)
|
||||
{
|
||||
nes.cpu.SetIRQ(IRQ_MAPPER);
|
||||
/// nes.cpu.IRQ_NotPending();
|
||||
}
|
||||
|
||||
// For Split mode!
|
||||
if (scanline == 0)
|
||||
{
|
||||
split_yofs = (ushort)(split_scroll & 0x07);
|
||||
split_addr = (ushort)(((split_scroll & 0xF8) << 2));
|
||||
}
|
||||
else if (nes.ppu.IsDispON())
|
||||
{
|
||||
if (split_yofs == 7)
|
||||
{
|
||||
split_yofs = 0;
|
||||
if ((split_addr & 0x03E0) == 0x03A0)
|
||||
{
|
||||
split_addr &= 0x001F;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((split_addr & 0x03E0) == 0x03E0)
|
||||
{
|
||||
split_addr &= 0x001F;
|
||||
}
|
||||
else
|
||||
{
|
||||
split_addr += 0x0020;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
split_yofs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper005::PPU_ExtLatchX(INT x)
|
||||
public override void PPU_ExtLatchX(int x)
|
||||
{
|
||||
split_x = (byte)x;
|
||||
}
|
||||
|
||||
//void Mapper005::PPU_ExtLatch(WORD addr, BYTE& chr_l, BYTE& chr_h, BYTE& attr )
|
||||
public override void PPU_ExtLatch(ushort addr, ref byte chr_l, ref byte chr_h, ref byte attr)
|
||||
{
|
||||
ushort ntbladr, attradr, tileadr, tileofs;
|
||||
ushort tile_yofs;
|
||||
uint tilebank;
|
||||
bool bSplit;
|
||||
|
||||
tile_yofs = nes.ppu.GetTILEY();
|
||||
|
||||
bSplit = false;
|
||||
if ((split_control & 0x80) != 0)
|
||||
{
|
||||
if ((split_control & 0x40) == 0)
|
||||
{
|
||||
// Left side
|
||||
if ((split_control & 0x1F) > split_x)
|
||||
{
|
||||
bSplit = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Right side
|
||||
if ((split_control & 0x1F) <= split_x)
|
||||
{
|
||||
bSplit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bSplit)
|
||||
{
|
||||
if (nametable_type[(addr & 0x0C00) >> 10] == 3)
|
||||
{
|
||||
// Fill mode
|
||||
if (graphic_mode == 1)
|
||||
{
|
||||
// ExGraphic mode
|
||||
ntbladr = (ushort)(0x2000 + (addr & 0x0FFF));
|
||||
// Get Nametable
|
||||
tileadr = (ushort)(fill_chr * 0x10 + tile_yofs);
|
||||
// Get TileBank
|
||||
tilebank = (uint)(0x1000 * ((VRAM[0x0800 + (ntbladr & 0x03FF)] & 0x3F) % VROM_4K_SIZE));
|
||||
// Attribute
|
||||
attr = (byte)((fill_pal << 2) & 0x0C);
|
||||
// Get Pattern
|
||||
chr_l = VROM[tilebank + tileadr];
|
||||
chr_h = VROM[tilebank + tileadr + 8];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal
|
||||
tileofs = (ushort)((PPUREG[0] & PPU_BGTBL_BIT) != 0 ? 0x1000 : 0x0000);
|
||||
tileadr = (ushort)(tileofs + fill_chr * 0x10 + tile_yofs);
|
||||
attr = (byte)((fill_pal << 2) & 0x0C);
|
||||
// Get Pattern
|
||||
if (chr_type != 0)
|
||||
{
|
||||
chr_l = PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||
chr_h = PPU_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||
}
|
||||
else
|
||||
{
|
||||
chr_l = BG_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||
chr_h = BG_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (graphic_mode == 1)
|
||||
{
|
||||
// ExGraphic mode
|
||||
ntbladr = (ushort)(0x2000 + (addr & 0x0FFF));
|
||||
// Get Nametable
|
||||
tileadr = (ushort)(PPU_MEM_BANK[ntbladr >> 10][ntbladr & 0x03FF] * 0x10 + tile_yofs);
|
||||
// Get TileBank
|
||||
tilebank = (uint)(0x1000 * ((VRAM[0x0800 + (ntbladr & 0x03FF)] & 0x3F) % VROM_4K_SIZE));
|
||||
// Get Attribute
|
||||
attr = (byte)((VRAM[0x0800 + (ntbladr & 0x03FF)] & 0xC0) >> 4);
|
||||
// Get Pattern
|
||||
chr_l = VROM[tilebank + tileadr];
|
||||
chr_h = VROM[tilebank + tileadr + 8];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal or ExVRAM
|
||||
tileofs = (ushort)((PPUREG[0] & PPU_BGTBL_BIT) != 0 ? 0x1000 : 0x0000);
|
||||
ntbladr = (ushort)(0x2000 + (addr & 0x0FFF));
|
||||
attradr = (ushort)(0x23C0 + (addr & 0x0C00) + ((addr & 0x0380) >> 4) + ((addr & 0x001C) >> 2));
|
||||
// Get Nametable
|
||||
tileadr = (ushort)(tileofs + PPU_MEM_BANK[ntbladr >> 10][ntbladr & 0x03FF] * 0x10 + tile_yofs);
|
||||
// Get Attribute
|
||||
attr = PPU_MEM_BANK[attradr >> 10][attradr & 0x03FF];
|
||||
if ((ntbladr & 0x0002) != 0) attr >>= 2;
|
||||
if ((ntbladr & 0x0040) != 0) attr >>= 4;
|
||||
attr = (byte)((attr & 0x03) << 2);
|
||||
// Get Pattern
|
||||
if (chr_type != 0)
|
||||
{
|
||||
chr_l = PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||
chr_h = PPU_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||
}
|
||||
else
|
||||
{
|
||||
chr_l = BG_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||
chr_h = BG_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ntbladr = (ushort)(((split_addr & 0x03E0) | (split_x & 0x1F)) & 0x03FF);
|
||||
// Get Split TileBank
|
||||
tilebank = (uint)(0x1000 * (split_page % VROM_4K_SIZE));
|
||||
tileadr = (ushort)(VRAM[0x0800 + ntbladr] * 0x10 + split_yofs);
|
||||
// Get Attribute
|
||||
attradr = (ushort)(0x03C0 + ((ntbladr & 0x0380) >> 4) + ((ntbladr & 0x001C) >> 2));
|
||||
attr = VRAM[0x0800 + attradr];
|
||||
if ((ntbladr & 0x0002) != 0) attr >>= 2;
|
||||
if ((ntbladr & 0x0040) != 0) attr >>= 4;
|
||||
attr = (byte)((attr & 0x03) << 2);
|
||||
// Get Pattern
|
||||
chr_l = VROM[tilebank + tileadr];
|
||||
chr_h = VROM[tilebank + tileadr + 8];
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper005::SaveState(LPBYTE p)
|
||||
public override void SaveState(byte[] p)
|
||||
{
|
||||
p[0] = prg_size;
|
||||
p[1] = chr_size;
|
||||
p[2] = sram_we_a;
|
||||
p[3] = sram_we_b;
|
||||
p[4] = graphic_mode;
|
||||
p[5] = nametable_mode;
|
||||
p[6] = nametable_type[0];
|
||||
p[7] = nametable_type[1];
|
||||
p[8] = nametable_type[2];
|
||||
p[9] = nametable_type[3];
|
||||
p[10] = sram_page;
|
||||
p[11] = fill_chr;
|
||||
p[12] = fill_pal;
|
||||
p[13] = split_control;
|
||||
p[14] = split_scroll;
|
||||
p[15] = split_page;
|
||||
p[16] = chr_mode;
|
||||
p[17] = irq_status;
|
||||
p[18] = irq_enable;
|
||||
p[19] = irq_line;
|
||||
p[20] = irq_scanline;
|
||||
p[21] = irq_clear;
|
||||
p[22] = mult_a;
|
||||
p[23] = mult_b;
|
||||
|
||||
INT i, j;
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
p[24 + j * 8 + i] = chr_page[j, i];
|
||||
}
|
||||
}
|
||||
// for( i = 0; i < 8; i++ ) {
|
||||
// p[40+i] = BG_MEM_PAGE[i];
|
||||
// }
|
||||
}
|
||||
|
||||
//void Mapper005::LoadState(LPBYTE p)
|
||||
public override void LoadState(byte[] p)
|
||||
{
|
||||
prg_size = p[0];
|
||||
chr_size = p[1];
|
||||
sram_we_a = p[2];
|
||||
sram_we_b = p[3];
|
||||
graphic_mode = p[4];
|
||||
nametable_mode = p[5];
|
||||
nametable_type[0] = p[6];
|
||||
nametable_type[1] = p[7];
|
||||
nametable_type[2] = p[8];
|
||||
nametable_type[3] = p[9];
|
||||
sram_page = p[10];
|
||||
fill_chr = p[11];
|
||||
fill_pal = p[12];
|
||||
split_control = p[13];
|
||||
split_scroll = p[14];
|
||||
split_page = p[15];
|
||||
chr_mode = p[16];
|
||||
irq_status = p[17];
|
||||
irq_enable = p[18];
|
||||
irq_line = p[19];
|
||||
irq_scanline = p[20];
|
||||
irq_clear = p[21];
|
||||
mult_a = p[22];
|
||||
mult_b = p[23];
|
||||
|
||||
INT i, j;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
chr_page[j, i] = p[24 + j * 8 + i];
|
||||
}
|
||||
}
|
||||
// // BGバンクの再設定処理
|
||||
// for( i = 0; i < 8; i++ ) {
|
||||
// BG_MEM_PAGE[i] = p[40+i]%VROM_1K_SIZE;
|
||||
// }
|
||||
// for( i = 0; i < 8; i++ ) {
|
||||
// BG_MEM_BANK[i] = VROM+0x0400*BG_MEM_PAGE[i];
|
||||
// }
|
||||
|
||||
SetBank_PPU();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override bool IsStateSave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26977049b3ea7ad4fa3b5c35a325ae48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,112 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper006 FFE F4xxx //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper006 : Mapper
|
||||
{
|
||||
BYTE irq_enable;
|
||||
INT irq_counter;
|
||||
public Mapper006(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetPROM_32K_Bank(0, 1, 14, 15);
|
||||
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
SetVROM_8K_Bank(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCRAM_8K_Bank(0);
|
||||
}
|
||||
|
||||
irq_enable = 0;
|
||||
irq_counter = 0;
|
||||
}
|
||||
|
||||
//void Mapper006::WriteLow(WORD addr, BYTE data)
|
||||
public override void WriteLow(ushort addr, byte data)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x42FE:
|
||||
if ((data & 0x10) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
|
||||
else SetVRAM_Mirror(VRAM_MIRROR4L);
|
||||
break;
|
||||
case 0x42FF:
|
||||
if ((data & 0x10) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
break;
|
||||
|
||||
case 0x4501:
|
||||
irq_enable = 0;
|
||||
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0x4502:
|
||||
irq_counter = (irq_counter & 0xFF00) | data;
|
||||
break;
|
||||
case 0x4503:
|
||||
irq_counter = (irq_counter & 0x00FF) | ((INT)data << 8);
|
||||
irq_enable = 0xFF;
|
||||
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
default:
|
||||
base.WriteLow(addr, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper006::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
SetPROM_16K_Bank(4, (data & 0x3C) >> 2);
|
||||
SetCRAM_8K_Bank(data & 0x03);
|
||||
}
|
||||
|
||||
//void Mapper006::HSync(INT scanline)
|
||||
public override void HSync(int scanline)
|
||||
{
|
||||
if (irq_enable != 0)
|
||||
{
|
||||
irq_counter += 133;
|
||||
if (irq_counter >= 0xFFFF)
|
||||
{
|
||||
// nes.cpu.IRQ();
|
||||
irq_counter = 0;
|
||||
|
||||
nes.cpu.SetIRQ(IRQ_MAPPER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper006::SaveState(LPBYTE p)
|
||||
public override void SaveState(byte[] p)
|
||||
{
|
||||
//p[0] = irq_enable;
|
||||
//*(INT*)&p[1] = irq_counter;
|
||||
}
|
||||
|
||||
//void Mapper006::LoadState(LPBYTE p)
|
||||
public override void LoadState(byte[] p)
|
||||
{
|
||||
//irq_enable = p[0];
|
||||
//irq_counter = *(INT*)&p[1];
|
||||
}
|
||||
|
||||
|
||||
public override bool IsStateSave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0672fe1374d484f4ab1c824d0882bfdd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,59 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper007 AOROM/AMROM //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper007 : Mapper
|
||||
{
|
||||
|
||||
BYTE patch;
|
||||
public Mapper007(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
patch = 0;
|
||||
|
||||
SetPROM_32K_Bank(0);
|
||||
SetVRAM_Mirror(VRAM_MIRROR4L);
|
||||
|
||||
uint crc = nes.rom.GetPROM_CRC();
|
||||
if (crc == 0x3c9fe649)
|
||||
{ // WWF Wrestlemania Challenge(U)
|
||||
SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
patch = 1;
|
||||
}
|
||||
if (crc == 0x09874777)
|
||||
{ // Marble Madness(U)
|
||||
nes.SetRenderMethod( EnumRenderMethod.TILE_RENDER);
|
||||
}
|
||||
|
||||
if (crc == 0x279710DC // Battletoads (U)
|
||||
|| crc == 0xCEB65B06)
|
||||
{ // Battletoads Double Dragon (U)
|
||||
nes.SetRenderMethod( EnumRenderMethod.PRE_ALL_RENDER);
|
||||
//::memset(WRAM, 0, sizeof(WRAM));
|
||||
MemoryUtility.ZEROMEMORY(WRAM, WRAM.Length);
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper007::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
SetPROM_32K_Bank(data & 0x07);
|
||||
|
||||
if (patch!=0)
|
||||
{
|
||||
if ((data & 0x10)!=0) SetVRAM_Mirror(VRAM_MIRROR4H);
|
||||
else SetVRAM_Mirror(VRAM_MIRROR4L);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 063872d968d91234a9a22755e3db7aab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,32 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper008 FFE F3xxx //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper008 : Mapper
|
||||
{
|
||||
|
||||
public Mapper008(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetPROM_32K_Bank(0, 1, 2, 3);
|
||||
SetVROM_8K_Bank(0);
|
||||
}
|
||||
|
||||
//void Mapper008::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
SetPROM_16K_Bank(4, (data & 0xF8) >> 3);
|
||||
SetVROM_8K_Bank(data & 0x07);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e39136ad8af00f4c95499cab3a0aa45
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,129 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper009 Nintendo MMC2 //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper009 : Mapper
|
||||
{
|
||||
BYTE[] reg = new byte[4];
|
||||
BYTE latch_a, latch_b;
|
||||
|
||||
public Mapper009(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetPROM_32K_Bank(0, PROM_8K_SIZE - 3, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
|
||||
|
||||
reg[0] = 0; reg[1] = 4;
|
||||
reg[2] = 0; reg[3] = 0;
|
||||
|
||||
latch_a = 0xFE;
|
||||
latch_b = 0xFE;
|
||||
SetVROM_4K_Bank(0, 4);
|
||||
SetVROM_4K_Bank(4, 0);
|
||||
|
||||
nes.ppu.SetChrLatchMode(true);
|
||||
}
|
||||
|
||||
//void Mapper009::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
switch (addr & 0xF000)
|
||||
{
|
||||
case 0xA000:
|
||||
SetPROM_8K_Bank(4, data);
|
||||
break;
|
||||
case 0xB000:
|
||||
reg[0] = data;
|
||||
if (latch_a == 0xFD)
|
||||
{
|
||||
SetVROM_4K_Bank(0, reg[0]);
|
||||
}
|
||||
break;
|
||||
case 0xC000:
|
||||
reg[1] = data;
|
||||
if (latch_a == 0xFE)
|
||||
{
|
||||
SetVROM_4K_Bank(0, reg[1]);
|
||||
}
|
||||
break;
|
||||
case 0xD000:
|
||||
reg[2] = data;
|
||||
if (latch_b == 0xFD)
|
||||
{
|
||||
SetVROM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
break;
|
||||
case 0xE000:
|
||||
reg[3] = data;
|
||||
if (latch_b == 0xFE)
|
||||
{
|
||||
SetVROM_4K_Bank(4, reg[3]);
|
||||
}
|
||||
break;
|
||||
case 0xF000:
|
||||
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper009::PPU_ChrLatch(WORD addr)
|
||||
public override void PPU_ChrLatch(ushort addr)
|
||||
{
|
||||
if ((addr & 0x1FF0) == 0x0FD0 && latch_a != 0xFD)
|
||||
{
|
||||
latch_a = 0xFD;
|
||||
SetVROM_4K_Bank(0, reg[0]);
|
||||
}
|
||||
else if ((addr & 0x1FF0) == 0x0FE0 && latch_a != 0xFE)
|
||||
{
|
||||
latch_a = 0xFE;
|
||||
SetVROM_4K_Bank(0, reg[1]);
|
||||
}
|
||||
else if ((addr & 0x1FF0) == 0x1FD0 && latch_b != 0xFD)
|
||||
{
|
||||
latch_b = 0xFD;
|
||||
SetVROM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
else if ((addr & 0x1FF0) == 0x1FE0 && latch_b != 0xFE)
|
||||
{
|
||||
latch_b = 0xFE;
|
||||
SetVROM_4K_Bank(4, reg[3]);
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper009::SaveState(LPBYTE p)
|
||||
public override void SaveState(byte[] p)
|
||||
{
|
||||
p[0] = reg[0];
|
||||
p[1] = reg[1];
|
||||
p[2] = reg[2];
|
||||
p[3] = reg[3];
|
||||
p[4] = latch_a;
|
||||
p[5] = latch_b;
|
||||
}
|
||||
|
||||
//void Mapper009::LoadState(LPBYTE p)
|
||||
public override void LoadState(byte[] p)
|
||||
{
|
||||
reg[0] = p[0];
|
||||
reg[1] = p[1];
|
||||
reg[2] = p[2];
|
||||
reg[3] = p[3];
|
||||
latch_a = p[4];
|
||||
latch_b = p[5];
|
||||
}
|
||||
|
||||
public override bool IsStateSave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60942642eeee2e04fbe2fad967c2400d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,129 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper010 Nintendo MMC4 //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper010 : Mapper
|
||||
{
|
||||
BYTE[] reg = new byte[4];
|
||||
BYTE latch_a, latch_b;
|
||||
|
||||
public Mapper010(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
|
||||
|
||||
reg[0] = 0; reg[1] = 4;
|
||||
reg[2] = 0; reg[3] = 0;
|
||||
|
||||
latch_a = 0xFE;
|
||||
latch_b = 0xFE;
|
||||
SetVROM_4K_Bank(0, 4);
|
||||
SetVROM_4K_Bank(4, 0);
|
||||
|
||||
nes.ppu.SetChrLatchMode(true);
|
||||
}
|
||||
|
||||
//void Mapper010::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
switch (addr & 0xF000)
|
||||
{
|
||||
case 0xA000:
|
||||
SetPROM_16K_Bank(4, data);
|
||||
break;
|
||||
case 0xB000:
|
||||
reg[0] = data;
|
||||
if (latch_a == 0xFD)
|
||||
{
|
||||
SetVROM_4K_Bank(0, reg[0]);
|
||||
}
|
||||
break;
|
||||
case 0xC000:
|
||||
reg[1] = data;
|
||||
if (latch_a == 0xFE)
|
||||
{
|
||||
SetVROM_4K_Bank(0, reg[1]);
|
||||
}
|
||||
break;
|
||||
case 0xD000:
|
||||
reg[2] = data;
|
||||
if (latch_b == 0xFD)
|
||||
{
|
||||
SetVROM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
break;
|
||||
case 0xE000:
|
||||
reg[3] = data;
|
||||
if (latch_b == 0xFE)
|
||||
{
|
||||
SetVROM_4K_Bank(4, reg[3]);
|
||||
}
|
||||
break;
|
||||
case 0xF000:
|
||||
if ((data & 0x01) != 0)
|
||||
SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper010::PPU_ChrLatch(WORD addr)
|
||||
public override void PPU_ChrLatch(ushort addr)
|
||||
{
|
||||
if ((addr & 0x1FF0) == 0x0FD0 && latch_a != 0xFD)
|
||||
{
|
||||
latch_a = 0xFD;
|
||||
SetVROM_4K_Bank(0, reg[0]);
|
||||
}
|
||||
else if ((addr & 0x1FF0) == 0x0FE0 && latch_a != 0xFE)
|
||||
{
|
||||
latch_a = 0xFE;
|
||||
SetVROM_4K_Bank(0, reg[1]);
|
||||
}
|
||||
else if ((addr & 0x1FF0) == 0x1FD0 && latch_b != 0xFD)
|
||||
{
|
||||
latch_b = 0xFD;
|
||||
SetVROM_4K_Bank(4, reg[2]);
|
||||
}
|
||||
else if ((addr & 0x1FF0) == 0x1FE0 && latch_b != 0xFE)
|
||||
{
|
||||
latch_b = 0xFE;
|
||||
SetVROM_4K_Bank(4, reg[3]);
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper010::SaveState(LPBYTE p)
|
||||
public override void SaveState(byte[] p)
|
||||
{
|
||||
p[0] = reg[0];
|
||||
p[1] = reg[1];
|
||||
p[2] = reg[2];
|
||||
p[3] = reg[3];
|
||||
p[4] = latch_a;
|
||||
p[5] = latch_b;
|
||||
}
|
||||
|
||||
//void Mapper010::LoadState(LPBYTE p)
|
||||
public override void LoadState(byte[] p)
|
||||
{
|
||||
reg[0] = p[0];
|
||||
reg[1] = p[1];
|
||||
reg[2] = p[2];
|
||||
reg[3] = p[3];
|
||||
latch_a = p[4];
|
||||
latch_b = p[5];
|
||||
}
|
||||
public override bool IsStateSave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0beeffcb64a5c124c9ef8d2b428f723e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,42 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper011 Color Dreams //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper011 : Mapper
|
||||
{
|
||||
|
||||
public Mapper011(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetPROM_32K_Bank(0);
|
||||
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
SetVROM_8K_Bank(0);
|
||||
// SetVROM_8K_Bank( 1 );
|
||||
}
|
||||
SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
}
|
||||
|
||||
//void Mapper011::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
//DEBUGOUT("WR A:%04X D:%02X\n", addr, data);
|
||||
SetPROM_32K_Bank(data);
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
SetVROM_8K_Bank(data >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d46cb68121988e498159e8a53b0cb90
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,331 @@
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper012 : Mapper
|
||||
{
|
||||
uint vb0, vb1;
|
||||
BYTE[] reg = new byte[8];
|
||||
BYTE prg0, prg1;
|
||||
BYTE chr01, chr23, chr4, chr5, chr6, chr7;
|
||||
BYTE we_sram;
|
||||
|
||||
BYTE irq_enable;
|
||||
BYTE irq_counter;
|
||||
BYTE irq_latch;
|
||||
BYTE irq_request;
|
||||
BYTE irq_preset;
|
||||
BYTE irq_preset_vbl;
|
||||
|
||||
public Mapper012(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
for (INT i = 0; i < 8; i++)
|
||||
{
|
||||
reg[i] = 0x00;
|
||||
}
|
||||
|
||||
prg0 = 0;
|
||||
prg1 = 1;
|
||||
SetBank_CPU();
|
||||
|
||||
vb0 = 0;
|
||||
vb1 = 0;
|
||||
chr01 = 0;
|
||||
chr23 = 2;
|
||||
chr4 = 4;
|
||||
chr5 = 5;
|
||||
chr6 = 6;
|
||||
chr7 = 7;
|
||||
SetBank_PPU();
|
||||
|
||||
we_sram = 0; // Disable
|
||||
irq_enable = 0; // Disable
|
||||
irq_counter = 0;
|
||||
irq_latch = 0xFF;
|
||||
irq_request = 0;
|
||||
irq_preset = 0;
|
||||
irq_preset_vbl = 0;
|
||||
}
|
||||
|
||||
//void Mapper012::WriteLow(WORD addr, BYTE data)
|
||||
public override void WriteLow(ushort addr, byte data)
|
||||
{
|
||||
if (addr > 0x4100 && addr < 0x6000)
|
||||
{
|
||||
vb0 = (byte)((data & 0x01) << 8);
|
||||
vb1 = (byte)((data & 0x10) << 4);
|
||||
SetBank_PPU();
|
||||
}
|
||||
else
|
||||
{
|
||||
base.WriteLow(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
//BYTE Mapper012::ReadLow(WORD addr)
|
||||
public override byte ReadLow(ushort addr)
|
||||
{
|
||||
return 0x01;
|
||||
}
|
||||
|
||||
//void Mapper012::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes.GetScanline(), nes.cpu.GetTotalCycles() );
|
||||
|
||||
switch (addr & 0xE001)
|
||||
{
|
||||
case 0x8000:
|
||||
reg[0] = data;
|
||||
SetBank_CPU();
|
||||
SetBank_PPU();
|
||||
break;
|
||||
case 0x8001:
|
||||
reg[1] = data;
|
||||
|
||||
switch (reg[0] & 0x07)
|
||||
{
|
||||
case 0x00:
|
||||
chr01 = (byte)(data & 0xFE);
|
||||
SetBank_PPU();
|
||||
break;
|
||||
case 0x01:
|
||||
chr23 = (byte)(data & 0xFE);
|
||||
SetBank_PPU();
|
||||
break;
|
||||
case 0x02:
|
||||
chr4 = data;
|
||||
SetBank_PPU();
|
||||
break;
|
||||
case 0x03:
|
||||
chr5 = data;
|
||||
SetBank_PPU();
|
||||
break;
|
||||
case 0x04:
|
||||
chr6 = data;
|
||||
SetBank_PPU();
|
||||
break;
|
||||
case 0x05:
|
||||
chr7 = data;
|
||||
SetBank_PPU();
|
||||
break;
|
||||
case 0x06:
|
||||
prg0 = data;
|
||||
SetBank_CPU();
|
||||
break;
|
||||
case 0x07:
|
||||
prg1 = data;
|
||||
SetBank_CPU();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xA000:
|
||||
reg[2] = data;
|
||||
if (!nes.rom.Is4SCREEN())
|
||||
{
|
||||
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
}
|
||||
break;
|
||||
case 0xA001:
|
||||
reg[3] = data;
|
||||
break;
|
||||
case 0xC000:
|
||||
reg[4] = data;
|
||||
irq_latch = data;
|
||||
break;
|
||||
case 0xC001:
|
||||
reg[5] = data;
|
||||
if (nes.GetScanline() < 240)
|
||||
{
|
||||
irq_counter |= 0x80;
|
||||
irq_preset = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
irq_counter |= 0x80;
|
||||
irq_preset_vbl = 0xFF;
|
||||
irq_preset = 0;
|
||||
}
|
||||
break;
|
||||
case 0xE000:
|
||||
reg[6] = data;
|
||||
irq_enable = 0;
|
||||
irq_request = 0;
|
||||
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0xE001:
|
||||
reg[7] = data;
|
||||
irq_enable = 1;
|
||||
irq_request = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper012::HSync(INT scanline)
|
||||
public override void HSync(int scanline)
|
||||
{
|
||||
if ((scanline >= 0 && scanline <= 239) && nes.ppu.IsDispON())
|
||||
{
|
||||
if (irq_preset_vbl != 0)
|
||||
{
|
||||
irq_counter = irq_latch;
|
||||
irq_preset_vbl = 0;
|
||||
}
|
||||
if (irq_preset != 0)
|
||||
{
|
||||
irq_counter = irq_latch;
|
||||
irq_preset = 0;
|
||||
}
|
||||
else if (irq_counter > 0)
|
||||
{
|
||||
irq_counter--;
|
||||
}
|
||||
|
||||
if (irq_counter == 0)
|
||||
{
|
||||
// Some game set irq_latch to zero to disable irq. So check it here.
|
||||
if (irq_enable != 0 && irq_latch != 0)
|
||||
{
|
||||
irq_request = 0xFF;
|
||||
nes.cpu.SetIRQ(IRQ_MAPPER);
|
||||
}
|
||||
irq_preset = 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetBank_CPU()
|
||||
{
|
||||
if ((reg[0] & 0x40) != 0)
|
||||
{
|
||||
SetPROM_32K_Bank(PROM_8K_SIZE - 2, prg1, prg0, PROM_8K_SIZE - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPROM_32K_Bank(prg0, prg1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SetBank_PPU()
|
||||
{
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
if ((reg[0] & 0x80) != 0)
|
||||
{
|
||||
SetVROM_8K_Bank(
|
||||
(int)(vb0 + chr4),
|
||||
(int)(vb0 + chr5),
|
||||
(int)(vb0 + chr6),
|
||||
(int)(vb0 + chr7),
|
||||
(int)(vb1 + chr01),
|
||||
(int)(vb1 + chr01 + 1),
|
||||
(int)(vb1 + chr23),
|
||||
(int)(vb1 + chr23 + 1)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVROM_8K_Bank(
|
||||
(int)(vb0 + chr01),
|
||||
(int)(vb0 + chr01 + 1),
|
||||
(int)(vb0 + chr23),
|
||||
(int)(vb0 + chr23 + 1),
|
||||
(int)(vb1 + chr4),
|
||||
(int)(vb1 + chr5),
|
||||
(int)(vb1 + chr6),
|
||||
(int)(vb1 + chr7))
|
||||
;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((reg[0] & 0x80) != 0)
|
||||
{
|
||||
SetCRAM_1K_Bank(4, (chr01 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(5, (chr01 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(6, (chr23 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(7, (chr23 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(0, chr4 & 0x07);
|
||||
SetCRAM_1K_Bank(1, chr5 & 0x07);
|
||||
SetCRAM_1K_Bank(2, chr6 & 0x07);
|
||||
SetCRAM_1K_Bank(3, chr7 & 0x07);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCRAM_1K_Bank(0, (chr01 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(1, (chr01 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(2, (chr23 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(3, (chr23 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(4, chr4 & 0x07);
|
||||
SetCRAM_1K_Bank(5, chr5 & 0x07);
|
||||
SetCRAM_1K_Bank(6, chr6 & 0x07);
|
||||
SetCRAM_1K_Bank(7, chr7 & 0x07);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//void Mapper012::SaveState(LPBYTE p)
|
||||
public override void SaveState(byte[] p)
|
||||
{
|
||||
//for (INT i = 0; i < 8; i++)
|
||||
//{
|
||||
// p[i] = reg[i];
|
||||
//}
|
||||
//p[8] = prg0;
|
||||
//p[9] = prg1;
|
||||
//p[10] = chr01;
|
||||
//p[11] = chr23;
|
||||
//p[12] = chr4;
|
||||
//p[13] = chr5;
|
||||
//p[14] = chr6;
|
||||
//p[15] = chr7;
|
||||
//p[16] = irq_enable;
|
||||
//p[17] = (BYTE)irq_counter;
|
||||
//p[18] = irq_latch;
|
||||
//p[19] = irq_request;
|
||||
//p[20] = irq_preset;
|
||||
//p[21] = irq_preset_vbl;
|
||||
//*((DWORD*)&p[22]) = vb0;
|
||||
//*((DWORD*)&p[26]) = vb1;
|
||||
}
|
||||
|
||||
//void Mapper012::LoadState(LPBYTE p)
|
||||
public override void LoadState(byte[] p)
|
||||
{
|
||||
//for (INT i = 0; i < 8; i++)
|
||||
//{
|
||||
// reg[i] = p[i];
|
||||
//}
|
||||
//prg0 = p[8];
|
||||
//prg1 = p[9];
|
||||
//chr01 = p[10];
|
||||
//chr23 = p[11];
|
||||
//chr4 = p[12];
|
||||
//chr5 = p[13];
|
||||
//chr6 = p[14];
|
||||
//chr7 = p[15];
|
||||
//irq_enable = p[16];
|
||||
//irq_counter = (INT)p[17];
|
||||
//irq_latch = p[18];
|
||||
//irq_request = p[19];
|
||||
//irq_preset = p[20];
|
||||
//irq_preset_vbl = p[21];
|
||||
//vb0 = *((DWORD*)&p[22]);
|
||||
//vb1 = *((DWORD*)&p[26]);
|
||||
}
|
||||
|
||||
|
||||
public override bool IsStateSave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0d9dccfbd35bbf458c8f5d100e2f89b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,33 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper013 CPROM //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper013 : Mapper
|
||||
{
|
||||
|
||||
public Mapper013(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetPROM_32K_Bank(0, 1, 2, 3);
|
||||
SetCRAM_4K_Bank(0, 0);
|
||||
SetCRAM_4K_Bank(4, 0);
|
||||
}
|
||||
|
||||
//void Mapper013::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
SetPROM_32K_Bank((data & 0x30) >> 4);
|
||||
SetCRAM_4K_Bank(4, data & 0x03);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 660200e3200da7d4eb9925d2b63afef5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,93 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper015 100-in-1 chip //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
using static VirtualNes.MMU;
|
||||
using static VirtualNes.Core.CPU;
|
||||
using INT = System.Int32;
|
||||
using BYTE = System.Byte;
|
||||
using Codice.CM.Client.Differences;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
{
|
||||
public class Mapper015 : Mapper
|
||||
{
|
||||
|
||||
public Mapper015(NES parent) : base(parent) { }
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetPROM_32K_Bank(0, 1, 2, 3);
|
||||
}
|
||||
|
||||
//void Mapper015::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x8000:
|
||||
if ((data & 0x80) != 0)
|
||||
{
|
||||
SetPROM_8K_Bank(4, (data & 0x3F) * 2 + 1);
|
||||
SetPROM_8K_Bank(5, (data & 0x3F) * 2 + 0);
|
||||
SetPROM_8K_Bank(6, (data & 0x3F) * 2 + 3);
|
||||
SetPROM_8K_Bank(7, (data & 0x3F) * 2 + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPROM_8K_Bank(4, (data & 0x3F) * 2 + 0);
|
||||
SetPROM_8K_Bank(5, (data & 0x3F) * 2 + 1);
|
||||
SetPROM_8K_Bank(6, (data & 0x3F) * 2 + 2);
|
||||
SetPROM_8K_Bank(7, (data & 0x3F) * 2 + 3);
|
||||
}
|
||||
if ((data & 0x40) != 0)
|
||||
SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
break;
|
||||
case 0x8001:
|
||||
if ((data & 0x80) != 0)
|
||||
{
|
||||
SetPROM_8K_Bank(6, (data & 0x3F) * 2 + 1);
|
||||
SetPROM_8K_Bank(7, (data & 0x3F) * 2 + 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPROM_8K_Bank(6, (data & 0x3F) * 2 + 0);
|
||||
SetPROM_8K_Bank(7, (data & 0x3F) * 2 + 1);
|
||||
}
|
||||
break;
|
||||
case 0x8002:
|
||||
if ((data & 0x80) != 0)
|
||||
{
|
||||
SetPROM_8K_Bank(4, (data & 0x3F) * 2 + 1);
|
||||
SetPROM_8K_Bank(5, (data & 0x3F) * 2 + 1);
|
||||
SetPROM_8K_Bank(6, (data & 0x3F) * 2 + 1);
|
||||
SetPROM_8K_Bank(7, (data & 0x3F) * 2 + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPROM_8K_Bank(4, (data & 0x3F) * 2 + 0);
|
||||
SetPROM_8K_Bank(5, (data & 0x3F) * 2 + 0);
|
||||
SetPROM_8K_Bank(6, (data & 0x3F) * 2 + 0);
|
||||
SetPROM_8K_Bank(7, (data & 0x3F) * 2 + 0);
|
||||
}
|
||||
break;
|
||||
case 0x8003:
|
||||
if ((data & 0x80) != 0)
|
||||
{
|
||||
SetPROM_8K_Bank(6, (data & 0x3F) * 2 + 1);
|
||||
SetPROM_8K_Bank(7, (data & 0x3F) * 2 + 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPROM_8K_Bank(6, (data & 0x3F) * 2 + 0);
|
||||
SetPROM_8K_Bank(7, (data & 0x3F) * 2 + 1);
|
||||
}
|
||||
if ((data & 0x40) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a00ec8072aa26648bcd7bef203e9a39
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -22,6 +22,7 @@ namespace VirtualNes.Core
|
||||
BYTE irq_latch;
|
||||
BYTE irq_request;
|
||||
int MMC4prg, MMC4chr;
|
||||
|
||||
public Mapper245(NES parent) : base(parent)
|
||||
{
|
||||
}
|
||||
@ -30,92 +31,92 @@ namespace VirtualNes.Core
|
||||
//void Mapper245::Reset()
|
||||
public override void Reset()
|
||||
{
|
||||
for (INT i = 0; i < 8; i++)
|
||||
{
|
||||
reg[i] = 0x00;
|
||||
}
|
||||
|
||||
prg0 = 0;
|
||||
prg1 = 1;
|
||||
|
||||
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
|
||||
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
SetVROM_8K_Bank(0);
|
||||
}
|
||||
|
||||
we_sram = 0; // Disable
|
||||
irq_enable = 0; // Disable
|
||||
irq_counter = 0;
|
||||
irq_latch = 0;
|
||||
irq_request = 0;
|
||||
|
||||
for (INT i = 0; i < 8; i++)
|
||||
{
|
||||
reg[i] = 0x00;
|
||||
}
|
||||
|
||||
prg0 = 0;
|
||||
prg1 = 1;
|
||||
|
||||
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
|
||||
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
SetVROM_8K_Bank(0);
|
||||
}
|
||||
|
||||
we_sram = 0; // Disable
|
||||
irq_enable = 0; // Disable
|
||||
irq_counter = 0;
|
||||
irq_latch = 0;
|
||||
irq_request = 0;
|
||||
|
||||
nes.SetIrqType(NES.IRQMETHOD.IRQ_CLOCK);
|
||||
}
|
||||
|
||||
//void Mapper245::Write(WORD addr, BYTE data)
|
||||
public override void Write(ushort addr, byte data)
|
||||
{
|
||||
switch (addr & 0xF7FF)
|
||||
{
|
||||
case 0x8000:
|
||||
reg[0] = data;
|
||||
break;
|
||||
case 0x8001:
|
||||
reg[1] = data;
|
||||
switch (reg[0])
|
||||
{
|
||||
case 0x00:
|
||||
reg[3] = (byte)((data & 2) << 5);
|
||||
SetPROM_8K_Bank(6, 0x3E | reg[3]);
|
||||
SetPROM_8K_Bank(7, 0x3F | reg[3]);
|
||||
break;
|
||||
case 0x06:
|
||||
prg0 = data;
|
||||
break;
|
||||
case 0x07:
|
||||
prg1 = data;
|
||||
break;
|
||||
}
|
||||
SetPROM_8K_Bank(4, prg0 | reg[3]);
|
||||
SetPROM_8K_Bank(5, prg1 | reg[3]);
|
||||
break;
|
||||
case 0xA000:
|
||||
reg[2] = data;
|
||||
if (!nes.rom.Is4SCREEN())
|
||||
{
|
||||
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
}
|
||||
break;
|
||||
case 0xA001:
|
||||
|
||||
break;
|
||||
case 0xC000:
|
||||
reg[4] = data;
|
||||
irq_counter = data;
|
||||
irq_request = 0;
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0xC001:
|
||||
reg[5] = data;
|
||||
irq_latch = data;
|
||||
irq_request = 0;
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0xE000:
|
||||
reg[6] = data;
|
||||
irq_enable = 0;
|
||||
irq_request = 0;
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0xE001:
|
||||
reg[7] = data;
|
||||
irq_enable = 1;
|
||||
irq_request = 0;
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
switch (addr & 0xF7FF)
|
||||
{
|
||||
case 0x8000:
|
||||
reg[0] = data;
|
||||
break;
|
||||
case 0x8001:
|
||||
reg[1] = data;
|
||||
switch (reg[0])
|
||||
{
|
||||
case 0x00:
|
||||
reg[3] = (byte)((data & 2) << 5);
|
||||
SetPROM_8K_Bank(6, 0x3E | reg[3]);
|
||||
SetPROM_8K_Bank(7, 0x3F | reg[3]);
|
||||
break;
|
||||
case 0x06:
|
||||
prg0 = data;
|
||||
break;
|
||||
case 0x07:
|
||||
prg1 = data;
|
||||
break;
|
||||
}
|
||||
SetPROM_8K_Bank(4, prg0 | reg[3]);
|
||||
SetPROM_8K_Bank(5, prg1 | reg[3]);
|
||||
break;
|
||||
case 0xA000:
|
||||
reg[2] = data;
|
||||
if (!nes.rom.Is4SCREEN())
|
||||
{
|
||||
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
|
||||
else SetVRAM_Mirror(VRAM_VMIRROR);
|
||||
}
|
||||
break;
|
||||
case 0xA001:
|
||||
|
||||
break;
|
||||
case 0xC000:
|
||||
reg[4] = data;
|
||||
irq_counter = data;
|
||||
irq_request = 0;
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0xC001:
|
||||
reg[5] = data;
|
||||
irq_latch = data;
|
||||
irq_request = 0;
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0xE000:
|
||||
reg[6] = data;
|
||||
irq_enable = 0;
|
||||
irq_request = 0;
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
case 0xE001:
|
||||
reg[7] = data;
|
||||
irq_enable = 1;
|
||||
irq_request = 0;
|
||||
nes.cpu.ClrIRQ(IRQ_MAPPER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,27 +131,27 @@ namespace VirtualNes.Core
|
||||
//void Mapper245::HSync(INT scanline)
|
||||
public override void HSync(int scanline)
|
||||
{
|
||||
if ((scanline >= 0 && scanline <= 239))
|
||||
{
|
||||
if (nes.ppu.IsDispON())
|
||||
{
|
||||
if (irq_enable != 0 && irq_request == 0)
|
||||
{
|
||||
if (scanline == 0)
|
||||
{
|
||||
if (irq_counter != 0)
|
||||
{
|
||||
irq_counter--;
|
||||
}
|
||||
}
|
||||
if ((irq_counter--) == 0)
|
||||
{
|
||||
irq_request = 0xFF;
|
||||
irq_counter = irq_latch;
|
||||
nes.cpu.SetIRQ(IRQ_MAPPER);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((scanline >= 0 && scanline <= 239))
|
||||
{
|
||||
if (nes.ppu.IsDispON())
|
||||
{
|
||||
if (irq_enable != 0 && irq_request == 0)
|
||||
{
|
||||
if (scanline == 0)
|
||||
{
|
||||
if (irq_counter != 0)
|
||||
{
|
||||
irq_counter--;
|
||||
}
|
||||
}
|
||||
if ((irq_counter--) == 0)
|
||||
{
|
||||
irq_request = 0xFF;
|
||||
irq_counter = irq_latch;
|
||||
nes.cpu.SetIRQ(IRQ_MAPPER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if( irq_request && (nes.GetIrqType() == NES::IRQ_HSYNC) ) {
|
||||
// nes.cpu.IRQ_NotPending();
|
||||
@ -164,43 +165,43 @@ namespace VirtualNes.Core
|
||||
|
||||
void SetBank_PPU()
|
||||
{
|
||||
if ((VROM_1K_SIZE) != 0)
|
||||
{
|
||||
if (((reg[0] & 0x80)! + 0) != 0)
|
||||
{
|
||||
SetVROM_8K_Bank(chr4, chr5, chr6, chr7,
|
||||
chr23 + 1, chr23, chr01 + 1, chr01);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVROM_8K_Bank(chr01, chr01 + 1, chr23, chr23 + 1,
|
||||
chr4, chr5, chr6, chr7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((reg[0] & 0x80) != 0)
|
||||
{
|
||||
SetCRAM_1K_Bank(4, (chr01 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(5, (chr01 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(6, (chr23 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(7, (chr23 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(0, chr4 & 0x07);
|
||||
SetCRAM_1K_Bank(1, chr5 & 0x07);
|
||||
SetCRAM_1K_Bank(2, chr6 & 0x07);
|
||||
SetCRAM_1K_Bank(3, chr7 & 0x07);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCRAM_1K_Bank(0, (chr01 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(1, (chr01 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(2, (chr23 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(3, (chr23 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(4, chr4 & 0x07);
|
||||
SetCRAM_1K_Bank(5, chr5 & 0x07);
|
||||
SetCRAM_1K_Bank(6, chr6 & 0x07);
|
||||
SetCRAM_1K_Bank(7, chr7 & 0x07);
|
||||
}
|
||||
if (VROM_1K_SIZE != 0)
|
||||
{
|
||||
if ((reg[0] & 0x80) != 0)
|
||||
{
|
||||
SetVROM_8K_Bank(chr4, chr5, chr6, chr7,
|
||||
chr23 + 1, chr23, chr01 + 1, chr01);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetVROM_8K_Bank(chr01, chr01 + 1, chr23, chr23 + 1,
|
||||
chr4, chr5, chr6, chr7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((reg[0] & 0x80) != 0)
|
||||
{
|
||||
SetCRAM_1K_Bank(4, (chr01 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(5, (chr01 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(6, (chr23 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(7, (chr23 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(0, chr4 & 0x07);
|
||||
SetCRAM_1K_Bank(1, chr5 & 0x07);
|
||||
SetCRAM_1K_Bank(2, chr6 & 0x07);
|
||||
SetCRAM_1K_Bank(3, chr7 & 0x07);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCRAM_1K_Bank(0, (chr01 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(1, (chr01 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(2, (chr23 + 0) & 0x07);
|
||||
SetCRAM_1K_Bank(3, (chr23 + 1) & 0x07);
|
||||
SetCRAM_1K_Bank(4, chr4 & 0x07);
|
||||
SetCRAM_1K_Bank(5, chr5 & 0x07);
|
||||
SetCRAM_1K_Bank(6, chr6 & 0x07);
|
||||
SetCRAM_1K_Bank(7, chr7 & 0x07);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1147,6 +1147,16 @@ namespace VirtualNes.Core
|
||||
bChrLatch = bMode;
|
||||
}
|
||||
|
||||
internal void SetExtNameTableMode(bool bMode)
|
||||
{
|
||||
bExtNameTable = bMode;
|
||||
}
|
||||
|
||||
internal void SetExtMonoMode(bool bMode)
|
||||
{
|
||||
bExtMono = bMode;
|
||||
}
|
||||
|
||||
public struct Sprite
|
||||
{
|
||||
public byte y
|
||||
|
||||
@ -91,7 +91,9 @@ Mapper支持越多,通俗讲就是支持更多卡带。
|
||||
|
||||
我们的项目也必须支持上! 咱们也同步要进行一个补充
|
||||
|
||||
追加了特殊的失传Mapper 162,163,175,176,178,192,195,199,216 (from https://github.com/yamanyandakure/VirtuaNES097)
|
||||
追加了特殊的失传Mapper 35,111,162,163,175,176,178,192,195,199,216 (from https://github.com/yamanyandakure/VirtuaNES097)
|
||||
|
||||
后续补充二次,修正 Mapper199 参照叶枫VirtuaNESex_src(20191105)
|
||||
|
||||
|
||||
|
||||
|
||||
203
References/VirtuaNESex_src_191105/7z/7z.h
Normal file
203
References/VirtuaNESex_src_191105/7z/7z.h
Normal file
@ -0,0 +1,203 @@
|
||||
/* 7z.h -- 7z interface
|
||||
2010-03-11 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_H
|
||||
#define __7Z_H
|
||||
|
||||
#include "7zBuf.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define k7zStartHeaderSize 0x20
|
||||
#define k7zSignatureSize 6
|
||||
extern Byte k7zSignature[k7zSignatureSize];
|
||||
#define k7zMajorVersion 0
|
||||
|
||||
enum EIdEnum
|
||||
{
|
||||
k7zIdEnd,
|
||||
k7zIdHeader,
|
||||
k7zIdArchiveProperties,
|
||||
k7zIdAdditionalStreamsInfo,
|
||||
k7zIdMainStreamsInfo,
|
||||
k7zIdFilesInfo,
|
||||
k7zIdPackInfo,
|
||||
k7zIdUnpackInfo,
|
||||
k7zIdSubStreamsInfo,
|
||||
k7zIdSize,
|
||||
k7zIdCRC,
|
||||
k7zIdFolder,
|
||||
k7zIdCodersUnpackSize,
|
||||
k7zIdNumUnpackStream,
|
||||
k7zIdEmptyStream,
|
||||
k7zIdEmptyFile,
|
||||
k7zIdAnti,
|
||||
k7zIdName,
|
||||
k7zIdCTime,
|
||||
k7zIdATime,
|
||||
k7zIdMTime,
|
||||
k7zIdWinAttributes,
|
||||
k7zIdComment,
|
||||
k7zIdEncodedHeader,
|
||||
k7zIdStartPos,
|
||||
k7zIdDummy
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
UInt64 MethodID;
|
||||
CBuf Props;
|
||||
} CSzCoderInfo;
|
||||
|
||||
void SzCoderInfo_Init(CSzCoderInfo *p);
|
||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 InIndex;
|
||||
UInt32 OutIndex;
|
||||
} CSzBindPair;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzCoderInfo *Coders;
|
||||
CSzBindPair *BindPairs;
|
||||
UInt32 *PackStreams;
|
||||
UInt64 *UnpackSizes;
|
||||
UInt32 NumCoders;
|
||||
UInt32 NumBindPairs;
|
||||
UInt32 NumPackStreams;
|
||||
int UnpackCRCDefined;
|
||||
UInt32 UnpackCRC;
|
||||
|
||||
UInt32 NumUnpackStreams;
|
||||
} CSzFolder;
|
||||
|
||||
void SzFolder_Init(CSzFolder *p);
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *stream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 Low;
|
||||
UInt32 High;
|
||||
} CNtfsFileTime;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CNtfsFileTime MTime;
|
||||
UInt64 Size;
|
||||
UInt32 Crc;
|
||||
UInt32 Attrib;
|
||||
Byte HasStream;
|
||||
Byte IsDir;
|
||||
Byte IsAnti;
|
||||
Byte CrcDefined;
|
||||
Byte MTimeDefined;
|
||||
Byte AttribDefined;
|
||||
} CSzFileItem;
|
||||
|
||||
void SzFile_Init(CSzFileItem *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt64 *PackSizes;
|
||||
Byte *PackCRCsDefined;
|
||||
UInt32 *PackCRCs;
|
||||
CSzFolder *Folders;
|
||||
CSzFileItem *Files;
|
||||
UInt32 NumPackStreams;
|
||||
UInt32 NumFolders;
|
||||
UInt32 NumFiles;
|
||||
} CSzAr;
|
||||
|
||||
void SzAr_Init(CSzAr *p);
|
||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
||||
|
||||
|
||||
/*
|
||||
SzExtract extracts file from archive
|
||||
|
||||
*outBuffer must be 0 before first call for each new archive.
|
||||
|
||||
Extracting cache:
|
||||
If you need to decompress more than one file, you can send
|
||||
these values from previous call:
|
||||
*blockIndex,
|
||||
*outBuffer,
|
||||
*outBufferSize
|
||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||
it will increase decompression speed.
|
||||
|
||||
If you use external function, you can declare these 3 cache variables
|
||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||
|
||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzAr db;
|
||||
|
||||
UInt64 startPosAfterHeader;
|
||||
UInt64 dataPos;
|
||||
|
||||
UInt32 *FolderStartPackStreamIndex;
|
||||
UInt64 *PackStreamStartPositions;
|
||||
UInt32 *FolderStartFileIndex;
|
||||
UInt32 *FileIndexToFolderIndexMap;
|
||||
|
||||
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||
CBuf FileNames; /* UTF-16-LE */
|
||||
} CSzArEx;
|
||||
|
||||
void SzArEx_Init(CSzArEx *p);
|
||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
||||
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||
|
||||
/*
|
||||
if dest == NULL, the return value specifies the required size of the buffer,
|
||||
in 16-bit characters, including the null-terminating character.
|
||||
if dest != NULL, the return value specifies the number of 16-bit characters that
|
||||
are written to the dest, including the null-terminating character. */
|
||||
|
||||
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||
|
||||
SRes SzArEx_Extract(
|
||||
const CSzArEx *db,
|
||||
ILookInStream *inStream,
|
||||
UInt32 fileIndex, /* index of file */
|
||||
UInt32 *blockIndex, /* index of solid block */
|
||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||
size_t *outBufferSize, /* buffer size for output buffer */
|
||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||
ISzAlloc *allocMain,
|
||||
ISzAlloc *allocTemp);
|
||||
|
||||
|
||||
/*
|
||||
SzArEx_Open Errors:
|
||||
SZ_ERROR_NO_ARCHIVE
|
||||
SZ_ERROR_ARCHIVE
|
||||
SZ_ERROR_UNSUPPORTED
|
||||
SZ_ERROR_MEM
|
||||
SZ_ERROR_CRC
|
||||
SZ_ERROR_INPUT_EOF
|
||||
SZ_ERROR_FAIL
|
||||
*/
|
||||
|
||||
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
76
References/VirtuaNESex_src_191105/7z/7zAlloc.c
Normal file
76
References/VirtuaNESex_src_191105/7z/7zAlloc.c
Normal file
@ -0,0 +1,76 @@
|
||||
/* 7zAlloc.c -- Allocation functions
|
||||
2010-10-29 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "7zAlloc.h"
|
||||
|
||||
/* #define _SZ_ALLOC_DEBUG */
|
||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
int g_allocCount = 0;
|
||||
int g_allocCountTemp = 0;
|
||||
|
||||
#endif
|
||||
|
||||
void *SzAlloc(void *p, size_t size)
|
||||
{
|
||||
p = p;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
|
||||
g_allocCount++;
|
||||
#endif
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFree(void *p, void *address)
|
||||
{
|
||||
p = p;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
{
|
||||
g_allocCount--;
|
||||
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
|
||||
}
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
||||
void *SzAllocTemp(void *p, size_t size)
|
||||
{
|
||||
p = p;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
|
||||
g_allocCountTemp++;
|
||||
#ifdef _WIN32
|
||||
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||
#endif
|
||||
#endif
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void SzFreeTemp(void *p, void *address)
|
||||
{
|
||||
p = p;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
{
|
||||
g_allocCountTemp--;
|
||||
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
HeapFree(GetProcessHeap(), 0, address);
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
15
References/VirtuaNESex_src_191105/7z/7zAlloc.h
Normal file
15
References/VirtuaNESex_src_191105/7z/7zAlloc.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* 7zAlloc.h -- Allocation functions
|
||||
2010-10-29 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_ALLOC_H
|
||||
#define __7Z_ALLOC_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void *SzAlloc(void *p, size_t size);
|
||||
void SzFree(void *p, void *address);
|
||||
|
||||
void *SzAllocTemp(void *p, size_t size);
|
||||
void SzFreeTemp(void *p, void *address);
|
||||
|
||||
#endif
|
||||
36
References/VirtuaNESex_src_191105/7z/7zBuf.c
Normal file
36
References/VirtuaNESex_src_191105/7z/7zBuf.c
Normal file
@ -0,0 +1,36 @@
|
||||
/* 7zBuf.c -- Byte Buffer
|
||||
2008-03-28
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "7zBuf.h"
|
||||
|
||||
void Buf_Init(CBuf *p)
|
||||
{
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
}
|
||||
|
||||
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
|
||||
{
|
||||
p->size = 0;
|
||||
if (size == 0)
|
||||
{
|
||||
p->data = 0;
|
||||
return 1;
|
||||
}
|
||||
p->data = (Byte *)alloc->Alloc(alloc, size);
|
||||
if (p->data != 0)
|
||||
{
|
||||
p->size = size;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Buf_Free(CBuf *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->data);
|
||||
p->data = 0;
|
||||
p->size = 0;
|
||||
}
|
||||
39
References/VirtuaNESex_src_191105/7z/7zBuf.h
Normal file
39
References/VirtuaNESex_src_191105/7z/7zBuf.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* 7zBuf.h -- Byte Buffer
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_BUF_H
|
||||
#define __7Z_BUF_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *data;
|
||||
size_t size;
|
||||
} CBuf;
|
||||
|
||||
void Buf_Init(CBuf *p);
|
||||
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
|
||||
void Buf_Free(CBuf *p, ISzAlloc *alloc);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *data;
|
||||
size_t size;
|
||||
size_t pos;
|
||||
} CDynBuf;
|
||||
|
||||
void DynBuf_Construct(CDynBuf *p);
|
||||
void DynBuf_SeekToBeg(CDynBuf *p);
|
||||
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
|
||||
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
74
References/VirtuaNESex_src_191105/7z/7zCrc.c
Normal file
74
References/VirtuaNESex_src_191105/7z/7zCrc.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* 7zCrc.c -- CRC32 calculation
|
||||
2009-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "7zCrc.h"
|
||||
#include "CpuArch.h"
|
||||
|
||||
#define kCrcPoly 0xEDB88320
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
#define CRC_NUM_TABLES 8
|
||||
#else
|
||||
#define CRC_NUM_TABLES 1
|
||||
#endif
|
||||
|
||||
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
|
||||
static CRC_FUNC g_CrcUpdate;
|
||||
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
||||
|
||||
#if CRC_NUM_TABLES == 1
|
||||
|
||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
|
||||
#endif
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
||||
{
|
||||
return g_CrcUpdate(v, data, size, g_CrcTable);
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
|
||||
{
|
||||
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
|
||||
}
|
||||
|
||||
void MY_FAST_CALL CrcGenerateTable()
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = i;
|
||||
unsigned j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
g_CrcTable[i] = r;
|
||||
}
|
||||
#if CRC_NUM_TABLES == 1
|
||||
g_CrcUpdate = CrcUpdateT1;
|
||||
#else
|
||||
for (; i < 256 * CRC_NUM_TABLES; i++)
|
||||
{
|
||||
UInt32 r = g_CrcTable[i - 256];
|
||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||
}
|
||||
g_CrcUpdate = CrcUpdateT4;
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
if (!CPU_Is_InOrder())
|
||||
g_CrcUpdate = CrcUpdateT8;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
25
References/VirtuaNESex_src_191105/7z/7zCrc.h
Normal file
25
References/VirtuaNESex_src_191105/7z/7zCrc.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* 7zCrc.h -- CRC32 calculation
|
||||
2009-11-21 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_CRC_H
|
||||
#define __7Z_CRC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
extern UInt32 g_CrcTable[];
|
||||
|
||||
/* Call CrcGenerateTable one time before other CRC functions */
|
||||
void MY_FAST_CALL CrcGenerateTable(void);
|
||||
|
||||
#define CRC_INIT_VAL 0xFFFFFFFF
|
||||
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
|
||||
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
|
||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
34
References/VirtuaNESex_src_191105/7z/7zCrcOpt.c
Normal file
34
References/VirtuaNESex_src_191105/7z/7zCrcOpt.c
Normal file
@ -0,0 +1,34 @@
|
||||
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
|
||||
2009-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "CpuArch.h"
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
|
||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
for (; size >= 4; size -= 4, p += 4)
|
||||
{
|
||||
v ^= *(const UInt32 *)p;
|
||||
v =
|
||||
table[0x300 + (v & 0xFF)] ^
|
||||
table[0x200 + ((v >> 8) & 0xFF)] ^
|
||||
table[0x100 + ((v >> 16) & 0xFF)] ^
|
||||
table[0x000 + ((v >> 24))];
|
||||
}
|
||||
for (; size > 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
return CrcUpdateT4(v, data, size, table);
|
||||
}
|
||||
|
||||
#endif
|
||||
470
References/VirtuaNESex_src_191105/7z/7zDec.c
Normal file
470
References/VirtuaNESex_src_191105/7z/7zDec.c
Normal file
@ -0,0 +1,470 @@
|
||||
/* 7zDec.c -- Decoding from 7z folder
|
||||
2010-11-02 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* #define _7ZIP_PPMD_SUPPPORT */
|
||||
|
||||
#include "7z.h"
|
||||
|
||||
#include "Bcj2.h"
|
||||
#include "Bra.h"
|
||||
#include "CpuArch.h"
|
||||
#include "LzmaDec.h"
|
||||
#include "Lzma2Dec.h"
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
#include "Ppmd7.h"
|
||||
#endif
|
||||
|
||||
#define k_Copy 0
|
||||
#define k_LZMA2 0x21
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ 0x03030103
|
||||
#define k_PPC 0x03030205
|
||||
#define k_ARM 0x03030501
|
||||
#define k_ARMT 0x03030701
|
||||
#define k_SPARC 0x03030805
|
||||
#define k_BCJ2 0x0303011B
|
||||
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
|
||||
#define k_PPMD 0x30401
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IByteIn p;
|
||||
const Byte *cur;
|
||||
const Byte *end;
|
||||
const Byte *begin;
|
||||
UInt64 processed;
|
||||
Bool extra;
|
||||
SRes res;
|
||||
ILookInStream *inStream;
|
||||
} CByteInToLook;
|
||||
|
||||
static Byte ReadByte(void *pp)
|
||||
{
|
||||
CByteInToLook *p = (CByteInToLook *)pp;
|
||||
if (p->cur != p->end)
|
||||
return *p->cur++;
|
||||
if (p->res == SZ_OK)
|
||||
{
|
||||
size_t size = p->cur - p->begin;
|
||||
p->processed += size;
|
||||
p->res = p->inStream->Skip(p->inStream, size);
|
||||
size = (1 << 25);
|
||||
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
|
||||
p->cur = p->begin;
|
||||
p->end = p->begin + size;
|
||||
if (size != 0)
|
||||
return *p->cur++;;
|
||||
}
|
||||
p->extra = True;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CPpmd7 ppmd;
|
||||
CByteInToLook s;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
s.p.Read = ReadByte;
|
||||
s.inStream = inStream;
|
||||
s.begin = s.end = s.cur = NULL;
|
||||
s.extra = False;
|
||||
s.res = SZ_OK;
|
||||
s.processed = 0;
|
||||
|
||||
if (coder->Props.size != 5)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
{
|
||||
unsigned order = coder->Props.data[0];
|
||||
UInt32 memSize = GetUi32(coder->Props.data + 1);
|
||||
if (order < PPMD7_MIN_ORDER ||
|
||||
order > PPMD7_MAX_ORDER ||
|
||||
memSize < PPMD7_MIN_MEM_SIZE ||
|
||||
memSize > PPMD7_MAX_MEM_SIZE)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
Ppmd7_Construct(&ppmd);
|
||||
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
|
||||
return SZ_ERROR_MEM;
|
||||
Ppmd7_Init(&ppmd, order);
|
||||
}
|
||||
{
|
||||
CPpmd7z_RangeDec rc;
|
||||
Ppmd7z_RangeDec_CreateVTable(&rc);
|
||||
rc.Stream = &s.p;
|
||||
if (!Ppmd7z_RangeDec_Init(&rc))
|
||||
res = SZ_ERROR_DATA;
|
||||
else if (s.extra)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else
|
||||
{
|
||||
SizeT i;
|
||||
for (i = 0; i < outSize; i++)
|
||||
{
|
||||
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
|
||||
if (s.extra || sym < 0)
|
||||
break;
|
||||
outBuffer[i] = (Byte)sym;
|
||||
}
|
||||
if (i != outSize)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
|
||||
res = SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
Ppmd7_Free(&ppmd, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CLzmaDec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
LzmaDec_Construct(&state);
|
||||
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
|
||||
state.dic = outBuffer;
|
||||
state.dicBufSize = outSize;
|
||||
LzmaDec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
||||
{
|
||||
if (state.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
||||
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LzmaDec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CLzma2Dec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
Lzma2Dec_Construct(&state);
|
||||
if (coder->Props.size != 1)
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
|
||||
state.decoder.dic = outBuffer;
|
||||
state.decoder.dicBufSize = outSize;
|
||||
Lzma2Dec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
|
||||
{
|
||||
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Lzma2Dec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
||||
{
|
||||
while (inSize > 0)
|
||||
{
|
||||
void *inBuf;
|
||||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
outBuffer += curSize;
|
||||
inSize -= curSize;
|
||||
RINOK(inStream->Skip((void *)inStream, curSize));
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static Bool IS_MAIN_METHOD(UInt32 m)
|
||||
{
|
||||
switch(m)
|
||||
{
|
||||
case k_Copy:
|
||||
case k_LZMA:
|
||||
case k_LZMA2:
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
case k_PPMD:
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||
{
|
||||
return
|
||||
c->NumInStreams == 1 &&
|
||||
c->NumOutStreams == 1 &&
|
||||
c->MethodID <= (UInt32)0xFFFFFFFF &&
|
||||
IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||
}
|
||||
|
||||
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
|
||||
|
||||
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||
{
|
||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumCoders == 1)
|
||||
{
|
||||
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 2)
|
||||
{
|
||||
CSzCoderInfo *c = &f->Coders[1];
|
||||
if (c->MethodID > (UInt32)0xFFFFFFFF ||
|
||||
c->NumInStreams != 1 ||
|
||||
c->NumOutStreams != 1 ||
|
||||
f->NumPackStreams != 1 ||
|
||||
f->PackStreams[0] != 0 ||
|
||||
f->NumBindPairs != 1 ||
|
||||
f->BindPairs[0].InIndex != 1 ||
|
||||
f->BindPairs[0].OutIndex != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch ((UInt32)c->MethodID)
|
||||
{
|
||||
case k_BCJ:
|
||||
case k_ARM:
|
||||
break;
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 4)
|
||||
{
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
|
||||
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
||||
!IS_BCJ2(&f->Coders[3]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumPackStreams != 4 ||
|
||||
f->PackStreams[0] != 2 ||
|
||||
f->PackStreams[1] != 6 ||
|
||||
f->PackStreams[2] != 1 ||
|
||||
f->PackStreams[3] != 0 ||
|
||||
f->NumBindPairs != 3 ||
|
||||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
||||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
||||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
{
|
||||
UInt64 sum = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < index; i++)
|
||||
sum += values[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
|
||||
|
||||
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||
Byte *tempBuf[])
|
||||
{
|
||||
UInt32 ci;
|
||||
SizeT tempSizes[3] = { 0, 0, 0};
|
||||
SizeT tempSize3 = 0;
|
||||
Byte *tempBuf3 = 0;
|
||||
|
||||
RINOK(CheckSupportedFolder(folder));
|
||||
|
||||
for (ci = 0; ci < folder->NumCoders; ci++)
|
||||
{
|
||||
CSzCoderInfo *coder = &folder->Coders[ci];
|
||||
|
||||
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
|
||||
{
|
||||
UInt32 si = 0;
|
||||
UInt64 offset;
|
||||
UInt64 inSize;
|
||||
Byte *outBufCur = outBuffer;
|
||||
SizeT outSizeCur = outSize;
|
||||
if (folder->NumCoders == 4)
|
||||
{
|
||||
UInt32 indices[] = { 3, 2, 0 };
|
||||
UInt64 unpackSize = folder->UnpackSizes[ci];
|
||||
si = indices[ci];
|
||||
if (ci < 2)
|
||||
{
|
||||
Byte *temp;
|
||||
outSizeCur = (SizeT)unpackSize;
|
||||
if (outSizeCur != unpackSize)
|
||||
return SZ_ERROR_MEM;
|
||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||
if (temp == 0 && outSizeCur != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
outBufCur = tempBuf[1 - ci] = temp;
|
||||
tempSizes[1 - ci] = outSizeCur;
|
||||
}
|
||||
else if (ci == 2)
|
||||
{
|
||||
if (unpackSize > outSize) /* check it */
|
||||
return SZ_ERROR_PARAM;
|
||||
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||
}
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
offset = GetSum(packSizes, si);
|
||||
inSize = packSizes[si];
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
|
||||
if (coder->MethodID == k_Copy)
|
||||
{
|
||||
if (inSize != outSizeCur) /* check it */
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||
}
|
||||
else if (coder->MethodID == k_LZMA)
|
||||
{
|
||||
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
else if (coder->MethodID == k_LZMA2)
|
||||
{
|
||||
RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
#else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ2)
|
||||
{
|
||||
UInt64 offset = GetSum(packSizes, 1);
|
||||
UInt64 s3Size = packSizes[1];
|
||||
SRes res;
|
||||
if (ci != 3)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
tempSizes[2] = (SizeT)s3Size;
|
||||
if (tempSizes[2] != s3Size)
|
||||
return SZ_ERROR_MEM;
|
||||
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
||||
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||
RINOK(res)
|
||||
|
||||
res = Bcj2_Decode(
|
||||
tempBuf3, tempSize3,
|
||||
tempBuf[0], tempSizes[0],
|
||||
tempBuf[1], tempSizes[1],
|
||||
tempBuf[2], tempSizes[2],
|
||||
outBuffer, outSize);
|
||||
RINOK(res)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ci != 1)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch(coder->MethodID)
|
||||
{
|
||||
case k_BCJ:
|
||||
{
|
||||
UInt32 state;
|
||||
x86_Convert_Init(state);
|
||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||
break;
|
||||
}
|
||||
CASE_BRA_CONV(ARM)
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
Byte *tempBuf[3] = { 0, 0, 0};
|
||||
int i;
|
||||
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
IAlloc_Free(allocMain, tempBuf[i]);
|
||||
return res;
|
||||
}
|
||||
284
References/VirtuaNESex_src_191105/7z/7zFile.c
Normal file
284
References/VirtuaNESex_src_191105/7z/7zFile.c
Normal file
@ -0,0 +1,284 @@
|
||||
/* 7zFile.c -- File IO
|
||||
2009-11-24 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "7zFile.h"
|
||||
|
||||
#ifndef USE_WINDOWS_FILE
|
||||
|
||||
#ifndef UNDER_CE
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
ReadFile and WriteFile functions in Windows have BUG:
|
||||
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
|
||||
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
|
||||
(Insufficient system resources exist to complete the requested service).
|
||||
Probably in some version of Windows there are problems with other sizes:
|
||||
for 32 MB (maybe also for 16 MB).
|
||||
And message can be "Network connection was lost"
|
||||
*/
|
||||
|
||||
#define kChunkSizeMax (1 << 22)
|
||||
|
||||
#endif
|
||||
|
||||
void File_Construct(CSzFile *p)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
p->handle = INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
p->file = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
|
||||
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
p->handle = CreateFileA(name,
|
||||
writeMode ? GENERIC_WRITE : GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL,
|
||||
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||
#else
|
||||
p->file = fopen(name, writeMode ? "wb+" : "rb");
|
||||
return (p->file != 0) ? 0 :
|
||||
#ifdef UNDER_CE
|
||||
2; /* ENOENT */
|
||||
#else
|
||||
errno;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
|
||||
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
|
||||
{
|
||||
p->handle = CreateFileW(name,
|
||||
writeMode ? GENERIC_WRITE : GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL,
|
||||
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||
}
|
||||
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
|
||||
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
|
||||
#endif
|
||||
|
||||
WRes File_Close(CSzFile *p)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
if (p->handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!CloseHandle(p->handle))
|
||||
return GetLastError();
|
||||
p->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
#else
|
||||
if (p->file != NULL)
|
||||
{
|
||||
int res = fclose(p->file);
|
||||
if (res != 0)
|
||||
return res;
|
||||
p->file = NULL;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes File_Read(CSzFile *p, void *data, size_t *size)
|
||||
{
|
||||
size_t originalSize = *size;
|
||||
if (originalSize == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
*size = 0;
|
||||
do
|
||||
{
|
||||
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
|
||||
DWORD processed = 0;
|
||||
BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
|
||||
data = (void *)((Byte *)data + processed);
|
||||
originalSize -= processed;
|
||||
*size += processed;
|
||||
if (!res)
|
||||
return GetLastError();
|
||||
if (processed == 0)
|
||||
break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
*size = fread(data, 1, originalSize, p->file);
|
||||
if (*size == originalSize)
|
||||
return 0;
|
||||
return ferror(p->file);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes File_Write(CSzFile *p, const void *data, size_t *size)
|
||||
{
|
||||
size_t originalSize = *size;
|
||||
if (originalSize == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
*size = 0;
|
||||
do
|
||||
{
|
||||
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
|
||||
DWORD processed = 0;
|
||||
BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
|
||||
data = (void *)((Byte *)data + processed);
|
||||
originalSize -= processed;
|
||||
*size += processed;
|
||||
if (!res)
|
||||
return GetLastError();
|
||||
if (processed == 0)
|
||||
break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
*size = fwrite(data, 1, originalSize, p->file);
|
||||
if (*size == originalSize)
|
||||
return 0;
|
||||
return ferror(p->file);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
LARGE_INTEGER value;
|
||||
DWORD moveMethod;
|
||||
value.LowPart = (DWORD)*pos;
|
||||
value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
|
||||
switch (origin)
|
||||
{
|
||||
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
|
||||
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
|
||||
case SZ_SEEK_END: moveMethod = FILE_END; break;
|
||||
default: return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
|
||||
if (value.LowPart == 0xFFFFFFFF)
|
||||
{
|
||||
WRes res = GetLastError();
|
||||
if (res != NO_ERROR)
|
||||
return res;
|
||||
}
|
||||
*pos = ((Int64)value.HighPart << 32) | value.LowPart;
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
int moveMethod;
|
||||
int res;
|
||||
switch (origin)
|
||||
{
|
||||
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
|
||||
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
|
||||
case SZ_SEEK_END: moveMethod = SEEK_END; break;
|
||||
default: return 1;
|
||||
}
|
||||
res = fseek(p->file, (long)*pos, moveMethod);
|
||||
*pos = ftell(p->file);
|
||||
return res;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes File_GetLength(CSzFile *p, UInt64 *length)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
DWORD sizeHigh;
|
||||
DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
|
||||
if (sizeLow == 0xFFFFFFFF)
|
||||
{
|
||||
DWORD res = GetLastError();
|
||||
if (res != NO_ERROR)
|
||||
return res;
|
||||
}
|
||||
*length = (((UInt64)sizeHigh) << 32) + sizeLow;
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
long pos = ftell(p->file);
|
||||
int res = fseek(p->file, 0, SEEK_END);
|
||||
*length = ftell(p->file);
|
||||
fseek(p->file, pos, SEEK_SET);
|
||||
return res;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileSeqInStream ---------- */
|
||||
|
||||
static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CFileSeqInStream *p = (CFileSeqInStream *)pp;
|
||||
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
|
||||
}
|
||||
|
||||
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
|
||||
{
|
||||
p->s.Read = FileSeqInStream_Read;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileInStream ---------- */
|
||||
|
||||
static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CFileInStream *p = (CFileInStream *)pp;
|
||||
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
|
||||
}
|
||||
|
||||
static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
CFileInStream *p = (CFileInStream *)pp;
|
||||
return File_Seek(&p->file, pos, origin);
|
||||
}
|
||||
|
||||
void FileInStream_CreateVTable(CFileInStream *p)
|
||||
{
|
||||
p->s.Read = FileInStream_Read;
|
||||
p->s.Seek = FileInStream_Seek;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileOutStream ---------- */
|
||||
|
||||
static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
|
||||
{
|
||||
CFileOutStream *p = (CFileOutStream *)pp;
|
||||
File_Write(&p->file, data, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void FileOutStream_CreateVTable(CFileOutStream *p)
|
||||
{
|
||||
p->s.Write = FileOutStream_Write;
|
||||
}
|
||||
83
References/VirtuaNESex_src_191105/7z/7zFile.h
Normal file
83
References/VirtuaNESex_src_191105/7z/7zFile.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* 7zFile.h -- File IO
|
||||
2009-11-24 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_FILE_H
|
||||
#define __7Z_FILE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define USE_WINDOWS_FILE
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/* ---------- File ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
HANDLE handle;
|
||||
#else
|
||||
FILE *file;
|
||||
#endif
|
||||
} CSzFile;
|
||||
|
||||
void File_Construct(CSzFile *p);
|
||||
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
|
||||
WRes InFile_Open(CSzFile *p, const char *name);
|
||||
WRes OutFile_Open(CSzFile *p, const char *name);
|
||||
#endif
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
|
||||
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
|
||||
#endif
|
||||
WRes File_Close(CSzFile *p);
|
||||
|
||||
/* reads max(*size, remain file's size) bytes */
|
||||
WRes File_Read(CSzFile *p, void *data, size_t *size);
|
||||
|
||||
/* writes *size bytes */
|
||||
WRes File_Write(CSzFile *p, const void *data, size_t *size);
|
||||
|
||||
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
|
||||
WRes File_GetLength(CSzFile *p, UInt64 *length);
|
||||
|
||||
|
||||
/* ---------- FileInStream ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
CSzFile file;
|
||||
} CFileSeqInStream;
|
||||
|
||||
void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeekInStream s;
|
||||
CSzFile file;
|
||||
} CFileInStream;
|
||||
|
||||
void FileInStream_CreateVTable(CFileInStream *p);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqOutStream s;
|
||||
CSzFile file;
|
||||
} CFileOutStream;
|
||||
|
||||
void FileOutStream_CreateVTable(CFileOutStream *p);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
1402
References/VirtuaNESex_src_191105/7z/7zIn.c
Normal file
1402
References/VirtuaNESex_src_191105/7z/7zIn.c
Normal file
File diff suppressed because it is too large
Load Diff
438
References/VirtuaNESex_src_191105/7z/7zMain.c
Normal file
438
References/VirtuaNESex_src_191105/7z/7zMain.c
Normal file
@ -0,0 +1,438 @@
|
||||
/* 7zMain.c - Test application for 7z Decoder
|
||||
2010-10-28 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "7z/7z.h"
|
||||
#include "7z/7zAlloc.h"
|
||||
#include "7z/7zCrc.h"
|
||||
#include "7z/7zFile.h"
|
||||
#include "7z/7zVersion.h"
|
||||
|
||||
/*
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
*/
|
||||
#ifndef USE_WINDOWS_FILE
|
||||
/* for mkdir */
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||
|
||||
static int Buf_EnsureSize(CBuf *dest, size_t size)
|
||||
{
|
||||
if (dest->size >= size)
|
||||
return 1;
|
||||
Buf_Free(dest, &g_Alloc);
|
||||
return Buf_Create(dest, size, &g_Alloc);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
|
||||
static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
|
||||
{
|
||||
size_t destPos = 0, srcPos = 0;
|
||||
for (;;)
|
||||
{
|
||||
unsigned numAdds;
|
||||
UInt32 value;
|
||||
if (srcPos == srcLen)
|
||||
{
|
||||
*destLen = destPos;
|
||||
return True;
|
||||
}
|
||||
value = src[srcPos++];
|
||||
if (value < 0x80)
|
||||
{
|
||||
if (dest)
|
||||
dest[destPos] = (char)value;
|
||||
destPos++;
|
||||
continue;
|
||||
}
|
||||
if (value >= 0xD800 && value < 0xE000)
|
||||
{
|
||||
UInt32 c2;
|
||||
if (value >= 0xDC00 || srcPos == srcLen)
|
||||
break;
|
||||
c2 = src[srcPos++];
|
||||
if (c2 < 0xDC00 || c2 >= 0xE000)
|
||||
break;
|
||||
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
||||
}
|
||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
|
||||
break;
|
||||
if (dest)
|
||||
dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
|
||||
destPos++;
|
||||
do
|
||||
{
|
||||
numAdds--;
|
||||
if (dest)
|
||||
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
|
||||
destPos++;
|
||||
}
|
||||
while (numAdds != 0);
|
||||
}
|
||||
*destLen = destPos;
|
||||
return False;
|
||||
}
|
||||
|
||||
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
|
||||
{
|
||||
size_t destLen = 0;
|
||||
Bool res;
|
||||
Utf16_To_Utf8(NULL, &destLen, src, srcLen);
|
||||
destLen += 1;
|
||||
if (!Buf_EnsureSize(dest, destLen))
|
||||
return SZ_ERROR_MEM;
|
||||
res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
|
||||
dest->data[destLen] = 0;
|
||||
return res ? SZ_OK : SZ_ERROR_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
|
||||
{
|
||||
int len = 0;
|
||||
for (len = 0; s[len] != '\0'; len++);
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
int size = len * 3 + 100;
|
||||
if (!Buf_EnsureSize(buf, size))
|
||||
return SZ_ERROR_MEM;
|
||||
{
|
||||
char defaultChar = '_';
|
||||
BOOL defUsed;
|
||||
int numChars = WideCharToMultiByte(fileMode ?
|
||||
(
|
||||
#ifdef UNDER_CE
|
||||
CP_ACP
|
||||
#else
|
||||
AreFileApisANSI() ? CP_ACP : CP_OEMCP
|
||||
#endif
|
||||
) : CP_OEMCP,
|
||||
0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
|
||||
if (numChars == 0 || numChars >= size)
|
||||
return SZ_ERROR_FAIL;
|
||||
buf->data[numChars] = 0;
|
||||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
#else
|
||||
fileMode = fileMode;
|
||||
return Utf16_To_Utf8Buf(buf, s, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static WRes MyCreateDir(const UInt16 *name)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
|
||||
|
||||
#else
|
||||
|
||||
CBuf buf;
|
||||
WRes res;
|
||||
Buf_Init(&buf);
|
||||
RINOK(Utf16_To_Char(&buf, name, 1));
|
||||
|
||||
res =
|
||||
#ifdef _WIN32
|
||||
_mkdir((const char *)buf.data)
|
||||
#else
|
||||
mkdir((const char *)buf.data, 0777)
|
||||
#endif
|
||||
== 0 ? 0 : errno;
|
||||
Buf_Free(&buf, &g_Alloc);
|
||||
return res;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
return OutFile_OpenW(p, name);
|
||||
#else
|
||||
CBuf buf;
|
||||
WRes res;
|
||||
Buf_Init(&buf);
|
||||
RINOK(Utf16_To_Char(&buf, name, 1));
|
||||
res = OutFile_Open(p, (const char *)buf.data);
|
||||
Buf_Free(&buf, &g_Alloc);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
static SRes PrintString(const UInt16 *s)
|
||||
{
|
||||
CBuf buf;
|
||||
SRes res;
|
||||
Buf_Init(&buf);
|
||||
res = Utf16_To_Char(&buf, s, 0);
|
||||
if (res == SZ_OK)
|
||||
fputs((const char *)buf.data, stdout);
|
||||
Buf_Free(&buf, &g_Alloc);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void UInt64ToStr(UInt64 value, char *s)
|
||||
{
|
||||
char temp[32];
|
||||
int pos = 0;
|
||||
do
|
||||
{
|
||||
temp[pos++] = (char)('0' + (unsigned)(value % 10));
|
||||
value /= 10;
|
||||
}
|
||||
while (value != 0);
|
||||
do
|
||||
*s++ = temp[--pos];
|
||||
while (pos);
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
static char *UIntToStr(char *s, unsigned value, int numDigits)
|
||||
{
|
||||
char temp[16];
|
||||
int pos = 0;
|
||||
do
|
||||
temp[pos++] = (char)('0' + (value % 10));
|
||||
while (value /= 10);
|
||||
for (numDigits -= pos; numDigits > 0; numDigits--)
|
||||
*s++ = '0';
|
||||
do
|
||||
*s++ = temp[--pos];
|
||||
while (pos);
|
||||
*s = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
#define PERIOD_4 (4 * 365 + 1)
|
||||
#define PERIOD_100 (PERIOD_4 * 25 - 1)
|
||||
#define PERIOD_400 (PERIOD_100 * 4 + 1)
|
||||
|
||||
static void ConvertFileTimeToString(const CNtfsFileTime *ft, char *s)
|
||||
{
|
||||
unsigned year, mon, day, hour, min, sec;
|
||||
UInt64 v64 = (ft->Low | ((UInt64)ft->High << 32)) / 10000000;
|
||||
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
unsigned t;
|
||||
UInt32 v;
|
||||
sec = (unsigned)(v64 % 60); v64 /= 60;
|
||||
min = (unsigned)(v64 % 60); v64 /= 60;
|
||||
hour = (unsigned)(v64 % 24); v64 /= 24;
|
||||
|
||||
v = (UInt32)v64;
|
||||
|
||||
year = (unsigned)(1601 + v / PERIOD_400 * 400);
|
||||
v %= PERIOD_400;
|
||||
|
||||
t = v / PERIOD_100; if (t == 4) t = 3; year += t * 100; v -= t * PERIOD_100;
|
||||
t = v / PERIOD_4; if (t == 25) t = 24; year += t * 4; v -= t * PERIOD_4;
|
||||
t = v / 365; if (t == 4) t = 3; year += t; v -= t * 365;
|
||||
|
||||
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
|
||||
ms[1] = 29;
|
||||
for (mon = 1; mon <= 12; mon++)
|
||||
{
|
||||
unsigned s = ms[mon - 1];
|
||||
if (v < s)
|
||||
break;
|
||||
v -= s;
|
||||
}
|
||||
day = (unsigned)v + 1;
|
||||
s = UIntToStr(s, year, 4); *s++ = '-';
|
||||
s = UIntToStr(s, mon, 2); *s++ = '-';
|
||||
s = UIntToStr(s, day, 2); *s++ = ' ';
|
||||
s = UIntToStr(s, hour, 2); *s++ = ':';
|
||||
s = UIntToStr(s, min, 2); *s++ = ':';
|
||||
s = UIntToStr(s, sec, 2);
|
||||
}
|
||||
|
||||
void PrintError(char *sz)
|
||||
{
|
||||
printf("\nERROR: %s\n", sz);
|
||||
}
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
#define kEmptyAttribChar '.'
|
||||
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
|
||||
{
|
||||
s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : kEmptyAttribChar);
|
||||
s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY) != 0) ? 'R': kEmptyAttribChar);
|
||||
s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? 'H': kEmptyAttribChar);
|
||||
s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? 'S': kEmptyAttribChar);
|
||||
s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? 'A': kEmptyAttribChar);
|
||||
s[5] = '\0';
|
||||
}
|
||||
#else
|
||||
static void GetAttribString(UInt32, Bool, char *s)
|
||||
{
|
||||
s[0] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
int SevenZipUnCompress( char *fname, unsigned char ** ppBuf,size_t * lpdwSize)
|
||||
{
|
||||
CFileInStream archiveStream;
|
||||
CLookToRead lookStream;
|
||||
CSzArEx db;
|
||||
SRes res;
|
||||
ISzAlloc allocImp;
|
||||
ISzAlloc allocTempImp;
|
||||
UInt16 *temp = NULL;
|
||||
size_t tempSize = 0;
|
||||
|
||||
int bHasRomFile = 0;
|
||||
int bExtractRomOK = 0;
|
||||
//枚举文件,找到NES或者UNF文件,找不到直接返回
|
||||
allocImp.Alloc = SzAlloc;
|
||||
allocImp.Free = SzFree;
|
||||
|
||||
allocTempImp.Alloc = SzAllocTemp;
|
||||
allocTempImp.Free = SzFreeTemp;
|
||||
|
||||
if (InFile_Open(&archiveStream.file, fname))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FileInStream_CreateVTable(&archiveStream);
|
||||
LookToRead_CreateVTable(&lookStream, False);
|
||||
|
||||
lookStream.realStream = &archiveStream.s;
|
||||
LookToRead_Init(&lookStream);
|
||||
|
||||
CrcGenerateTable();
|
||||
|
||||
SzArEx_Init(&db);
|
||||
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
UInt32 i;
|
||||
|
||||
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
|
||||
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
|
||||
|
||||
for (i = 0; i < db.db.NumFiles; i++)
|
||||
{
|
||||
size_t offset = 0;
|
||||
size_t outSizeProcessed = 0;
|
||||
const CSzFileItem *f = db.db.Files + i;
|
||||
size_t len;
|
||||
|
||||
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
||||
|
||||
if (len > tempSize)
|
||||
{
|
||||
SzFree(NULL, temp);
|
||||
tempSize = len;
|
||||
temp = (UInt16 *)SzAlloc(NULL, tempSize * sizeof(temp[0]));
|
||||
if (temp == 0)
|
||||
{
|
||||
res = SZ_ERROR_MEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SzArEx_GetFileNameUtf16(&db, i, temp);
|
||||
//获取文件信息
|
||||
{
|
||||
char attr[8];
|
||||
GetAttribString(f->AttribDefined ? f->Attrib : 0, f->IsDir, attr);// f->IsDir 文件是否是目录
|
||||
|
||||
//UInt64ToStr(f->Size, s);//f->Size 文件大小
|
||||
if(f->IsDir!=1)
|
||||
{
|
||||
//检测扩展名
|
||||
if(len>5)
|
||||
{
|
||||
//"*.nes",
|
||||
//"*.unf",
|
||||
//"*.fds",
|
||||
//"*.nsf",
|
||||
if(wcsicmp(L".nes",&temp[len-5])==0)
|
||||
{
|
||||
bHasRomFile =1;
|
||||
}
|
||||
else if(wcsicmp(L".unf",&temp[len-5])==0)
|
||||
{
|
||||
bHasRomFile =1;
|
||||
}
|
||||
else if(wcsicmp(L".fds",&temp[len-5])==0)
|
||||
{
|
||||
bHasRomFile =1;
|
||||
}
|
||||
else if(wcsicmp(L".nsf",&temp[len-5])==0)
|
||||
{
|
||||
bHasRomFile =1;
|
||||
}
|
||||
}
|
||||
//if( (f->Size>16000)&&(f->Size<10000000) )
|
||||
//bHasRomFile =1;
|
||||
}
|
||||
|
||||
if(bHasRomFile==0)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bHasRomFile)
|
||||
{
|
||||
res = SzArEx_Extract(&db, &lookStream.s, i,&blockIndex, ppBuf, lpdwSize,&offset, &outSizeProcessed,&allocImp, &allocTempImp);
|
||||
if (res != SZ_OK)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
bExtractRomOK = 1;
|
||||
if(offset!=0)
|
||||
{//重组
|
||||
void *pRom = malloc(f->Size);
|
||||
memcpy(pRom,*ppBuf+offset,f->Size);
|
||||
*lpdwSize = f->Size;
|
||||
free(*ppBuf);
|
||||
*ppBuf = pRom;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bExtractRomOK)
|
||||
break;
|
||||
}//结束文件枚举循环
|
||||
IAlloc_Free(&allocImp, outBuffer);
|
||||
}
|
||||
SzArEx_Free(&db, &allocImp);
|
||||
SzFree(NULL, temp);
|
||||
|
||||
File_Close(&archiveStream.file);
|
||||
/*if (res == SZ_OK)
|
||||
{
|
||||
printf("\nEverything is Ok\n");
|
||||
return 0;
|
||||
}*/
|
||||
return bExtractRomOK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
int MY_CDECL main(int c, char *v[])
|
||||
{
|
||||
unsigned char *pBuf = 0;
|
||||
size_t fileLen;
|
||||
int i = SevenZipUnCompress(v[1],&pBuf,&fileLen);
|
||||
free(pBuf); pBuf = 0;
|
||||
printf("%d",i);
|
||||
}
|
||||
*/
|
||||
169
References/VirtuaNESex_src_191105/7z/7zStream.c
Normal file
169
References/VirtuaNESex_src_191105/7z/7zStream.c
Normal file
@ -0,0 +1,169 @@
|
||||
/* 7zStream.c -- 7z Stream functions
|
||||
2010-03-11 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
|
||||
{
|
||||
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
||||
{
|
||||
size_t processed = 1;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||
}
|
||||
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
||||
{
|
||||
Int64 t = offset;
|
||||
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
||||
}
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
||||
{
|
||||
const void *lookBuf;
|
||||
if (*size == 0)
|
||||
return SZ_OK;
|
||||
RINOK(stream->Look(stream, &lookBuf, size));
|
||||
memcpy(buf, lookBuf, *size);
|
||||
return stream->Skip(stream, *size);
|
||||
}
|
||||
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
||||
{
|
||||
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
|
||||
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0)
|
||||
{
|
||||
p->pos = 0;
|
||||
size2 = LookToRead_BUF_SIZE;
|
||||
res = p->realStream->Read(p->realStream, p->buf, &size2);
|
||||
p->size = size2;
|
||||
}
|
||||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0)
|
||||
{
|
||||
p->pos = 0;
|
||||
if (*size > LookToRead_BUF_SIZE)
|
||||
*size = LookToRead_BUF_SIZE;
|
||||
res = p->realStream->Read(p->realStream, p->buf, size);
|
||||
size2 = p->size = *size;
|
||||
}
|
||||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Skip(void *pp, size_t offset)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
p->pos += offset;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t rem = p->size - p->pos;
|
||||
if (rem == 0)
|
||||
return p->realStream->Read(p->realStream, buf, size);
|
||||
if (rem > *size)
|
||||
rem = *size;
|
||||
memcpy(buf, p->buf + p->pos, rem);
|
||||
p->pos += rem;
|
||||
*size = rem;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
p->pos = p->size = 0;
|
||||
return p->realStream->Seek(p->realStream, pos, origin);
|
||||
}
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
||||
{
|
||||
p->s.Look = lookahead ?
|
||||
LookToRead_Look_Lookahead :
|
||||
LookToRead_Look_Exact;
|
||||
p->s.Skip = LookToRead_Skip;
|
||||
p->s.Read = LookToRead_Read;
|
||||
p->s.Seek = LookToRead_Seek;
|
||||
}
|
||||
|
||||
void LookToRead_Init(CLookToRead *p)
|
||||
{
|
||||
p->pos = p->size = 0;
|
||||
}
|
||||
|
||||
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CSecToLook *p = (CSecToLook *)pp;
|
||||
return LookInStream_LookRead(p->realStream, buf, size);
|
||||
}
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p)
|
||||
{
|
||||
p->s.Read = SecToLook_Read;
|
||||
}
|
||||
|
||||
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CSecToRead *p = (CSecToRead *)pp;
|
||||
return p->realStream->Read(p->realStream, buf, size);
|
||||
}
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p)
|
||||
{
|
||||
p->s.Read = SecToRead_Read;
|
||||
}
|
||||
7
References/VirtuaNESex_src_191105/7z/7zVersion.h
Normal file
7
References/VirtuaNESex_src_191105/7z/7zVersion.h
Normal file
@ -0,0 +1,7 @@
|
||||
#define MY_VER_MAJOR 9
|
||||
#define MY_VER_MINOR 20
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION "9.20"
|
||||
#define MY_DATE "2010-11-18"
|
||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
||||
132
References/VirtuaNESex_src_191105/7z/Bcj2.c
Normal file
132
References/VirtuaNESex_src_191105/7z/Bcj2.c
Normal file
@ -0,0 +1,132 @@
|
||||
/* Bcj2.c -- Converter for x86 code (BCJ2)
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Bcj2.h"
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CProb UInt32
|
||||
#else
|
||||
#define CProb UInt16
|
||||
#endif
|
||||
|
||||
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
|
||||
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
|
||||
|
||||
#define kNumTopBits 24
|
||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||
|
||||
#define kNumBitModelTotalBits 11
|
||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||
#define kNumMoveBits 5
|
||||
|
||||
#define RC_READ_BYTE (*buffer++)
|
||||
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
|
||||
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
|
||||
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
|
||||
|
||||
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
|
||||
|
||||
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
|
||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
|
||||
|
||||
int Bcj2_Decode(
|
||||
const Byte *buf0, SizeT size0,
|
||||
const Byte *buf1, SizeT size1,
|
||||
const Byte *buf2, SizeT size2,
|
||||
const Byte *buf3, SizeT size3,
|
||||
Byte *outBuf, SizeT outSize)
|
||||
{
|
||||
CProb p[256 + 2];
|
||||
SizeT inPos = 0, outPos = 0;
|
||||
|
||||
const Byte *buffer, *bufferLim;
|
||||
UInt32 range, code;
|
||||
Byte prevByte = 0;
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
||||
p[i] = kBitModelTotal >> 1;
|
||||
|
||||
buffer = buf3;
|
||||
bufferLim = buffer + size3;
|
||||
RC_INIT2
|
||||
|
||||
if (outSize == 0)
|
||||
return SZ_OK;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
CProb *prob;
|
||||
UInt32 bound;
|
||||
UInt32 ttt;
|
||||
|
||||
SizeT limit = size0 - inPos;
|
||||
if (outSize - outPos < limit)
|
||||
limit = outSize - outPos;
|
||||
while (limit != 0)
|
||||
{
|
||||
Byte b = buf0[inPos];
|
||||
outBuf[outPos++] = b;
|
||||
if (IsJ(prevByte, b))
|
||||
break;
|
||||
inPos++;
|
||||
prevByte = b;
|
||||
limit--;
|
||||
}
|
||||
|
||||
if (limit == 0 || outPos == outSize)
|
||||
break;
|
||||
|
||||
b = buf0[inPos++];
|
||||
|
||||
if (b == 0xE8)
|
||||
prob = p + prevByte;
|
||||
else if (b == 0xE9)
|
||||
prob = p + 256;
|
||||
else
|
||||
prob = p + 257;
|
||||
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob)
|
||||
prevByte = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 dest;
|
||||
const Byte *v;
|
||||
UPDATE_1(prob)
|
||||
if (b == 0xE8)
|
||||
{
|
||||
v = buf1;
|
||||
if (size1 < 4)
|
||||
return SZ_ERROR_DATA;
|
||||
buf1 += 4;
|
||||
size1 -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = buf2;
|
||||
if (size2 < 4)
|
||||
return SZ_ERROR_DATA;
|
||||
buf2 += 4;
|
||||
size2 -= 4;
|
||||
}
|
||||
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
|
||||
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
|
||||
outBuf[outPos++] = (Byte)dest;
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = (Byte)(dest >> 8);
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = (Byte)(dest >> 16);
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
|
||||
}
|
||||
}
|
||||
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
|
||||
}
|
||||
38
References/VirtuaNESex_src_191105/7z/Bcj2.h
Normal file
38
References/VirtuaNESex_src_191105/7z/Bcj2.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* Bcj2.h -- Converter for x86 code (BCJ2)
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __BCJ2_H
|
||||
#define __BCJ2_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
outSize <= FullOutputSize,
|
||||
where FullOutputSize is full size of output stream of x86_2 filter.
|
||||
|
||||
If buf0 overlaps outBuf, there are two required conditions:
|
||||
1) (buf0 >= outBuf)
|
||||
2) (buf0 + size0 >= outBuf + FullOutputSize).
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
int Bcj2_Decode(
|
||||
const Byte *buf0, SizeT size0,
|
||||
const Byte *buf1, SizeT size1,
|
||||
const Byte *buf2, SizeT size2,
|
||||
const Byte *buf3, SizeT size3,
|
||||
Byte *outBuf, SizeT outSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
133
References/VirtuaNESex_src_191105/7z/Bra.c
Normal file
133
References/VirtuaNESex_src_191105/7z/Bra.c
Normal file
@ -0,0 +1,133 @@
|
||||
/* Bra.c -- Converters for RISC code
|
||||
2010-04-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 8;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0xEB)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 2;
|
||||
data[i + 2] = (Byte)(dest >> 16);
|
||||
data[i + 1] = (Byte)(dest >> 8);
|
||||
data[i + 0] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 4;
|
||||
for (i = 0; i <= size; i += 2)
|
||||
{
|
||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||
(data[i + 3] & 0xF8) == 0xF8)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src =
|
||||
(((UInt32)data[i + 1] & 0x7) << 19) |
|
||||
((UInt32)data[i + 0] << 11) |
|
||||
(((UInt32)data[i + 3] & 0x7) << 8) |
|
||||
(data[i + 2]);
|
||||
|
||||
src <<= 1;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 1;
|
||||
|
||||
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
||||
data[i + 0] = (Byte)(dest >> 11);
|
||||
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
||||
data[i + 2] = (Byte)dest;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
||||
{
|
||||
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3] & (~3));
|
||||
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] &= 0x3;
|
||||
data[i + 3] |= dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
||||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
||||
{
|
||||
UInt32 src =
|
||||
((UInt32)data[i + 0] << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3]);
|
||||
UInt32 dest;
|
||||
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + i + src;
|
||||
else
|
||||
dest = src - (ip + i);
|
||||
dest >>= 2;
|
||||
|
||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
||||
|
||||
data[i + 0] = (Byte)(dest >> 24);
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
68
References/VirtuaNESex_src_191105/7z/Bra.h
Normal file
68
References/VirtuaNESex_src_191105/7z/Bra.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* Bra.h -- Branch converters for executables
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __BRA_H
|
||||
#define __BRA_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
These functions convert relative addresses to absolute addresses
|
||||
in CALL instructions to increase the compression ratio.
|
||||
|
||||
In:
|
||||
data - data buffer
|
||||
size - size of data
|
||||
ip - current virtual Instruction Pinter (IP) value
|
||||
state - state variable for x86 converter
|
||||
encoding - 0 (for decoding), 1 (for encoding)
|
||||
|
||||
Out:
|
||||
state - state variable for x86 converter
|
||||
|
||||
Returns:
|
||||
The number of processed bytes. If you call these functions with multiple calls,
|
||||
you must start next call with first byte after block of processed bytes.
|
||||
|
||||
Type Endian Alignment LookAhead
|
||||
|
||||
x86 little 1 4
|
||||
ARMT little 2 2
|
||||
ARM little 4 0
|
||||
PPC big 4 0
|
||||
SPARC big 4 0
|
||||
IA64 little 16 0
|
||||
|
||||
size must be >= Alignment + LookAhead, if it's not last block.
|
||||
If (size < Alignment + LookAhead), converter returns 0.
|
||||
|
||||
Example:
|
||||
|
||||
UInt32 ip = 0;
|
||||
for ()
|
||||
{
|
||||
; size must be >= Alignment + LookAhead, if it's not last block
|
||||
SizeT processed = Convert(data, size, ip, 1);
|
||||
data += processed;
|
||||
size -= processed;
|
||||
ip += processed;
|
||||
}
|
||||
*/
|
||||
|
||||
#define x86_Convert_Init(state) { state = 0; }
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
85
References/VirtuaNESex_src_191105/7z/Bra86.c
Normal file
85
References/VirtuaNESex_src_191105/7z/Bra86.c
Normal file
@ -0,0 +1,85 @@
|
||||
/* Bra86.c -- Converter for x86 code (BCJ)
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
||||
|
||||
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||
{
|
||||
SizeT bufferPos = 0, prevPosT;
|
||||
UInt32 prevMask = *state & 0x7;
|
||||
if (size < 5)
|
||||
return 0;
|
||||
ip += 5;
|
||||
prevPosT = (SizeT)0 - 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *p = data + bufferPos;
|
||||
Byte *limit = data + size - 4;
|
||||
for (; p < limit; p++)
|
||||
if ((*p & 0xFE) == 0xE8)
|
||||
break;
|
||||
bufferPos = (SizeT)(p - data);
|
||||
if (p >= limit)
|
||||
break;
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
if (prevPosT > 3)
|
||||
prevMask = 0;
|
||||
else
|
||||
{
|
||||
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
||||
if (prevMask != 0)
|
||||
{
|
||||
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
||||
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
||||
{
|
||||
prevPosT = bufferPos;
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos;
|
||||
|
||||
if (Test86MSByte(p[4]))
|
||||
{
|
||||
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||
UInt32 dest;
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
int index;
|
||||
if (encoding)
|
||||
dest = (ip + (UInt32)bufferPos) + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)bufferPos);
|
||||
if (prevMask == 0)
|
||||
break;
|
||||
index = kMaskToBitNumber[prevMask] * 8;
|
||||
b = (Byte)(dest >> (24 - index));
|
||||
if (!Test86MSByte(b))
|
||||
break;
|
||||
src = dest ^ ((1 << (32 - index)) - 1);
|
||||
}
|
||||
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||
p[3] = (Byte)(dest >> 16);
|
||||
p[2] = (Byte)(dest >> 8);
|
||||
p[1] = (Byte)dest;
|
||||
bufferPos += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
||||
return bufferPos;
|
||||
}
|
||||
168
References/VirtuaNESex_src_191105/7z/CpuArch.c
Normal file
168
References/VirtuaNESex_src_191105/7z/CpuArch.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* CpuArch.c -- CPU specific code
|
||||
2010-10-26: Igor Pavlov : Public domain */
|
||||
|
||||
#include "CpuArch.h"
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
|
||||
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
|
||||
#define USE_ASM
|
||||
#endif
|
||||
|
||||
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
|
||||
static UInt32 CheckFlag(UInt32 flag)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm mov EDX, EAX;
|
||||
__asm xor EAX, flag;
|
||||
__asm push EAX;
|
||||
__asm popfd;
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm xor EAX, EDX;
|
||||
__asm push EDX;
|
||||
__asm popfd;
|
||||
__asm and flag, EAX;
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"movl %%EAX,%%EDX\n\t"
|
||||
"xorl %0,%%EAX\n\t"
|
||||
"push %%EAX\n\t"
|
||||
"popf\n\t"
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"xorl %%EDX,%%EAX\n\t"
|
||||
"push %%EDX\n\t"
|
||||
"popf\n\t"
|
||||
"andl %%EAX, %0\n\t":
|
||||
"=c" (flag) : "c" (flag));
|
||||
#endif
|
||||
return flag;
|
||||
}
|
||||
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
|
||||
#else
|
||||
#define CHECK_CPUID_IS_SUPPORTED
|
||||
#endif
|
||||
|
||||
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
||||
{
|
||||
#ifdef USE_ASM
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
UInt32 a2, b2, c2, d2;
|
||||
__asm xor EBX, EBX;
|
||||
__asm xor ECX, ECX;
|
||||
__asm xor EDX, EDX;
|
||||
__asm mov EAX, function;
|
||||
__asm cpuid;
|
||||
__asm mov a2, EAX;
|
||||
__asm mov b2, EBX;
|
||||
__asm mov c2, ECX;
|
||||
__asm mov d2, EDX;
|
||||
|
||||
*a = a2;
|
||||
*b = b2;
|
||||
*c = c2;
|
||||
*d = d2;
|
||||
|
||||
#else
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"cpuid"
|
||||
: "=a" (*a) ,
|
||||
"=b" (*b) ,
|
||||
"=c" (*c) ,
|
||||
"=d" (*d)
|
||||
: "0" (function)) ;
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
int CPUInfo[4];
|
||||
__cpuid(CPUInfo, function);
|
||||
*a = CPUInfo[0];
|
||||
*b = CPUInfo[1];
|
||||
*c = CPUInfo[2];
|
||||
*d = CPUInfo[3];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||||
{
|
||||
CHECK_CPUID_IS_SUPPORTED
|
||||
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||||
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
||||
return True;
|
||||
}
|
||||
|
||||
static UInt32 kVendors[][3] =
|
||||
{
|
||||
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
||||
{ 0x68747541, 0x69746E65, 0x444D4163},
|
||||
{ 0x746E6543, 0x48727561, 0x736C7561}
|
||||
};
|
||||
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
|
||||
{
|
||||
const UInt32 *v = kVendors[i];
|
||||
if (v[0] == p->vendor[0] &&
|
||||
v[1] == p->vendor[1] &&
|
||||
v[2] == p->vendor[2])
|
||||
return (int)i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Bool CPU_Is_InOrder()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
int firm;
|
||||
UInt32 family, model;
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return True;
|
||||
family = x86cpuid_GetFamily(&p);
|
||||
model = x86cpuid_GetModel(&p);
|
||||
firm = x86cpuid_GetFirm(&p);
|
||||
switch (firm)
|
||||
{
|
||||
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
|
||||
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||||
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
||||
static Bool CPU_Sys_Is_SSE_Supported()
|
||||
{
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!GetVersionEx(&vi))
|
||||
return False;
|
||||
return (vi.dwMajorVersion >= 5);
|
||||
}
|
||||
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
|
||||
#else
|
||||
#define CHECK_SYS_SSE_SUPPORT
|
||||
#endif
|
||||
|
||||
Bool CPU_Is_Aes_Supported()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
CHECK_SYS_SSE_SUPPORT
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return False;
|
||||
return (p.c >> 25) & 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
155
References/VirtuaNESex_src_191105/7z/CpuArch.h
Normal file
155
References/VirtuaNESex_src_191105/7z/CpuArch.h
Normal file
@ -0,0 +1,155 @@
|
||||
/* CpuArch.h -- CPU specific code
|
||||
2010-10-26: Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __CPU_ARCH_H
|
||||
#define __CPU_ARCH_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/*
|
||||
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||||
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
|
||||
|
||||
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||||
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
|
||||
*/
|
||||
|
||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
||||
#define MY_CPU_AMD64
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
|
||||
#define MY_CPU_64BIT
|
||||
#endif
|
||||
|
||||
#if defined(_M_IX86) || defined(__i386__)
|
||||
#define MY_CPU_X86
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||||
#define MY_CPU_X86_OR_AMD64
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) || defined(_M_ARM)
|
||||
#define MY_CPU_32BIT
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_ARM)
|
||||
#define MY_CPU_ARM_LE
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_IA64)
|
||||
#define MY_CPU_IA64_LE
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86_OR_AMD64)
|
||||
#define MY_CPU_LE_UNALIGN
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
|
||||
#define MY_CPU_LE
|
||||
#endif
|
||||
|
||||
#if defined(__BIG_ENDIAN__)
|
||||
#define MY_CPU_BE
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||||
Stop_Compiling_Bad_Endian
|
||||
#endif
|
||||
|
||||
#ifdef MY_CPU_LE_UNALIGN
|
||||
|
||||
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
|
||||
|
||||
#else
|
||||
|
||||
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||
|
||||
#define GetUi32(p) ( \
|
||||
((const Byte *)(p))[0] | \
|
||||
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[3] << 24))
|
||||
|
||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||
|
||||
#define SetUi16(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
|
||||
|
||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||
|
||||
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
||||
SetUi32(p, (UInt32)_x64_); \
|
||||
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||
|
||||
#else
|
||||
|
||||
#define GetBe32(p) ( \
|
||||
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||
((const Byte *)(p))[3] )
|
||||
|
||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||
|
||||
#endif
|
||||
|
||||
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 maxFunc;
|
||||
UInt32 vendor[3];
|
||||
UInt32 ver;
|
||||
UInt32 b;
|
||||
UInt32 c;
|
||||
UInt32 d;
|
||||
} Cx86cpuid;
|
||||
|
||||
enum
|
||||
{
|
||||
CPU_FIRM_INTEL,
|
||||
CPU_FIRM_AMD,
|
||||
CPU_FIRM_VIA
|
||||
};
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||
|
||||
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
|
||||
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
|
||||
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
|
||||
|
||||
Bool CPU_Is_InOrder();
|
||||
Bool CPU_Is_Aes_Supported();
|
||||
|
||||
#endif
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
356
References/VirtuaNESex_src_191105/7z/Lzma2Dec.c
Normal file
356
References/VirtuaNESex_src_191105/7z/Lzma2Dec.c
Normal file
@ -0,0 +1,356 @@
|
||||
/* Lzma2Dec.c -- LZMA2 Decoder
|
||||
2009-05-03 : Igor Pavlov : Public domain */
|
||||
|
||||
/* #define SHOW_DEBUG_INFO */
|
||||
|
||||
#ifdef SHOW_DEBUG_INFO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Lzma2Dec.h"
|
||||
|
||||
/*
|
||||
00000000 - EOS
|
||||
00000001 U U - Uncompressed Reset Dic
|
||||
00000010 U U - Uncompressed No Reset
|
||||
100uuuuu U U P P - LZMA no reset
|
||||
101uuuuu U U P P - LZMA reset state
|
||||
110uuuuu U U P P S - LZMA reset state + new prop
|
||||
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
|
||||
|
||||
u, U - Unpack Size
|
||||
P - Pack Size
|
||||
S - Props
|
||||
*/
|
||||
|
||||
#define LZMA2_CONTROL_LZMA (1 << 7)
|
||||
#define LZMA2_CONTROL_COPY_NO_RESET 2
|
||||
#define LZMA2_CONTROL_COPY_RESET_DIC 1
|
||||
#define LZMA2_CONTROL_EOF 0
|
||||
|
||||
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
|
||||
|
||||
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
|
||||
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
|
||||
|
||||
#define LZMA2_LCLP_MAX 4
|
||||
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
|
||||
|
||||
#ifdef SHOW_DEBUG_INFO
|
||||
#define PRF(x) x
|
||||
#else
|
||||
#define PRF(x)
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA2_STATE_CONTROL,
|
||||
LZMA2_STATE_UNPACK0,
|
||||
LZMA2_STATE_UNPACK1,
|
||||
LZMA2_STATE_PACK0,
|
||||
LZMA2_STATE_PACK1,
|
||||
LZMA2_STATE_PROP,
|
||||
LZMA2_STATE_DATA,
|
||||
LZMA2_STATE_DATA_CONT,
|
||||
LZMA2_STATE_FINISHED,
|
||||
LZMA2_STATE_ERROR
|
||||
} ELzma2State;
|
||||
|
||||
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
if (prop > 40)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
|
||||
props[0] = (Byte)LZMA2_LCLP_MAX;
|
||||
props[1] = (Byte)(dicSize);
|
||||
props[2] = (Byte)(dicSize >> 8);
|
||||
props[3] = (Byte)(dicSize >> 16);
|
||||
props[4] = (Byte)(dicSize >> 24);
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||
{
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||
{
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||
}
|
||||
|
||||
void Lzma2Dec_Init(CLzma2Dec *p)
|
||||
{
|
||||
p->state = LZMA2_STATE_CONTROL;
|
||||
p->needInitDic = True;
|
||||
p->needInitState = True;
|
||||
p->needInitProp = True;
|
||||
LzmaDec_Init(&p->decoder);
|
||||
}
|
||||
|
||||
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
||||
{
|
||||
switch(p->state)
|
||||
{
|
||||
case LZMA2_STATE_CONTROL:
|
||||
p->control = b;
|
||||
PRF(printf("\n %4X ", p->decoder.dicPos));
|
||||
PRF(printf(" %2X", b));
|
||||
if (p->control == 0)
|
||||
return LZMA2_STATE_FINISHED;
|
||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||
{
|
||||
if ((p->control & 0x7F) > 2)
|
||||
return LZMA2_STATE_ERROR;
|
||||
p->unpackSize = 0;
|
||||
}
|
||||
else
|
||||
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
|
||||
return LZMA2_STATE_UNPACK0;
|
||||
|
||||
case LZMA2_STATE_UNPACK0:
|
||||
p->unpackSize |= (UInt32)b << 8;
|
||||
return LZMA2_STATE_UNPACK1;
|
||||
|
||||
case LZMA2_STATE_UNPACK1:
|
||||
p->unpackSize |= (UInt32)b;
|
||||
p->unpackSize++;
|
||||
PRF(printf(" %8d", p->unpackSize));
|
||||
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
|
||||
|
||||
case LZMA2_STATE_PACK0:
|
||||
p->packSize = (UInt32)b << 8;
|
||||
return LZMA2_STATE_PACK1;
|
||||
|
||||
case LZMA2_STATE_PACK1:
|
||||
p->packSize |= (UInt32)b;
|
||||
p->packSize++;
|
||||
PRF(printf(" %8d", p->packSize));
|
||||
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
|
||||
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
|
||||
|
||||
case LZMA2_STATE_PROP:
|
||||
{
|
||||
int lc, lp;
|
||||
if (b >= (9 * 5 * 5))
|
||||
return LZMA2_STATE_ERROR;
|
||||
lc = b % 9;
|
||||
b /= 9;
|
||||
p->decoder.prop.pb = b / 5;
|
||||
lp = b % 5;
|
||||
if (lc + lp > LZMA2_LCLP_MAX)
|
||||
return LZMA2_STATE_ERROR;
|
||||
p->decoder.prop.lc = lc;
|
||||
p->decoder.prop.lp = lp;
|
||||
p->needInitProp = False;
|
||||
return LZMA2_STATE_DATA;
|
||||
}
|
||||
}
|
||||
return LZMA2_STATE_ERROR;
|
||||
}
|
||||
|
||||
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
|
||||
{
|
||||
memcpy(p->dic + p->dicPos, src, size);
|
||||
p->dicPos += size;
|
||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
p->processedPos += (UInt32)size;
|
||||
}
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
|
||||
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT inSize = *srcLen;
|
||||
*srcLen = 0;
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
|
||||
while (p->state != LZMA2_STATE_FINISHED)
|
||||
{
|
||||
SizeT dicPos = p->decoder.dicPos;
|
||||
if (p->state == LZMA2_STATE_ERROR)
|
||||
return SZ_ERROR_DATA;
|
||||
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
|
||||
{
|
||||
if (*srcLen == inSize)
|
||||
{
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
(*srcLen)++;
|
||||
p->state = Lzma2Dec_UpdateState(p, *src++);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
SizeT destSizeCur = dicLimit - dicPos;
|
||||
SizeT srcSizeCur = inSize - *srcLen;
|
||||
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
||||
|
||||
if (p->unpackSize <= destSizeCur)
|
||||
{
|
||||
destSizeCur = (SizeT)p->unpackSize;
|
||||
curFinishMode = LZMA_FINISH_END;
|
||||
}
|
||||
|
||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||
{
|
||||
if (*srcLen == inSize)
|
||||
{
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
if (p->state == LZMA2_STATE_DATA)
|
||||
{
|
||||
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
||||
if (initDic)
|
||||
p->needInitProp = p->needInitState = True;
|
||||
else if (p->needInitDic)
|
||||
return SZ_ERROR_DATA;
|
||||
p->needInitDic = False;
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||
}
|
||||
|
||||
if (srcSizeCur > destSizeCur)
|
||||
srcSizeCur = destSizeCur;
|
||||
|
||||
if (srcSizeCur == 0)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
||||
|
||||
src += srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
p->unpackSize -= (UInt32)srcSizeCur;
|
||||
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeT outSizeProcessed;
|
||||
SRes res;
|
||||
|
||||
if (p->state == LZMA2_STATE_DATA)
|
||||
{
|
||||
int mode = LZMA2_GET_LZMA_MODE(p);
|
||||
Bool initDic = (mode == 3);
|
||||
Bool initState = (mode > 0);
|
||||
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||
p->needInitDic = False;
|
||||
p->needInitState = False;
|
||||
p->state = LZMA2_STATE_DATA_CONT;
|
||||
}
|
||||
if (srcSizeCur > p->packSize)
|
||||
srcSizeCur = (SizeT)p->packSize;
|
||||
|
||||
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||
|
||||
src += srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
p->packSize -= (UInt32)srcSizeCur;
|
||||
|
||||
outSizeProcessed = p->decoder.dicPos - dicPos;
|
||||
p->unpackSize -= (UInt32)outSizeProcessed;
|
||||
|
||||
RINOK(res);
|
||||
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
return res;
|
||||
|
||||
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
||||
{
|
||||
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
|
||||
p->unpackSize != 0 || p->packSize != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
p->state = LZMA2_STATE_CONTROL;
|
||||
}
|
||||
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
}
|
||||
}
|
||||
}
|
||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen, inSize = *srcLen;
|
||||
*srcLen = *destLen = 0;
|
||||
for (;;)
|
||||
{
|
||||
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
|
||||
ELzmaFinishMode curFinishMode;
|
||||
SRes res;
|
||||
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
||||
p->decoder.dicPos = 0;
|
||||
dicPos = p->decoder.dicPos;
|
||||
if (outSize > p->decoder.dicBufSize - dicPos)
|
||||
{
|
||||
outSizeCur = p->decoder.dicBufSize;
|
||||
curFinishMode = LZMA_FINISH_ANY;
|
||||
}
|
||||
else
|
||||
{
|
||||
outSizeCur = dicPos + outSize;
|
||||
curFinishMode = finishMode;
|
||||
}
|
||||
|
||||
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||
src += srcSizeCur;
|
||||
inSize -= srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
outSizeCur = p->decoder.dicPos - dicPos;
|
||||
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
|
||||
dest += outSizeCur;
|
||||
outSize -= outSizeCur;
|
||||
*destLen += outSizeCur;
|
||||
if (res != 0)
|
||||
return res;
|
||||
if (outSizeCur == 0 || outSize == 0)
|
||||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
|
||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
|
||||
{
|
||||
CLzma2Dec decoder;
|
||||
SRes res;
|
||||
SizeT outSize = *destLen, inSize = *srcLen;
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
|
||||
Lzma2Dec_Construct(&decoder);
|
||||
|
||||
*destLen = *srcLen = 0;
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
decoder.decoder.dic = dest;
|
||||
decoder.decoder.dicBufSize = outSize;
|
||||
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
|
||||
|
||||
*srcLen = inSize;
|
||||
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
|
||||
*destLen = decoder.decoder.dicPos;
|
||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
res = SZ_ERROR_INPUT_EOF;
|
||||
|
||||
LzmaDec_FreeProbs(&decoder.decoder, alloc);
|
||||
return res;
|
||||
}
|
||||
84
References/VirtuaNESex_src_191105/7z/Lzma2Dec.h
Normal file
84
References/VirtuaNESex_src_191105/7z/Lzma2Dec.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* Lzma2Dec.h -- LZMA2 Decoder
|
||||
2009-05-03 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA2_DEC_H
|
||||
#define __LZMA2_DEC_H
|
||||
|
||||
#include "LzmaDec.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ---------- State Interface ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaDec decoder;
|
||||
UInt32 packSize;
|
||||
UInt32 unpackSize;
|
||||
int state;
|
||||
Byte control;
|
||||
Bool needInitDic;
|
||||
Bool needInitState;
|
||||
Bool needInitProp;
|
||||
} CLzma2Dec;
|
||||
|
||||
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
|
||||
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
|
||||
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
|
||||
|
||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||
void Lzma2Dec_Init(CLzma2Dec *p);
|
||||
|
||||
|
||||
/*
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
|
||||
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/*
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
999
References/VirtuaNESex_src_191105/7z/LzmaDec.c
Normal file
999
References/VirtuaNESex_src_191105/7z/LzmaDec.c
Normal file
@ -0,0 +1,999 @@
|
||||
/* LzmaDec.c -- LZMA Decoder
|
||||
2009-09-20 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "LzmaDec.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define kNumTopBits 24
|
||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||
|
||||
#define kNumBitModelTotalBits 11
|
||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||
#define kNumMoveBits 5
|
||||
|
||||
#define RC_INIT_SIZE 5
|
||||
|
||||
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
|
||||
|
||||
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
|
||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
|
||||
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
||||
{ UPDATE_0(p); i = (i + i); A0; } else \
|
||||
{ UPDATE_1(p); i = (i + i) + 1; A1; }
|
||||
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
|
||||
|
||||
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
|
||||
#define TREE_DECODE(probs, limit, i) \
|
||||
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
|
||||
|
||||
/* #define _LZMA_SIZE_OPT */
|
||||
|
||||
#ifdef _LZMA_SIZE_OPT
|
||||
#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
|
||||
#else
|
||||
#define TREE_6_DECODE(probs, i) \
|
||||
{ i = 1; \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
TREE_GET_BIT(probs, i); \
|
||||
i -= 0x40; }
|
||||
#endif
|
||||
|
||||
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
|
||||
|
||||
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||
#define UPDATE_0_CHECK range = bound;
|
||||
#define UPDATE_1_CHECK range -= bound; code -= bound;
|
||||
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
|
||||
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
|
||||
{ UPDATE_1_CHECK; i = (i + i) + 1; A1; }
|
||||
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
|
||||
#define TREE_DECODE_CHECK(probs, limit, i) \
|
||||
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
|
||||
|
||||
|
||||
#define kNumPosBitsMax 4
|
||||
#define kNumPosStatesMax (1 << kNumPosBitsMax)
|
||||
|
||||
#define kLenNumLowBits 3
|
||||
#define kLenNumLowSymbols (1 << kLenNumLowBits)
|
||||
#define kLenNumMidBits 3
|
||||
#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
||||
#define kLenNumHighBits 8
|
||||
#define kLenNumHighSymbols (1 << kLenNumHighBits)
|
||||
|
||||
#define LenChoice 0
|
||||
#define LenChoice2 (LenChoice + 1)
|
||||
#define LenLow (LenChoice2 + 1)
|
||||
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
||||
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
||||
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
||||
|
||||
|
||||
#define kNumStates 12
|
||||
#define kNumLitStates 7
|
||||
|
||||
#define kStartPosModelIndex 4
|
||||
#define kEndPosModelIndex 14
|
||||
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
||||
|
||||
#define kNumPosSlotBits 6
|
||||
#define kNumLenToPosStates 4
|
||||
|
||||
#define kNumAlignBits 4
|
||||
#define kAlignTableSize (1 << kNumAlignBits)
|
||||
|
||||
#define kMatchMinLen 2
|
||||
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
|
||||
|
||||
#define IsMatch 0
|
||||
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
||||
#define IsRepG0 (IsRep + kNumStates)
|
||||
#define IsRepG1 (IsRepG0 + kNumStates)
|
||||
#define IsRepG2 (IsRepG1 + kNumStates)
|
||||
#define IsRep0Long (IsRepG2 + kNumStates)
|
||||
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
||||
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
||||
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
||||
#define LenCoder (Align + kAlignTableSize)
|
||||
#define RepLenCoder (LenCoder + kNumLenProbs)
|
||||
#define Literal (RepLenCoder + kNumLenProbs)
|
||||
|
||||
#define LZMA_BASE_SIZE 1846
|
||||
#define LZMA_LIT_SIZE 768
|
||||
|
||||
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
|
||||
|
||||
#if Literal != LZMA_BASE_SIZE
|
||||
StopCompilingDueBUG
|
||||
#endif
|
||||
|
||||
#define LZMA_DIC_MIN (1 << 12)
|
||||
|
||||
/* First LZMA-symbol is always decoded.
|
||||
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
|
||||
Out:
|
||||
Result:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_DATA - Error
|
||||
p->remainLen:
|
||||
< kMatchSpecLenStart : normal remain
|
||||
= kMatchSpecLenStart : finished
|
||||
= kMatchSpecLenStart + 1 : Flush marker
|
||||
= kMatchSpecLenStart + 2 : State Init Marker
|
||||
*/
|
||||
|
||||
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||
{
|
||||
CLzmaProb *probs = p->probs;
|
||||
|
||||
unsigned state = p->state;
|
||||
UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
|
||||
unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
|
||||
unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
|
||||
unsigned lc = p->prop.lc;
|
||||
|
||||
Byte *dic = p->dic;
|
||||
SizeT dicBufSize = p->dicBufSize;
|
||||
SizeT dicPos = p->dicPos;
|
||||
|
||||
UInt32 processedPos = p->processedPos;
|
||||
UInt32 checkDicSize = p->checkDicSize;
|
||||
unsigned len = 0;
|
||||
|
||||
const Byte *buf = p->buf;
|
||||
UInt32 range = p->range;
|
||||
UInt32 code = p->code;
|
||||
|
||||
do
|
||||
{
|
||||
CLzmaProb *prob;
|
||||
UInt32 bound;
|
||||
unsigned ttt;
|
||||
unsigned posState = processedPos & pbMask;
|
||||
|
||||
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
unsigned symbol;
|
||||
UPDATE_0(prob);
|
||||
prob = probs + Literal;
|
||||
if (checkDicSize != 0 || processedPos != 0)
|
||||
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
||||
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
||||
|
||||
if (state < kNumLitStates)
|
||||
{
|
||||
state -= (state < 4) ? state : 3;
|
||||
symbol = 1;
|
||||
do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||
unsigned offs = 0x100;
|
||||
state -= (state < 10) ? 3 : 6;
|
||||
symbol = 1;
|
||||
do
|
||||
{
|
||||
unsigned bit;
|
||||
CLzmaProb *probLit;
|
||||
matchByte <<= 1;
|
||||
bit = (matchByte & offs);
|
||||
probLit = prob + offs + bit + symbol;
|
||||
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
}
|
||||
dic[dicPos++] = (Byte)symbol;
|
||||
processedPos++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
prob = probs + IsRep + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
state += kNumStates;
|
||||
prob = probs + LenCoder;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
if (checkDicSize == 0 && processedPos == 0)
|
||||
return SZ_ERROR_DATA;
|
||||
prob = probs + IsRepG0 + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||
dicPos++;
|
||||
processedPos++;
|
||||
state = state < kNumLitStates ? 9 : 11;
|
||||
continue;
|
||||
}
|
||||
UPDATE_1(prob);
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 distance;
|
||||
UPDATE_1(prob);
|
||||
prob = probs + IsRepG1 + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
distance = rep1;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
prob = probs + IsRepG2 + state;
|
||||
IF_BIT_0(prob)
|
||||
{
|
||||
UPDATE_0(prob);
|
||||
distance = rep2;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(prob);
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
rep2 = rep1;
|
||||
}
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
state = state < kNumLitStates ? 8 : 11;
|
||||
prob = probs + RepLenCoder;
|
||||
}
|
||||
{
|
||||
unsigned limit, offset;
|
||||
CLzmaProb *probLen = prob + LenChoice;
|
||||
IF_BIT_0(probLen)
|
||||
{
|
||||
UPDATE_0(probLen);
|
||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||
offset = 0;
|
||||
limit = (1 << kLenNumLowBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(probLen);
|
||||
probLen = prob + LenChoice2;
|
||||
IF_BIT_0(probLen)
|
||||
{
|
||||
UPDATE_0(probLen);
|
||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||
offset = kLenNumLowSymbols;
|
||||
limit = (1 << kLenNumMidBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(probLen);
|
||||
probLen = prob + LenHigh;
|
||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||
limit = (1 << kLenNumHighBits);
|
||||
}
|
||||
}
|
||||
TREE_DECODE(probLen, limit, len);
|
||||
len += offset;
|
||||
}
|
||||
|
||||
if (state >= kNumStates)
|
||||
{
|
||||
UInt32 distance;
|
||||
prob = probs + PosSlot +
|
||||
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
|
||||
TREE_6_DECODE(prob, distance);
|
||||
if (distance >= kStartPosModelIndex)
|
||||
{
|
||||
unsigned posSlot = (unsigned)distance;
|
||||
int numDirectBits = (int)(((distance >> 1) - 1));
|
||||
distance = (2 | (distance & 1));
|
||||
if (posSlot < kEndPosModelIndex)
|
||||
{
|
||||
distance <<= numDirectBits;
|
||||
prob = probs + SpecPos + distance - posSlot - 1;
|
||||
{
|
||||
UInt32 mask = 1;
|
||||
unsigned i = 1;
|
||||
do
|
||||
{
|
||||
GET_BIT2(prob + i, i, ; , distance |= mask);
|
||||
mask <<= 1;
|
||||
}
|
||||
while (--numDirectBits != 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numDirectBits -= kNumAlignBits;
|
||||
do
|
||||
{
|
||||
NORMALIZE
|
||||
range >>= 1;
|
||||
|
||||
{
|
||||
UInt32 t;
|
||||
code -= range;
|
||||
t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
|
||||
distance = (distance << 1) + (t + 1);
|
||||
code += range & t;
|
||||
}
|
||||
/*
|
||||
distance <<= 1;
|
||||
if (code >= range)
|
||||
{
|
||||
code -= range;
|
||||
distance |= 1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
while (--numDirectBits != 0);
|
||||
prob = probs + Align;
|
||||
distance <<= kNumAlignBits;
|
||||
{
|
||||
unsigned i = 1;
|
||||
GET_BIT2(prob + i, i, ; , distance |= 1);
|
||||
GET_BIT2(prob + i, i, ; , distance |= 2);
|
||||
GET_BIT2(prob + i, i, ; , distance |= 4);
|
||||
GET_BIT2(prob + i, i, ; , distance |= 8);
|
||||
}
|
||||
if (distance == (UInt32)0xFFFFFFFF)
|
||||
{
|
||||
len += kMatchSpecLenStart;
|
||||
state -= kNumStates;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
rep0 = distance + 1;
|
||||
if (checkDicSize == 0)
|
||||
{
|
||||
if (distance >= processedPos)
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
else if (distance >= checkDicSize)
|
||||
return SZ_ERROR_DATA;
|
||||
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
||||
}
|
||||
|
||||
len += kMatchMinLen;
|
||||
|
||||
if (limit == dicPos)
|
||||
return SZ_ERROR_DATA;
|
||||
{
|
||||
SizeT rem = limit - dicPos;
|
||||
unsigned curLen = ((rem < len) ? (unsigned)rem : len);
|
||||
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
|
||||
|
||||
processedPos += curLen;
|
||||
|
||||
len -= curLen;
|
||||
if (pos + curLen <= dicBufSize)
|
||||
{
|
||||
Byte *dest = dic + dicPos;
|
||||
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
|
||||
const Byte *lim = dest + curLen;
|
||||
dicPos += curLen;
|
||||
do
|
||||
*(dest) = (Byte)*(dest + src);
|
||||
while (++dest != lim);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
dic[dicPos++] = dic[pos];
|
||||
if (++pos == dicBufSize)
|
||||
pos = 0;
|
||||
}
|
||||
while (--curLen != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (dicPos < limit && buf < bufLimit);
|
||||
NORMALIZE;
|
||||
p->buf = buf;
|
||||
p->range = range;
|
||||
p->code = code;
|
||||
p->remainLen = len;
|
||||
p->dicPos = dicPos;
|
||||
p->processedPos = processedPos;
|
||||
p->reps[0] = rep0;
|
||||
p->reps[1] = rep1;
|
||||
p->reps[2] = rep2;
|
||||
p->reps[3] = rep3;
|
||||
p->state = state;
|
||||
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
||||
{
|
||||
if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
|
||||
{
|
||||
Byte *dic = p->dic;
|
||||
SizeT dicPos = p->dicPos;
|
||||
SizeT dicBufSize = p->dicBufSize;
|
||||
unsigned len = p->remainLen;
|
||||
UInt32 rep0 = p->reps[0];
|
||||
if (limit - dicPos < len)
|
||||
len = (unsigned)(limit - dicPos);
|
||||
|
||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
|
||||
p->processedPos += len;
|
||||
p->remainLen -= len;
|
||||
while (len-- != 0)
|
||||
{
|
||||
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||
dicPos++;
|
||||
}
|
||||
p->dicPos = dicPos;
|
||||
}
|
||||
}
|
||||
|
||||
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||
{
|
||||
do
|
||||
{
|
||||
SizeT limit2 = limit;
|
||||
if (p->checkDicSize == 0)
|
||||
{
|
||||
UInt32 rem = p->prop.dicSize - p->processedPos;
|
||||
if (limit - p->dicPos > rem)
|
||||
limit2 = p->dicPos + rem;
|
||||
}
|
||||
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
|
||||
if (p->processedPos >= p->prop.dicSize)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
LzmaDec_WriteRem(p, limit);
|
||||
}
|
||||
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
|
||||
|
||||
if (p->remainLen > kMatchSpecLenStart)
|
||||
{
|
||||
p->remainLen = kMatchSpecLenStart;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DUMMY_ERROR, /* unexpected end of input stream */
|
||||
DUMMY_LIT,
|
||||
DUMMY_MATCH,
|
||||
DUMMY_REP
|
||||
} ELzmaDummy;
|
||||
|
||||
static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
|
||||
{
|
||||
UInt32 range = p->range;
|
||||
UInt32 code = p->code;
|
||||
const Byte *bufLimit = buf + inSize;
|
||||
CLzmaProb *probs = p->probs;
|
||||
unsigned state = p->state;
|
||||
ELzmaDummy res;
|
||||
|
||||
{
|
||||
CLzmaProb *prob;
|
||||
UInt32 bound;
|
||||
unsigned ttt;
|
||||
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
|
||||
|
||||
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK
|
||||
|
||||
/* if (bufLimit - buf >= 7) return DUMMY_LIT; */
|
||||
|
||||
prob = probs + Literal;
|
||||
if (p->checkDicSize != 0 || p->processedPos != 0)
|
||||
prob += (LZMA_LIT_SIZE *
|
||||
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
||||
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
||||
|
||||
if (state < kNumLitStates)
|
||||
{
|
||||
unsigned symbol = 1;
|
||||
do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
|
||||
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
|
||||
unsigned offs = 0x100;
|
||||
unsigned symbol = 1;
|
||||
do
|
||||
{
|
||||
unsigned bit;
|
||||
CLzmaProb *probLit;
|
||||
matchByte <<= 1;
|
||||
bit = (matchByte & offs);
|
||||
probLit = prob + offs + bit + symbol;
|
||||
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
|
||||
}
|
||||
while (symbol < 0x100);
|
||||
}
|
||||
res = DUMMY_LIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned len;
|
||||
UPDATE_1_CHECK;
|
||||
|
||||
prob = probs + IsRep + state;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
state = 0;
|
||||
prob = probs + LenCoder;
|
||||
res = DUMMY_MATCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
res = DUMMY_REP;
|
||||
prob = probs + IsRepG0 + state;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
NORMALIZE_CHECK;
|
||||
return DUMMY_REP;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
prob = probs + IsRepG1 + state;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
prob = probs + IsRepG2 + state;
|
||||
IF_BIT_0_CHECK(prob)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
}
|
||||
}
|
||||
}
|
||||
state = kNumStates;
|
||||
prob = probs + RepLenCoder;
|
||||
}
|
||||
{
|
||||
unsigned limit, offset;
|
||||
CLzmaProb *probLen = prob + LenChoice;
|
||||
IF_BIT_0_CHECK(probLen)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||
offset = 0;
|
||||
limit = 1 << kLenNumLowBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
probLen = prob + LenChoice2;
|
||||
IF_BIT_0_CHECK(probLen)
|
||||
{
|
||||
UPDATE_0_CHECK;
|
||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||
offset = kLenNumLowSymbols;
|
||||
limit = 1 << kLenNumMidBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1_CHECK;
|
||||
probLen = prob + LenHigh;
|
||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||
limit = 1 << kLenNumHighBits;
|
||||
}
|
||||
}
|
||||
TREE_DECODE_CHECK(probLen, limit, len);
|
||||
len += offset;
|
||||
}
|
||||
|
||||
if (state < 4)
|
||||
{
|
||||
unsigned posSlot;
|
||||
prob = probs + PosSlot +
|
||||
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
||||
kNumPosSlotBits);
|
||||
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
||||
if (posSlot >= kStartPosModelIndex)
|
||||
{
|
||||
int numDirectBits = ((posSlot >> 1) - 1);
|
||||
|
||||
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
|
||||
|
||||
if (posSlot < kEndPosModelIndex)
|
||||
{
|
||||
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
numDirectBits -= kNumAlignBits;
|
||||
do
|
||||
{
|
||||
NORMALIZE_CHECK
|
||||
range >>= 1;
|
||||
code -= range & (((code - range) >> 31) - 1);
|
||||
/* if (code >= range) code -= range; */
|
||||
}
|
||||
while (--numDirectBits != 0);
|
||||
prob = probs + Align;
|
||||
numDirectBits = kNumAlignBits;
|
||||
}
|
||||
{
|
||||
unsigned i = 1;
|
||||
do
|
||||
{
|
||||
GET_BIT_CHECK(prob + i, i);
|
||||
}
|
||||
while (--numDirectBits != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NORMALIZE_CHECK;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
|
||||
{
|
||||
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
|
||||
p->range = 0xFFFFFFFF;
|
||||
p->needFlush = 0;
|
||||
}
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||
{
|
||||
p->needFlush = 1;
|
||||
p->remainLen = 0;
|
||||
p->tempBufSize = 0;
|
||||
|
||||
if (initDic)
|
||||
{
|
||||
p->processedPos = 0;
|
||||
p->checkDicSize = 0;
|
||||
p->needInitState = 1;
|
||||
}
|
||||
if (initState)
|
||||
p->needInitState = 1;
|
||||
}
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p)
|
||||
{
|
||||
p->dicPos = 0;
|
||||
LzmaDec_InitDicAndState(p, True, True);
|
||||
}
|
||||
|
||||
static void LzmaDec_InitStateReal(CLzmaDec *p)
|
||||
{
|
||||
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
|
||||
UInt32 i;
|
||||
CLzmaProb *probs = p->probs;
|
||||
for (i = 0; i < numProbs; i++)
|
||||
probs[i] = kBitModelTotal >> 1;
|
||||
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
|
||||
p->state = 0;
|
||||
p->needInitState = 0;
|
||||
}
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT inSize = *srcLen;
|
||||
(*srcLen) = 0;
|
||||
LzmaDec_WriteRem(p, dicLimit);
|
||||
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
|
||||
while (p->remainLen != kMatchSpecLenStart)
|
||||
{
|
||||
int checkEndMarkNow;
|
||||
|
||||
if (p->needFlush != 0)
|
||||
{
|
||||
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
||||
p->tempBuf[p->tempBufSize++] = *src++;
|
||||
if (p->tempBufSize < RC_INIT_SIZE)
|
||||
{
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (p->tempBuf[0] != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_InitRc(p, p->tempBuf);
|
||||
p->tempBufSize = 0;
|
||||
}
|
||||
|
||||
checkEndMarkNow = 0;
|
||||
if (p->dicPos >= dicLimit)
|
||||
{
|
||||
if (p->remainLen == 0 && p->code == 0)
|
||||
{
|
||||
*status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (finishMode == LZMA_FINISH_ANY)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (p->remainLen != 0)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
checkEndMarkNow = 1;
|
||||
}
|
||||
|
||||
if (p->needInitState)
|
||||
LzmaDec_InitStateReal(p);
|
||||
|
||||
if (p->tempBufSize == 0)
|
||||
{
|
||||
SizeT processed;
|
||||
const Byte *bufLimit;
|
||||
if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||
{
|
||||
int dummyRes = LzmaDec_TryDummy(p, src, inSize);
|
||||
if (dummyRes == DUMMY_ERROR)
|
||||
{
|
||||
memcpy(p->tempBuf, src, inSize);
|
||||
p->tempBufSize = (unsigned)inSize;
|
||||
(*srcLen) += inSize;
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
bufLimit = src;
|
||||
}
|
||||
else
|
||||
bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
|
||||
p->buf = src;
|
||||
if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
processed = (SizeT)(p->buf - src);
|
||||
(*srcLen) += processed;
|
||||
src += processed;
|
||||
inSize -= processed;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned rem = p->tempBufSize, lookAhead = 0;
|
||||
while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
|
||||
p->tempBuf[rem++] = src[lookAhead++];
|
||||
p->tempBufSize = rem;
|
||||
if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
|
||||
{
|
||||
int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
|
||||
if (dummyRes == DUMMY_ERROR)
|
||||
{
|
||||
(*srcLen) += lookAhead;
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
p->buf = p->tempBuf;
|
||||
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
|
||||
(*srcLen) += lookAhead;
|
||||
src += lookAhead;
|
||||
inSize -= lookAhead;
|
||||
p->tempBufSize = 0;
|
||||
}
|
||||
}
|
||||
if (p->code == 0)
|
||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
|
||||
}
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen;
|
||||
SizeT inSize = *srcLen;
|
||||
*srcLen = *destLen = 0;
|
||||
for (;;)
|
||||
{
|
||||
SizeT inSizeCur = inSize, outSizeCur, dicPos;
|
||||
ELzmaFinishMode curFinishMode;
|
||||
SRes res;
|
||||
if (p->dicPos == p->dicBufSize)
|
||||
p->dicPos = 0;
|
||||
dicPos = p->dicPos;
|
||||
if (outSize > p->dicBufSize - dicPos)
|
||||
{
|
||||
outSizeCur = p->dicBufSize;
|
||||
curFinishMode = LZMA_FINISH_ANY;
|
||||
}
|
||||
else
|
||||
{
|
||||
outSizeCur = dicPos + outSize;
|
||||
curFinishMode = finishMode;
|
||||
}
|
||||
|
||||
res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
|
||||
src += inSizeCur;
|
||||
inSize -= inSizeCur;
|
||||
*srcLen += inSizeCur;
|
||||
outSizeCur = p->dicPos - dicPos;
|
||||
memcpy(dest, p->dic + dicPos, outSizeCur);
|
||||
dest += outSizeCur;
|
||||
outSize -= outSizeCur;
|
||||
*destLen += outSizeCur;
|
||||
if (res != 0)
|
||||
return res;
|
||||
if (outSizeCur == 0 || outSize == 0)
|
||||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->probs);
|
||||
p->probs = 0;
|
||||
}
|
||||
|
||||
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->dic);
|
||||
p->dic = 0;
|
||||
}
|
||||
|
||||
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
LzmaDec_FreeProbs(p, alloc);
|
||||
LzmaDec_FreeDict(p, alloc);
|
||||
}
|
||||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
Byte d;
|
||||
|
||||
if (size < LZMA_PROPS_SIZE)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
else
|
||||
dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
|
||||
|
||||
if (dicSize < LZMA_DIC_MIN)
|
||||
dicSize = LZMA_DIC_MIN;
|
||||
p->dicSize = dicSize;
|
||||
|
||||
d = data[0];
|
||||
if (d >= (9 * 5 * 5))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
p->lc = d % 9;
|
||||
d /= 9;
|
||||
p->pb = d / 5;
|
||||
p->lp = d % 5;
|
||||
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
||||
if (p->probs == 0 || numProbs != p->numProbs)
|
||||
{
|
||||
LzmaDec_FreeProbs(p, alloc);
|
||||
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
||||
p->numProbs = numProbs;
|
||||
if (p->probs == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||
{
|
||||
CLzmaProps propNew;
|
||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
||||
p->prop = propNew;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||
{
|
||||
CLzmaProps propNew;
|
||||
SizeT dicBufSize;
|
||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
||||
dicBufSize = propNew.dicSize;
|
||||
if (p->dic == 0 || dicBufSize != p->dicBufSize)
|
||||
{
|
||||
LzmaDec_FreeDict(p, alloc);
|
||||
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
||||
if (p->dic == 0)
|
||||
{
|
||||
LzmaDec_FreeProbs(p, alloc);
|
||||
return SZ_ERROR_MEM;
|
||||
}
|
||||
}
|
||||
p->dicBufSize = dicBufSize;
|
||||
p->prop = propNew;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc)
|
||||
{
|
||||
CLzmaDec p;
|
||||
SRes res;
|
||||
SizeT inSize = *srcLen;
|
||||
SizeT outSize = *destLen;
|
||||
*srcLen = *destLen = 0;
|
||||
if (inSize < RC_INIT_SIZE)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
|
||||
LzmaDec_Construct(&p);
|
||||
res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
|
||||
if (res != 0)
|
||||
return res;
|
||||
p.dic = dest;
|
||||
p.dicBufSize = outSize;
|
||||
|
||||
LzmaDec_Init(&p);
|
||||
|
||||
*srcLen = inSize;
|
||||
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
|
||||
|
||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
res = SZ_ERROR_INPUT_EOF;
|
||||
|
||||
(*destLen) = p.dicPos;
|
||||
LzmaDec_FreeProbs(&p, alloc);
|
||||
return res;
|
||||
}
|
||||
231
References/VirtuaNESex_src_191105/7z/LzmaDec.h
Normal file
231
References/VirtuaNESex_src_191105/7z/LzmaDec.h
Normal file
@ -0,0 +1,231 @@
|
||||
/* LzmaDec.h -- LZMA Decoder
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA_DEC_H
|
||||
#define __LZMA_DEC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* #define _LZMA_PROB32 */
|
||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CLzmaProb UInt32
|
||||
#else
|
||||
#define CLzmaProb UInt16
|
||||
#endif
|
||||
|
||||
|
||||
/* ---------- LZMA Properties ---------- */
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaProps
|
||||
{
|
||||
unsigned lc, lp, pb;
|
||||
UInt32 dicSize;
|
||||
} CLzmaProps;
|
||||
|
||||
/* LzmaProps_Decode - decodes properties
|
||||
Returns:
|
||||
SZ_OK
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||
|
||||
|
||||
/* ---------- LZMA Decoder state ---------- */
|
||||
|
||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||
|
||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaProps prop;
|
||||
CLzmaProb *probs;
|
||||
Byte *dic;
|
||||
const Byte *buf;
|
||||
UInt32 range, code;
|
||||
SizeT dicPos;
|
||||
SizeT dicBufSize;
|
||||
UInt32 processedPos;
|
||||
UInt32 checkDicSize;
|
||||
unsigned state;
|
||||
UInt32 reps[4];
|
||||
unsigned remainLen;
|
||||
int needFlush;
|
||||
int needInitState;
|
||||
UInt32 numProbs;
|
||||
unsigned tempBufSize;
|
||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||
} CLzmaDec;
|
||||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p);
|
||||
|
||||
/* There are two types of LZMA streams:
|
||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_FINISH_ANY, /* finish at any point */
|
||||
LZMA_FINISH_END /* block must be finished at the end */
|
||||
} ELzmaFinishMode;
|
||||
|
||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||
|
||||
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||
|
||||
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||
and output value of destLen will be less than output buffer size limit.
|
||||
You can check status result also.
|
||||
|
||||
You can use multiple checks to test data integrity after full decompression:
|
||||
1) Check Result and "status" variable.
|
||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||
You must use correct finish mode in that case. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||
} ELzmaStatus;
|
||||
|
||||
/* ELzmaStatus is used only as output value for function call */
|
||||
|
||||
|
||||
/* ---------- Interfaces ---------- */
|
||||
|
||||
/* There are 3 levels of interfaces:
|
||||
1) Dictionary Interface
|
||||
2) Buffer Interface
|
||||
3) One Call Interface
|
||||
You can select any of these interfaces, but don't mix functions from different
|
||||
groups for same object. */
|
||||
|
||||
|
||||
/* There are two variants to allocate state for Dictionary Interface:
|
||||
1) LzmaDec_Allocate / LzmaDec_Free
|
||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||
You can use variant 2, if you set dictionary buffer manually.
|
||||
For Buffer Interface you must always use variant 1.
|
||||
|
||||
LzmaDec_Allocate* can return:
|
||||
SZ_OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
|
||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||
|
||||
/* ---------- Dictionary Interface ---------- */
|
||||
|
||||
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||
dictionary to some other external buffer.
|
||||
You must work with CLzmaDec variables directly in this interface.
|
||||
|
||||
STEPS:
|
||||
LzmaDec_Constr()
|
||||
LzmaDec_Allocate()
|
||||
for (each new stream)
|
||||
{
|
||||
LzmaDec_Init()
|
||||
while (it needs more decompression)
|
||||
{
|
||||
LzmaDec_DecodeToDic()
|
||||
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||
}
|
||||
}
|
||||
LzmaDec_Free()
|
||||
*/
|
||||
|
||||
/* LzmaDec_DecodeToDic
|
||||
|
||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- Buffer Interface ---------- */
|
||||
|
||||
/* It's zlib-like interface.
|
||||
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||
to work with CLzmaDec variables manually.
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaDecode
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
81
References/VirtuaNESex_src_191105/7z/Ppmd.h
Normal file
81
References/VirtuaNESex_src_191105/7z/Ppmd.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* Ppmd.h -- PPMD codec common code
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#ifndef __PPMD_H
|
||||
#define __PPMD_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "CpuArch.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#ifdef MY_CPU_32BIT
|
||||
#define PPMD_32BIT
|
||||
#endif
|
||||
|
||||
#define PPMD_INT_BITS 7
|
||||
#define PPMD_PERIOD_BITS 7
|
||||
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
|
||||
|
||||
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
|
||||
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
|
||||
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
|
||||
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
|
||||
|
||||
#define PPMD_N1 4
|
||||
#define PPMD_N2 4
|
||||
#define PPMD_N3 4
|
||||
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
|
||||
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
|
||||
|
||||
/* SEE-contexts for PPM-contexts with masked symbols */
|
||||
typedef struct
|
||||
{
|
||||
UInt16 Summ; /* Freq */
|
||||
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
|
||||
Byte Count; /* Count to next change of Shift */
|
||||
} CPpmd_See;
|
||||
|
||||
#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
|
||||
{ (p)->Summ <<= 1; (p)->Count = (Byte)(3 << (p)->Shift++); }
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte Symbol;
|
||||
Byte Freq;
|
||||
UInt16 SuccessorLow;
|
||||
UInt16 SuccessorHigh;
|
||||
} CPpmd_State;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
CPpmd_State *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_State_Ref;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
void *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_Void_Ref;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
Byte *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd_Byte_Ref;
|
||||
|
||||
#define PPMD_SetAllBitsIn256Bytes(p) \
|
||||
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
|
||||
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
708
References/VirtuaNESex_src_191105/7z/Ppmd7.c
Normal file
708
References/VirtuaNESex_src_191105/7z/Ppmd7.c
Normal file
@ -0,0 +1,708 @@
|
||||
/* Ppmd7.c -- PPMdH codec
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include "Ppmd7.h"
|
||||
|
||||
const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||
static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051};
|
||||
|
||||
#define MAX_FREQ 124
|
||||
#define UNIT_SIZE 12
|
||||
|
||||
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
|
||||
#define U2I(nu) (p->Units2Indx[(nu) - 1])
|
||||
#define I2U(indx) (p->Indx2Units[indx])
|
||||
|
||||
#ifdef PPMD_32BIT
|
||||
#define REF(ptr) (ptr)
|
||||
#else
|
||||
#define REF(ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
|
||||
#endif
|
||||
|
||||
#define STATS_REF(ptr) ((CPpmd_State_Ref)REF(ptr))
|
||||
|
||||
#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref))
|
||||
#define STATS(ctx) Ppmd7_GetStats(p, ctx)
|
||||
#define ONE_STATE(ctx) Ppmd7Context_OneState(ctx)
|
||||
#define SUFFIX(ctx) CTX((ctx)->Suffix)
|
||||
|
||||
typedef CPpmd7_Context * CTX_PTR;
|
||||
|
||||
struct CPpmd7_Node_;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
struct CPpmd7_Node_ *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd7_Node_Ref;
|
||||
|
||||
typedef struct CPpmd7_Node_
|
||||
{
|
||||
UInt16 Stamp; /* must be at offset 0 as CPpmd7_Context::NumStats. Stamp=0 means free */
|
||||
UInt16 NU;
|
||||
CPpmd7_Node_Ref Next; /* must be at offset >= 4 */
|
||||
CPpmd7_Node_Ref Prev;
|
||||
} CPpmd7_Node;
|
||||
|
||||
#ifdef PPMD_32BIT
|
||||
#define NODE(ptr) (ptr)
|
||||
#else
|
||||
#define NODE(offs) ((CPpmd7_Node *)(p->Base + (offs)))
|
||||
#endif
|
||||
|
||||
void Ppmd7_Construct(CPpmd7 *p)
|
||||
{
|
||||
unsigned i, k, m;
|
||||
|
||||
p->Base = 0;
|
||||
|
||||
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
||||
{
|
||||
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
||||
do { p->Units2Indx[k++] = (Byte)i; } while(--step);
|
||||
p->Indx2Units[i] = (Byte)k;
|
||||
}
|
||||
|
||||
p->NS2BSIndx[0] = (0 << 1);
|
||||
p->NS2BSIndx[1] = (1 << 1);
|
||||
memset(p->NS2BSIndx + 2, (2 << 1), 9);
|
||||
memset(p->NS2BSIndx + 11, (3 << 1), 256 - 11);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
p->NS2Indx[i] = (Byte)i;
|
||||
for (m = i, k = 1; i < 256; i++)
|
||||
{
|
||||
p->NS2Indx[i] = (Byte)m;
|
||||
if (--k == 0)
|
||||
k = (++m) - 2;
|
||||
}
|
||||
|
||||
memset(p->HB2Flag, 0, 0x40);
|
||||
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
|
||||
}
|
||||
|
||||
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->Base);
|
||||
p->Size = 0;
|
||||
p->Base = 0;
|
||||
}
|
||||
|
||||
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
|
||||
{
|
||||
if (p->Base == 0 || p->Size != size)
|
||||
{
|
||||
Ppmd7_Free(p, alloc);
|
||||
p->AlignOffset =
|
||||
#ifdef PPMD_32BIT
|
||||
(4 - size) & 3;
|
||||
#else
|
||||
4 - (size & 3);
|
||||
#endif
|
||||
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
|
||||
#ifndef PPMD_32BIT
|
||||
+ UNIT_SIZE
|
||||
#endif
|
||||
)) == 0)
|
||||
return False;
|
||||
p->Size = size;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
static void InsertNode(CPpmd7 *p, void *node, unsigned indx)
|
||||
{
|
||||
*((CPpmd_Void_Ref *)node) = p->FreeList[indx];
|
||||
p->FreeList[indx] = REF(node);
|
||||
}
|
||||
|
||||
static void *RemoveNode(CPpmd7 *p, unsigned indx)
|
||||
{
|
||||
CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]);
|
||||
p->FreeList[indx] = *node;
|
||||
return node;
|
||||
}
|
||||
|
||||
static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx)
|
||||
{
|
||||
unsigned i, nu = I2U(oldIndx) - I2U(newIndx);
|
||||
ptr = (Byte *)ptr + U2B(I2U(newIndx));
|
||||
if (I2U(i = U2I(nu)) != nu)
|
||||
{
|
||||
unsigned k = I2U(--i);
|
||||
InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1);
|
||||
}
|
||||
InsertNode(p, ptr, i);
|
||||
}
|
||||
|
||||
static void GlueFreeBlocks(CPpmd7 *p)
|
||||
{
|
||||
#ifdef PPMD_32BIT
|
||||
CPpmd7_Node headItem;
|
||||
CPpmd7_Node_Ref head = &headItem;
|
||||
#else
|
||||
CPpmd7_Node_Ref head = p->AlignOffset + p->Size;
|
||||
#endif
|
||||
|
||||
CPpmd7_Node_Ref n = head;
|
||||
unsigned i;
|
||||
|
||||
p->GlueCount = 255;
|
||||
|
||||
/* create doubly-linked list of free blocks */
|
||||
for (i = 0; i < PPMD_NUM_INDEXES; i++)
|
||||
{
|
||||
UInt16 nu = I2U(i);
|
||||
CPpmd7_Node_Ref next = (CPpmd7_Node_Ref)p->FreeList[i];
|
||||
p->FreeList[i] = 0;
|
||||
while (next != 0)
|
||||
{
|
||||
CPpmd7_Node *node = NODE(next);
|
||||
node->Next = n;
|
||||
n = NODE(n)->Prev = next;
|
||||
next = *(const CPpmd7_Node_Ref *)node;
|
||||
node->Stamp = 0;
|
||||
node->NU = (UInt16)nu;
|
||||
}
|
||||
}
|
||||
NODE(head)->Stamp = 1;
|
||||
NODE(head)->Next = n;
|
||||
NODE(n)->Prev = head;
|
||||
if (p->LoUnit != p->HiUnit)
|
||||
((CPpmd7_Node *)p->LoUnit)->Stamp = 1;
|
||||
|
||||
/* Glue free blocks */
|
||||
while (n != head)
|
||||
{
|
||||
CPpmd7_Node *node = NODE(n);
|
||||
UInt32 nu = (UInt32)node->NU;
|
||||
for (;;)
|
||||
{
|
||||
CPpmd7_Node *node2 = NODE(n) + nu;
|
||||
nu += node2->NU;
|
||||
if (node2->Stamp != 0 || nu >= 0x10000)
|
||||
break;
|
||||
NODE(node2->Prev)->Next = node2->Next;
|
||||
NODE(node2->Next)->Prev = node2->Prev;
|
||||
node->NU = (UInt16)nu;
|
||||
}
|
||||
n = node->Next;
|
||||
}
|
||||
|
||||
/* Fill lists of free blocks */
|
||||
for (n = NODE(head)->Next; n != head;)
|
||||
{
|
||||
CPpmd7_Node *node = NODE(n);
|
||||
unsigned nu;
|
||||
CPpmd7_Node_Ref next = node->Next;
|
||||
for (nu = node->NU; nu > 128; nu -= 128, node += 128)
|
||||
InsertNode(p, node, PPMD_NUM_INDEXES - 1);
|
||||
if (I2U(i = U2I(nu)) != nu)
|
||||
{
|
||||
unsigned k = I2U(--i);
|
||||
InsertNode(p, node + k, nu - k - 1);
|
||||
}
|
||||
InsertNode(p, node, i);
|
||||
n = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void *AllocUnitsRare(CPpmd7 *p, unsigned indx)
|
||||
{
|
||||
unsigned i;
|
||||
void *retVal;
|
||||
if (p->GlueCount == 0)
|
||||
{
|
||||
GlueFreeBlocks(p);
|
||||
if (p->FreeList[indx] != 0)
|
||||
return RemoveNode(p, indx);
|
||||
}
|
||||
i = indx;
|
||||
do
|
||||
{
|
||||
if (++i == PPMD_NUM_INDEXES)
|
||||
{
|
||||
UInt32 numBytes = U2B(I2U(indx));
|
||||
p->GlueCount--;
|
||||
return ((UInt32)(p->UnitsStart - p->Text) > numBytes) ? (p->UnitsStart -= numBytes) : (NULL);
|
||||
}
|
||||
}
|
||||
while (p->FreeList[i] == 0);
|
||||
retVal = RemoveNode(p, i);
|
||||
SplitBlock(p, retVal, i, indx);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static void *AllocUnits(CPpmd7 *p, unsigned indx)
|
||||
{
|
||||
UInt32 numBytes;
|
||||
if (p->FreeList[indx] != 0)
|
||||
return RemoveNode(p, indx);
|
||||
numBytes = U2B(I2U(indx));
|
||||
if (numBytes <= (UInt32)(p->HiUnit - p->LoUnit))
|
||||
{
|
||||
void *retVal = p->LoUnit;
|
||||
p->LoUnit += numBytes;
|
||||
return retVal;
|
||||
}
|
||||
return AllocUnitsRare(p, indx);
|
||||
}
|
||||
|
||||
#define MyMem12Cpy(dest, src, num) \
|
||||
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
|
||||
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
|
||||
|
||||
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
||||
{
|
||||
unsigned i0 = U2I(oldNU);
|
||||
unsigned i1 = U2I(newNU);
|
||||
if (i0 == i1)
|
||||
return oldPtr;
|
||||
if (p->FreeList[i1] != 0)
|
||||
{
|
||||
void *ptr = RemoveNode(p, i1);
|
||||
MyMem12Cpy(ptr, oldPtr, newNU);
|
||||
InsertNode(p, oldPtr, i0);
|
||||
return ptr;
|
||||
}
|
||||
SplitBlock(p, oldPtr, i0, i1);
|
||||
return oldPtr;
|
||||
}
|
||||
|
||||
#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
|
||||
|
||||
static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
|
||||
{
|
||||
(p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
|
||||
(p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
|
||||
}
|
||||
|
||||
static void RestartModel(CPpmd7 *p)
|
||||
{
|
||||
unsigned i, k, m;
|
||||
|
||||
memset(p->FreeList, 0, sizeof(p->FreeList));
|
||||
p->Text = p->Base + p->AlignOffset;
|
||||
p->HiUnit = p->Text + p->Size;
|
||||
p->LoUnit = p->UnitsStart = p->HiUnit - p->Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE;
|
||||
p->GlueCount = 0;
|
||||
|
||||
p->OrderFall = p->MaxOrder;
|
||||
p->RunLength = p->InitRL = -(Int32)((p->MaxOrder < 12) ? p->MaxOrder : 12) - 1;
|
||||
p->PrevSuccess = 0;
|
||||
|
||||
p->MinContext = p->MaxContext = (CTX_PTR)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */
|
||||
p->MinContext->Suffix = 0;
|
||||
p->MinContext->NumStats = 256;
|
||||
p->MinContext->SummFreq = 256 + 1;
|
||||
p->FoundState = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */
|
||||
p->LoUnit += U2B(256 / 2);
|
||||
p->MinContext->Stats = REF(p->FoundState);
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
CPpmd_State *s = &p->FoundState[i];
|
||||
s->Symbol = (Byte)i;
|
||||
s->Freq = 1;
|
||||
SetSuccessor(s, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
for (k = 0; k < 8; k++)
|
||||
{
|
||||
UInt16 *dest = p->BinSumm[i] + k;
|
||||
UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2));
|
||||
for (m = 0; m < 64; m += 8)
|
||||
dest[m] = val;
|
||||
}
|
||||
|
||||
for (i = 0; i < 25; i++)
|
||||
for (k = 0; k < 16; k++)
|
||||
{
|
||||
CPpmd_See *s = &p->See[i][k];
|
||||
s->Summ = (UInt16)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4));
|
||||
s->Count = 4;
|
||||
}
|
||||
}
|
||||
|
||||
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder)
|
||||
{
|
||||
p->MaxOrder = maxOrder;
|
||||
RestartModel(p);
|
||||
p->DummySee.Shift = PPMD_PERIOD_BITS;
|
||||
p->DummySee.Summ = 0; /* unused */
|
||||
p->DummySee.Count = 64; /* unused */
|
||||
}
|
||||
|
||||
static CTX_PTR CreateSuccessors(CPpmd7 *p, Bool skip)
|
||||
{
|
||||
CPpmd_State upState;
|
||||
CTX_PTR c = p->MinContext;
|
||||
CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState);
|
||||
CPpmd_State *ps[PPMD7_MAX_ORDER];
|
||||
unsigned numPs = 0;
|
||||
|
||||
if (!skip)
|
||||
ps[numPs++] = p->FoundState;
|
||||
|
||||
while (c->Suffix)
|
||||
{
|
||||
CPpmd_Void_Ref successor;
|
||||
CPpmd_State *s;
|
||||
c = SUFFIX(c);
|
||||
if (c->NumStats != 1)
|
||||
{
|
||||
for (s = STATS(c); s->Symbol != p->FoundState->Symbol; s++);
|
||||
}
|
||||
else
|
||||
s = ONE_STATE(c);
|
||||
successor = SUCCESSOR(s);
|
||||
if (successor != upBranch)
|
||||
{
|
||||
c = CTX(successor);
|
||||
if (numPs == 0)
|
||||
return c;
|
||||
break;
|
||||
}
|
||||
ps[numPs++] = s;
|
||||
}
|
||||
|
||||
upState.Symbol = *(const Byte *)Ppmd7_GetPtr(p, upBranch);
|
||||
SetSuccessor(&upState, upBranch + 1);
|
||||
|
||||
if (c->NumStats == 1)
|
||||
upState.Freq = ONE_STATE(c)->Freq;
|
||||
else
|
||||
{
|
||||
UInt32 cf, s0;
|
||||
CPpmd_State *s;
|
||||
for (s = STATS(c); s->Symbol != upState.Symbol; s++);
|
||||
cf = s->Freq - 1;
|
||||
s0 = c->SummFreq - c->NumStats - cf;
|
||||
upState.Freq = (Byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0) : ((2 * cf + 3 * s0 - 1) / (2 * s0))));
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* Create Child */
|
||||
CTX_PTR c1; /* = AllocContext(p); */
|
||||
if (p->HiUnit != p->LoUnit)
|
||||
c1 = (CTX_PTR)(p->HiUnit -= UNIT_SIZE);
|
||||
else if (p->FreeList[0] != 0)
|
||||
c1 = (CTX_PTR)RemoveNode(p, 0);
|
||||
else
|
||||
{
|
||||
c1 = (CTX_PTR)AllocUnitsRare(p, 0);
|
||||
if (!c1)
|
||||
return NULL;
|
||||
}
|
||||
c1->NumStats = 1;
|
||||
*ONE_STATE(c1) = upState;
|
||||
c1->Suffix = REF(c);
|
||||
SetSuccessor(ps[--numPs], REF(c1));
|
||||
c = c1;
|
||||
}
|
||||
while (numPs != 0);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static void SwapStates(CPpmd_State *t1, CPpmd_State *t2)
|
||||
{
|
||||
CPpmd_State tmp = *t1;
|
||||
*t1 = *t2;
|
||||
*t2 = tmp;
|
||||
}
|
||||
|
||||
static void UpdateModel(CPpmd7 *p)
|
||||
{
|
||||
CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p->FoundState);
|
||||
CTX_PTR c;
|
||||
unsigned s0, ns;
|
||||
|
||||
if (p->FoundState->Freq < MAX_FREQ / 4 && p->MinContext->Suffix != 0)
|
||||
{
|
||||
c = SUFFIX(p->MinContext);
|
||||
|
||||
if (c->NumStats == 1)
|
||||
{
|
||||
CPpmd_State *s = ONE_STATE(c);
|
||||
if (s->Freq < 32)
|
||||
s->Freq++;
|
||||
}
|
||||
else
|
||||
{
|
||||
CPpmd_State *s = STATS(c);
|
||||
if (s->Symbol != p->FoundState->Symbol)
|
||||
{
|
||||
do { s++; } while (s->Symbol != p->FoundState->Symbol);
|
||||
if (s[0].Freq >= s[-1].Freq)
|
||||
{
|
||||
SwapStates(&s[0], &s[-1]);
|
||||
s--;
|
||||
}
|
||||
}
|
||||
if (s->Freq < MAX_FREQ - 9)
|
||||
{
|
||||
s->Freq += 2;
|
||||
c->SummFreq += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p->OrderFall == 0)
|
||||
{
|
||||
p->MinContext = p->MaxContext = CreateSuccessors(p, True);
|
||||
if (p->MinContext == 0)
|
||||
{
|
||||
RestartModel(p);
|
||||
return;
|
||||
}
|
||||
SetSuccessor(p->FoundState, REF(p->MinContext));
|
||||
return;
|
||||
}
|
||||
|
||||
*p->Text++ = p->FoundState->Symbol;
|
||||
successor = REF(p->Text);
|
||||
if (p->Text >= p->UnitsStart)
|
||||
{
|
||||
RestartModel(p);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fSuccessor)
|
||||
{
|
||||
if (fSuccessor <= successor)
|
||||
{
|
||||
CTX_PTR cs = CreateSuccessors(p, False);
|
||||
if (cs == NULL)
|
||||
{
|
||||
RestartModel(p);
|
||||
return;
|
||||
}
|
||||
fSuccessor = REF(cs);
|
||||
}
|
||||
if (--p->OrderFall == 0)
|
||||
{
|
||||
successor = fSuccessor;
|
||||
p->Text -= (p->MaxContext != p->MinContext);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSuccessor(p->FoundState, successor);
|
||||
fSuccessor = REF(p->MinContext);
|
||||
}
|
||||
|
||||
s0 = p->MinContext->SummFreq - (ns = p->MinContext->NumStats) - (p->FoundState->Freq - 1);
|
||||
|
||||
for (c = p->MaxContext; c != p->MinContext; c = SUFFIX(c))
|
||||
{
|
||||
unsigned ns1;
|
||||
UInt32 cf, sf;
|
||||
if ((ns1 = c->NumStats) != 1)
|
||||
{
|
||||
if ((ns1 & 1) == 0)
|
||||
{
|
||||
/* Expand for one UNIT */
|
||||
unsigned oldNU = ns1 >> 1;
|
||||
unsigned i = U2I(oldNU);
|
||||
if (i != U2I(oldNU + 1))
|
||||
{
|
||||
void *ptr = AllocUnits(p, i + 1);
|
||||
void *oldPtr;
|
||||
if (!ptr)
|
||||
{
|
||||
RestartModel(p);
|
||||
return;
|
||||
}
|
||||
oldPtr = STATS(c);
|
||||
MyMem12Cpy(ptr, oldPtr, oldNU);
|
||||
InsertNode(p, oldPtr, i);
|
||||
c->Stats = STATS_REF(ptr);
|
||||
}
|
||||
}
|
||||
c->SummFreq = (UInt16)(c->SummFreq + (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & (c->SummFreq <= 8 * ns1)));
|
||||
}
|
||||
else
|
||||
{
|
||||
CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
|
||||
if (!s)
|
||||
{
|
||||
RestartModel(p);
|
||||
return;
|
||||
}
|
||||
*s = *ONE_STATE(c);
|
||||
c->Stats = REF(s);
|
||||
if (s->Freq < MAX_FREQ / 4 - 1)
|
||||
s->Freq <<= 1;
|
||||
else
|
||||
s->Freq = MAX_FREQ - 4;
|
||||
c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 3));
|
||||
}
|
||||
cf = 2 * (UInt32)p->FoundState->Freq * (c->SummFreq + 6);
|
||||
sf = (UInt32)s0 + c->SummFreq;
|
||||
if (cf < 6 * sf)
|
||||
{
|
||||
cf = 1 + (cf > sf) + (cf >= 4 * sf);
|
||||
c->SummFreq += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf);
|
||||
c->SummFreq = (UInt16)(c->SummFreq + cf);
|
||||
}
|
||||
{
|
||||
CPpmd_State *s = STATS(c) + ns1;
|
||||
SetSuccessor(s, successor);
|
||||
s->Symbol = p->FoundState->Symbol;
|
||||
s->Freq = (Byte)cf;
|
||||
c->NumStats = (UInt16)(ns1 + 1);
|
||||
}
|
||||
}
|
||||
p->MaxContext = p->MinContext = CTX(fSuccessor);
|
||||
}
|
||||
|
||||
static void Rescale(CPpmd7 *p)
|
||||
{
|
||||
unsigned i, adder, sumFreq, escFreq;
|
||||
CPpmd_State *stats = STATS(p->MinContext);
|
||||
CPpmd_State *s = p->FoundState;
|
||||
{
|
||||
CPpmd_State tmp = *s;
|
||||
for (; s != stats; s--)
|
||||
s[0] = s[-1];
|
||||
*s = tmp;
|
||||
}
|
||||
escFreq = p->MinContext->SummFreq - s->Freq;
|
||||
s->Freq += 4;
|
||||
adder = (p->OrderFall != 0);
|
||||
s->Freq = (Byte)((s->Freq + adder) >> 1);
|
||||
sumFreq = s->Freq;
|
||||
|
||||
i = p->MinContext->NumStats - 1;
|
||||
do
|
||||
{
|
||||
escFreq -= (++s)->Freq;
|
||||
s->Freq = (Byte)((s->Freq + adder) >> 1);
|
||||
sumFreq += s->Freq;
|
||||
if (s[0].Freq > s[-1].Freq)
|
||||
{
|
||||
CPpmd_State *s1 = s;
|
||||
CPpmd_State tmp = *s1;
|
||||
do
|
||||
s1[0] = s1[-1];
|
||||
while (--s1 != stats && tmp.Freq > s1[-1].Freq);
|
||||
*s1 = tmp;
|
||||
}
|
||||
}
|
||||
while (--i);
|
||||
|
||||
if (s->Freq == 0)
|
||||
{
|
||||
unsigned numStats = p->MinContext->NumStats;
|
||||
unsigned n0, n1;
|
||||
do { i++; } while ((--s)->Freq == 0);
|
||||
escFreq += i;
|
||||
p->MinContext->NumStats = (UInt16)(p->MinContext->NumStats - i);
|
||||
if (p->MinContext->NumStats == 1)
|
||||
{
|
||||
CPpmd_State tmp = *stats;
|
||||
do
|
||||
{
|
||||
tmp.Freq = (Byte)(tmp.Freq - (tmp.Freq >> 1));
|
||||
escFreq >>= 1;
|
||||
}
|
||||
while (escFreq > 1);
|
||||
InsertNode(p, stats, U2I(((numStats + 1) >> 1)));
|
||||
*(p->FoundState = ONE_STATE(p->MinContext)) = tmp;
|
||||
return;
|
||||
}
|
||||
n0 = (numStats + 1) >> 1;
|
||||
n1 = (p->MinContext->NumStats + 1) >> 1;
|
||||
if (n0 != n1)
|
||||
p->MinContext->Stats = STATS_REF(ShrinkUnits(p, stats, n0, n1));
|
||||
}
|
||||
p->MinContext->SummFreq = (UInt16)(sumFreq + escFreq - (escFreq >> 1));
|
||||
p->FoundState = STATS(p->MinContext);
|
||||
}
|
||||
|
||||
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
|
||||
{
|
||||
CPpmd_See *see;
|
||||
unsigned nonMasked = p->MinContext->NumStats - numMasked;
|
||||
if (p->MinContext->NumStats != 256)
|
||||
{
|
||||
see = p->See[p->NS2Indx[nonMasked - 1]] +
|
||||
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
|
||||
2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
|
||||
4 * (numMasked > nonMasked) +
|
||||
p->HiBitsFlag;
|
||||
{
|
||||
unsigned r = (see->Summ >> see->Shift);
|
||||
see->Summ = (UInt16)(see->Summ - r);
|
||||
*escFreq = r + (r == 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
see = &p->DummySee;
|
||||
*escFreq = 1;
|
||||
}
|
||||
return see;
|
||||
}
|
||||
|
||||
static void NextContext(CPpmd7 *p)
|
||||
{
|
||||
CTX_PTR c = CTX(SUCCESSOR(p->FoundState));
|
||||
if (p->OrderFall == 0 && (Byte *)c > p->Text)
|
||||
p->MinContext = p->MaxContext = c;
|
||||
else
|
||||
UpdateModel(p);
|
||||
}
|
||||
|
||||
void Ppmd7_Update1(CPpmd7 *p)
|
||||
{
|
||||
CPpmd_State *s = p->FoundState;
|
||||
s->Freq += 4;
|
||||
p->MinContext->SummFreq += 4;
|
||||
if (s[0].Freq > s[-1].Freq)
|
||||
{
|
||||
SwapStates(&s[0], &s[-1]);
|
||||
p->FoundState = --s;
|
||||
if (s->Freq > MAX_FREQ)
|
||||
Rescale(p);
|
||||
}
|
||||
NextContext(p);
|
||||
}
|
||||
|
||||
void Ppmd7_Update1_0(CPpmd7 *p)
|
||||
{
|
||||
p->PrevSuccess = (2 * p->FoundState->Freq > p->MinContext->SummFreq);
|
||||
p->RunLength += p->PrevSuccess;
|
||||
p->MinContext->SummFreq += 4;
|
||||
if ((p->FoundState->Freq += 4) > MAX_FREQ)
|
||||
Rescale(p);
|
||||
NextContext(p);
|
||||
}
|
||||
|
||||
void Ppmd7_UpdateBin(CPpmd7 *p)
|
||||
{
|
||||
p->FoundState->Freq = (Byte)(p->FoundState->Freq + (p->FoundState->Freq < 128 ? 1: 0));
|
||||
p->PrevSuccess = 1;
|
||||
p->RunLength++;
|
||||
NextContext(p);
|
||||
}
|
||||
|
||||
void Ppmd7_Update2(CPpmd7 *p)
|
||||
{
|
||||
p->MinContext->SummFreq += 4;
|
||||
if ((p->FoundState->Freq += 4) > MAX_FREQ)
|
||||
Rescale(p);
|
||||
p->RunLength = p->InitRL;
|
||||
UpdateModel(p);
|
||||
}
|
||||
140
References/VirtuaNESex_src_191105/7z/Ppmd7.h
Normal file
140
References/VirtuaNESex_src_191105/7z/Ppmd7.h
Normal file
@ -0,0 +1,140 @@
|
||||
/* Ppmd7.h -- PPMdH compression codec
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
/* This code supports virtual RangeDecoder and includes the implementation
|
||||
of RangeCoder from 7z, instead of RangeCoder from original PPMd var.H.
|
||||
If you need the compatibility with original PPMd var.H, you can use external RangeDecoder */
|
||||
|
||||
#ifndef __PPMD7_H
|
||||
#define __PPMD7_H
|
||||
|
||||
#include "Ppmd.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define PPMD7_MIN_ORDER 2
|
||||
#define PPMD7_MAX_ORDER 64
|
||||
|
||||
#define PPMD7_MIN_MEM_SIZE (1 << 11)
|
||||
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
|
||||
|
||||
struct CPpmd7_Context_;
|
||||
|
||||
typedef
|
||||
#ifdef PPMD_32BIT
|
||||
struct CPpmd7_Context_ *
|
||||
#else
|
||||
UInt32
|
||||
#endif
|
||||
CPpmd7_Context_Ref;
|
||||
|
||||
typedef struct CPpmd7_Context_
|
||||
{
|
||||
UInt16 NumStats;
|
||||
UInt16 SummFreq;
|
||||
CPpmd_State_Ref Stats;
|
||||
CPpmd7_Context_Ref Suffix;
|
||||
} CPpmd7_Context;
|
||||
|
||||
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CPpmd7_Context *MinContext, *MaxContext;
|
||||
CPpmd_State *FoundState;
|
||||
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
|
||||
Int32 RunLength, InitRL; /* must be 32-bit at least */
|
||||
|
||||
UInt32 Size;
|
||||
UInt32 GlueCount;
|
||||
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
|
||||
UInt32 AlignOffset;
|
||||
|
||||
Byte Indx2Units[PPMD_NUM_INDEXES];
|
||||
Byte Units2Indx[128];
|
||||
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
|
||||
Byte NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||
CPpmd_See DummySee, See[25][16];
|
||||
UInt16 BinSumm[128][64];
|
||||
} CPpmd7;
|
||||
|
||||
void Ppmd7_Construct(CPpmd7 *p);
|
||||
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
|
||||
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
|
||||
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
|
||||
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||
|
||||
|
||||
/* ---------- Internal Functions ---------- */
|
||||
|
||||
extern const Byte PPMD7_kExpEscape[16];
|
||||
|
||||
#ifdef PPMD_32BIT
|
||||
#define Ppmd7_GetPtr(p, ptr) (ptr)
|
||||
#define Ppmd7_GetContext(p, ptr) (ptr)
|
||||
#define Ppmd7_GetStats(p, ctx) ((ctx)->Stats)
|
||||
#else
|
||||
#define Ppmd7_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
|
||||
#define Ppmd7_GetContext(p, offs) ((CPpmd7_Context *)Ppmd7_GetPtr((p), (offs)))
|
||||
#define Ppmd7_GetStats(p, ctx) ((CPpmd_State *)Ppmd7_GetPtr((p), ((ctx)->Stats)))
|
||||
#endif
|
||||
|
||||
void Ppmd7_Update1(CPpmd7 *p);
|
||||
void Ppmd7_Update1_0(CPpmd7 *p);
|
||||
void Ppmd7_Update2(CPpmd7 *p);
|
||||
void Ppmd7_UpdateBin(CPpmd7 *p);
|
||||
|
||||
#define Ppmd7_GetBinSumm(p) \
|
||||
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
|
||||
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
|
||||
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
|
||||
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
|
||||
((p->RunLength >> 26) & 0x20)]
|
||||
|
||||
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
||||
|
||||
|
||||
/* ---------- Decode ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 (*GetThreshold)(void *p, UInt32 total);
|
||||
void (*Decode)(void *p, UInt32 start, UInt32 size);
|
||||
UInt32 (*DecodeBit)(void *p, UInt32 size0);
|
||||
} IPpmd7_RangeDec;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IPpmd7_RangeDec p;
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
IByteIn *Stream;
|
||||
} CPpmd7z_RangeDec;
|
||||
|
||||
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
|
||||
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
|
||||
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||||
|
||||
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
|
||||
|
||||
|
||||
/* ---------- Encode ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt64 Low;
|
||||
UInt32 Range;
|
||||
Byte Cache;
|
||||
UInt64 CacheSize;
|
||||
IByteOut *Stream;
|
||||
} CPpmd7z_RangeEnc;
|
||||
|
||||
void Ppmd7z_RangeEnc_Init(CPpmd7z_RangeEnc *p);
|
||||
void Ppmd7z_RangeEnc_FlushData(CPpmd7z_RangeEnc *p);
|
||||
|
||||
void Ppmd7_EncodeSymbol(CPpmd7 *p, CPpmd7z_RangeEnc *rc, int symbol);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
187
References/VirtuaNESex_src_191105/7z/Ppmd7Dec.c
Normal file
187
References/VirtuaNESex_src_191105/7z/Ppmd7Dec.c
Normal file
@ -0,0 +1,187 @@
|
||||
/* Ppmd7Dec.c -- PPMdH Decoder
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include "Ppmd7.h"
|
||||
|
||||
#define kTopValue (1 << 24)
|
||||
|
||||
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
|
||||
{
|
||||
unsigned i;
|
||||
p->Code = 0;
|
||||
p->Range = 0xFFFFFFFF;
|
||||
if (p->Stream->Read((void *)p->Stream) != 0)
|
||||
return False;
|
||||
for (i = 0; i < 4; i++)
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
return (p->Code < 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static UInt32 Range_GetThreshold(void *pp, UInt32 total)
|
||||
{
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
return (p->Code) / (p->Range /= total);
|
||||
}
|
||||
|
||||
static void Range_Normalize(CPpmd7z_RangeDec *p)
|
||||
{
|
||||
if (p->Range < kTopValue)
|
||||
{
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
p->Range <<= 8;
|
||||
if (p->Range < kTopValue)
|
||||
{
|
||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
||||
p->Range <<= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Range_Decode(void *pp, UInt32 start, UInt32 size)
|
||||
{
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
p->Code -= start * p->Range;
|
||||
p->Range *= size;
|
||||
Range_Normalize(p);
|
||||
}
|
||||
|
||||
static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
|
||||
{
|
||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
||||
UInt32 newBound = (p->Range >> 14) * size0;
|
||||
UInt32 symbol;
|
||||
if (p->Code < newBound)
|
||||
{
|
||||
symbol = 0;
|
||||
p->Range = newBound;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol = 1;
|
||||
p->Code -= newBound;
|
||||
p->Range -= newBound;
|
||||
}
|
||||
Range_Normalize(p);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
|
||||
{
|
||||
p->p.GetThreshold = Range_GetThreshold;
|
||||
p->p.Decode = Range_Decode;
|
||||
p->p.DecodeBit = Range_DecodeBit;
|
||||
}
|
||||
|
||||
|
||||
#define MASK(sym) ((signed char *)charMask)[sym]
|
||||
|
||||
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
|
||||
{
|
||||
size_t charMask[256 / sizeof(size_t)];
|
||||
if (p->MinContext->NumStats != 1)
|
||||
{
|
||||
CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext);
|
||||
unsigned i;
|
||||
UInt32 count, hiCnt;
|
||||
if ((count = rc->GetThreshold(rc, p->MinContext->SummFreq)) < (hiCnt = s->Freq))
|
||||
{
|
||||
Byte symbol;
|
||||
rc->Decode(rc, 0, s->Freq);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update1_0(p);
|
||||
return symbol;
|
||||
}
|
||||
p->PrevSuccess = 0;
|
||||
i = p->MinContext->NumStats - 1;
|
||||
do
|
||||
{
|
||||
if ((hiCnt += (++s)->Freq) > count)
|
||||
{
|
||||
Byte symbol;
|
||||
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update1(p);
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
while (--i);
|
||||
if (count >= p->MinContext->SummFreq)
|
||||
return -2;
|
||||
p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol];
|
||||
rc->Decode(rc, hiCnt, p->MinContext->SummFreq - hiCnt);
|
||||
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||
MASK(s->Symbol) = 0;
|
||||
i = p->MinContext->NumStats - 1;
|
||||
do { MASK((--s)->Symbol) = 0; } while (--i);
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt16 *prob = Ppmd7_GetBinSumm(p);
|
||||
if (rc->DecodeBit(rc, *prob) == 0)
|
||||
{
|
||||
Byte symbol;
|
||||
*prob = (UInt16)PPMD_UPDATE_PROB_0(*prob);
|
||||
symbol = (p->FoundState = Ppmd7Context_OneState(p->MinContext))->Symbol;
|
||||
Ppmd7_UpdateBin(p);
|
||||
return symbol;
|
||||
}
|
||||
*prob = (UInt16)PPMD_UPDATE_PROB_1(*prob);
|
||||
p->InitEsc = PPMD7_kExpEscape[*prob >> 10];
|
||||
PPMD_SetAllBitsIn256Bytes(charMask);
|
||||
MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0;
|
||||
p->PrevSuccess = 0;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
CPpmd_State *ps[256], *s;
|
||||
UInt32 freqSum, count, hiCnt;
|
||||
CPpmd_See *see;
|
||||
unsigned i, num, numMasked = p->MinContext->NumStats;
|
||||
do
|
||||
{
|
||||
p->OrderFall++;
|
||||
if (!p->MinContext->Suffix)
|
||||
return -1;
|
||||
p->MinContext = Ppmd7_GetContext(p, p->MinContext->Suffix);
|
||||
}
|
||||
while (p->MinContext->NumStats == numMasked);
|
||||
hiCnt = 0;
|
||||
s = Ppmd7_GetStats(p, p->MinContext);
|
||||
i = 0;
|
||||
num = p->MinContext->NumStats - numMasked;
|
||||
do
|
||||
{
|
||||
int k = (int)(MASK(s->Symbol));
|
||||
hiCnt += (s->Freq & k);
|
||||
ps[i] = s++;
|
||||
i -= k;
|
||||
}
|
||||
while (i != num);
|
||||
|
||||
see = Ppmd7_MakeEscFreq(p, numMasked, &freqSum);
|
||||
freqSum += hiCnt;
|
||||
count = rc->GetThreshold(rc, freqSum);
|
||||
|
||||
if (count < hiCnt)
|
||||
{
|
||||
Byte symbol;
|
||||
CPpmd_State **pps = ps;
|
||||
for (hiCnt = 0; (hiCnt += (*pps)->Freq) <= count; pps++);
|
||||
s = *pps;
|
||||
rc->Decode(rc, hiCnt - s->Freq, s->Freq);
|
||||
Ppmd_See_Update(see);
|
||||
p->FoundState = s;
|
||||
symbol = s->Symbol;
|
||||
Ppmd7_Update2(p);
|
||||
return symbol;
|
||||
}
|
||||
if (count >= freqSum)
|
||||
return -2;
|
||||
rc->Decode(rc, hiCnt, freqSum - hiCnt);
|
||||
see->Summ = (UInt16)(see->Summ + freqSum);
|
||||
do { MASK(ps[--i]->Symbol) = 0; } while (i != 0);
|
||||
}
|
||||
}
|
||||
254
References/VirtuaNESex_src_191105/7z/Types.h
Normal file
254
References/VirtuaNESex_src_191105/7z/Types.h
Normal file
@ -0,0 +1,254 @@
|
||||
/* Types.h -- Basic types
|
||||
2010-10-09 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef EXTERN_C_BEGIN
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C_BEGIN extern "C" {
|
||||
#define EXTERN_C_END }
|
||||
#else
|
||||
#define EXTERN_C_BEGIN
|
||||
#define EXTERN_C_END
|
||||
#endif
|
||||
#endif
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define SZ_OK 0
|
||||
|
||||
#define SZ_ERROR_DATA 1
|
||||
#define SZ_ERROR_MEM 2
|
||||
#define SZ_ERROR_CRC 3
|
||||
#define SZ_ERROR_UNSUPPORTED 4
|
||||
#define SZ_ERROR_PARAM 5
|
||||
#define SZ_ERROR_INPUT_EOF 6
|
||||
#define SZ_ERROR_OUTPUT_EOF 7
|
||||
#define SZ_ERROR_READ 8
|
||||
#define SZ_ERROR_WRITE 9
|
||||
#define SZ_ERROR_PROGRESS 10
|
||||
#define SZ_ERROR_FAIL 11
|
||||
#define SZ_ERROR_THREAD 12
|
||||
|
||||
#define SZ_ERROR_ARCHIVE 16
|
||||
#define SZ_ERROR_NO_ARCHIVE 17
|
||||
|
||||
typedef int SRes;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef DWORD WRes;
|
||||
#else
|
||||
typedef int WRes;
|
||||
#endif
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#ifdef _LZMA_UINT32_IS_ULONG
|
||||
typedef long Int32;
|
||||
typedef unsigned long UInt32;
|
||||
#else
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
|
||||
#ifdef _SZ_NO_INT_64
|
||||
|
||||
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||
NOTES: Some code will work incorrectly in that case! */
|
||||
|
||||
typedef long Int64;
|
||||
typedef unsigned long UInt64;
|
||||
|
||||
#else
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#define UINT64_CONST(n) n
|
||||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#define UINT64_CONST(n) n ## ULL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||
typedef UInt32 SizeT;
|
||||
#else
|
||||
typedef size_t SizeT;
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define MY_STD_CALL __stdcall
|
||||
#else
|
||||
#define MY_STD_CALL
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define MY_NO_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define MY_NO_INLINE
|
||||
#endif
|
||||
|
||||
#define MY_CDECL __cdecl
|
||||
#define MY_FAST_CALL __fastcall
|
||||
|
||||
#else
|
||||
|
||||
#define MY_CDECL
|
||||
#define MY_FAST_CALL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||
} IByteIn;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*Write)(void *p, Byte b);
|
||||
} IByteOut;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
} ISeqInStream;
|
||||
|
||||
/* it can return SZ_ERROR_INPUT_EOF */
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||
/* Returns: result - the number of actually written bytes.
|
||||
(result < size) means error */
|
||||
} ISeqOutStream;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SZ_SEEK_SET = 0,
|
||||
SZ_SEEK_CUR = 1,
|
||||
SZ_SEEK_END = 2
|
||||
} ESzSeek;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ISeekInStream;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Look)(void *p, const void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
SRes (*Skip)(void *p, size_t offset);
|
||||
/* offset must be <= output(*size) of Look */
|
||||
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ILookInStream;
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
||||
|
||||
/* reads via ILookInStream::Read */
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
||||
|
||||
#define LookToRead_BUF_SIZE (1 << 14)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ILookInStream s;
|
||||
ISeekInStream *realStream;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
Byte buf[LookToRead_BUF_SIZE];
|
||||
} CLookToRead;
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||
void LookToRead_Init(CLookToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToLook;
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToRead;
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||
/* Returns: result. (result != SZ_OK) means break.
|
||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||
} ICompressProgress;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
} ISzAlloc;
|
||||
|
||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define CHAR_PATH_SEPARATOR '\\'
|
||||
#define WCHAR_PATH_SEPARATOR L'\\'
|
||||
#define STRING_PATH_SEPARATOR "\\"
|
||||
#define WSTRING_PATH_SEPARATOR L"\\"
|
||||
|
||||
#else
|
||||
|
||||
#define CHAR_PATH_SEPARATOR '/'
|
||||
#define WCHAR_PATH_SEPARATOR L'/'
|
||||
#define STRING_PATH_SEPARATOR "/"
|
||||
#define WSTRING_PATH_SEPARATOR L"/"
|
||||
|
||||
#endif
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
106
References/VirtuaNESex_src_191105/AboutDlg.cpp
Normal file
106
References/VirtuaNESex_src_191105/AboutDlg.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
//
|
||||
// 僶乕僕儑儞僟僀傾儘僌僋儔僗
|
||||
//
|
||||
//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "VirtuaNESres.h"
|
||||
#include "DebugOut.h"
|
||||
#include "App.h"
|
||||
#include "Pathlib.h"
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "AboutDlg.h"
|
||||
|
||||
DLG_MESSAGE_BEGIN(CAboutDlg)
|
||||
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
|
||||
|
||||
DLG_COMMAND_BEGIN()
|
||||
DLG_ON_COMMAND( IDOK, OnOK )
|
||||
DLG_ON_COMMAND( IDCANCEL, OnCancel )
|
||||
DLG_ON_COMMAND( IDC_VER_WEBSITE, OnWebsite )
|
||||
DLG_COMMAND_END()
|
||||
DLG_MESSAGE_END()
|
||||
|
||||
INT CAboutDlg::DoModal( HWND hWndParent )
|
||||
{
|
||||
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_VERSION),
|
||||
hWndParent, g_DlgProc, (LPARAM)this );
|
||||
}
|
||||
|
||||
DLGMSG CAboutDlg::OnInitDialog( DLGMSGPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CAboutDlg::OnInitDialog\n" );
|
||||
|
||||
::SendDlgItemMessage( m_hWnd, IDC_VER_ICON, STM_SETICON,
|
||||
(WPARAM)CApp::LoadIcon( IDI_ICON ), 0 );
|
||||
|
||||
TCHAR str[256];
|
||||
|
||||
::wsprintf( str, "VirtuaNESex version %01d.%01d%01d%s",
|
||||
(VIRTUANES_VERSION&0xF00)>>8,
|
||||
(VIRTUANES_VERSION&0x0F0)>>4,
|
||||
(VIRTUANES_VERSION&0x00F),
|
||||
VIRTUANES_FIXVERSION );
|
||||
|
||||
::SetDlgItemText( m_hWnd, IDC_VER_VERSION, str );
|
||||
|
||||
::wsprintf( str,
|
||||
"编译时间:\r\n\
|
||||
%s %s\r\n\r\n\
|
||||
代码贡献者:\r\n\
|
||||
tpu \r\n\
|
||||
temryu \r\n\
|
||||
byemu \r\n\
|
||||
叶枫 \r\n\
|
||||
心傷誰知",
|
||||
__DATE__,__TIME__);
|
||||
::SetDlgItemText( m_hWnd, IDC_VER_CONTRIBUTOR, str );
|
||||
|
||||
// ::SetDlgItemText( m_hWnd, IDC_VER_WEBSITE, VIRTUANES_WEBSITE );
|
||||
|
||||
m_Website.Attach( ::GetDlgItem( m_hWnd, IDC_VER_WEBSITE ), VIRTUANES_WEBSITE );
|
||||
|
||||
string email, mailto;
|
||||
email = VIRTUANES_EMAILNAME;
|
||||
email += "@";
|
||||
email += VIRTUANES_EMAILDOMAIN;
|
||||
mailto = "mailto:" + email;
|
||||
|
||||
m_Email.Attach( ::GetDlgItem( m_hWnd, IDC_VER_EMAIL ), email.c_str(), mailto.c_str() );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGCMD CAboutDlg::OnOK( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CAboutDlg::OnOK\n" );
|
||||
|
||||
// m_Website.Detach();
|
||||
// m_Email.Detach();
|
||||
|
||||
::EndDialog( m_hWnd, IDOK );
|
||||
}
|
||||
|
||||
DLGCMD CAboutDlg::OnCancel( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CAboutDlg::OnCancel\n" );
|
||||
|
||||
// m_Website.Detach();
|
||||
// m_Email.Detach();
|
||||
|
||||
::EndDialog( m_hWnd, IDCANCEL );
|
||||
}
|
||||
|
||||
DLGCMD CAboutDlg::OnWebsite( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CAboutDlg::OnCancel\n" );
|
||||
|
||||
::ShellExecute( HWND_DESKTOP, "open", VIRTUANES_WEBSITE, NULL, NULL, SW_SHOWNORMAL );
|
||||
// ::ShellExecute( m_hWnd, "open", VIRTUANES_WEBSITE, NULL, NULL, SW_SHOWNORMAL );
|
||||
}
|
||||
|
||||
36
References/VirtuaNESex_src_191105/AboutDlg.h
Normal file
36
References/VirtuaNESex_src_191105/AboutDlg.h
Normal file
@ -0,0 +1,36 @@
|
||||
//
|
||||
// バージョンダイアログクラス
|
||||
//
|
||||
#ifndef __CABOUTDLG_INCLUDED__
|
||||
#define __CABOUTDLG_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "CHyperLink.h"
|
||||
|
||||
class CAboutDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
// Override from CWnd
|
||||
INT DoModal( HWND hWndParent );
|
||||
|
||||
protected:
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGCMD OnOK( DLGCMDPARAM );
|
||||
DLGCMD OnCancel( DLGCMDPARAM );
|
||||
DLGCMD OnWebsite( DLGCMDPARAM );
|
||||
//
|
||||
|
||||
CHyperLink m_Website;
|
||||
CHyperLink m_Email;
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // !__CABOUTDLG_INCLUDED__
|
||||
|
||||
81
References/VirtuaNESex_src_191105/App.cpp
Normal file
81
References/VirtuaNESex_src_191105/App.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
//
|
||||
// アプリケーションサポートクラス
|
||||
//
|
||||
#include "VirtuaNESres.h"
|
||||
#include "App.h"
|
||||
|
||||
// _tWinMainからの引数そのまま
|
||||
HINSTANCE CApp::m_hInstance = NULL;
|
||||
HINSTANCE CApp::m_hPrevInstance = NULL;
|
||||
LPTSTR CApp::m_lpCmdLine = NULL;
|
||||
INT CApp::m_nCmdShow = 0;
|
||||
|
||||
// 言語リソースプラグインのインスタンスハンドル
|
||||
HINSTANCE CApp::m_hPlugin = NULL;
|
||||
// メインウインドウのウインドウハンドル
|
||||
HWND CApp::m_hWnd = NULL;
|
||||
// メインウインドウのメニューハンドル
|
||||
HMENU CApp::m_hMenu = NULL;
|
||||
|
||||
// プログラムのパス(起動時のパス)
|
||||
CHAR CApp::m_szModulePath[_MAX_PATH];
|
||||
|
||||
// エラーストリング(テンポラリ)
|
||||
CHAR szErrorString[256];
|
||||
|
||||
// エラー処理用
|
||||
INT CApp::m_ErrorStringTableID[] = {
|
||||
IDS_ERROR,
|
||||
IDS_ERROR_STARTUP,
|
||||
IDS_ERROR_UNKNOWN,
|
||||
IDS_ERROR_OPEN,
|
||||
IDS_ERROR_READ,
|
||||
IDS_ERROR_WRITE,
|
||||
IDS_ERROR_OUTOFMEMORY,
|
||||
|
||||
IDS_ERROR_ILLEGALOPCODE,
|
||||
IDS_ERROR_UNSUPPORTFORMAT,
|
||||
IDS_ERROR_INVALIDNESHEADER,
|
||||
IDS_ERROR_SMALLFILE,
|
||||
IDS_ERROR_UNSUPPORTMAPPER,
|
||||
IDS_ERROR_NODISKBIOS,
|
||||
IDS_ERROR_UNSUPPORTDISK,
|
||||
IDS_ERROR_ILLEGALDISKSIZE,
|
||||
|
||||
IDS_ERROR_ILLEGALMAPPERNO,
|
||||
IDS_ERROR_ILLEGALHEADER,
|
||||
|
||||
IDS_ERROR_ILLEGALSTATECRC,
|
||||
IDS_ERROR_ILLEGALMOVIEOLD,
|
||||
IDS_ERROR_ILLEGALMOVIEVER,
|
||||
IDS_ERROR_ILLEGALMOVIECRC,
|
||||
IDS_ERROR_ILLEGALMOVIEOLD_A,
|
||||
IDS_ERROR_ILLEGALMOVIEVER_A,
|
||||
IDS_ERROR_ILLEGALMOVIECRC_A,
|
||||
|
||||
IDS_ERROR_NETWORKDISCONNECT,
|
||||
IDS_ERROR_NETWORKERROR,
|
||||
0,
|
||||
};
|
||||
|
||||
CHAR CApp::m_ErrorString[ERRORSTRING_MAX][256];
|
||||
|
||||
void CApp::LoadErrorString()
|
||||
{
|
||||
if( !m_hPlugin )
|
||||
return;
|
||||
|
||||
for( INT i = 0; m_ErrorStringTableID[i]; i++ ) {
|
||||
LoadString( m_ErrorStringTableID[i], m_ErrorString[i], sizeof(m_ErrorString[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
CHAR* CApp::GetErrorString( INT nID )
|
||||
{
|
||||
for( INT i = 0; m_ErrorStringTableID[i]; i++ ) {
|
||||
if( m_ErrorStringTableID[i] == nID )
|
||||
return m_ErrorString[i];
|
||||
}
|
||||
return ""; // NULL ストリングとして渡す
|
||||
}
|
||||
|
||||
76
References/VirtuaNESex_src_191105/App.h
Normal file
76
References/VirtuaNESex_src_191105/App.h
Normal file
@ -0,0 +1,76 @@
|
||||
//
|
||||
// アプリケーションサポートクラス
|
||||
//
|
||||
|
||||
#ifndef __CAPP_INCLUDED__
|
||||
#define __CAPP_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ERRORSTRING_MAX 32
|
||||
|
||||
class CApp {
|
||||
public:
|
||||
// 起動時に設定する
|
||||
static void SetInstance( HINSTANCE hInstance ) { m_hInstance = hInstance; }
|
||||
static void SetPrevInstance( HINSTANCE hInstance ) { m_hPrevInstance = hInstance; }
|
||||
static void SetCmdLine( LPSTR lpCmdLine ) { m_lpCmdLine = lpCmdLine; }
|
||||
static void SetCmdShow( INT nCmdShow ) { m_nCmdShow = nCmdShow; }
|
||||
|
||||
static void SetHWnd( HWND hWnd ) { m_hWnd = hWnd; }
|
||||
static void SetMenu( HMENU hMenu ) { m_hMenu = hMenu; }
|
||||
static void SetPlugin( HINSTANCE hPlugin ) { m_hPlugin = hPlugin; LoadErrorString(); }
|
||||
|
||||
static void SetModulePath( LPCSTR lpModulePath ) { ::strcpy( m_szModulePath, lpModulePath ); }
|
||||
|
||||
// アプリ内部で使用する
|
||||
static HINSTANCE GetInstance() { return m_hInstance; }
|
||||
static HINSTANCE GetPrevInstance() { return m_hPrevInstance; }
|
||||
static LPTSTR GetCmdLine() { return m_lpCmdLine; }
|
||||
static INT GetCmdShow() { return m_nCmdShow; }
|
||||
|
||||
static HWND GetHWnd() { return m_hWnd; }
|
||||
static HMENU GetMenu() { return m_hMenu; }
|
||||
static HINSTANCE GetPlugin() { return m_hPlugin; }
|
||||
|
||||
static LPCSTR GetModulePath() { return m_szModulePath; }
|
||||
|
||||
static HMENU LoadMenu( UINT uID ) { return ::LoadMenu( m_hPlugin, MAKEINTRESOURCE(uID) ); }
|
||||
static HICON LoadIcon( UINT uID ) { return ::LoadIcon( m_hInstance, MAKEINTRESOURCE(uID) ); }
|
||||
static INT LoadString( UINT uID, LPTSTR lpBuffer, INT nBufferMax ) {
|
||||
return ::LoadString( m_hPlugin, uID, lpBuffer, nBufferMax ); }
|
||||
|
||||
// エラー処理用
|
||||
static void LoadErrorString();
|
||||
static CHAR* GetErrorString( INT nID );
|
||||
|
||||
protected:
|
||||
// WinMain からの引数そのまま
|
||||
static HINSTANCE m_hInstance;
|
||||
static HINSTANCE m_hPrevInstance;
|
||||
static LPSTR m_lpCmdLine;
|
||||
static INT m_nCmdShow;
|
||||
|
||||
// 言語リソースプラグインのインスタンスハンドル
|
||||
static HINSTANCE m_hPlugin;
|
||||
// メインウインドウのウインドウハンドル
|
||||
static HWND m_hWnd;
|
||||
// メインウインドウのメニューハンドル
|
||||
static HMENU m_hMenu;
|
||||
|
||||
// プログラムのパス(起動時のパス)
|
||||
static CHAR m_szModulePath[_MAX_PATH];
|
||||
|
||||
// エラー処理用
|
||||
static INT m_ErrorStringTableID[ERRORSTRING_MAX];
|
||||
static CHAR m_ErrorString[ERRORSTRING_MAX][256];
|
||||
private:
|
||||
};
|
||||
|
||||
// エラーメッセージ用テンポラリ
|
||||
extern CHAR szErrorString[256];
|
||||
|
||||
#endif // !__CAPP_INCLUDED__
|
||||
332
References/VirtuaNESex_src_191105/Archive.cpp
Normal file
332
References/VirtuaNESex_src_191105/Archive.cpp
Normal file
@ -0,0 +1,332 @@
|
||||
//
|
||||
// アーカイブファイル操作
|
||||
//
|
||||
// Original:NesterJ arc.cpp arc.h by Mikami Kana
|
||||
// Original:NNNesterJ ulunzip.cpp
|
||||
//
|
||||
// Zlib use!
|
||||
// Reprogrammed by Norix
|
||||
//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mbstring.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "typedef.h"
|
||||
#include "macro.h"
|
||||
#include "DebugOut.h"
|
||||
|
||||
#include "App.h"
|
||||
#include "Pathlib.h"
|
||||
|
||||
#include "VirtuaNESres.h"
|
||||
|
||||
#define UNZ_BUFSIZE (65536)
|
||||
|
||||
#include "unzip.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
int SevenZipUnCompress( char *fname, unsigned char ** ppBuf,size_t * lpdwSize);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
#define FNAME_MAX32 512
|
||||
|
||||
typedef struct {
|
||||
DWORD dwOriginalSize;
|
||||
DWORD dwCompressedSize;
|
||||
DWORD dwCRC;
|
||||
UINT uFlag;
|
||||
UINT uOSType;
|
||||
WORD wRatio;
|
||||
WORD wDate;
|
||||
WORD wTime;
|
||||
char szFileName[FNAME_MAX32 + 1];
|
||||
char dummy1[3];
|
||||
char szAttribute[8];
|
||||
char szMode[8];
|
||||
} INDIVIDUALINFO, *LPINDIVIDUALINFO;
|
||||
#pragma pack()
|
||||
|
||||
// Un??? use function
|
||||
typedef int(WINAPI *EXECUTECOMMAND)(HWND,LPCSTR,LPSTR,const DWORD);
|
||||
typedef BOOL(WINAPI *CHECKARCHIVE)(LPCSTR,const int);
|
||||
typedef int(WINAPI *EXTRACTMEM)(HWND,LPCSTR,LPBYTE,const DWORD,time_t,LPWORD,LPDWORD);
|
||||
typedef HGLOBAL(WINAPI *OPENARCHIVE)(HWND,LPCSTR,const DWORD);
|
||||
typedef int(WINAPI *CLOSEARCHIVE)(HGLOBAL);
|
||||
typedef int(WINAPI *FINDFIRST)(HGLOBAL,LPCSTR,INDIVIDUALINFO*);
|
||||
|
||||
static LPCSTR pszArchiver[] = {
|
||||
"UNLHA32",
|
||||
"UNZIP32",
|
||||
"UNRAR32",
|
||||
"CAB32",
|
||||
NULL
|
||||
};
|
||||
|
||||
static LPCSTR pszFuncPrefix[] = {
|
||||
"Unlha",
|
||||
"UnZip",
|
||||
"Unrar",
|
||||
"Cab",
|
||||
};
|
||||
|
||||
static LPCSTR pszCommand[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
"-e -u \"%s\" \"%s\" \"%s\"",
|
||||
"-x -j \"%s\" \"%s\" \"%s\"",
|
||||
};
|
||||
|
||||
static LPCSTR pszExtension[] = {
|
||||
"*.nes",
|
||||
"*.fds",
|
||||
"*.nsf",
|
||||
NULL
|
||||
};
|
||||
|
||||
static BOOL bFileMatching[] = {
|
||||
FALSE,
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
};
|
||||
|
||||
#define FREEDLL(h) if( h ) { FreeLibrary(h);h=NULL; }
|
||||
|
||||
#define M_ERROR_MESSAGE_OFF 0x00800000L
|
||||
|
||||
// zlibを使用したZIP解凍ルーチン
|
||||
BOOL ZlibUnZip( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize )
|
||||
{
|
||||
unzFile unzipFile = NULL;
|
||||
unz_global_info unzipGlobalInfo;
|
||||
unz_file_info unzipFileInfo;
|
||||
char fname_buf[256];
|
||||
|
||||
*ppBuf = NULL;
|
||||
*lpdwSize = 0;
|
||||
|
||||
if( !(unzipFile = unzOpen( (const char*)fname )) )
|
||||
return FALSE;
|
||||
|
||||
if( unzGetGlobalInfo( unzipFile, &unzipGlobalInfo ) != UNZ_OK ) {
|
||||
unzClose( unzipFile );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for( uLong i = 0; i < unzipGlobalInfo.number_entry; i++ ) {
|
||||
if( unzGetCurrentFileInfo( unzipFile, &unzipFileInfo, fname_buf, sizeof(fname_buf), NULL, 0, NULL, 0 ) != UNZ_OK )
|
||||
break;
|
||||
|
||||
char* pExt = ::PathFindExtension( fname_buf );
|
||||
if( _stricmp( pExt, ".nes" ) == 0 || _stricmp( pExt, ".fds" ) == 0 || _stricmp( pExt, ".nsf" ) == 0 ) {
|
||||
if( unzipFileInfo.uncompressed_size ) {
|
||||
if( unzOpenCurrentFile( unzipFile ) != UNZ_OK )
|
||||
break;
|
||||
|
||||
if( unzipFileInfo.uncompressed_size > 0 ) {
|
||||
if( !(*ppBuf = (LPBYTE)::malloc( unzipFileInfo.uncompressed_size )) )
|
||||
break;
|
||||
|
||||
uInt size = unzReadCurrentFile( unzipFile, *ppBuf, unzipFileInfo.uncompressed_size );
|
||||
if( size != unzipFileInfo.uncompressed_size )
|
||||
break;
|
||||
}
|
||||
*lpdwSize = unzipFileInfo.uncompressed_size;
|
||||
|
||||
if( unzCloseCurrentFile( unzipFile ) != UNZ_OK )
|
||||
break;
|
||||
unzClose( unzipFile );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Next file
|
||||
if( (i+1) < unzipGlobalInfo.number_entry ) {
|
||||
if( unzGoToNextFile( unzipFile ) != UNZ_OK ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FREE( *ppBuf );
|
||||
|
||||
if( unzipFile ) {
|
||||
unzCloseCurrentFile( unzipFile );
|
||||
unzClose( unzipFile );
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL UnCompress( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize )
|
||||
{
|
||||
HMODULE hDLL;
|
||||
INDIVIDUALINFO idvinfo;
|
||||
|
||||
char* pExt = ::PathFindExtension( fname );
|
||||
if( _stricmp( pExt, ".zip" ) == 0 ) {
|
||||
// ZIPならまずzlibライブラリの解凍を使ってみる
|
||||
if( ZlibUnZip( fname, ppBuf, lpdwSize ) ) {
|
||||
// DEBUGOUT( "zlib unzip ok! [%s]\n", fname );
|
||||
return TRUE;
|
||||
}
|
||||
} else if( _stricmp( pExt, ".7z" ) == 0 ) {
|
||||
return SevenZipUnCompress((char*)fname, ppBuf, (size_t*)lpdwSize);
|
||||
}
|
||||
|
||||
|
||||
hDLL = NULL;
|
||||
for( INT i = 0; pszArchiver[i]; i++ ) {
|
||||
// DLLアンロード
|
||||
FREEDLL( hDLL );
|
||||
|
||||
// DLLロード
|
||||
if( !(hDLL = LoadLibrary( pszArchiver[i] )) )
|
||||
continue;
|
||||
|
||||
CHAR szTemp[256];
|
||||
sprintf( szTemp, "%sCheckArchive", pszFuncPrefix[i] );
|
||||
CHECKARCHIVE CheckArchive;
|
||||
if( !(CheckArchive = (CHECKARCHIVE)GetProcAddress( hDLL, szTemp )) )
|
||||
continue;
|
||||
// 対応するアーカイブかチェックする
|
||||
if( !CheckArchive( fname, 1 ) )
|
||||
continue;
|
||||
|
||||
// アーカイブ内に対応するファイルがあるかのチェック
|
||||
OPENARCHIVE OpenArchive;
|
||||
CLOSEARCHIVE CloseArchive;
|
||||
FINDFIRST FindFirst;
|
||||
|
||||
sprintf( szTemp, "%sOpenArchive", pszFuncPrefix[i] );
|
||||
OpenArchive = (OPENARCHIVE)GetProcAddress( hDLL, szTemp );
|
||||
sprintf( szTemp, "%sFindFirst", pszFuncPrefix[i] );
|
||||
FindFirst = (FINDFIRST)GetProcAddress( hDLL, szTemp );
|
||||
sprintf( szTemp, "%sCloseArchive", pszFuncPrefix[i] );
|
||||
CloseArchive = (CLOSEARCHIVE)GetProcAddress( hDLL, szTemp );
|
||||
|
||||
HGLOBAL hARC;
|
||||
BOOL bFound = FALSE;
|
||||
for( INT j = 0; pszExtension[j]; j++ ) {
|
||||
if( !(hARC = OpenArchive( NULL, fname, M_ERROR_MESSAGE_OFF ) ) ) {
|
||||
CloseArchive( hARC );
|
||||
break;
|
||||
}
|
||||
INT ret = FindFirst( hARC, pszExtension[j], &idvinfo );
|
||||
CloseArchive( hARC );
|
||||
if( ret == 0 ) { // Found!!
|
||||
bFound = TRUE;
|
||||
break;
|
||||
} else if( ret == -1 ) { // Not found.
|
||||
} else { // 異常終了
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !bFound )
|
||||
continue;
|
||||
|
||||
if( !pszCommand[i] ) {
|
||||
// メモリ解凍あり(UNLHA32,UNZIP32)
|
||||
*lpdwSize = idvinfo.dwOriginalSize;
|
||||
*ppBuf = (LPBYTE)malloc( *lpdwSize );
|
||||
|
||||
CHAR szCmd [256];
|
||||
CHAR szFunc[256];
|
||||
|
||||
if( !bFileMatching[i] ) {
|
||||
sprintf( szCmd, "\"%s\" \"%s\"", fname, idvinfo.szFileName );
|
||||
} else {
|
||||
// UNZIP32 only
|
||||
BYTE szFile[FNAME_MAX32+1];
|
||||
LPBYTE lpF0, lpF1;
|
||||
|
||||
// 正規表現を切るオプションが欲しかった....
|
||||
lpF0 = (LPBYTE)idvinfo.szFileName;
|
||||
lpF1 = szFile;
|
||||
while( *lpF0 ) {
|
||||
if( *lpF0 == '[' || *lpF0 == ']' ) {
|
||||
*lpF1++ = '\\';
|
||||
}
|
||||
_mbsncpy( lpF1, lpF0, 1 );
|
||||
lpF0 = _mbsinc( lpF0 );
|
||||
lpF1 = _mbsinc( lpF1 );
|
||||
}
|
||||
*lpF1 = '\0';
|
||||
|
||||
sprintf( szCmd, "\"%s\" \"%s\"", fname, szFile );
|
||||
}
|
||||
sprintf( szFunc, "%sExtractMem", pszFuncPrefix[i] );
|
||||
|
||||
EXTRACTMEM ExtractMem;
|
||||
ExtractMem = (EXTRACTMEM)GetProcAddress( hDLL, szFunc );
|
||||
INT ret = ExtractMem( NULL, szCmd, (LPBYTE)(*ppBuf), *lpdwSize, NULL, NULL, NULL );
|
||||
FREEDLL( hDLL );
|
||||
if( ret == 0 )
|
||||
return TRUE;
|
||||
} else {
|
||||
// メモリ解凍が無い場合
|
||||
CHAR szCmd [256];
|
||||
CHAR szTempPath[_MAX_PATH];
|
||||
EXECUTECOMMAND ExecuteCommand;
|
||||
|
||||
GetTempPath( _MAX_PATH, szTempPath );
|
||||
//DEBUGOUT( "TempPath:%s\n", szTempPath );
|
||||
|
||||
sprintf( szCmd, pszCommand[i], fname, szTempPath, idvinfo.szFileName );
|
||||
ExecuteCommand = (EXECUTECOMMAND)GetProcAddress( hDLL, pszFuncPrefix[i] );
|
||||
ExecuteCommand( NULL, szCmd, NULL, 0 );
|
||||
FREEDLL( hDLL );
|
||||
|
||||
string FileName = CPathlib::MakePath( szTempPath, idvinfo.szFileName );
|
||||
|
||||
FILE *fp = NULL;
|
||||
if( (fp = fopen( FileName.c_str(), "rb" )) ) {
|
||||
// ファイルサイズ取得
|
||||
fseek( fp, 0, SEEK_END );
|
||||
*lpdwSize = ftell( fp );
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
if( *lpdwSize < 17 ) {
|
||||
// ファイルサイズが小さすぎます
|
||||
throw CApp::GetErrorString( IDS_ERROR_SMALLFILE );
|
||||
}
|
||||
|
||||
// テンポラリメモリ確保
|
||||
if( !(*ppBuf = (LPBYTE)malloc( *lpdwSize )) ) {
|
||||
FCLOSE( fp );
|
||||
// メモリを確保出来ません
|
||||
throw CApp::GetErrorString( IDS_ERROR_OUTOFMEMORY );
|
||||
}
|
||||
// サイズ分読み込み
|
||||
if( fread( *ppBuf, *lpdwSize, 1, fp ) != 1 ) {
|
||||
FCLOSE( fp );
|
||||
FREE( *ppBuf );
|
||||
// ファイルの読み込みに失敗しました
|
||||
throw CApp::GetErrorString( IDS_ERROR_READ );
|
||||
}
|
||||
FCLOSE( fp );
|
||||
DeleteFile( FileName.c_str() );
|
||||
} else {
|
||||
// xxx ファイルを開けません
|
||||
LPCSTR szErrStr = CApp::GetErrorString( IDS_ERROR_OPEN );
|
||||
sprintf( szErrorString, szErrStr, fname );
|
||||
throw szErrorString;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
FREEDLL( hDLL );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
// Archive
|
||||
12
References/VirtuaNESex_src_191105/Archive.h
Normal file
12
References/VirtuaNESex_src_191105/Archive.h
Normal file
@ -0,0 +1,12 @@
|
||||
//
|
||||
// アーカイブファイル操作
|
||||
//
|
||||
#ifndef __CARCHIVEFILE_INCLUDED__
|
||||
#define __CARCHIVEFILE_INCLUDED__
|
||||
|
||||
#include "typedef.h"
|
||||
|
||||
extern BOOL UnCompress( LPCSTR fname, LPBYTE* ppBuf, LPDWORD lpdwSize );
|
||||
|
||||
#endif // !__CARCHIVEFILE_INCLUDED__
|
||||
|
||||
250
References/VirtuaNESex_src_191105/CHyperLink.h
Normal file
250
References/VirtuaNESex_src_191105/CHyperLink.h
Normal file
@ -0,0 +1,250 @@
|
||||
#ifndef __CHYPERLINK_INCLUDED__
|
||||
#define __CHYPERLINK_INCLUDED__
|
||||
|
||||
//
|
||||
// スタティックコントロールをSubclass化してハイパーリンクをサポート
|
||||
//
|
||||
// Usage: CHyperLink hyperlink;
|
||||
// hyperlink.Attach( GetDlgItem( hWnd, IDC_URL ) );
|
||||
//
|
||||
class CHyperLink
|
||||
{
|
||||
public:
|
||||
CHyperLink() : m_hWnd(NULL), m_lpLabel(NULL),
|
||||
m_hCursor(NULL), m_hFont(NULL),
|
||||
m_lpHyperLink(NULL), m_lpfnOldWndProc(NULL)
|
||||
{
|
||||
}
|
||||
~CHyperLink()
|
||||
{
|
||||
Detach();
|
||||
}
|
||||
|
||||
// コントロールにアタッチする
|
||||
BOOL Attach( HWND hWnd, LPCSTR lpLabel = NULL, LPCSTR lpHyperLink = NULL )
|
||||
{
|
||||
if( m_hWnd )
|
||||
return FALSE; // 既にAttach済み
|
||||
|
||||
m_hWnd = hWnd;
|
||||
|
||||
// 文字列をコピー
|
||||
if( lpLabel ) {
|
||||
m_lpLabel = new CHAR[::lstrlen(lpLabel)+1];
|
||||
::lstrcpy( m_lpLabel, lpLabel );
|
||||
::SendMessage( m_hWnd, WM_SETTEXT, 0, (LPARAM)m_lpLabel );
|
||||
}
|
||||
// 表示とハイパーリンクが同じ場合はハイパーリンクはラベルと同じに
|
||||
if( lpLabel && !lpHyperLink ) {
|
||||
m_lpHyperLink = new CHAR[::lstrlen(lpLabel)+1];
|
||||
::lstrcpy( m_lpHyperLink, lpLabel );
|
||||
}
|
||||
// ハイパーリンクが別の場合
|
||||
if( lpHyperLink ) {
|
||||
m_lpHyperLink = new CHAR[::lstrlen(lpHyperLink)+1];
|
||||
::lstrcpy( m_lpHyperLink, lpHyperLink );
|
||||
}
|
||||
|
||||
// ポイントカーソル(無ければデフォルト)
|
||||
m_hCursor = ::LoadCursor( NULL, MAKEINTRESOURCE(32649) );
|
||||
|
||||
// アンダーラインフォントの作成
|
||||
HFONT m_hOldFont = (HFONT)::SendMessage( hWnd, WM_GETFONT, 0, 0 );
|
||||
LOGFONT lFont;
|
||||
::GetObject( m_hOldFont, sizeof(LOGFONT), &lFont );
|
||||
lFont.lfUnderline = TRUE;
|
||||
m_hFont = ::CreateFontIndirect( &lFont );
|
||||
|
||||
// ラベルの表示領域を計算
|
||||
CalcLabelRectangle();
|
||||
|
||||
// スタイルの変更(通知をイネーブルにする)
|
||||
DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE );
|
||||
dwStyle |= SS_NOTIFY;
|
||||
::SetWindowLong( hWnd, GWL_STYLE, (LONG)dwStyle );
|
||||
|
||||
// コントロールのサブクラス化
|
||||
m_lpfnOldWndProc = (WNDPROC)::SetWindowLong( hWnd, GWL_WNDPROC, (LONG)HyperLinkProc );
|
||||
|
||||
// Thisを埋め込む
|
||||
::SetWindowLong( hWnd, GWL_USERDATA, (LONG)this );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Detach()
|
||||
{
|
||||
if( m_hWnd ) {
|
||||
// サブクラス化を解除
|
||||
if( m_lpfnOldWndProc ) {
|
||||
::SetWindowLong( m_hWnd, GWL_WNDPROC, (LONG)m_lpfnOldWndProc );
|
||||
m_lpfnOldWndProc = NULL;
|
||||
}
|
||||
|
||||
// フォントを削除
|
||||
if( m_hFont ) {
|
||||
::DeleteObject( (HGDIOBJ)m_hFont );
|
||||
m_hFont = NULL;
|
||||
}
|
||||
|
||||
// 文字列を削除
|
||||
if( m_lpLabel ) {
|
||||
delete[] m_lpLabel;
|
||||
m_lpLabel = NULL;
|
||||
}
|
||||
if( m_lpHyperLink ) {
|
||||
delete[] m_lpHyperLink;
|
||||
m_lpHyperLink = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m_hWnd = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetLabel( LPCSTR lpLabel )
|
||||
{
|
||||
if( m_lpLabel ) {
|
||||
delete[] m_lpLabel;
|
||||
}
|
||||
|
||||
m_lpLabel = new CHAR[::lstrlen(lpLabel)+1];
|
||||
::lstrcpy( m_lpLabel, lpLabel );
|
||||
|
||||
// コントロールに文字列を設定
|
||||
::SendMessage( m_hWnd, WM_SETTEXT, 0, (LPARAM)m_lpLabel );
|
||||
|
||||
// ラベルの表示領域を計算
|
||||
CalcLabelRectangle();
|
||||
}
|
||||
|
||||
BOOL SetHyperLink( LPCSTR lpHyperLink )
|
||||
{
|
||||
if( m_lpHyperLink ) {
|
||||
delete[] m_lpHyperLink;
|
||||
}
|
||||
|
||||
m_lpHyperLink = new CHAR[::lstrlen(lpHyperLink)+1];
|
||||
::lstrcpy( m_lpHyperLink, lpHyperLink );
|
||||
}
|
||||
|
||||
protected:
|
||||
BOOL CalcLabelRectangle()
|
||||
{
|
||||
if( !::IsWindow(m_hWnd) )
|
||||
return FALSE;
|
||||
|
||||
if( !m_lpLabel )
|
||||
return FALSE;
|
||||
|
||||
RECT rcClient;
|
||||
::GetClientRect( m_hWnd, &rcClient );
|
||||
m_rcLabel = rcClient;
|
||||
|
||||
HDC hDC = ::GetDC( m_hWnd );
|
||||
HFONT hOldFont = (HFONT)::SelectObject( hDC, m_hFont );
|
||||
|
||||
// スタイル
|
||||
DWORD dwStyle = ::GetWindowLong( m_hWnd, GWL_STYLE );
|
||||
INT nDrawStyle = DT_LEFT;
|
||||
if( dwStyle && SS_CENTER ) {
|
||||
nDrawStyle = DT_CENTER;
|
||||
} else if( dwStyle && SS_RIGHT ) {
|
||||
nDrawStyle = DT_RIGHT;
|
||||
}
|
||||
|
||||
// 文字列表示と描画領域の計算
|
||||
::DrawText( hDC, m_lpLabel, -1, &m_rcLabel, nDrawStyle | DT_WORDBREAK | DT_CALCRECT );
|
||||
|
||||
::SelectObject( hDC, hOldFont );
|
||||
|
||||
// スタイルによってオフセットを計算
|
||||
if( dwStyle & SS_CENTER ) {
|
||||
::OffsetRect( &m_rcLabel, (rcClient.right - m_rcLabel.right) / 2, 0 );
|
||||
} else if (dwStyle & SS_RIGHT) {
|
||||
::OffsetRect( &m_rcLabel, rcClient.right - m_rcLabel.right, 0 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK HyperLinkProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
CHyperLink* pHyperLink = reinterpret_cast<CHyperLink*>(::GetWindowLong( hWnd, GWL_USERDATA));
|
||||
|
||||
switch( msg ) {
|
||||
case WM_DESTROY:
|
||||
{
|
||||
// 2003/10/11 リリース後にfix...
|
||||
WNDPROC pWndProcOld = pHyperLink->m_lpfnOldWndProc;
|
||||
pHyperLink->Detach();
|
||||
return CallWindowProc( pWndProcOld, hWnd, msg, wParam, lParam );
|
||||
}
|
||||
break;
|
||||
case WM_LBUTTONDOWN: {
|
||||
POINT pt = { LOWORD(lParam), HIWORD(lParam) };
|
||||
if( pHyperLink->m_lpLabel && pHyperLink->m_lpHyperLink ) {
|
||||
if( ::PtInRect( &pHyperLink->m_rcLabel, pt ) ) {
|
||||
::ShellExecute( hWnd, NULL, pHyperLink->m_lpHyperLink, NULL, NULL, SW_SHOWNORMAL );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE: {
|
||||
POINT pt = { LOWORD(lParam), HIWORD(lParam) };
|
||||
if( pHyperLink->m_lpLabel && pHyperLink->m_lpHyperLink ) {
|
||||
if( ::PtInRect( &pHyperLink->m_rcLabel, pt ) ) {
|
||||
::SetCursor( pHyperLink->m_hCursor );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_PAINT: {
|
||||
PAINTSTRUCT ps;
|
||||
HDC hDC = ::BeginPaint( hWnd, &ps );
|
||||
DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE );
|
||||
INT nDrawStyle = DT_LEFT;
|
||||
if( dwStyle && SS_CENTER ) {
|
||||
nDrawStyle = DT_CENTER;
|
||||
} else if( dwStyle && SS_RIGHT ) {
|
||||
nDrawStyle = DT_RIGHT;
|
||||
}
|
||||
|
||||
// アトリビュート
|
||||
::SetBkMode( hDC, TRANSPARENT );
|
||||
::SetTextColor( hDC, 0x00FF0000 );
|
||||
|
||||
// 文字列表示
|
||||
if( pHyperLink->m_lpLabel ) {
|
||||
HFONT hOldFont = (HFONT)::SelectObject( hDC, pHyperLink->m_hFont );
|
||||
::DrawText( hDC, pHyperLink->m_lpLabel, -1, &pHyperLink->m_rcLabel, nDrawStyle | DT_WORDBREAK );
|
||||
::SelectObject( hDC, hOldFont );
|
||||
}
|
||||
|
||||
::EndPaint( hWnd, &ps );
|
||||
}
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CallWindowProc( pHyperLink->m_lpfnOldWndProc, hWnd, msg, wParam, lParam );
|
||||
}
|
||||
|
||||
HWND m_hWnd;
|
||||
HFONT m_hFont;
|
||||
HFONT m_hOldFont;
|
||||
HCURSOR m_hCursor;
|
||||
WNDPROC m_lpfnOldWndProc;
|
||||
|
||||
RECT m_rcLabel;
|
||||
|
||||
LPSTR m_lpLabel;
|
||||
LPSTR m_lpHyperLink;
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // !__CHYPERLINK_INCLUDED__
|
||||
277
References/VirtuaNESex_src_191105/ChatDlg.cpp
Normal file
277
References/VirtuaNESex_src_191105/ChatDlg.cpp
Normal file
@ -0,0 +1,277 @@
|
||||
//
|
||||
// チャットダイアログクラス
|
||||
//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <mbstring.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "typedef.h"
|
||||
#include "macro.h"
|
||||
|
||||
#include "VirtuaNESres.h"
|
||||
#include "DebugOut.h"
|
||||
#include "App.h"
|
||||
#include "Pathlib.h"
|
||||
#include "Config.h"
|
||||
|
||||
#include "NetPlay.h"
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "ChatDlg.h"
|
||||
|
||||
// メッセージ
|
||||
DLG_MESSAGE_BEGIN(CChatDlg)
|
||||
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
|
||||
DLG_ON_MESSAGE( WM_DESTROY, OnDestroy )
|
||||
DLG_ON_MESSAGE( WM_CLOSE, OnClose )
|
||||
DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate )
|
||||
DLG_ON_MESSAGE( WM_SETCURSOR, OnSetCursor )
|
||||
DLG_ON_MESSAGE( WM_SIZE, OnSize )
|
||||
DLG_ON_MESSAGE( WM_CTLCOLORSTATIC, OnControlColorStatic )
|
||||
DLG_ON_MESSAGE( WM_COPYDATA, OnCopyData )
|
||||
|
||||
// コマンド
|
||||
DLG_COMMAND_BEGIN()
|
||||
DLG_ON_COMMAND_NOTIFY( IDC_NCT_MESSAGE, EN_SETFOCUS, OnMessageFocus )
|
||||
DLG_ON_COMMAND( IDOK, OnOK )
|
||||
DLG_ON_COMMAND( IDCANCEL, OnCancel )
|
||||
DLG_ON_COMMAND( IDC_NCT_SEND, OnSend )
|
||||
DLG_COMMAND_END()
|
||||
// Notify メッセージ
|
||||
DLG_NOTIFY_BEGIN()
|
||||
DLG_NOTIFY_END()
|
||||
DLG_MESSAGE_END()
|
||||
|
||||
BOOL CChatDlg::Create( HWND hWndParent )
|
||||
{
|
||||
// 親はデスクトップにする
|
||||
m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_NETPLAY_CHAT),
|
||||
NULL, g_DlgProc, (LPARAM)this );
|
||||
if( !m_hWnd )
|
||||
return FALSE;
|
||||
|
||||
// モードレスダイアログリストに加える
|
||||
CWndList::Add( this );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CChatDlg::Destroy()
|
||||
{
|
||||
if( m_hWnd ) {
|
||||
// モードレスダイアログリストから削除
|
||||
CWndList::Del( this );
|
||||
|
||||
::GetWindowRect( m_hWnd, &Config.netplay.rcChatPos );
|
||||
|
||||
::DestroyWindow( m_hWnd );
|
||||
m_hWnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CChatDlg::SetEditText()
|
||||
{
|
||||
CHAR szText[256+1];
|
||||
|
||||
::GetWindowText( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), szText, sizeof(szText)-1 );
|
||||
::SetWindowText( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), "" );
|
||||
|
||||
if( ::strlen(szText) ) {
|
||||
// clear message window
|
||||
if( ::StrCmpI( szText, "/clear" ) == 0 ) {
|
||||
::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_SETSEL, 0, -1 );
|
||||
::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, FALSE, (WPARAM)"" );
|
||||
return;
|
||||
}
|
||||
|
||||
string str;
|
||||
|
||||
if( NetPlay.IsConnect() ) {
|
||||
str = "(";
|
||||
str = str + Config.netplay.szNick;
|
||||
str = str + ") ";
|
||||
}
|
||||
|
||||
str = str + szText;
|
||||
str = str + "\r\n";
|
||||
|
||||
// 相手に送信
|
||||
if( NetPlay.IsConnect() ) {
|
||||
NetPlay.ChatSend( (LPSTR)str.c_str() );
|
||||
}
|
||||
|
||||
// 自分自身のメッセージを表示
|
||||
INT n = GetWindowTextLength( GetDlgItem( m_hWnd, IDC_NCT_MESSAGE ) );
|
||||
::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_SETSEL, (WPARAM)n, (LPARAM)n );
|
||||
::SendDlgItemMessage( m_hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)str.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
DLGMSG CChatDlg::OnCopyData( DLGMSGPARAM )
|
||||
{
|
||||
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
|
||||
CHAR* lpStr = (CHAR*)pcds->lpData;
|
||||
|
||||
INT n = GetWindowTextLength( GetDlgItem( hWnd, IDC_NCT_MESSAGE ) );
|
||||
::SendDlgItemMessage( hWnd, IDC_NCT_MESSAGE, EM_SETSEL, (WPARAM)n, (LPARAM)n );
|
||||
::SendDlgItemMessage( hWnd, IDC_NCT_MESSAGE, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)lpStr );
|
||||
|
||||
if( ::GetFocus() != m_hWnd && ::strlen( lpStr ) > 0 ) {
|
||||
::MessageBeep( MB_OK );
|
||||
// ::PlaySound( "MailBeep", NULL, SND_ALIAS|SND_ASYNC );
|
||||
}
|
||||
|
||||
// メッセージが来たらポップアップさせるため
|
||||
::SendMessage( CApp::GetHWnd(), WM_VNS_CHATPOPUP, 0, 0 );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGMSG CChatDlg::OnInitDialog( DLGMSGPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CChatDlg::OnInitDialog\n" );
|
||||
|
||||
NetPlay.SetChatWnd( m_hWnd );
|
||||
|
||||
// 位置情報を保存
|
||||
::GetClientRect( m_hWnd, &m_rcClient );
|
||||
::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_MESSAGE), &m_rcMessage );
|
||||
::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_EDIT), &m_rcEdit );
|
||||
::GetWindowRect( ::GetDlgItem(m_hWnd, IDC_NCT_SEND), &m_rcButton );
|
||||
|
||||
// クライアント座標への変換
|
||||
::ScreenToClient( m_hWnd, (POINT*)&m_rcMessage.left );
|
||||
::ScreenToClient( m_hWnd, (POINT*)&m_rcMessage.right );
|
||||
::ScreenToClient( m_hWnd, (POINT*)&m_rcEdit.left );
|
||||
::ScreenToClient( m_hWnd, (POINT*)&m_rcEdit.right );
|
||||
::ScreenToClient( m_hWnd, (POINT*)&m_rcButton.left );
|
||||
::ScreenToClient( m_hWnd, (POINT*)&m_rcButton.right );
|
||||
|
||||
// ウインドウ位置/サイズの設定
|
||||
// RECT rc = Config.launcher.rcWindowPos;
|
||||
// if( (rc.right-rc.left) && (rc.bottom-rc.top) ) {
|
||||
// ::SetWindowPos( m_hWnd, NULL, rc.left, rc.top, RCWIDTH(rc), RCHEIGHT(rc), SWP_NOZORDER );
|
||||
// }
|
||||
|
||||
// ウインドウ位置/サイズの設定
|
||||
RECT rc = Config.netplay.rcChatPos;
|
||||
if( (rc.right-rc.left) && (rc.bottom-rc.top) ) {
|
||||
::SetWindowPos( m_hWnd, NULL, rc.left, rc.top, RCWIDTH(rc), RCHEIGHT(rc), SWP_NOZORDER );
|
||||
}
|
||||
|
||||
// 表示
|
||||
::ShowWindow( m_hWnd, SW_SHOW );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGMSG CChatDlg::OnDestroy( DLGMSGPARAM )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGMSG CChatDlg::OnClose( DLGMSGPARAM )
|
||||
{
|
||||
::ShowWindow( m_hWnd, SW_HIDE ); // 非表示にするだけ
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGMSG CChatDlg::OnActivate( DLGMSGPARAM )
|
||||
{
|
||||
if( LOWORD(wParam) == WA_INACTIVE ) {
|
||||
// DEBUGOUT( "CChatDlg::OnActivate:Inactive\n" );
|
||||
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 );
|
||||
|
||||
Config.InputKeyboardDisable( FALSE );
|
||||
} else {
|
||||
// DEBUGOUT( "CChatDlg::OnActivate:Active\n" );
|
||||
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 );
|
||||
|
||||
Config.InputKeyboardDisable( TRUE );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGMSG CChatDlg::OnSetCursor( DLGMSGPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CChatDlg::OnSetCursor\n" );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DLGMSG CChatDlg::OnSize( DLGMSGPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CChatDlg::OnSize\n" );
|
||||
HWND hWndCtrl;
|
||||
RECT rcC, rcT;
|
||||
::GetClientRect( m_hWnd, &rcC );
|
||||
|
||||
// メッセージ枠
|
||||
if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_MESSAGE )) ) {
|
||||
rcT.left = rcC.left;
|
||||
rcT.right = rcC.right;
|
||||
rcT.top = rcC.top;
|
||||
rcT.bottom = rcC.bottom - (m_rcClient.bottom-m_rcMessage.bottom);
|
||||
::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE );
|
||||
}
|
||||
if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_EDIT )) ) {
|
||||
rcT.left = rcC.left;
|
||||
rcT.right = rcC.right - (m_rcClient.right-m_rcEdit.right);
|
||||
rcT.top = rcC.bottom - (m_rcClient.bottom-m_rcEdit.top);
|
||||
rcT.bottom = rcC.bottom - (m_rcClient.bottom-m_rcEdit.bottom);
|
||||
::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE );
|
||||
}
|
||||
if( (hWndCtrl = ::GetDlgItem( m_hWnd, IDC_NCT_SEND )) ) {
|
||||
rcT.left = rcC.right - (m_rcClient.right-m_rcButton.left);
|
||||
rcT.right = rcT.left + RCWIDTH(m_rcButton);
|
||||
rcT.top = rcC.bottom - (m_rcClient.bottom-m_rcButton.top);
|
||||
rcT.bottom = rcT.top + RCHEIGHT(m_rcButton);
|
||||
::MoveWindow( hWndCtrl, rcT.left, rcT.top, RCWIDTH(rcT), RCHEIGHT(rcT), TRUE );
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DLGMSG CChatDlg::OnControlColorStatic( DLGMSGPARAM )
|
||||
{
|
||||
if( (HWND)lParam == ::GetDlgItem( m_hWnd, IDC_NCT_MESSAGE ) ) {
|
||||
SetBkColor( (HDC)wParam, (COLORREF)0x00FFFFFF );
|
||||
bResult = (LRESULT)GetStockObject( WHITE_BRUSH );
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DLGCMD CChatDlg::OnMessageFocus( DLGCMDPARAM )
|
||||
{
|
||||
DEBUGOUT( "CChatDlg::OnMessageFocus\n" );
|
||||
|
||||
// ::SetFocus( ::GetDlgItem( m_hWnd, IDC_NCT_EDIT ) );
|
||||
::SetFocus( m_hWnd );
|
||||
}
|
||||
|
||||
DLGCMD CChatDlg::OnOK( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CChatDlg::OnOK\n" );
|
||||
SetEditText();
|
||||
}
|
||||
|
||||
DLGCMD CChatDlg::OnCancel( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CChatDlg::OnCancel\n" );
|
||||
::ShowWindow( m_hWnd, SW_HIDE ); // 非表示にするだけ
|
||||
}
|
||||
|
||||
DLGCMD CChatDlg::OnSend( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CChatDlg::OnSend\n" );
|
||||
SetEditText();
|
||||
|
||||
::SetFocus( ::GetDlgItem( m_hWnd, IDC_NCT_EDIT ) );
|
||||
}
|
||||
|
||||
55
References/VirtuaNESex_src_191105/ChatDlg.h
Normal file
55
References/VirtuaNESex_src_191105/ChatDlg.h
Normal file
@ -0,0 +1,55 @@
|
||||
//
|
||||
// チャットダイアログクラス
|
||||
//
|
||||
#ifndef __CCHATDLG_INCLUDED__
|
||||
#define __CCHATDLG_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "Wnd.h"
|
||||
|
||||
class CChatDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
// Override from CWnd
|
||||
BOOL Create( HWND hWndParent );
|
||||
void Destroy();
|
||||
|
||||
// Set Message
|
||||
void SetEditText();
|
||||
protected:
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGMSG OnDestroy( DLGMSGPARAM );
|
||||
DLGMSG OnClose( DLGMSGPARAM );
|
||||
DLGMSG OnActivate( DLGMSGPARAM );
|
||||
DLGMSG OnSetCursor( DLGMSGPARAM );
|
||||
DLGMSG OnSize( DLGMSGPARAM );
|
||||
|
||||
DLGMSG OnControlColorStatic( DLGMSGPARAM );
|
||||
|
||||
DLGMSG OnCopyData( DLGMSGPARAM );
|
||||
|
||||
DLGCMD OnMessageFocus( DLGCMDPARAM );
|
||||
|
||||
DLGCMD OnOK( DLGCMDPARAM );
|
||||
DLGCMD OnCancel( DLGCMDPARAM );
|
||||
DLGCMD OnSend( DLGCMDPARAM );
|
||||
//
|
||||
|
||||
// 位置
|
||||
RECT m_rcClient; // クライアントエリア
|
||||
RECT m_rcMessage; // メッセージ枠
|
||||
RECT m_rcEdit; // エディット枠
|
||||
RECT m_rcButton; // 送信ボタン
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // !__CCHATDLG_INCLUDED__
|
||||
|
||||
1561
References/VirtuaNESex_src_191105/CheatDlg.cpp
Normal file
1561
References/VirtuaNESex_src_191105/CheatDlg.cpp
Normal file
File diff suppressed because it is too large
Load Diff
175
References/VirtuaNESex_src_191105/CheatDlg.h
Normal file
175
References/VirtuaNESex_src_191105/CheatDlg.h
Normal file
@ -0,0 +1,175 @@
|
||||
//
|
||||
// チートダイアログクラス
|
||||
//
|
||||
#ifndef __CCHEATDLG_INCLUDED__
|
||||
#define __CCHEATDLG_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "cheat.h"
|
||||
|
||||
// サーチダイアログ
|
||||
class CSearchDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
// Override from CWnd
|
||||
BOOL Create( HWND hWndParent );
|
||||
void Destroy();
|
||||
|
||||
protected:
|
||||
void OnListUpdate();
|
||||
|
||||
// Utils
|
||||
DWORD GetNesMemory( INT length, DWORD addr );
|
||||
DWORD GetSearchMemory( INT length, DWORD addr );
|
||||
DWORD GetSearchMemoryOld( INT length, DWORD addr );
|
||||
|
||||
BOOL CompareData( INT type, DWORD dataA, DWORD dataB );
|
||||
BOOL CompareRange( INT length, DWORD dataA, DWORD dataB, DWORD range );
|
||||
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGMSG OnActivate( DLGMSGPARAM );
|
||||
DLGMSG OnClose( DLGMSGPARAM );
|
||||
|
||||
DLGMSG OnContextMenu( DLGMSGPARAM );
|
||||
|
||||
DLGCMD OnOK( DLGCMDPARAM );
|
||||
DLGCMD OnCancel( DLGCMDPARAM );
|
||||
|
||||
DLGCMD OnRadixCommand( DLGCMDPARAM );
|
||||
DLGCMD OnLengthCommand( DLGCMDPARAM );
|
||||
|
||||
DLGCMD OnStart( DLGCMDPARAM );
|
||||
DLGCMD OnUpdate( DLGCMDPARAM );
|
||||
DLGCMD OnUndo( DLGCMDPARAM );
|
||||
|
||||
DLGCMD OnSearchCommand( DLGCMDPARAM );
|
||||
DLGCMD OnSearchData( DLGCMDPARAM );
|
||||
DLGCMD OnWriteData( DLGCMDPARAM );
|
||||
|
||||
DLGCMD OnCodeAppend( DLGCMDPARAM );
|
||||
//
|
||||
DLGNOTIFY OnDoubleClickListView( DLGNOTIFYPARAM );
|
||||
|
||||
private:
|
||||
HMENU m_hMenu;
|
||||
HMENU m_hSubMenu;
|
||||
|
||||
BOOL m_bShortCutDisable;
|
||||
|
||||
WORD m_Address;
|
||||
|
||||
INT m_nRadix;
|
||||
INT m_nLength;
|
||||
|
||||
struct RESULT {
|
||||
BYTE RAM_N[0x0800]; // RAM New value
|
||||
BYTE RAM_O[0x0800]; // RAM Old value
|
||||
BYTE RAM_F[0x0800]; // RAM Flag
|
||||
|
||||
BYTE SRAM_N[0x2000]; // RAM New value
|
||||
BYTE SRAM_O[0x2000]; // RAM Old value
|
||||
BYTE SRAM_F[0x2000]; // RAM Flag
|
||||
};
|
||||
|
||||
struct RESULT m_Result; // 今回データ
|
||||
struct RESULT m_ResultOld; // 1回前
|
||||
};
|
||||
|
||||
// チートコード編集ダイアログ
|
||||
class CCheatCodeEditDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
// Override from CWnd
|
||||
INT DoModal( HWND hWndParent );
|
||||
|
||||
//
|
||||
CHEATCODE m_Code;
|
||||
INT m_nRadix;
|
||||
|
||||
protected:
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGCMD OnOK( DLGCMDPARAM );
|
||||
DLGCMD OnCancel( DLGCMDPARAM );
|
||||
//
|
||||
private:
|
||||
};
|
||||
|
||||
// チートコード入力ダイアログ
|
||||
class CCheatCodeInputDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
// Override from CWnd
|
||||
INT DoModal( HWND hWndParent );
|
||||
|
||||
string m_Codes;
|
||||
string m_Comment;
|
||||
|
||||
protected:
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGCMD OnOK( DLGCMDPARAM );
|
||||
DLGCMD OnCancel( DLGCMDPARAM );
|
||||
//
|
||||
private:
|
||||
};
|
||||
|
||||
// チートコードダイアログ
|
||||
class CCheatCodeDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
// Override from CWnd
|
||||
INT DoModal( HWND hWndParent );
|
||||
|
||||
protected:
|
||||
void OnListUpdate();
|
||||
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGMSG OnDestroy( DLGMSGPARAM );
|
||||
DLGMSG OnTimer( DLGMSGPARAM );
|
||||
|
||||
DLGNOTIFY OnKeyDownListView( DLGNOTIFYPARAM );
|
||||
DLGNOTIFY OnClickListView( DLGNOTIFYPARAM );
|
||||
DLGNOTIFY OnDblClkListView( DLGNOTIFYPARAM );
|
||||
|
||||
DLGCMD OnOK( DLGCMDPARAM );
|
||||
DLGCMD OnCancel( DLGCMDPARAM );
|
||||
|
||||
DLGCMD OnEnable( DLGCMDPARAM );
|
||||
DLGCMD OnDisable( DLGCMDPARAM );
|
||||
DLGCMD OnClear( DLGCMDPARAM );
|
||||
DLGCMD OnRemove( DLGCMDPARAM );
|
||||
|
||||
DLGCMD OnInput( DLGCMDPARAM );
|
||||
DLGCMD OnEdit( DLGCMDPARAM );
|
||||
|
||||
DLGCMD OnLoad( DLGCMDPARAM );
|
||||
DLGCMD OnSave( DLGCMDPARAM );
|
||||
|
||||
// Image List
|
||||
HIMAGELIST m_hImageList;
|
||||
|
||||
// Timer
|
||||
UINT m_uTimerID;
|
||||
|
||||
// Temp buffer
|
||||
vector<CHEATCODE> m_CheatCode;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // !__CCHEATDLG_INCLUDED__
|
||||
|
||||
35
References/VirtuaNESex_src_191105/Com.cpp
Normal file
35
References/VirtuaNESex_src_191105/Com.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// COM—˜—pƒTƒ|<7C>[ƒgƒNƒ‰ƒX
|
||||
//
|
||||
#include <objbase.h>
|
||||
#include "DebugOut.h"
|
||||
#include "Com.h"
|
||||
|
||||
INT COM::m_nRefCount = 0;
|
||||
|
||||
LRESULT COM::AddRef()
|
||||
{
|
||||
if( !m_nRefCount ) {
|
||||
HRESULT hr;
|
||||
if( (hr = ::CoInitialize( NULL )) != S_OK ) {
|
||||
DEBUGOUT( "COM::AddRef() CoInitialize failed.\n" );
|
||||
return hr;
|
||||
}
|
||||
DEBUGOUT( "COM::AddRef() CoInitialize.\n" );
|
||||
}
|
||||
m_nRefCount++;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
void COM::Release()
|
||||
{
|
||||
if( !m_nRefCount ) {
|
||||
DEBUGOUT( "COM::Release() too many released.\n" );
|
||||
return;
|
||||
}
|
||||
if( !(--m_nRefCount) ) {
|
||||
::CoUninitialize();
|
||||
DEBUGOUT( "COM::AddRef() CoUninitialize.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
21
References/VirtuaNESex_src_191105/Com.h
Normal file
21
References/VirtuaNESex_src_191105/Com.h
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// COM利用サポートクラス
|
||||
//
|
||||
#ifndef __CCOM_INCLUDED__
|
||||
#define __CCOM_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
class COM
|
||||
{
|
||||
public:
|
||||
static LRESULT AddRef();
|
||||
static void Release();
|
||||
|
||||
protected:
|
||||
static INT m_nRefCount;
|
||||
};
|
||||
|
||||
#endif // !__CCOM_INCLUDED__
|
||||
|
||||
817
References/VirtuaNESex_src_191105/Config.cpp
Normal file
817
References/VirtuaNESex_src_191105/Config.cpp
Normal file
@ -0,0 +1,817 @@
|
||||
//
|
||||
// 設定保存クラス
|
||||
//
|
||||
#include "VirtuaNESres.h"
|
||||
#include "DebugOut.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "Registry.h"
|
||||
|
||||
#include "DirectInput.h"
|
||||
#include "extsoundfile.h"
|
||||
|
||||
// Global instance
|
||||
CConfig Config;
|
||||
|
||||
// Sampling rate table
|
||||
INT CConfig::SamplingRateTable[] = {
|
||||
11025, 8, 11025, 16, 22050, 8, 22050, 16,
|
||||
44100, 8, 44100, 16, 48000, 8, 48000, 16,
|
||||
};
|
||||
|
||||
// Shortcut key IDs table
|
||||
INT CConfig::ShortcutKeyID[] = {
|
||||
// Main controls
|
||||
ID_OPEN, IDS_CUT_OPEN, 0,
|
||||
ID_CLOSE, IDS_CUT_CLOSE, 1,
|
||||
ID_LAUNCHER, IDS_CUT_LAUNCHER, 2,
|
||||
|
||||
ID_NETPLAY_CONNECT, IDS_CUT_NETPLAY_CONNECT, 3,
|
||||
ID_NETPLAY_DISCONNECT, IDS_CUT_NETPLAY_DISCONNECT, 4,
|
||||
ID_NETPLAY_CHAT, IDS_CUT_NETPLAY_CHAT, 5,
|
||||
|
||||
ID_ROMINFO, IDS_CUT_ROMINFO, 8,
|
||||
ID_WAVERECORD, IDS_CUT_WAVERECORD, 9,
|
||||
ID_EXIT, IDS_CUT_EXIT, 15,
|
||||
|
||||
// Emulation controls
|
||||
ID_HWRESET, IDS_CUT_HWRESET, 16,
|
||||
ID_SWRESET, IDS_CUT_SWRESET, 17,
|
||||
ID_PAUSE, IDS_CUT_PAUSE, 18,
|
||||
ID_ONEFRAME, IDS_CUT_ONEFRAME, 23,
|
||||
ID_THROTTLE, IDS_CUT_THROTTLE, 19,
|
||||
ID_KEYTHROTTLE, IDS_CUT_KEYTHROTTLE, 24,
|
||||
|
||||
ID_FRAMESKIP_AUTO, IDS_CUT_FRAMESKIP_AUTO, 20,
|
||||
ID_FRAMESKIP_UP, IDS_CUT_FRAMESKIP_UP, 21,
|
||||
ID_FRAMESKIP_DOWN, IDS_CUT_FRAMESKIP_DOWN, 22,
|
||||
|
||||
// State controls
|
||||
ID_STATE_LOAD, IDS_CUT_STATE_LOAD, 32,
|
||||
ID_STATE_SAVE, IDS_CUT_STATE_SAVE, 33,
|
||||
ID_STATE_UP, IDS_CUT_STATE_UP, 34,
|
||||
ID_STATE_DOWN, IDS_CUT_STATE_DOWN, 35,
|
||||
ID_STATE_SLOT0, IDS_CUT_STATE_SLOT0, 36,
|
||||
ID_STATE_SLOT1, IDS_CUT_STATE_SLOT1, 37,
|
||||
ID_STATE_SLOT2, IDS_CUT_STATE_SLOT2, 38,
|
||||
ID_STATE_SLOT3, IDS_CUT_STATE_SLOT3, 39,
|
||||
ID_STATE_SLOT4, IDS_CUT_STATE_SLOT4, 40,
|
||||
ID_STATE_SLOT5, IDS_CUT_STATE_SLOT5, 41,
|
||||
ID_STATE_SLOT6, IDS_CUT_STATE_SLOT6, 42,
|
||||
ID_STATE_SLOT7, IDS_CUT_STATE_SLOT7, 43,
|
||||
ID_STATE_SLOT8, IDS_CUT_STATE_SLOT8, 44,
|
||||
ID_STATE_SLOT9, IDS_CUT_STATE_SLOT9, 45,
|
||||
|
||||
// QuickLoad
|
||||
ID_QUICKLOAD_SLOT0, IDS_CUT_QUICKLOAD_SLOT0, 256,
|
||||
ID_QUICKLOAD_SLOT1, IDS_CUT_QUICKLOAD_SLOT1, 257,
|
||||
ID_QUICKLOAD_SLOT2, IDS_CUT_QUICKLOAD_SLOT2, 258,
|
||||
ID_QUICKLOAD_SLOT3, IDS_CUT_QUICKLOAD_SLOT3, 259,
|
||||
ID_QUICKLOAD_SLOT4, IDS_CUT_QUICKLOAD_SLOT4, 260,
|
||||
ID_QUICKLOAD_SLOT5, IDS_CUT_QUICKLOAD_SLOT5, 261,
|
||||
ID_QUICKLOAD_SLOT6, IDS_CUT_QUICKLOAD_SLOT6, 262,
|
||||
ID_QUICKLOAD_SLOT7, IDS_CUT_QUICKLOAD_SLOT7, 263,
|
||||
ID_QUICKLOAD_SLOT8, IDS_CUT_QUICKLOAD_SLOT8, 264,
|
||||
ID_QUICKLOAD_SLOT9, IDS_CUT_QUICKLOAD_SLOT9, 265,
|
||||
// QuickSave
|
||||
ID_QUICKSAVE_SLOT0, IDS_CUT_QUICKSAVE_SLOT0, 266,
|
||||
ID_QUICKSAVE_SLOT1, IDS_CUT_QUICKSAVE_SLOT1, 267,
|
||||
ID_QUICKSAVE_SLOT2, IDS_CUT_QUICKSAVE_SLOT2, 268,
|
||||
ID_QUICKSAVE_SLOT3, IDS_CUT_QUICKSAVE_SLOT3, 269,
|
||||
ID_QUICKSAVE_SLOT4, IDS_CUT_QUICKSAVE_SLOT4, 270,
|
||||
ID_QUICKSAVE_SLOT5, IDS_CUT_QUICKSAVE_SLOT5, 271,
|
||||
ID_QUICKSAVE_SLOT6, IDS_CUT_QUICKSAVE_SLOT6, 272,
|
||||
ID_QUICKSAVE_SLOT7, IDS_CUT_QUICKSAVE_SLOT7, 273,
|
||||
ID_QUICKSAVE_SLOT8, IDS_CUT_QUICKSAVE_SLOT8, 274,
|
||||
ID_QUICKSAVE_SLOT9, IDS_CUT_QUICKSAVE_SLOT9, 275,
|
||||
|
||||
// Disk controls
|
||||
ID_DISK_EJECT, IDS_CUT_DISK_EJECT, 48,
|
||||
ID_DISK_0A, IDS_CUT_DISK_0A, 49,
|
||||
ID_DISK_0B, IDS_CUT_DISK_0B, 50,
|
||||
ID_DISK_1A, IDS_CUT_DISK_1A, 51,
|
||||
ID_DISK_1B, IDS_CUT_DISK_1B, 52,
|
||||
|
||||
// Movie controls
|
||||
ID_MOVIE_PLAY, IDS_CUT_MOVIE_PLAY, 56,
|
||||
ID_MOVIE_REC, IDS_CUT_MOVIE_REC, 57,
|
||||
ID_MOVIE_REC_APPEND, IDS_CUT_MOVIE_REC_APPEND, 58,
|
||||
ID_MOVIE_STOP, IDS_CUT_MOVIE_STOP, 59,
|
||||
ID_MOVIE_INFO, IDS_CUT_MOVIE_INFO, 60,
|
||||
|
||||
// Screen controls
|
||||
ID_ZOOMx1, IDS_CUT_ZOOMx1, 64,
|
||||
ID_ZOOMx2, IDS_CUT_ZOOMx2, 65,
|
||||
ID_ZOOMx3, IDS_CUT_ZOOMx3, 66,
|
||||
ID_ZOOMx4, IDS_CUT_ZOOMx4, 67,
|
||||
ID_FULLSCREEN, IDS_CUT_FULLSCREEN, 68,
|
||||
|
||||
// Sound controls
|
||||
ID_MUTE_0, IDS_CUT_MUTE_MASTER, 72,
|
||||
ID_MUTE_1, IDS_CUT_MUTE_RECTANGLE1, 73,
|
||||
ID_MUTE_2, IDS_CUT_MUTE_RECTANGLE2, 74,
|
||||
ID_MUTE_3, IDS_CUT_MUTE_TRIANGLE, 75,
|
||||
ID_MUTE_4, IDS_CUT_MUTE_NOISE, 76,
|
||||
ID_MUTE_5, IDS_CUT_MUTE_DPCM, 77,
|
||||
ID_MUTE_6, IDS_CUT_MUTE_EXTERNAL1, 78,
|
||||
ID_MUTE_7, IDS_CUT_MUTE_EXTERNAL2, 79,
|
||||
ID_MUTE_8, IDS_CUT_MUTE_EXTERNAL3, 80,
|
||||
ID_MUTE_9, IDS_CUT_MUTE_EXTERNAL4, 81,
|
||||
ID_MUTE_A, IDS_CUT_MUTE_EXTERNAL5, 82,
|
||||
ID_MUTE_B, IDS_CUT_MUTE_EXTERNAL6, 83,
|
||||
ID_MUTE_C, IDS_CUT_MUTE_EXTERNAL7, 84,
|
||||
ID_MUTE_D, IDS_CUT_MUTE_EXTERNAL8, 85,
|
||||
|
||||
// Tape controls
|
||||
ID_TAPE_PLAY, IDS_CUT_TAPE_PLAY, 90,
|
||||
ID_TAPE_REC, IDS_CUT_TAPE_REC, 91,
|
||||
ID_TAPE_STOP, IDS_CUT_TAPE_STOP, 92,
|
||||
|
||||
// Other controls
|
||||
ID_SNAPSHOT, IDS_CUT_SNAPSHOT, 96,
|
||||
ID_FPSDISP, IDS_CUT_FPSDISP, 97,
|
||||
ID_TVASPECT, IDS_CUT_TVASPECT, 98,
|
||||
ID_TVFRAME, IDS_CUT_TVFRAME, 99,
|
||||
ID_SCANLINE, IDS_CUT_SCANLINE, 100,
|
||||
ID_ALLLINE, IDS_CUT_ALLLINE, 101,
|
||||
ID_ALLSPRITE, IDS_CUT_ALLSPRITE, 102,
|
||||
ID_LEFTCLIP, IDS_CUT_LEFTCLIP, 105,
|
||||
ID_SYNCDRAW, IDS_CUT_SYNCDRAW, 103,
|
||||
ID_FITSCREEN, IDS_CUT_FITSCREEN, 104,
|
||||
|
||||
// Tool controls
|
||||
ID_SEARCH, IDS_CUT_SEARCH, 110,
|
||||
ID_CHEAT, IDS_CUT_CHEAT, 111,
|
||||
ID_CHEAT_ENABLE, IDS_CUT_CHEAT_ENABLE, 112,
|
||||
ID_CHEAT_DISABLE, IDS_CUT_CHEAT_DISABLE, 113,
|
||||
ID_GENIE, IDS_CUT_GENIE, 114,
|
||||
|
||||
ID_VIEW_PATTERN, IDS_CUT_VIEW_PATTERN, 116,
|
||||
ID_VIEW_NAMETABLE, IDS_CUT_VIEW_NAMETABLE, 117,
|
||||
ID_VIEW_PALETTE, IDS_CUT_VIEW_PALETTE, 118,
|
||||
|
||||
ID_VIEW_MEMORY, IDS_CUT_VIEW_MEMORY, 119,
|
||||
|
||||
0, 0, 0
|
||||
};
|
||||
|
||||
void CConfig::Load()
|
||||
{
|
||||
INT i, j;
|
||||
string ret;
|
||||
string section;
|
||||
CHAR keys[64];
|
||||
CHAR szTemp[MAX_PATH];
|
||||
WORD szKeyTemp[64];
|
||||
|
||||
// General
|
||||
section = "General";
|
||||
|
||||
general.bDoubleExecute = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DoubleExecute", general.bDoubleExecute );
|
||||
general.bStartupLauncher = (BOOL)CRegistry::GetProfileInt( section.c_str(), "StartupLauncher", general.bStartupLauncher );
|
||||
|
||||
// general.bWindowSave = CRegistry::GetProfileInt( section.c_str(), "WindowPosSave", general.bWindowSave );
|
||||
general.bWindowZoom = CRegistry::GetProfileInt( section.c_str(), "WindowZoom", general.bWindowZoom );
|
||||
|
||||
RECT rc;
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
|
||||
general.rcWindowPos = rc;
|
||||
}
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "SearchDialogPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
|
||||
general.rcSearchDlgPos = rc;
|
||||
}
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "PatternViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
|
||||
general.rcPatternViewPos = rc;
|
||||
}
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "NameTableViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
|
||||
general.rcNameTableViewPos = rc;
|
||||
}
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "PaletteViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
|
||||
general.rcPaletteViewPos = rc;
|
||||
}
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "MemoryViewPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
|
||||
general.rcMemoryViewPos = rc;
|
||||
}
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "BarcodePos", (LPBYTE)&rc, sizeof(RECT) ) ) {
|
||||
general.rcBarcodePos = rc;
|
||||
}
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "PaletteEditPos", (LPBYTE)&rc, sizeof(RECT) ) ) {
|
||||
general.rcPaletteEditPos = rc;
|
||||
}
|
||||
|
||||
general.nScreenZoom = CRegistry::GetProfileInt( section.c_str(), "ScreenZoom", general.nScreenZoom );
|
||||
|
||||
general.bNoJoystickID = (BOOL)CRegistry::GetProfileInt( section.c_str(), "NoJoystickID", general.bNoJoystickID );
|
||||
|
||||
general.nJoyAxisDisable = CRegistry::GetProfileInt( section.c_str(), "JoyAxisDisable", general.nJoyAxisDisable );
|
||||
|
||||
if( general.nJoyAxisDisable ) {
|
||||
// 以前の設定を引き継ぐ為
|
||||
WORD bits = 0;
|
||||
switch( general.nJoyAxisDisable ) {
|
||||
case 1:
|
||||
bits = (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5);
|
||||
break;
|
||||
case 2:
|
||||
bits = (1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5);
|
||||
break;
|
||||
case 3:
|
||||
bits = (1<<2)|(1<<3)|(1<<4)|(1<<5);
|
||||
break;
|
||||
case 4:
|
||||
bits = (1<<3)|(1<<4)|(1<<5);
|
||||
break;
|
||||
case 5:
|
||||
bits = (1<<4)|(1<<5);
|
||||
break;
|
||||
case 6:
|
||||
bits = (1<<5);
|
||||
break;
|
||||
}
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
general.JoyAxisSetting[i] = bits;
|
||||
}
|
||||
|
||||
general.nJoyAxisDisable = 0;
|
||||
} else {
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "JoyAxisSetting", szKeyTemp, 16*sizeof(WORD) ) ) {
|
||||
::memcpy( general.JoyAxisSetting, szKeyTemp, 16*sizeof(WORD) );
|
||||
}
|
||||
}
|
||||
// Paths
|
||||
section = "Path";
|
||||
|
||||
path.bRomAutoRunPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "RomAutoRunPathUse", path.bRomAutoRunPath );
|
||||
path.bRomPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "RomPathUse", path.bRomPath );
|
||||
path.bSavePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SavePathUse", path.bSavePath );
|
||||
path.bStatePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "StatePathUse", path.bStatePath );
|
||||
path.bSnapshotPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SnapshotPathUse", path.bSnapshotPath );
|
||||
path.bMoviePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "MoviePathUse", path.bMoviePath );
|
||||
path.bWavePath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "WavePathUse", path.bWavePath );
|
||||
path.bCheatPath = (BOOL)CRegistry::GetProfileInt( section.c_str(), "CheatPathUse", path.bCheatPath );
|
||||
|
||||
if( CRegistry::GetProfileString(section.c_str(), "RomAutoRunPath", szTemp, sizeof(szTemp))) {
|
||||
::strcpy(path.szRomAutoRunPath, szTemp);
|
||||
DEBUGOUT("RomAutoRunPath = %s\n", szTemp);
|
||||
} else {
|
||||
DEBUGOUT("RomAutoRunPath get failed! write default path\n");
|
||||
CRegistry::WriteProfileString( section.c_str(), "RomAutoRunPath", path.szRomAutoRunPath );
|
||||
}
|
||||
|
||||
if( CRegistry::GetProfileString( section.c_str(), "RomPath", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( path.szRomPath, szTemp );
|
||||
if( CRegistry::GetProfileString( section.c_str(), "SavePath", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( path.szSavePath, szTemp );
|
||||
if( CRegistry::GetProfileString( section.c_str(), "StatePath", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( path.szStatePath, szTemp );
|
||||
if( CRegistry::GetProfileString( section.c_str(), "SnapshotPath", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( path.szSnapshotPath, szTemp );
|
||||
if( CRegistry::GetProfileString( section.c_str(), "MoviePath", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( path.szMoviePath, szTemp );
|
||||
if( CRegistry::GetProfileString( section.c_str(), "WavePath", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( path.szWavePath, szTemp );
|
||||
if( CRegistry::GetProfileString( section.c_str(), "CheatPath", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( path.szCheatPath, szTemp );
|
||||
|
||||
// Emulator
|
||||
section = "Emulation";
|
||||
|
||||
emulator.bIllegalOp = (BOOL)CRegistry::GetProfileInt( section.c_str(), "IllegalOp", emulator.bIllegalOp );
|
||||
emulator.bAutoFrameSkip = (BOOL)CRegistry::GetProfileInt( section.c_str(), "AutoFrameSkip", emulator.bAutoFrameSkip );
|
||||
emulator.bThrottle = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Throttle", emulator.bThrottle );
|
||||
emulator.nThrottleFPS = CRegistry::GetProfileInt( section.c_str(), "ThrottleFPS", emulator.nThrottleFPS );
|
||||
emulator.bBackground = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Background", emulator.bBackground );
|
||||
emulator.nPriority = CRegistry::GetProfileInt( section.c_str(), "Priority", emulator.nPriority );
|
||||
emulator.bFourPlayer = (BOOL)CRegistry::GetProfileInt( section.c_str(), "FourPlayer", emulator.bFourPlayer );
|
||||
emulator.bCrcCheck = (BOOL)CRegistry::GetProfileInt( section.c_str(), "CrcCheck", emulator.bCrcCheck );
|
||||
emulator.bDiskThrottle = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DiskThrottle", emulator.bDiskThrottle );
|
||||
emulator.bLoadFullscreen= (BOOL)CRegistry::GetProfileInt( section.c_str(), "LoadFullscreen",emulator.bLoadFullscreen );
|
||||
emulator.bPNGsnapshot = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PNGsnapshot", emulator.bPNGsnapshot );
|
||||
|
||||
// Graphic
|
||||
section = "Graphics";
|
||||
|
||||
graphics.bAspect = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Aspect", graphics.bAspect );
|
||||
graphics.bAllSprite = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SpriteMax", graphics.bAllSprite );
|
||||
graphics.bAllLine = (BOOL)CRegistry::GetProfileInt( section.c_str(), "AllLine", graphics.bAllLine );
|
||||
graphics.bFPSDisp = (BOOL)CRegistry::GetProfileInt( section.c_str(), "FPSDisp", graphics.bFPSDisp );
|
||||
graphics.bTVFrame = (BOOL)CRegistry::GetProfileInt( section.c_str(), "TVFrameMode", graphics.bTVFrame );
|
||||
graphics.bScanline = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ScanlineMode", graphics.bScanline );
|
||||
graphics.nScanlineColor = CRegistry::GetProfileInt( section.c_str(), "ScanlineColor", graphics.nScanlineColor );
|
||||
graphics.bSyncDraw = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SyncDraw", graphics.bSyncDraw );
|
||||
graphics.bFitZoom = (BOOL)CRegistry::GetProfileInt( section.c_str(), "MaxZoom", graphics.bFitZoom );
|
||||
|
||||
graphics.bLeftClip = (BOOL)CRegistry::GetProfileInt( section.c_str(), "LeftClip", graphics.bLeftClip );
|
||||
|
||||
graphics.bWindowVSync = (BOOL)CRegistry::GetProfileInt( section.c_str(), "WindowVSync", graphics.bWindowVSync );
|
||||
graphics.bSyncNoSleep = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SyncNoSleep", graphics.bSyncNoSleep );
|
||||
|
||||
graphics.bDiskAccessLamp= (BOOL)CRegistry::GetProfileInt( section.c_str(), "DiskAccessLamp",graphics.bDiskAccessLamp );
|
||||
|
||||
graphics.bDoubleSize = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DoubleSize", graphics.bDoubleSize );
|
||||
graphics.bSystemMemory = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SystemMemory", graphics.bSystemMemory );
|
||||
graphics.bUseHEL = (BOOL)CRegistry::GetProfileInt( section.c_str(), "UseHEL", graphics.bUseHEL );
|
||||
|
||||
graphics.bNoSquareList = (BOOL)CRegistry::GetProfileInt( section.c_str(), "NoSquareList", graphics.bNoSquareList );
|
||||
|
||||
graphics.nGraphicsFilter= CRegistry::GetProfileInt( section.c_str(), "GraphicsFilter",graphics.nGraphicsFilter );
|
||||
|
||||
graphics.dwDisplayWidth = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayWidth", graphics.dwDisplayWidth );
|
||||
graphics.dwDisplayHeight = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayHeight", graphics.dwDisplayHeight );
|
||||
graphics.dwDisplayDepth = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayDepth", graphics.dwDisplayDepth );
|
||||
graphics.dwDisplayRate = (DWORD)CRegistry::GetProfileInt( section.c_str(), "DisplayRate", graphics.dwDisplayRate );
|
||||
|
||||
graphics.bPaletteFile = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PaletteUse", graphics.bPaletteFile );
|
||||
|
||||
if( CRegistry::GetProfileString( section.c_str(), "PaletteFile", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( graphics.szPaletteFile, szTemp );
|
||||
|
||||
// Sound
|
||||
section = "Sound";
|
||||
|
||||
sound.bEnable = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Enable", sound.bEnable );
|
||||
sound.nRate = CRegistry::GetProfileInt( section.c_str(), "SamplingRate", sound.nRate );
|
||||
sound.nBits = CRegistry::GetProfileInt( section.c_str(), "SamplingBits", sound.nBits );
|
||||
sound.nBufferSize = CRegistry::GetProfileInt( section.c_str(), "BufferSize", sound.nBufferSize );
|
||||
sound.nFilterType = CRegistry::GetProfileInt( section.c_str(), "FilterType", sound.nFilterType );
|
||||
|
||||
sound.bChangeTone = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ChangeTone", sound.bChangeTone );
|
||||
|
||||
sound.bDisableVolumeEffect = (BOOL)CRegistry::GetProfileInt( section.c_str(), "DisableVolumeEffect", sound.bDisableVolumeEffect );
|
||||
sound.bExtraSoundEnable = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ExtraSoundEnable", sound.bExtraSoundEnable );
|
||||
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "Volume", szTemp, sizeof(sound.nVolume) ) )
|
||||
::memcpy( sound.nVolume, szTemp, sizeof(sound.nVolume) );
|
||||
|
||||
// ShortCuts
|
||||
section = "ShortCut";
|
||||
for( i = 0; i < sizeof(shortcut.nShortCut)/(16*sizeof(WORD)); i++ ) {
|
||||
::wsprintf( keys, "Tbl%02d", i );
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), keys, szTemp, 16*sizeof(WORD) ) )
|
||||
::memcpy( &shortcut.nShortCut[i*16], szTemp, 16*sizeof(WORD) );
|
||||
}
|
||||
|
||||
// Controllers
|
||||
for( i = 0; i < 4; i++ ) {
|
||||
::wsprintf( keys, "Controller %d", i+1 );
|
||||
if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 64*sizeof(WORD) ) ) {
|
||||
::memcpy( controller.nButton[i], szKeyTemp, 64*sizeof(WORD) );
|
||||
} else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 32*sizeof(WORD) ) ) {
|
||||
// 古い設定を引き継ぐ為の措置
|
||||
::memcpy( &controller.nButton[i][ 0], &szKeyTemp[ 0], 16*sizeof(WORD) );
|
||||
::memcpy( &controller.nButton[i][32], &szKeyTemp[16], 16*sizeof(WORD) );
|
||||
::memcpy( controller.nButton[i], szKeyTemp, 32*sizeof(WORD) );
|
||||
} else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 20*sizeof(WORD) ) ) {
|
||||
// 古い設定を引き継ぐ為の措置
|
||||
::memcpy( &controller.nButton[i][ 0], &szKeyTemp[ 0], 10*sizeof(WORD) );
|
||||
::memcpy( &controller.nButton[i][32], &szKeyTemp[10], 10*sizeof(WORD) );
|
||||
// Micの変更
|
||||
if( i == 1 ) {
|
||||
controller.nButton[i][10] = szKeyTemp[ 8];
|
||||
controller.nButton[i][ 8] = 0;
|
||||
controller.nButton[i][42] = szKeyTemp[18];
|
||||
controller.nButton[i][40] = 0;
|
||||
}
|
||||
} else if( CRegistry::GetProfileBinary( keys, "Keys", szKeyTemp, 10*sizeof(WORD) ) ) {
|
||||
// 古い設定を引き継ぐ為の措置
|
||||
::memcpy( controller.nButton[i], szKeyTemp, 10*sizeof(WORD) );
|
||||
// Micの変更
|
||||
if( i == 1 ) {
|
||||
controller.nButton[i][10] = szKeyTemp[ 8];
|
||||
controller.nButton[i][ 8] = 0;
|
||||
}
|
||||
}
|
||||
if( CRegistry::GetProfileBinary( keys, "Rapid", szTemp, 2*sizeof(WORD) ) )
|
||||
::memcpy( controller.nRapid[i], szTemp, 2*sizeof(WORD) );
|
||||
}
|
||||
|
||||
// ExControllers
|
||||
for( i = 0; i < 4; i++ ) {
|
||||
if( i == 0 ) section = "Crazy Climber";
|
||||
if( i == 1 ) section = "Family Trainer";
|
||||
if( i == 2 ) section = "Exciting Boxing";
|
||||
if( i == 3 ) section = "Mahjang";
|
||||
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) {
|
||||
::memcpy( controller.nExButton[i], szKeyTemp, 64*sizeof(WORD) );
|
||||
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 32*sizeof(WORD) ) ) {
|
||||
::memcpy( &controller.nExButton[i][ 0], &szKeyTemp[ 0], 16*sizeof(WORD) );
|
||||
::memcpy( &controller.nExButton[i][32], &szKeyTemp[16], 16*sizeof(WORD) );
|
||||
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 20*sizeof(WORD) ) ) {
|
||||
// 古い設定を引き継ぐ為の措置
|
||||
::memcpy( &controller.nExButton[i][ 0], &szKeyTemp[ 0], 10*sizeof(WORD) );
|
||||
::memcpy( &controller.nExButton[i][32], &szKeyTemp[10], 10*sizeof(WORD) );
|
||||
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 10*sizeof(WORD) ) ) {
|
||||
// 古い設定を引き継ぐ為の措置
|
||||
::memcpy( controller.nExButton[i], szKeyTemp, 10*sizeof(WORD) );
|
||||
}
|
||||
}
|
||||
|
||||
// NSF Contoller
|
||||
section = "NSF controller";
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) {
|
||||
::memcpy( controller.nNsfButton, szKeyTemp, 64*sizeof(WORD) );
|
||||
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 32*sizeof(WORD) ) ) {
|
||||
::memcpy( &controller.nNsfButton[ 0], &szKeyTemp[ 0], 16*sizeof(WORD) );
|
||||
::memcpy( &controller.nNsfButton[32], &szKeyTemp[16], 16*sizeof(WORD) );
|
||||
} else if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 20*sizeof(WORD) ) ) {
|
||||
// 古い設定を引き継ぐ為の措置
|
||||
::memcpy( &controller.nNsfButton[ 0], &szKeyTemp[ 0], 10*sizeof(WORD) );
|
||||
::memcpy( &controller.nNsfButton[32], &szKeyTemp[10], 10*sizeof(WORD) );
|
||||
}
|
||||
|
||||
// VS-Unisystem
|
||||
section = "VS-Unisystem";
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "Keys", szKeyTemp, 64*sizeof(WORD) ) ) {
|
||||
::memcpy( controller.nVSUnisystem, szKeyTemp, 64*sizeof(WORD) );
|
||||
}
|
||||
|
||||
// Movie
|
||||
section = "Movie";
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "UsePlayer", szTemp, sizeof(movie.bUsePlayer) ) )
|
||||
::memcpy( movie.bUsePlayer, szTemp, sizeof(movie.bUsePlayer) );
|
||||
movie.bResetRec = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ResetRec", movie.bResetRec );
|
||||
movie.bRerecord = (BOOL)CRegistry::GetProfileInt( section.c_str(), "Rerecord", movie.bRerecord );
|
||||
movie.bLoopPlay = (BOOL)CRegistry::GetProfileInt( section.c_str(), "LoopPlay", movie.bLoopPlay );
|
||||
movie.bPadDisplay = (BOOL)CRegistry::GetProfileInt( section.c_str(), "PadDisplay", movie.bPadDisplay );
|
||||
|
||||
// Launcher
|
||||
section = "Launcher";
|
||||
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&rc, sizeof(RECT) ) )
|
||||
launcher.rcWindowPos = rc;
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "ColumnView", szTemp, sizeof(launcher.bHeaderView) ) )
|
||||
::memcpy( launcher.bHeaderView, szTemp, sizeof(launcher.bHeaderView) );
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "ColumnOrder", szTemp, sizeof(launcher.nHeaderOrder) ) )
|
||||
::memcpy( launcher.nHeaderOrder, szTemp, sizeof(launcher.nHeaderOrder) );
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "ColumnWidth", szTemp, sizeof(launcher.nHeaderWidth) ) )
|
||||
::memcpy( launcher.nHeaderWidth, szTemp, sizeof(launcher.nHeaderWidth) );
|
||||
|
||||
launcher.nListSelect = CRegistry::GetProfileInt( section.c_str(), "ListSelect", launcher.nListSelect );
|
||||
|
||||
launcher.bSortDir = (BOOL)CRegistry::GetProfileInt( section.c_str(), "SortDir", launcher.bSortDir );
|
||||
launcher.nSortType = CRegistry::GetProfileInt( section.c_str(), "SortType", launcher.nSortType );
|
||||
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "ColumnSort", szTemp, sizeof(launcher.nHeaderWidth) ) )
|
||||
::memcpy( launcher.nHeaderWidth, szTemp, sizeof(launcher.nHeaderWidth) );
|
||||
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "FolderUse", szTemp, sizeof(launcher.bFolderUse) ) )
|
||||
::memcpy( launcher.bFolderUse, szTemp, sizeof(launcher.bFolderUse) );
|
||||
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
::wsprintf( keys, "Folder%02d", i );
|
||||
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( launcher.szFolder[i], szTemp );
|
||||
}
|
||||
|
||||
if( CRegistry::GetProfileString( section.c_str(), "LastSelect", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( launcher.szLastSelect, szTemp );
|
||||
|
||||
launcher.bActivePause = (BOOL)CRegistry::GetProfileInt( section.c_str(), "ActivePause", launcher.bActivePause );
|
||||
|
||||
// ExtraSound
|
||||
section = "ExtraSound";
|
||||
|
||||
for( i = ESF_MOEPRO_STRIKE; i <= ESF_MOEPRO_WA; i++ ) {
|
||||
::wsprintf( keys, "Moepro%02d", i );
|
||||
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( extsound.szExtSoundFile[i], szTemp );
|
||||
}
|
||||
|
||||
for( i = ESF_DISKSYSTEM_BOOT, j = 0; i <= ESF_DISKSYSTEM_SEEKEND; i++, j++ ) {
|
||||
::wsprintf( keys, "DiskSound%02d", j );
|
||||
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( extsound.szExtSoundFile[i], szTemp );
|
||||
}
|
||||
|
||||
// NetPlay
|
||||
section = "Netplay";
|
||||
|
||||
if( CRegistry::GetProfileBinary( section.c_str(), "ChatPos", (LPBYTE)&rc, sizeof(RECT) ) )
|
||||
netplay.rcChatPos = rc;
|
||||
|
||||
if( CRegistry::GetProfileString( section.c_str(), "NickName", szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( netplay.szNick, szTemp );
|
||||
|
||||
netplay.nRecentPort = CRegistry::GetProfileInt( section.c_str(), "RecnetPortNum", netplay.nRecentPort );
|
||||
for( i = 0; i < netplay.nRecentPort; i++ ) {
|
||||
::wsprintf( keys, "RecentPort%02d", i );
|
||||
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( netplay.szRecentPort[i], szTemp );
|
||||
}
|
||||
|
||||
netplay.nRecentHost = CRegistry::GetProfileInt( section.c_str(), "RecnetHostNum", netplay.nRecentHost );
|
||||
for( i = 0; i < netplay.nRecentHost; i++ ) {
|
||||
::wsprintf( keys, "RecentHost%02d", i );
|
||||
if( CRegistry::GetProfileString( section.c_str(), keys, szTemp, sizeof(szTemp) ) )
|
||||
::strcpy( netplay.szRecentHost[i], szTemp );
|
||||
}
|
||||
}
|
||||
|
||||
void CConfig::Save()
|
||||
{
|
||||
INT i;
|
||||
string section;
|
||||
CHAR keys[64];
|
||||
|
||||
// General
|
||||
section = "General";
|
||||
|
||||
CRegistry::WriteProfileInt ( section.c_str(), "DoubleExecute", general.bDoubleExecute );
|
||||
CRegistry::WriteProfileInt ( section.c_str(), "StartupLauncher", general.bStartupLauncher );
|
||||
|
||||
// CRegistry::WriteProfileInt( section.c_str(), "WindowPosSave", general.bWindowSave );
|
||||
CRegistry::WriteProfileInt ( section.c_str(), "WindowZoom", general.bWindowZoom );
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&general.rcWindowPos, sizeof(RECT) );
|
||||
CRegistry::WriteProfileInt ( section.c_str(), "ScreenZoom", general.nScreenZoom );
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "SearchDialogPos", (LPBYTE)&general.rcSearchDlgPos, sizeof(RECT) );
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "PatternViewPos", (LPBYTE)&general.rcPatternViewPos, sizeof(RECT) );
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "NameTableViewPos", (LPBYTE)&general.rcNameTableViewPos, sizeof(RECT) );
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "PaletteViewPos", (LPBYTE)&general.rcPaletteViewPos, sizeof(RECT) );
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "MemoryViewPos", (LPBYTE)&general.rcMemoryViewPos, sizeof(RECT) );
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "BarcodePos", (LPBYTE)&general.rcBarcodePos, sizeof(RECT) );
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "PaletteEditPos", (LPBYTE)&general.rcPaletteEditPos, sizeof(RECT) );
|
||||
|
||||
CRegistry::WriteProfileInt ( section.c_str(), "JoyAxisDisable", general.nJoyAxisDisable );
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "JoyAxisSetting", (LPBYTE)general.JoyAxisSetting, 16*sizeof(WORD) );
|
||||
|
||||
// Paths
|
||||
section = "Path";
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "RomPathUse", path.bRomPath );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SavePathUse", path.bSavePath );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "StatePathUse", path.bStatePath );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SnapshotPathUse", path.bSnapshotPath );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "MoviePathUse", path.bMoviePath );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "WavePathUse", path.bWavePath );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "CheatPathUse", path.bCheatPath );
|
||||
|
||||
CRegistry::WriteProfileString( section.c_str(), "RomAutoRunPath", path.szRomAutoRunPath );
|
||||
CRegistry::WriteProfileString( section.c_str(), "RomPath", path.szRomPath );
|
||||
CRegistry::WriteProfileString( section.c_str(), "SavePath", path.szSavePath );
|
||||
CRegistry::WriteProfileString( section.c_str(), "StatePath", path.szStatePath );
|
||||
CRegistry::WriteProfileString( section.c_str(), "SnapshotPath", path.szSnapshotPath );
|
||||
CRegistry::WriteProfileString( section.c_str(), "MoviePath", path.szMoviePath );
|
||||
CRegistry::WriteProfileString( section.c_str(), "WavePath", path.szWavePath );
|
||||
CRegistry::WriteProfileString( section.c_str(), "CheatPath", path.szCheatPath );
|
||||
|
||||
// Emulation
|
||||
section = "Emulation";
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "IllegalOp", emulator.bIllegalOp );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "AutoFrameSkip", emulator.bAutoFrameSkip );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "Throttle", emulator.bThrottle );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "ThrottleFPS", emulator.nThrottleFPS );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "Background", emulator.bBackground );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "Priority", emulator.nPriority );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "FourPlayer", emulator.bFourPlayer );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "CrcCheck", emulator.bCrcCheck );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "DiskThrottle", emulator.bDiskThrottle );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "LoadFullscreen",emulator.bLoadFullscreen );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "PNGsnapshot", emulator.bPNGsnapshot );
|
||||
|
||||
// Graphic
|
||||
section = "Graphics";
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "Aspect", graphics.bAspect );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SpriteMax", graphics.bAllSprite );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "AllLine", graphics.bAllLine );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "FPSDisp", graphics.bFPSDisp );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "TVFrameMode", graphics.bTVFrame );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "ScanlineMode", graphics.bScanline );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "ScanlineColor", graphics.nScanlineColor );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SyncDraw", graphics.bSyncDraw );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "MaxZoom", graphics.bFitZoom );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "LeftClip", graphics.bLeftClip );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "WindowVSync", graphics.bWindowVSync );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "DiskAccessLamp",graphics.bDiskAccessLamp );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "DoubleSize", graphics.bDoubleSize );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SystemMemory", graphics.bSystemMemory );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "UseHEL", graphics.bUseHEL );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "NoSquareList", graphics.bNoSquareList );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "GraphicsFilter",graphics.nGraphicsFilter );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "DisplayWidth", graphics.dwDisplayWidth );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "DisplayHeight", graphics.dwDisplayHeight );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "DisplayDepth", graphics.dwDisplayDepth );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "DisplayRate", graphics.dwDisplayRate );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "PaletteUse", graphics.bPaletteFile );
|
||||
CRegistry::WriteProfileString( section.c_str(), "PaletteFile", graphics.szPaletteFile );
|
||||
|
||||
// Sound
|
||||
section = "Sound";
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "Enable", sound.bEnable );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "DisableVolumeEffect", sound.bDisableVolumeEffect );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "ExtraSoundEnable", sound.bExtraSoundEnable );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SamplingRate", sound.nRate );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SamplingBits", sound.nBits );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "BufferSize", sound.nBufferSize );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "FilterType", sound.nFilterType );
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "Volume", (LPBYTE)sound.nVolume, sizeof(sound.nVolume) );
|
||||
|
||||
// ShortCut
|
||||
section = "ShortCut";
|
||||
for( i = 0; i < sizeof(shortcut.nShortCut)/(16*sizeof(WORD)); i++ ) {
|
||||
::wsprintf( keys, "TBL%02d", i );
|
||||
CRegistry::WriteProfileBinary( section.c_str(), keys, (LPBYTE)&shortcut.nShortCut[i*16], 16*sizeof(WORD) );
|
||||
}
|
||||
|
||||
// Controllers
|
||||
for( i = 0; i < 4; i++ ) {
|
||||
::wsprintf( keys, "Controller %01d", i+1 );
|
||||
CRegistry::WriteProfileBinary( keys, "Keys", (LPBYTE)controller.nButton[i], 64*sizeof(WORD) );
|
||||
CRegistry::WriteProfileBinary( keys, "Rapid", (LPBYTE)controller.nRapid[i], 2*sizeof(WORD) );
|
||||
}
|
||||
|
||||
// ExControllers
|
||||
section = "Crazy Climber";
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[0], 64*sizeof(WORD) );
|
||||
section = "Family Trainer";
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[1], 64*sizeof(WORD) );
|
||||
section = "Exciting Boxing";
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[2], 64*sizeof(WORD) );
|
||||
section = "Mahjang";
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nExButton[3], 64*sizeof(WORD) );
|
||||
|
||||
// NSF Contoller
|
||||
section = "NSF controller";
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nNsfButton, 64*sizeof(WORD) );
|
||||
|
||||
// VS-Unisystem
|
||||
section = "VS-Unisystem";
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "Keys", (LPBYTE)controller.nVSUnisystem, 64*sizeof(WORD) );
|
||||
|
||||
// Movie
|
||||
section = "Movie";
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "UsePlayer", (LPBYTE)movie.bUsePlayer, sizeof(movie.bUsePlayer) );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "ResetRec", movie.bResetRec );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "Rerecord", movie.bRerecord );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "LoopPlay", movie.bLoopPlay );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "PadDisplay", movie.bPadDisplay );
|
||||
|
||||
// Launcher
|
||||
section = "Launcher";
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "WindowPos", (LPBYTE)&launcher.rcWindowPos, sizeof(RECT) );
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "ColumnView", (LPBYTE)launcher.bHeaderView, sizeof(launcher.bHeaderView) );
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "ColumnOrder", (LPBYTE)launcher.nHeaderOrder, sizeof(launcher.nHeaderOrder) );
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "ColumnWidth", (LPBYTE)launcher.nHeaderWidth, sizeof(launcher.nHeaderWidth) );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "ListSelect", launcher.nListSelect );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SortDir", launcher.bSortDir );
|
||||
CRegistry::WriteProfileInt( section.c_str(), "SortType", launcher.nSortType );
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "FolderUse", (LPBYTE)launcher.bFolderUse, sizeof(launcher.bFolderUse) );
|
||||
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
::wsprintf( keys, "Folder%02d", i );
|
||||
CRegistry::WriteProfileString( section.c_str(), keys, launcher.szFolder[i] );
|
||||
}
|
||||
|
||||
CRegistry::WriteProfileString( section.c_str(), "LastSelect", launcher.szLastSelect );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "ActivePause", launcher.bActivePause );
|
||||
|
||||
// NetPlay
|
||||
section = "Netplay";
|
||||
|
||||
CRegistry::WriteProfileBinary( section.c_str(), "ChatPos", (LPBYTE)&netplay.rcChatPos, sizeof(RECT) );
|
||||
|
||||
CRegistry::WriteProfileString( section.c_str(), "NickName", netplay.szNick );
|
||||
|
||||
CRegistry::WriteProfileInt( section.c_str(), "RecnetPortNum", netplay.nRecentPort );
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
::wsprintf( keys, "RecentPort%02d", i );
|
||||
CRegistry::WriteProfileString( section.c_str(), keys, netplay.szRecentPort[i] );
|
||||
}
|
||||
CRegistry::WriteProfileInt( section.c_str(), "RecnetHostNum", netplay.nRecentHost );
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
::wsprintf( keys, "RecentHost%02d", i );
|
||||
CRegistry::WriteProfileString( section.c_str(), keys, netplay.szRecentHost[i] );
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CConfig::ButtonCheck( INT nNo, INT nID )
|
||||
{
|
||||
if( m_bKeyboardDisable ) {
|
||||
if( (Config.controller.nButton[nNo][nID+ 0] >= 256) && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+ 0]]
|
||||
|| (Config.controller.nButton[nNo][nID+32] >= 256) && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+32]] )
|
||||
return TRUE;
|
||||
} else {
|
||||
if( Config.controller.nButton[nNo][nID+ 0] && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+ 0]]
|
||||
|| Config.controller.nButton[nNo][nID+32] && DirectInput.m_Sw[Config.controller.nButton[nNo][nID+32]] )
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CConfig::ExButtonCheck( INT nNo, INT nID )
|
||||
{
|
||||
if( Config.controller.nExButton[nNo][nID+ 0] && DirectInput.m_Sw[Config.controller.nExButton[nNo][nID+ 0]]
|
||||
|| Config.controller.nExButton[nNo][nID+32] && DirectInput.m_Sw[Config.controller.nExButton[nNo][nID+32]] )
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CConfig::NsfButtonCheck( INT nID )
|
||||
{
|
||||
if( Config.controller.nNsfButton[nID+ 0] && DirectInput.m_Sw[Config.controller.nNsfButton[nID+ 0]]
|
||||
|| Config.controller.nNsfButton[nID+32] && DirectInput.m_Sw[Config.controller.nNsfButton[nID+32]] )
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CConfig::ButtonCheck( INT nID, WORD* pKey )
|
||||
{
|
||||
if( pKey[nID+ 0] && DirectInput.m_Sw[pKey[nID+ 0]]
|
||||
|| pKey[nID+32] && DirectInput.m_Sw[pKey[nID+32]] )
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
string CConfig::ShortcutToKeyName( INT nShortcutKey )
|
||||
{
|
||||
string str;
|
||||
if( nShortcutKey == 0 ) {
|
||||
str = "----";
|
||||
} else {
|
||||
if( nShortcutKey & CCfgShortCut::K_ALT )
|
||||
str = str + "Alt+";
|
||||
if( nShortcutKey & CCfgShortCut::K_CTRL )
|
||||
str = str + "Ctrl+";
|
||||
if( nShortcutKey & CCfgShortCut::K_SHIFT )
|
||||
str = str + "Shift+";
|
||||
|
||||
str = str + DirectInput.SearchKeyName( nShortcutKey & 0x0FFF );
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
CGameOption GameOption;
|
||||
|
||||
void CGameOption::Load( DWORD crc )
|
||||
{
|
||||
CRegistry::SetRegistryKey( "GameOption.ini" );
|
||||
|
||||
CHAR szSection[256];
|
||||
::wsprintf( szSection, "%08X", crc );
|
||||
nRenderMethod = CRegistry::GetProfileInt( szSection, "RenderMethod", defRenderMethod );
|
||||
nIRQtype = CRegistry::GetProfileInt( szSection, "IRQtype", defIRQtype );
|
||||
bFrameIRQ = (BOOL)CRegistry::GetProfileInt( szSection, "FrameIRQ", defFrameIRQ );
|
||||
bVideoMode = (BOOL)CRegistry::GetProfileInt( szSection, "VideoMode", defVideoMode );
|
||||
}
|
||||
|
||||
void CGameOption::Save( LPCSTR name, DWORD crc )
|
||||
{
|
||||
CRegistry::SetRegistryKey( "GameOption.ini" );
|
||||
|
||||
CHAR szSection[256];
|
||||
::wsprintf( szSection, "%08X", crc );
|
||||
CRegistry::WriteProfileString( szSection, "Title", name );
|
||||
CRegistry::WriteProfileInt( szSection, "RenderMethod", nRenderMethod );
|
||||
CRegistry::WriteProfileInt( szSection, "IRQtype", nIRQtype );
|
||||
CRegistry::WriteProfileInt( szSection, "FrameIRQ", (INT)bFrameIRQ );
|
||||
CRegistry::WriteProfileInt( szSection, "VideoMode", (INT)bVideoMode );
|
||||
}
|
||||
|
||||
void CGameOption::Load( DWORD gid, DWORD mid )
|
||||
{
|
||||
CRegistry::SetRegistryKey( "GameOption.ini" );
|
||||
|
||||
CHAR szSection[256];
|
||||
::wsprintf( szSection, "%08X%08X", gid, mid );
|
||||
nRenderMethod = CRegistry::GetProfileInt( szSection, "RenderMethod", defRenderMethod );
|
||||
nIRQtype = CRegistry::GetProfileInt( szSection, "IRQtype", defIRQtype );
|
||||
bFrameIRQ = (BOOL)CRegistry::GetProfileInt( szSection, "FrameIRQ", defFrameIRQ );
|
||||
}
|
||||
|
||||
void CGameOption::Save( LPCSTR name, DWORD gid, DWORD mid )
|
||||
{
|
||||
CRegistry::SetRegistryKey( "GameOption.ini" );
|
||||
|
||||
CHAR szSection[256];
|
||||
::wsprintf( szSection, "%08X%08X", gid, mid );
|
||||
CRegistry::WriteProfileString( szSection, "Title", name );
|
||||
CRegistry::WriteProfileInt( szSection, "RenderMethod", nRenderMethod );
|
||||
CRegistry::WriteProfileInt( szSection, "IRQtype", nIRQtype );
|
||||
CRegistry::WriteProfileInt( szSection, "FrameIRQ", (INT)bFrameIRQ );
|
||||
}
|
||||
|
||||
783
References/VirtuaNESex_src_191105/Config.h
Normal file
783
References/VirtuaNESex_src_191105/Config.h
Normal file
@ -0,0 +1,783 @@
|
||||
//
|
||||
// 設定保存クラス
|
||||
//
|
||||
#ifndef __CCONFIG_INCLUDED__
|
||||
#define __CCONFIG_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#define DIRECTINPUT_VERSION 0x0700
|
||||
#include <dinput.h>
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "extsoundfile.h"
|
||||
|
||||
#include "typedef.h"
|
||||
#include "macro.h"
|
||||
|
||||
class CCfgGeneral
|
||||
{
|
||||
public:
|
||||
BOOL bDoubleExecute;
|
||||
BOOL bStartupLauncher;
|
||||
|
||||
BOOL bWindowSave;
|
||||
BOOL bWindowZoom;
|
||||
RECT rcWindowPos;
|
||||
|
||||
BOOL bScreenMode;
|
||||
BOOL nScreenZoom;
|
||||
|
||||
RECT rcSearchDlgPos;
|
||||
|
||||
RECT rcPatternViewPos;
|
||||
RECT rcNameTableViewPos;
|
||||
RECT rcPaletteViewPos;
|
||||
RECT rcMemoryViewPos;
|
||||
|
||||
RECT rcBarcodePos;
|
||||
RECT rcPaletteEditPos;
|
||||
|
||||
BOOL bNoJoystickID;
|
||||
|
||||
WORD JoyAxisSetting[16];
|
||||
|
||||
// ジョイパッドの軸の無効化
|
||||
// 0 : All enable
|
||||
// 1 : X軸以降全て
|
||||
// 2 : Y軸以降全て
|
||||
// 3 : Z軸以降全て
|
||||
// 4 : RX軸以降全て
|
||||
// 5 : RY軸以降全て
|
||||
// 6 : RZ軸以降全て
|
||||
INT nJoyAxisDisable;
|
||||
|
||||
void Default() {
|
||||
bWindowSave = FALSE;
|
||||
bWindowZoom = FALSE;
|
||||
rcWindowPos.left = rcWindowPos.right =
|
||||
rcWindowPos.top = rcWindowPos.bottom = 0;
|
||||
|
||||
bDoubleExecute = TRUE;
|
||||
bStartupLauncher = FALSE;
|
||||
|
||||
bScreenMode = FALSE;
|
||||
nScreenZoom = 0;
|
||||
|
||||
rcSearchDlgPos.left = rcSearchDlgPos.right =
|
||||
rcSearchDlgPos.top = rcSearchDlgPos.bottom = 0;
|
||||
|
||||
rcPatternViewPos.left = rcPatternViewPos.right =
|
||||
rcPatternViewPos.top = rcPatternViewPos.bottom = 0;
|
||||
rcNameTableViewPos.left = rcNameTableViewPos.right =
|
||||
rcNameTableViewPos.top = rcNameTableViewPos.bottom = 0;
|
||||
rcPaletteViewPos.left = rcPaletteViewPos.right =
|
||||
rcPaletteViewPos.top = rcPaletteViewPos.bottom = 0;
|
||||
rcMemoryViewPos.left = rcMemoryViewPos.right =
|
||||
rcMemoryViewPos.top = rcMemoryViewPos.bottom = 0;
|
||||
|
||||
rcBarcodePos.left = rcBarcodePos.right =
|
||||
rcBarcodePos.top = rcBarcodePos.bottom = 0;
|
||||
|
||||
rcPaletteEditPos.left = rcPaletteEditPos.right =
|
||||
rcPaletteEditPos.top = rcPaletteEditPos.bottom = 0;
|
||||
|
||||
bNoJoystickID = FALSE;
|
||||
nJoyAxisDisable = 0;
|
||||
|
||||
for( INT i = 0; i < 16; i++ ) {
|
||||
JoyAxisSetting[i] = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgPath
|
||||
{
|
||||
public:
|
||||
BOOL bRomAutoRunPath;//ミト<EFBE90>ユlヨェサィ100エ<30><EFBDB4>メメカキ耿<EFBDB7>モオトケヲトワ ト」ト簇<EFBE84>ヒミミハアラヤカッエ<EFBDAF>ェヨクカィホトシ<EFBE84>
|
||||
BOOL bRomPath;
|
||||
BOOL bRamPath;
|
||||
BOOL bSavePath;
|
||||
BOOL bStatePath;
|
||||
BOOL bSnapshotPath;
|
||||
BOOL bMoviePath;
|
||||
BOOL bWavePath;
|
||||
BOOL bCheatPath;
|
||||
|
||||
CHAR szRomAutoRunPath [_MAX_PATH];
|
||||
CHAR szRomPath [_MAX_PATH];
|
||||
CHAR szRamPath [_MAX_PATH];
|
||||
CHAR szSavePath [_MAX_PATH];
|
||||
CHAR szStatePath [_MAX_PATH];
|
||||
CHAR szSnapshotPath[_MAX_PATH];
|
||||
CHAR szMoviePath [_MAX_PATH];
|
||||
CHAR szWavePath [_MAX_PATH];
|
||||
CHAR szCheatPath [_MAX_PATH];
|
||||
|
||||
void Default() {
|
||||
#if 0
|
||||
bRomPath = bRamPath = bSavePath =
|
||||
bStatePath = bSnapshotPath =
|
||||
bMoviePath = bWavePath =
|
||||
bCheatPath = FALSE;
|
||||
szRomPath[0] = szRamPath[0] = szSavePath[0] =
|
||||
szStatePath[0] = szSnapshotPath[0] =
|
||||
szMoviePath[0] = szWavePath[0] =
|
||||
szCheatPath[0] = 0;
|
||||
#endif
|
||||
bRomPath = bRomPath = bSavePath =
|
||||
bStatePath = bSnapshotPath =
|
||||
bMoviePath = bWavePath =
|
||||
bCheatPath = TRUE;
|
||||
|
||||
bRomAutoRunPath = FALSE;
|
||||
|
||||
::lstrcpy( szRomAutoRunPath, ".\\" );
|
||||
::lstrcpy( szRomPath, ".\\roms\\" );
|
||||
::lstrcpy( szRamPath, ".\\ram\\" );
|
||||
::lstrcpy( szSavePath, ".\\save\\" );
|
||||
::lstrcpy( szStatePath, ".\\state\\" );
|
||||
::lstrcpy( szSnapshotPath, ".\\snapshot\\" );
|
||||
::lstrcpy( szMoviePath, ".\\movie\\" );
|
||||
::lstrcpy( szWavePath, ".\\wave\\" );
|
||||
::lstrcpy( szCheatPath, ".\\cheatcode\\" );
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgEmulator
|
||||
{
|
||||
public:
|
||||
BOOL bIllegalOp;
|
||||
BOOL bAutoFrameSkip;
|
||||
BOOL bThrottle;
|
||||
INT nThrottleFPS;
|
||||
BOOL bBackground;
|
||||
INT nPriority;
|
||||
BOOL bFourPlayer;
|
||||
BOOL bCrcCheck;
|
||||
BOOL bDiskThrottle;
|
||||
BOOL bLoadFullscreen;
|
||||
BOOL bPNGsnapshot;
|
||||
|
||||
void Default() {
|
||||
bIllegalOp = FALSE;
|
||||
bAutoFrameSkip = TRUE;
|
||||
bThrottle = TRUE;
|
||||
nThrottleFPS = 120; // 120FPS
|
||||
bBackground = FALSE;
|
||||
nPriority = 3; // Normal
|
||||
bFourPlayer = TRUE; // TRUE:NES FALSE:Famicom
|
||||
bCrcCheck = TRUE;
|
||||
bDiskThrottle = TRUE;
|
||||
bLoadFullscreen = FALSE;
|
||||
bPNGsnapshot = FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgGraphics
|
||||
{
|
||||
public:
|
||||
BOOL bAspect;
|
||||
BOOL bAllSprite;
|
||||
BOOL bAllLine;
|
||||
BOOL bFPSDisp;
|
||||
BOOL bTVFrame;
|
||||
BOOL bScanline;
|
||||
INT nScanlineColor;
|
||||
BOOL bSyncDraw;
|
||||
BOOL bFitZoom;
|
||||
|
||||
BOOL bLeftClip;
|
||||
|
||||
BOOL bWindowVSync;
|
||||
|
||||
BOOL bSyncNoSleep;
|
||||
|
||||
BOOL bDiskAccessLamp;
|
||||
|
||||
BOOL bDoubleSize;
|
||||
BOOL bSystemMemory;
|
||||
BOOL bUseHEL;
|
||||
|
||||
BOOL bNoSquareList;
|
||||
|
||||
INT nGraphicsFilter;
|
||||
|
||||
DWORD dwDisplayWidth;
|
||||
DWORD dwDisplayHeight;
|
||||
DWORD dwDisplayDepth;
|
||||
DWORD dwDisplayRate;
|
||||
|
||||
BOOL bPaletteFile;
|
||||
CHAR szPaletteFile[_MAX_PATH];
|
||||
|
||||
void Default() {
|
||||
bAspect = FALSE;
|
||||
bAllSprite = TRUE;
|
||||
bAllLine = FALSE;
|
||||
bFPSDisp = FALSE;
|
||||
bTVFrame = FALSE;
|
||||
bScanline = FALSE;
|
||||
nScanlineColor = 75;
|
||||
bSyncDraw = FALSE;
|
||||
bFitZoom = FALSE;
|
||||
|
||||
bLeftClip = TRUE;
|
||||
|
||||
bWindowVSync = FALSE;
|
||||
bSyncNoSleep = FALSE;
|
||||
|
||||
bDiskAccessLamp = FALSE;
|
||||
|
||||
bDoubleSize = FALSE;
|
||||
bSystemMemory = FALSE;
|
||||
bUseHEL = FALSE;
|
||||
|
||||
bNoSquareList = FALSE;
|
||||
|
||||
nGraphicsFilter = 0;
|
||||
|
||||
dwDisplayWidth = 640;
|
||||
dwDisplayHeight = 480;
|
||||
dwDisplayDepth = 16;
|
||||
dwDisplayRate = 0;
|
||||
|
||||
bPaletteFile = FALSE;
|
||||
szPaletteFile[0] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgSound
|
||||
{
|
||||
public:
|
||||
BOOL bEnable;
|
||||
INT nRate;
|
||||
INT nBits;
|
||||
INT nBufferSize;
|
||||
|
||||
INT nFilterType;
|
||||
|
||||
BOOL bChangeTone;
|
||||
|
||||
BOOL bDisableVolumeEffect;
|
||||
BOOL bExtraSoundEnable;
|
||||
|
||||
// 0:Master
|
||||
// 1:Rectangle 1
|
||||
// 2:Rectangle 2
|
||||
// 3:Triangle
|
||||
// 4:Noise
|
||||
// 5:DPCM
|
||||
// 6:VRC6
|
||||
// 7:VRC7
|
||||
// 8:FDS
|
||||
// 9:MMC5
|
||||
// 10:N106
|
||||
// 11:FME7
|
||||
SHORT nVolume[16];
|
||||
|
||||
void Default() {
|
||||
bEnable = TRUE;
|
||||
nRate = 22050;
|
||||
nBits = 8;
|
||||
nBufferSize = 4;
|
||||
|
||||
nFilterType = 0;
|
||||
|
||||
bChangeTone = FALSE;
|
||||
|
||||
bDisableVolumeEffect = FALSE;
|
||||
bExtraSoundEnable = TRUE;
|
||||
|
||||
for( INT i = 0; i < 16; i++ ) {
|
||||
nVolume[i] = 100;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgShortCut
|
||||
{
|
||||
public:
|
||||
WORD nShortCut[512];
|
||||
|
||||
enum {
|
||||
K_ALT = 0x8000,
|
||||
K_CTRL = 0x4000,
|
||||
K_SHIFT = 0x2000,
|
||||
};
|
||||
|
||||
void Default() {
|
||||
for( INT i = 0; i < (sizeof(nShortCut)/sizeof(WORD)); i++ ) {
|
||||
nShortCut[i] = 0;
|
||||
}
|
||||
|
||||
// Main controls
|
||||
nShortCut[ 0] = DIK_O+K_CTRL; // ID_OPEN
|
||||
nShortCut[ 1] = DIK_C+K_CTRL; // ID_CLOSE
|
||||
nShortCut[ 2] = DIK_L+K_CTRL; // ID_LAUNCHER
|
||||
nShortCut[ 3] = DIK_N+K_CTRL; // ID_NETPLAY_CONNECT
|
||||
nShortCut[ 4] = DIK_D+K_CTRL; // ID_NETPLAY_DISCONNECT
|
||||
nShortCut[ 5] = DIK_A+K_CTRL; // ID_NETPLAY_CHAT
|
||||
nShortCut[ 8] = DIK_I+K_CTRL; // ID_ROMINFO
|
||||
nShortCut[ 9] = DIK_W+K_CTRL; // ID_WAVERECORD
|
||||
nShortCut[ 15] = DIK_X+K_CTRL; // ID_EXIT
|
||||
|
||||
// Emulation controls
|
||||
nShortCut[ 16] = DIK_F1; // Hardware reset
|
||||
nShortCut[ 17] = DIK_F2; // Software reset
|
||||
nShortCut[ 18] = DIK_P; // Hardware pause
|
||||
nShortCut[ 19] = DIK_TAB; // Throttle(toggled)
|
||||
nShortCut[ 20] = DIK_NUMPADENTER; // Frame skip Auto
|
||||
nShortCut[ 21] = DIK_ADD; // Frame skip +
|
||||
nShortCut[ 22] = DIK_SUBTRACT; // Frame skip -
|
||||
|
||||
nShortCut[ 23] = DIK_SPACE; // One Frame step
|
||||
nShortCut[ 24] = DIK_BACKSPACE; // Throttle(Not toggle)
|
||||
|
||||
// State controls
|
||||
nShortCut[ 32] = DIK_L; // State Load
|
||||
nShortCut[ 33] = DIK_S; // State Save
|
||||
nShortCut[ 34] = DIK_F3; // State Slot +
|
||||
nShortCut[ 35] = DIK_F4; // State Slot -
|
||||
|
||||
// Disk controls
|
||||
nShortCut[ 48] = DIK_5; // Disk Eject
|
||||
nShortCut[ 49] = DIK_1; // Disk 0 Side A
|
||||
nShortCut[ 50] = DIK_2; // Disk 0 Side B
|
||||
nShortCut[ 51] = DIK_3; // Disk 1 Side A
|
||||
nShortCut[ 52] = DIK_4; // Disk 1 Side B
|
||||
|
||||
// Movie controls
|
||||
nShortCut[ 56] = DIK_P+K_ALT; // Movie Play
|
||||
nShortCut[ 57] = DIK_R+K_ALT; // Movie Rec
|
||||
nShortCut[ 58] = DIK_A+K_ALT; // Movie Rec Append
|
||||
nShortCut[ 59] = DIK_S+K_ALT; // Movie Stop
|
||||
nShortCut[ 60] = DIK_M+K_ALT; // Movie Info
|
||||
|
||||
// Screen controls
|
||||
nShortCut[ 64] = DIK_F5; // Zoom x1
|
||||
nShortCut[ 65] = DIK_F6; // Zoom x2
|
||||
nShortCut[ 66] = DIK_F7; // Zoom x3
|
||||
nShortCut[ 67] = DIK_F8; // Zoom x4
|
||||
nShortCut[ 68] = DIK_RETURN+K_ALT; // Fullscreen
|
||||
|
||||
// Sound controls
|
||||
nShortCut[ 72] = DIK_BACK+K_CTRL; // Mute Master
|
||||
nShortCut[ 73] = DIK_1+K_CTRL; // Mute Rectangle #1
|
||||
nShortCut[ 74] = DIK_2+K_CTRL; // Mute Rectangle #2
|
||||
nShortCut[ 75] = DIK_3+K_CTRL; // Mute Triangle
|
||||
nShortCut[ 76] = DIK_4+K_CTRL; // Mute Noise
|
||||
nShortCut[ 77] = DIK_5+K_CTRL; // Mute Dpcm
|
||||
nShortCut[ 78] = DIK_6+K_CTRL; // Mute External #1
|
||||
nShortCut[ 79] = DIK_7+K_CTRL; // Mute External #2
|
||||
nShortCut[ 80] = DIK_8+K_CTRL; // Mute External #3
|
||||
nShortCut[ 81] = DIK_9+K_CTRL; // Mute External #4
|
||||
nShortCut[ 82] = DIK_0+K_CTRL; // Mute External #5
|
||||
nShortCut[ 83] = DIK_MINUS+K_CTRL; // Mute External #6
|
||||
nShortCut[ 84] = DIK_CIRCUMFLEX+K_CTRL; // Mute External #7
|
||||
nShortCut[ 85] = DIK_YEN+K_CTRL; // Mute External #8
|
||||
|
||||
// Tape controls
|
||||
nShortCut[ 90] = 0; // Tape Play
|
||||
nShortCut[ 91] = 0; // Tape Rec
|
||||
nShortCut[ 92] = 0; // Tape Stop
|
||||
|
||||
// Other controls
|
||||
nShortCut[ 96] = DIK_P+K_CTRL; // Snapshot
|
||||
nShortCut[ 97] = DIK_F11; // FPSDISP
|
||||
nShortCut[ 98] = DIK_F12+K_CTRL; // TV Aspect
|
||||
nShortCut[ 99] = DIK_F11+K_CTRL; // TV frame
|
||||
nShortCut[100] = DIK_F12; // Scanline
|
||||
nShortCut[101] = DIK_F9+K_CTRL; // Show 240 lines
|
||||
nShortCut[102] = DIK_F9; // All sprites
|
||||
nShortCut[103] = DIK_F10; // Sync draw
|
||||
nShortCut[104] = DIK_F10+K_CTRL; // Fit screen
|
||||
nShortCut[105] = 0; // Left clip
|
||||
|
||||
// Cheat
|
||||
nShortCut[110] = DIK_HOME+K_CTRL; // Search
|
||||
nShortCut[111] = DIK_END+K_CTRL; // Cheat
|
||||
nShortCut[112] = DIK_INSERT; // Cheat enable
|
||||
nShortCut[113] = DIK_DELETE; // Cheat disable
|
||||
nShortCut[114] = 0; // GameGenie
|
||||
|
||||
// Tools
|
||||
nShortCut[116] = 0; // Pattern Viewer
|
||||
nShortCut[117] = 0; // NameTable Viewer
|
||||
nShortCut[118] = 0; // Palette Viewer
|
||||
|
||||
nShortCut[119] = 0; // Memory Viewer
|
||||
|
||||
// Quick Load/Save
|
||||
nShortCut[256] = DIK_NUMPAD0+K_CTRL; // QuickLoad Slot0
|
||||
nShortCut[257] = DIK_NUMPAD1+K_CTRL; // QuickLoad Slot1
|
||||
nShortCut[258] = DIK_NUMPAD2+K_CTRL; // QuickLoad Slot2
|
||||
nShortCut[259] = DIK_NUMPAD3+K_CTRL; // QuickLoad Slot3
|
||||
nShortCut[260] = DIK_NUMPAD4+K_CTRL; // QuickLoad Slot4
|
||||
nShortCut[261] = DIK_NUMPAD5+K_CTRL; // QuickLoad Slot5
|
||||
nShortCut[262] = DIK_NUMPAD6+K_CTRL; // QuickLoad Slot6
|
||||
nShortCut[263] = DIK_NUMPAD7+K_CTRL; // QuickLoad Slot7
|
||||
nShortCut[264] = DIK_NUMPAD8+K_CTRL; // QuickLoad Slot8
|
||||
nShortCut[265] = DIK_NUMPAD9+K_CTRL; // QuickLoad Slot9
|
||||
|
||||
nShortCut[266] = DIK_NUMPAD0+K_ALT; // QuickSave Slot0
|
||||
nShortCut[267] = DIK_NUMPAD1+K_ALT; // QuickSave Slot1
|
||||
nShortCut[268] = DIK_NUMPAD2+K_ALT; // QuickSave Slot2
|
||||
nShortCut[269] = DIK_NUMPAD3+K_ALT; // QuickSave Slot3
|
||||
nShortCut[270] = DIK_NUMPAD4+K_ALT; // QuickSave Slot4
|
||||
nShortCut[271] = DIK_NUMPAD5+K_ALT; // QuickSave Slot5
|
||||
nShortCut[272] = DIK_NUMPAD6+K_ALT; // QuickSave Slot6
|
||||
nShortCut[273] = DIK_NUMPAD7+K_ALT; // QuickSave Slot7
|
||||
nShortCut[274] = DIK_NUMPAD8+K_ALT; // QuickSave Slot8
|
||||
nShortCut[275] = DIK_NUMPAD9+K_ALT; // QuickSave Slot9
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgLanguage
|
||||
{
|
||||
public:
|
||||
LCID lcID;
|
||||
CHAR szLanguage[256];
|
||||
|
||||
void Default() {
|
||||
lcID = NULL;
|
||||
szLanguage[0] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgController
|
||||
{
|
||||
public:
|
||||
WORD nButton[4][64];
|
||||
WORD nRapid [4][ 2];
|
||||
// 0:Crazy Climber
|
||||
// 1:Famly Trainer
|
||||
// 2:Exciting Boxing
|
||||
// 3:Mahjang
|
||||
WORD nExButton[4][64];
|
||||
WORD nNsfButton[64];
|
||||
WORD nVSUnisystem[64];
|
||||
|
||||
void Default() {
|
||||
DefaultController1();
|
||||
DefaultController2();
|
||||
DefaultController3();
|
||||
DefaultController4();
|
||||
DefaultExController0();
|
||||
DefaultExController1();
|
||||
DefaultExController2();
|
||||
DefaultExController3();
|
||||
DefaultNsfController();
|
||||
DefaultVSUnisystem();
|
||||
}
|
||||
|
||||
void DefaultController1() {
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nButton[0][i] = 0;
|
||||
|
||||
nButton[0][ 0] = DIK_UP;
|
||||
nButton[0][ 1] = DIK_DOWN;
|
||||
nButton[0][ 2] = DIK_LEFT;
|
||||
nButton[0][ 3] = DIK_RIGHT;
|
||||
nButton[0][ 4] = DIK_X; // A
|
||||
nButton[0][ 5] = DIK_Z; // B
|
||||
nButton[0][ 6] = 0; // A Rapid
|
||||
nButton[0][ 7] = 0; // B Rapid
|
||||
nButton[0][ 8] = DIK_RSHIFT; // SELECT
|
||||
nButton[0][ 9] = DIK_RETURN; // START
|
||||
|
||||
nRapid[0][0] = 0; // A Rapid speed
|
||||
nRapid[0][1] = 0; // B Rapid speed
|
||||
}
|
||||
|
||||
void DefaultController2() {
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nButton[1][i] = 0;
|
||||
|
||||
nButton[1][ 0] = DIK_NUMPAD8;
|
||||
nButton[1][ 1] = DIK_NUMPAD2;
|
||||
nButton[1][ 2] = DIK_NUMPAD4;
|
||||
nButton[1][ 3] = DIK_NUMPAD6;
|
||||
nButton[1][ 4] = DIK_N; // A
|
||||
nButton[1][ 5] = DIK_B; // B
|
||||
nButton[1][ 6] = 0; // A Rapid
|
||||
nButton[1][ 7] = 0; // B Rapid
|
||||
nButton[1][ 8] = 0; // SELECT
|
||||
nButton[1][ 9] = 0; // START
|
||||
nButton[1][10] = DIK_M; // Mic
|
||||
|
||||
nRapid[1][0] = 0; // A Rapid speed
|
||||
nRapid[1][1] = 0; // B Rapid speed
|
||||
}
|
||||
|
||||
void DefaultController3() {
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nButton[2][i] = 0;
|
||||
|
||||
nRapid[2][0] = 0; // A Rapid speed
|
||||
nRapid[2][1] = 0; // B Rapid speed
|
||||
}
|
||||
|
||||
void DefaultController4() {
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nButton[3][i] = 0;
|
||||
|
||||
nRapid[3][0] = 0; // A Rapid speed
|
||||
nRapid[3][1] = 0; // B Rapid speed
|
||||
}
|
||||
|
||||
void DefaultExController0() {
|
||||
// Crazy Climberコントローラ(実際には存在しない)
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nExButton[0][i] = 0;
|
||||
// nExButton[0][ 0] = 0; // L up
|
||||
// nExButton[0][ 1] = 0; // L down
|
||||
// nExButton[0][ 2] = 0; // L left
|
||||
// nExButton[0][ 3] = 0; // L right
|
||||
// nExButton[0][ 4] = 0; // R up
|
||||
// nExButton[0][ 5] = 0; // R down
|
||||
// nExButton[0][ 6] = 0; // R left
|
||||
// nExButton[0][ 7] = 0; // R right
|
||||
}
|
||||
|
||||
void DefaultExController1() {
|
||||
// Famly Trainerコントローラ
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nExButton[1][i] = 0;
|
||||
}
|
||||
|
||||
void DefaultExController2() {
|
||||
// Exciting Boxingコントローラ
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nExButton[2][i] = 0;
|
||||
}
|
||||
|
||||
void DefaultExController3() {
|
||||
// Mahjangコントローラ
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nExButton[3][i] = 0;
|
||||
}
|
||||
|
||||
void DefaultNsfController() {
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nNsfButton[i] = 0;
|
||||
|
||||
nNsfButton[ 0] = DIK_UP; // Play
|
||||
nNsfButton[ 1] = DIK_DOWN; // Stop
|
||||
nNsfButton[ 2] = DIK_LEFT; // Number -1
|
||||
nNsfButton[ 3] = DIK_RIGHT; // Number +1
|
||||
nNsfButton[ 4] = DIK_PRIOR; // Number +16
|
||||
nNsfButton[ 5] = DIK_NEXT; // Number -16
|
||||
}
|
||||
|
||||
void DefaultVSUnisystem() {
|
||||
for( INT i = 0; i < 64; i++ )
|
||||
nVSUnisystem[i] = 0;
|
||||
|
||||
nVSUnisystem[0] = DIK_C; // Coin
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgMovie
|
||||
{
|
||||
public:
|
||||
BYTE bUsePlayer[4];
|
||||
BOOL bRerecord;
|
||||
BOOL bLoopPlay;
|
||||
BOOL bResetRec;
|
||||
BOOL bPadDisplay;
|
||||
|
||||
void Default() {
|
||||
bUsePlayer[0] = 0xFF;
|
||||
bUsePlayer[1] = 0x00;
|
||||
bUsePlayer[2] = 0x00;
|
||||
bUsePlayer[3] = 0x00;
|
||||
bRerecord = TRUE;
|
||||
bLoopPlay = FALSE;
|
||||
bResetRec = FALSE;
|
||||
bPadDisplay = FALSE;
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgLauncher
|
||||
{
|
||||
public:
|
||||
RECT rcWindowPos;
|
||||
|
||||
BYTE bHeaderView [16];
|
||||
BYTE nHeaderOrder[16];
|
||||
SHORT nHeaderWidth[16];
|
||||
|
||||
BOOL bActivePause;
|
||||
|
||||
INT nListSelect;
|
||||
|
||||
BOOL bSortDir;
|
||||
INT nSortType;
|
||||
|
||||
BYTE bFolderUse[16];
|
||||
CHAR szFolder[16][_MAX_PATH];
|
||||
|
||||
CHAR szLastSelect[_MAX_PATH];
|
||||
|
||||
void Default() {
|
||||
rcWindowPos.left = rcWindowPos.right =
|
||||
rcWindowPos.top = rcWindowPos.bottom = 0;
|
||||
|
||||
bActivePause = FALSE;
|
||||
|
||||
nListSelect = 0;
|
||||
|
||||
bSortDir = FALSE;
|
||||
nSortType = 0;
|
||||
|
||||
INT i;
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
bHeaderView [i] = TRUE;
|
||||
nHeaderOrder[i] = i;
|
||||
nHeaderWidth[i] = (i==0)?160:48;
|
||||
}
|
||||
|
||||
for( i = 0; i < 16; i++ ) {
|
||||
bFolderUse[i] = FALSE;
|
||||
szFolder[i][0] = '\0';
|
||||
}
|
||||
|
||||
szLastSelect[0] = '\0';
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgExtraSound
|
||||
{
|
||||
public:
|
||||
CHAR szExtSoundFile[ ESF_FILE_MAX ][ MAX_PATH ];
|
||||
|
||||
void Default() {
|
||||
for( INT i = 0; i < ESF_FILE_MAX; i++ ) {
|
||||
szExtSoundFile[i][0] = '\0';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CCfgNetPlay
|
||||
{
|
||||
public:
|
||||
RECT rcChatPos;
|
||||
|
||||
INT nRecentPort, nRecentHost;
|
||||
CHAR szRecentPort[16][_MAX_PATH+1];
|
||||
CHAR szRecentHost[16][_MAX_PATH+1];
|
||||
CHAR szNick[_MAX_PATH+1];
|
||||
|
||||
void Default() {
|
||||
rcChatPos.left = rcChatPos.right =
|
||||
rcChatPos.top = rcChatPos.bottom = 0;
|
||||
|
||||
::lstrcpy( szNick, "NoName" );
|
||||
|
||||
for( INT i = 0; i < 16; i++ ) {
|
||||
szRecentPort[i][0] = '\0';
|
||||
szRecentHost[i][0] = '\0';
|
||||
}
|
||||
::lstrcpy( szRecentPort[0], "10000" );
|
||||
::lstrcpy( szRecentHost[0], "localhost:10000" );
|
||||
|
||||
nRecentPort = 1;
|
||||
nRecentHost = 1;
|
||||
}
|
||||
};
|
||||
|
||||
class CConfig
|
||||
{
|
||||
public:
|
||||
CConfig() {
|
||||
m_bKeyboardDisable = FALSE;
|
||||
Default();
|
||||
}
|
||||
|
||||
CCfgGeneral general;
|
||||
CCfgPath path;
|
||||
CCfgEmulator emulator;
|
||||
CCfgGraphics graphics;
|
||||
CCfgSound sound;
|
||||
CCfgShortCut shortcut;
|
||||
CCfgLanguage language;
|
||||
CCfgController controller;
|
||||
CCfgMovie movie;
|
||||
CCfgLauncher launcher;
|
||||
CCfgExtraSound extsound;
|
||||
CCfgNetPlay netplay;
|
||||
|
||||
void Default() {
|
||||
general.Default();
|
||||
path.Default();
|
||||
emulator.Default();
|
||||
graphics.Default();
|
||||
sound.Default();
|
||||
shortcut.Default();
|
||||
language.Default();
|
||||
controller.Default();
|
||||
movie.Default();
|
||||
launcher.Default();
|
||||
extsound.Default();
|
||||
netplay.Default();
|
||||
}
|
||||
|
||||
void Load();
|
||||
void Save();
|
||||
|
||||
// Checker
|
||||
void InputKeyboardDisable( BOOL bEnable ) {
|
||||
m_bKeyboardDisable = bEnable;
|
||||
}
|
||||
|
||||
BOOL ButtonCheck( INT nNo, INT nID );
|
||||
BOOL ExButtonCheck( INT nNo, INT nID );
|
||||
BOOL NsfButtonCheck( INT nID );
|
||||
BOOL ButtonCheck( INT nID, WORD* pKey );
|
||||
|
||||
// Converter
|
||||
string ShortcutToKeyName( INT nShortcut );
|
||||
|
||||
// Table
|
||||
static INT SamplingRateTable[];
|
||||
static INT ShortcutKeyID[];
|
||||
protected:
|
||||
|
||||
BOOL m_bKeyboardDisable;
|
||||
private:
|
||||
};
|
||||
|
||||
// 個別ゲームオプション
|
||||
class CGameOption
|
||||
{
|
||||
public:
|
||||
// for Cartridge
|
||||
void Load( DWORD crc );
|
||||
void Save( LPCSTR name, DWORD crc );
|
||||
// for FDS
|
||||
void Load( DWORD gid, DWORD mid );
|
||||
void Save( LPCSTR name, DWORD gid, DWORD mid );
|
||||
|
||||
// Default保存
|
||||
INT defRenderMethod;
|
||||
INT defIRQtype;
|
||||
BOOL defFrameIRQ;
|
||||
BOOL defVideoMode;
|
||||
|
||||
// データ
|
||||
INT nRenderMethod;
|
||||
INT nIRQtype;
|
||||
BOOL bFrameIRQ;
|
||||
BOOL bVideoMode;
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
||||
extern CConfig Config;
|
||||
extern CGameOption GameOption;
|
||||
|
||||
#endif // !__CCONFIG_INCLUDED__
|
||||
516
References/VirtuaNESex_src_191105/ControllerDlg.cpp
Normal file
516
References/VirtuaNESex_src_191105/ControllerDlg.cpp
Normal file
@ -0,0 +1,516 @@
|
||||
//
|
||||
// コントローラダイアログクラス
|
||||
//
|
||||
//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "VirtuaNESres.h"
|
||||
#include "DebugOut.h"
|
||||
#include "App.h"
|
||||
#include "Pathlib.h"
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "ControllerDlg.h"
|
||||
|
||||
#include "DirectInput.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DLG_MESSAGE_BEGIN(CControllerPageDlg)
|
||||
// メッセージ
|
||||
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
|
||||
// NOTIFYメッセージ
|
||||
DLG_NOTIFY_BEGIN()
|
||||
DLG_NOTIFY_END()
|
||||
// コマンド
|
||||
DLG_COMMAND_BEGIN()
|
||||
DLG_ON_COMMAND_NOTIFY_RANGE( IDC_CTR_UP, IDC_CTR_END, STN_CLICKED, OnClicked )
|
||||
DLG_COMMAND_END()
|
||||
DLG_MESSAGE_END()
|
||||
|
||||
INT CControllerPageDlg::Create( UINT nID, HWND hWndParent )
|
||||
{
|
||||
m_nPageID = nID;
|
||||
|
||||
m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(nID),
|
||||
hWndParent, g_DlgProc, (LPARAM)this );
|
||||
return (m_hWnd)?TRUE:FALSE;
|
||||
}
|
||||
|
||||
void CControllerPageDlg::Destroy()
|
||||
{
|
||||
::DestroyWindow( m_hWnd );
|
||||
}
|
||||
|
||||
DLGCMD CControllerPageDlg::OnClicked( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerPageDlg::OnClicked uID=%d\n", uID );
|
||||
|
||||
// 親のタブコントロールをパスしてメッセージを通知:p
|
||||
HWND hWndParent, hWndOwner;
|
||||
hWndParent = ::GetParent( m_hWnd );
|
||||
hWndOwner = ::GetParent( hWndParent );
|
||||
::SendMessage( hWndOwner, WM_COMMAND, MAKELPARAM(uID,STN_CLICKED), (LPARAM)::GetDlgItem(m_hWnd,uID) );
|
||||
}
|
||||
|
||||
DLGMSG CControllerPageDlg::OnInitDialog( DLGMSGPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerPageDlg::OnInitDialog\n" );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
UINT CControllerDlg::ControllerPageID[] = {
|
||||
IDD_CTR_PLAYER1,
|
||||
IDD_CTR_PLAYER2,
|
||||
IDD_CTR_PLAYER3,
|
||||
IDD_CTR_PLAYER4,
|
||||
IDD_CTR_CRAZYCLIMBER,
|
||||
IDD_CTR_FAMLYTRAINER,
|
||||
IDD_CTR_EXCITINGBOXING,
|
||||
IDD_CTR_MAHJANG,
|
||||
IDD_CTR_NSFPLAYER,
|
||||
IDD_CTR_VSUNISYSTEM,
|
||||
0
|
||||
};
|
||||
|
||||
DLG_MESSAGE_BEGIN(CControllerDlg)
|
||||
// メッセージ
|
||||
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
|
||||
DLG_ON_MESSAGE( WM_DESTROY, OnDestroy )
|
||||
DLG_ON_MESSAGE( WM_TIMER, OnTimer )
|
||||
// NOTIFYメッセージ
|
||||
DLG_NOTIFY_BEGIN()
|
||||
DLG_ON_NOTIFY( IDC_CTR_TAB, TCN_SELCHANGE, OnSelectChange )
|
||||
DLG_NOTIFY_END()
|
||||
// コマンド
|
||||
DLG_COMMAND_BEGIN()
|
||||
DLG_ON_COMMAND( IDOK, OnOK )
|
||||
DLG_ON_COMMAND( IDCANCEL, OnCancel )
|
||||
DLG_ON_COMMAND( IDDEFAULT, OnDefault )
|
||||
DLG_ON_COMMAND_NOTIFY_RANGE( IDC_CTR_UP, IDC_CTR_END, STN_CLICKED, OnClicked )
|
||||
DLG_ON_COMMAND_NOTIFY( IDC_CTR_SELECT_COMBO, CBN_SELCHANGE, OnSettingSelectChange )
|
||||
DLG_COMMAND_END()
|
||||
DLG_MESSAGE_END()
|
||||
|
||||
INT CControllerDlg::DoModal( HWND hWndParent )
|
||||
{
|
||||
m_bCancelMode = FALSE;
|
||||
m_TimerID = 0;
|
||||
|
||||
m_SettingSel = 0;
|
||||
|
||||
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_CFG_CONTROLLER),
|
||||
hWndParent, g_DlgProc, (LPARAM)this );
|
||||
}
|
||||
|
||||
BOOL CControllerDlg::PreTranslateMessage( MSG* pMsg )
|
||||
{
|
||||
if( pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST ) {
|
||||
// DEBUGOUT( "CControllerDlg::PreTranslateMessage WM_KEY????\n" );
|
||||
return m_bCancelMode;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CControllerDlg::OnInitialMember()
|
||||
{
|
||||
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CTR_TAB );
|
||||
RECT rcT, rcP, rcW;
|
||||
INT page;
|
||||
|
||||
// for( INT page = 0; ControllerPageID[page]; page++ ) {
|
||||
for( page = 0; ControllerPageID[page]; page++ ) {
|
||||
m_Page[page].Create( ControllerPageID[page], hWndCtrl );
|
||||
|
||||
// 名前の取得
|
||||
CHAR szTitle[256];
|
||||
::GetWindowText( m_Page[page].m_hWnd, szTitle, sizeof(szTitle) );
|
||||
|
||||
// 名前を取得したらキャプションを消す
|
||||
LONG style;
|
||||
style = ::GetWindowLong( m_Page[page].m_hWnd, GWL_STYLE );
|
||||
style &= ~(WS_CAPTION|WS_BORDER|WS_OVERLAPPED);
|
||||
::SetWindowLong( m_Page[page].m_hWnd, GWL_STYLE, style );
|
||||
|
||||
// サイズ変更
|
||||
::GetWindowRect( m_Page[page].m_hWnd, &rcW );
|
||||
rcW.right -= ::GetSystemMetrics( SM_CXSIZEFRAME );
|
||||
rcW.bottom -= ::GetSystemMetrics( SM_CYCAPTION )+::GetSystemMetrics( SM_CYSIZEFRAME )*2;
|
||||
::SetWindowPos( m_Page[page].m_hWnd, NULL, 0, 0, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOMOVE|SWP_NOZORDER );
|
||||
|
||||
// タブに名前を設定する
|
||||
TCITEM tcitem;
|
||||
tcitem.mask = TCIF_TEXT;
|
||||
tcitem.pszText = szTitle;
|
||||
TabCtrl_InsertItem( hWndCtrl, page, &tcitem );
|
||||
|
||||
// // ページ位置の補正
|
||||
// ::GetClientRect( hWndCtrl, &rcT );
|
||||
// TabCtrl_AdjustRect( hWndCtrl, FALSE, &rcT );
|
||||
// ::GetWindowRect( m_Page[page].m_hWnd, &rcP );
|
||||
|
||||
// 計算
|
||||
// rcW.left = rcT.left + (RCWIDTH(rcT)-RCWIDTH(rcP))/2;
|
||||
// rcW.top = rcT.top + (RCHEIGHT(rcT)-RCHEIGHT(rcP))/2;
|
||||
// rcW.right = rcW.left + RCWIDTH(rcP);
|
||||
// rcW.bottom = rcW.top + RCHEIGHT(rcP);
|
||||
// ::SetWindowPos( m_Page[page].m_hWnd, NULL, rcW.left, rcW.top, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOZORDER|SWP_NOACTIVATE );
|
||||
|
||||
// 各ページのリストボックスの設定
|
||||
if( page < 4 ) {
|
||||
HWND hWndList;
|
||||
hWndList = ::GetDlgItem( m_Page[page].m_hWnd, IDC_CTR_A_RAPID_LIST );
|
||||
::SendMessage( hWndList, LB_INSERTSTRING, 0, (LPARAM)" 10FPS" );
|
||||
::SendMessage( hWndList, LB_INSERTSTRING, 1, (LPARAM)" 15FPS" );
|
||||
::SendMessage( hWndList, LB_INSERTSTRING, 2, (LPARAM)" 20FPS" );
|
||||
::SendMessage( hWndList, LB_INSERTSTRING, 3, (LPARAM)" 30FPS" );
|
||||
hWndList = ::GetDlgItem( m_Page[page].m_hWnd, IDC_CTR_B_RAPID_LIST );
|
||||
::SendMessage( hWndList, LB_INSERTSTRING, 0, (LPARAM)" 10FPS" );
|
||||
::SendMessage( hWndList, LB_INSERTSTRING, 1, (LPARAM)" 15FPS" );
|
||||
::SendMessage( hWndList, LB_INSERTSTRING, 2, (LPARAM)" 20FPS" );
|
||||
::SendMessage( hWndList, LB_INSERTSTRING, 3, (LPARAM)" 30FPS" );
|
||||
}
|
||||
|
||||
// ボタン名等の設定
|
||||
OnPageSetup( page );
|
||||
|
||||
::ShowWindow( m_Page[page].m_hWnd, (page==0)?SW_SHOW:SW_HIDE );
|
||||
}
|
||||
|
||||
// ページ位置再調整
|
||||
for( page = 0; ControllerPageID[page]; page++ ) {
|
||||
// ページ位置の補正
|
||||
::GetClientRect( hWndCtrl, &rcT );
|
||||
TabCtrl_AdjustRect( hWndCtrl, FALSE, &rcT );
|
||||
::GetWindowRect( m_Page[page].m_hWnd, &rcP );
|
||||
|
||||
// 計算
|
||||
rcW.left = rcT.left + (RCWIDTH(rcT)-RCWIDTH(rcP))/2;
|
||||
rcW.top = rcT.top + (RCHEIGHT(rcT)-RCHEIGHT(rcP))/2;
|
||||
rcW.right = rcW.left + RCWIDTH(rcP);
|
||||
rcW.bottom = rcW.top + RCHEIGHT(rcP);
|
||||
::SetWindowPos( m_Page[page].m_hWnd, NULL, rcW.left, rcW.top, RCWIDTH(rcW), RCHEIGHT(rcW), SWP_NOZORDER|SWP_NOACTIVATE );
|
||||
}
|
||||
|
||||
TabCtrl_SetCurSel( hWndCtrl, 0 );
|
||||
m_PageSel = 0;
|
||||
|
||||
m_PageNum = page;
|
||||
|
||||
// 設定コンボボックス
|
||||
::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_RESETCONTENT, 0, 0 );
|
||||
CHAR szStr[64];
|
||||
for( INT i = IDS_CTR_SELECT1; i <= IDS_CTR_SELECT2; i++ ) {
|
||||
CApp::LoadString( i, szStr, sizeof(szStr) );
|
||||
::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_INSERTSTRING, (WPARAM)i-IDS_CTR_SELECT1, (LPARAM)szStr );
|
||||
}
|
||||
::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_SETCURSEL, 0, 0 );
|
||||
}
|
||||
|
||||
void CControllerDlg::OnPageSetup( UINT nPage )
|
||||
{
|
||||
HWND hWnd = m_Page[nPage].m_hWnd;
|
||||
HWND hWndCtrl;
|
||||
INT nKey;
|
||||
LPCSTR lpStr;
|
||||
INT nOffset = m_SettingSel?32:0;
|
||||
|
||||
for( INT nID = IDC_CTR_UP; nID <= IDC_CTR_END; nID++ ) {
|
||||
if( (hWndCtrl = ::GetDlgItem( hWnd, nID )) ) {
|
||||
if( nPage < 4 ) {
|
||||
nKey = Config.controller.nButton[nPage][nID-IDC_CTR_UP+nOffset];
|
||||
} else if( ControllerPageID[nPage] == IDD_CTR_CRAZYCLIMBER ) {
|
||||
nKey = Config.controller.nExButton[0][nID-IDC_CTR_UP+nOffset];
|
||||
} else if( ControllerPageID[nPage] == IDD_CTR_FAMLYTRAINER ) {
|
||||
nKey = Config.controller.nExButton[1][nID-IDC_CTR_UP+nOffset];
|
||||
} else if( ControllerPageID[nPage] == IDD_CTR_EXCITINGBOXING ) {
|
||||
nKey = Config.controller.nExButton[2][nID-IDC_CTR_UP+nOffset];
|
||||
} else if( ControllerPageID[nPage] == IDD_CTR_MAHJANG ) {
|
||||
nKey = Config.controller.nExButton[3][nID-IDC_CTR_UP+nOffset];
|
||||
} else if( ControllerPageID[nPage] == IDD_CTR_NSFPLAYER ) {
|
||||
nKey = Config.controller.nNsfButton[nID-IDC_CTR_UP+nOffset];
|
||||
} else if( ControllerPageID[nPage] == IDD_CTR_VSUNISYSTEM ) {
|
||||
nKey = Config.controller.nVSUnisystem[nID-IDC_CTR_UP+nOffset];
|
||||
}
|
||||
if( (lpStr = DirectInput.SearchKeyName(nKey)) ) {
|
||||
::SetWindowText( hWndCtrl, lpStr );
|
||||
} else {
|
||||
::SetWindowText( hWndCtrl, "----" );
|
||||
}
|
||||
::InvalidateRect( hWndCtrl, NULL, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
if( nPage < 4 ) {
|
||||
::SendDlgItemMessage( hWnd, IDC_CTR_A_RAPID_LIST, LB_SETCURSEL,
|
||||
(WPARAM)Config.controller.nRapid[nPage][0], 0 );
|
||||
::SendDlgItemMessage( hWnd, IDC_CTR_B_RAPID_LIST, LB_SETCURSEL,
|
||||
(WPARAM)Config.controller.nRapid[nPage][1], 0 );
|
||||
}
|
||||
}
|
||||
|
||||
DLGMSG CControllerDlg::OnInitDialog( DLGMSGPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerDlg::OnInitDialog\n" );
|
||||
m_ConfigSave = Config.controller;
|
||||
|
||||
OnInitialMember();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGMSG CControllerDlg::OnDestroy( DLGMSGPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerDlg::OnDestroy\n" );
|
||||
|
||||
// チャイルドウインドウを破棄
|
||||
for( INT i = 0; i < m_PageNum; i++ ) {
|
||||
::DestroyWindow( m_Page[i].m_hWnd );
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DLGNOTIFY CControllerDlg::OnSelectChange( DLGNOTIFYPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerDlg::OnSelectChange\n" );
|
||||
|
||||
HWND hWndCtrl = ::GetDlgItem( m_hWnd, IDC_CTR_TAB );
|
||||
m_PageSel = TabCtrl_GetCurSel( hWndCtrl );
|
||||
|
||||
OnPageSetup( m_PageSel );
|
||||
|
||||
for( INT i = 0; i < m_PageNum; i++ ) {
|
||||
if( i == m_PageSel ) {
|
||||
::ShowWindow( m_Page[i].m_hWnd, SW_SHOW );
|
||||
} else {
|
||||
::ShowWindow( m_Page[i].m_hWnd, SW_HIDE );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_TimerID ) {
|
||||
::KillTimer( m_hWnd, m_TimerID );
|
||||
m_TimerID = 0;
|
||||
m_ControlID = 0;
|
||||
// ::InvalidateRect( hWndCtrl, NULL, TRUE );
|
||||
}
|
||||
m_bCancelMode = FALSE;
|
||||
}
|
||||
|
||||
DLGNOTIFY CControllerDlg::OnSettingSelectChange( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerDlg::OnSettingSelectChange\n" );
|
||||
|
||||
if( m_TimerID ) {
|
||||
::KillTimer( m_hWnd, m_TimerID );
|
||||
m_TimerID = 0;
|
||||
m_ControlID = 0;
|
||||
// ::InvalidateRect( ::GetDlgItem( m_hWnd, IDC_CTR_TAB ), NULL, TRUE );
|
||||
}
|
||||
m_bCancelMode = FALSE;
|
||||
|
||||
m_SettingSel = ::SendDlgItemMessage( m_hWnd, IDC_CTR_SELECT_COMBO, CB_GETCURSEL, 0, 0 );
|
||||
|
||||
OnPageSetup( m_PageSel );
|
||||
}
|
||||
|
||||
DLGCMD CControllerDlg::OnClicked( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerDlg::OnClicked uID=%d\n", uID );
|
||||
if( !m_TimerID ) {
|
||||
m_ControlID = uID;
|
||||
m_TimerCount = 0;
|
||||
m_TimerID = ::SetTimer( m_hWnd, 1, 50, NULL );
|
||||
m_bCancelMode = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
DLGMSG CControllerDlg::OnTimer( DLGMSGPARAM )
|
||||
{
|
||||
HWND hWndCtrl = ::GetDlgItem( m_Page[m_PageSel].m_hWnd, m_ControlID );
|
||||
INT nID = m_ControlID - IDC_CTR_UP;
|
||||
INT nOffset = m_SettingSel?32:0;
|
||||
|
||||
if( wParam == (WPARAM)m_TimerID ) {
|
||||
if( m_TimerCount == 0 )
|
||||
m_TimerStart = ::timeGetTime();
|
||||
m_TimerCount++;
|
||||
|
||||
DirectInput.Poll();
|
||||
|
||||
if( m_TimerCount > 60 ) {
|
||||
// TimeOut
|
||||
if( m_TimerID ) {
|
||||
::KillTimer( m_hWnd, m_TimerID );
|
||||
m_TimerID = 0;
|
||||
m_ControlID = 0;
|
||||
::InvalidateRect( hWndCtrl, NULL, TRUE );
|
||||
}
|
||||
m_bCancelMode = FALSE;
|
||||
} else {
|
||||
// Button push?
|
||||
BOOL bSet = FALSE;
|
||||
INT i;
|
||||
LPCSTR str;
|
||||
// Set cancel
|
||||
if( DirectInput.m_Sw[DIK_ESCAPE] ) {
|
||||
if( m_PageSel < 4 ) {
|
||||
Config.controller.nButton[m_PageSel][nID+nOffset] = 0;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_CRAZYCLIMBER ) {
|
||||
Config.controller.nExButton[0][nID+nOffset] = 0;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_FAMLYTRAINER ) {
|
||||
Config.controller.nExButton[1][nID+nOffset] = 0;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_EXCITINGBOXING ) {
|
||||
Config.controller.nExButton[2][nID+nOffset] = 0;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_MAHJANG ) {
|
||||
Config.controller.nExButton[3][nID+nOffset] = 0;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_NSFPLAYER ) {
|
||||
Config.controller.nNsfButton[nID+nOffset] = 0;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_VSUNISYSTEM ) {
|
||||
Config.controller.nVSUnisystem[nID+nOffset] = 0;
|
||||
}
|
||||
::SetWindowText( hWndCtrl, "----" );
|
||||
bSet = TRUE;
|
||||
} else {
|
||||
for( i = 0; i < 512; i++ ) {
|
||||
if( DirectInput.m_Sw[i] ) {
|
||||
if( (str=DirectInput.SearchKeyName( i )) ) {
|
||||
if( m_PageSel < 4 ) {
|
||||
Config.controller.nButton[m_PageSel][nID+nOffset] = i;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_CRAZYCLIMBER ) {
|
||||
Config.controller.nExButton[0][nID+nOffset] = i;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_FAMLYTRAINER ) {
|
||||
Config.controller.nExButton[1][nID+nOffset] = i;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_EXCITINGBOXING ) {
|
||||
Config.controller.nExButton[2][nID+nOffset] = i;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_MAHJANG ) {
|
||||
Config.controller.nExButton[3][nID+nOffset] = i;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_NSFPLAYER ) {
|
||||
Config.controller.nNsfButton[nID+nOffset] = i;
|
||||
} else if( ControllerPageID[m_PageSel] == IDD_CTR_VSUNISYSTEM ) {
|
||||
Config.controller.nVSUnisystem[nID+nOffset] = i;
|
||||
}
|
||||
::SetWindowText( hWndCtrl, str );
|
||||
bSet = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( bSet ) {
|
||||
// Button Pressed
|
||||
if( m_TimerID ) {
|
||||
::KillTimer( m_hWnd, m_TimerID );
|
||||
m_TimerID = 0;
|
||||
m_ControlID = 0;
|
||||
::InvalidateRect( hWndCtrl, NULL, TRUE );
|
||||
}
|
||||
m_bCancelMode = FALSE;
|
||||
} else {
|
||||
// Flashing
|
||||
HDC hDC = ::GetDC( hWndCtrl );
|
||||
RECT rc;
|
||||
::GetClientRect( hWndCtrl, &rc );
|
||||
DWORD c = ((::timeGetTime()-m_TimerStart)/3)&0xFF;
|
||||
if( c > 0x7F )
|
||||
c = 0x80 - (c - 0x7F);
|
||||
c *= 2;
|
||||
::SetBkColor( hDC, RGB(c,c,c) );
|
||||
::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL );
|
||||
::ReleaseDC( hWndCtrl, hDC );
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DLGCMD CControllerDlg::OnOK( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerDlg::OnOK\n" );
|
||||
|
||||
if( m_TimerID ) {
|
||||
::KillTimer( m_hWnd, m_TimerID );
|
||||
m_TimerID = 0;
|
||||
m_ControlID = 0;
|
||||
}
|
||||
m_bCancelMode = FALSE;
|
||||
|
||||
for( INT page = 0; page < 4; page++ ) {
|
||||
Config.controller.nRapid[page][0] = ::SendDlgItemMessage( m_Page[page].m_hWnd, IDC_CTR_A_RAPID_LIST, LB_GETCURSEL, 0, 0 );
|
||||
Config.controller.nRapid[page][1] = ::SendDlgItemMessage( m_Page[page].m_hWnd, IDC_CTR_B_RAPID_LIST, LB_GETCURSEL, 0, 0 );
|
||||
}
|
||||
|
||||
::EndDialog( m_hWnd, IDOK );
|
||||
}
|
||||
|
||||
DLGCMD CControllerDlg::OnCancel( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerDlg::OnCancel\n" );
|
||||
// if( m_bCancelMode )
|
||||
// return;
|
||||
if( m_TimerID ) {
|
||||
::KillTimer( m_hWnd, m_TimerID );
|
||||
m_TimerID = 0;
|
||||
m_ControlID = 0;
|
||||
}
|
||||
m_bCancelMode = FALSE;
|
||||
|
||||
Config.controller = m_ConfigSave;
|
||||
|
||||
::EndDialog( m_hWnd, IDCANCEL );
|
||||
}
|
||||
|
||||
DLGCMD CControllerDlg::OnDefault( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CControllerDlg::OnDefault\n" );
|
||||
if( m_TimerID ) {
|
||||
::KillTimer( m_hWnd, m_TimerID );
|
||||
m_TimerID = 0;
|
||||
m_ControlID = 0;
|
||||
}
|
||||
m_bCancelMode = FALSE;
|
||||
|
||||
switch( ControllerPageID[m_PageSel] ) {
|
||||
case IDD_CTR_PLAYER1:
|
||||
Config.controller.DefaultController1();
|
||||
break;
|
||||
case IDD_CTR_PLAYER2:
|
||||
Config.controller.DefaultController2();
|
||||
break;
|
||||
case IDD_CTR_PLAYER3:
|
||||
Config.controller.DefaultController3();
|
||||
break;
|
||||
case IDD_CTR_PLAYER4:
|
||||
Config.controller.DefaultController4();
|
||||
break;
|
||||
case IDD_CTR_CRAZYCLIMBER:
|
||||
Config.controller.DefaultExController0();
|
||||
break;
|
||||
case IDD_CTR_FAMLYTRAINER:
|
||||
Config.controller.DefaultExController1();
|
||||
break;
|
||||
case IDD_CTR_EXCITINGBOXING:
|
||||
Config.controller.DefaultExController2();
|
||||
break;
|
||||
case IDD_CTR_MAHJANG:
|
||||
Config.controller.DefaultExController3();
|
||||
break;
|
||||
case IDD_CTR_NSFPLAYER:
|
||||
Config.controller.DefaultNsfController();
|
||||
break;
|
||||
case IDD_CTR_VSUNISYSTEM:
|
||||
Config.controller.DefaultVSUnisystem();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
OnPageSetup( m_PageSel );
|
||||
}
|
||||
|
||||
81
References/VirtuaNESex_src_191105/ControllerDlg.h
Normal file
81
References/VirtuaNESex_src_191105/ControllerDlg.h
Normal file
@ -0,0 +1,81 @@
|
||||
//
|
||||
// コントローラダイアログクラス
|
||||
//
|
||||
#ifndef __CCONTROLLERDLG_INCLUDED__
|
||||
#define __CCONTROLLERDLG_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "Config.h"
|
||||
|
||||
class CControllerPageDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
BOOL Create( UINT nID, HWND hWndParent );
|
||||
// Override from CWnd
|
||||
void Destroy();
|
||||
|
||||
protected:
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGCMD OnClicked( DLGCMDPARAM );
|
||||
//
|
||||
|
||||
UINT m_nPageID;
|
||||
private:
|
||||
};
|
||||
|
||||
class CControllerDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
// Override from CWnd
|
||||
INT DoModal( HWND hWndParent );
|
||||
|
||||
// Override from CWnd
|
||||
BOOL PreTranslateMessage( MSG* pMsg );
|
||||
protected:
|
||||
void OnInitialMember();
|
||||
void OnPageSetup( UINT nPage );
|
||||
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGMSG OnDestroy( DLGMSGPARAM );
|
||||
DLGMSG OnTimer( DLGMSGPARAM );
|
||||
DLGNOTIFY OnSelectChange( DLGNOTIFYPARAM );
|
||||
DLGNOTIFY OnSettingSelectChange( DLGCMDPARAM );
|
||||
DLGCMD OnClicked( DLGCMDPARAM );
|
||||
DLGCMD OnOK( DLGCMDPARAM );
|
||||
DLGCMD OnCancel( DLGCMDPARAM );
|
||||
DLGCMD OnDefault( DLGCMDPARAM );
|
||||
//
|
||||
|
||||
enum { PAGE_MAX=12 };
|
||||
|
||||
BOOL m_bCancelMode;
|
||||
|
||||
INT m_ControlID;
|
||||
INT m_TimerID;
|
||||
INT m_TimerStart;
|
||||
INT m_TimerCount;
|
||||
|
||||
INT m_SettingSel;
|
||||
|
||||
INT m_PageSel;
|
||||
INT m_PageNum;
|
||||
CControllerPageDlg m_Page[PAGE_MAX];
|
||||
|
||||
CCfgController m_ConfigSave;
|
||||
|
||||
static UINT ControllerPageID[];
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // !__CCONTROLLERDLG_INCLUDED__
|
||||
|
||||
71
References/VirtuaNESex_src_191105/Crclib.cpp
Normal file
71
References/VirtuaNESex_src_191105/Crclib.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// CRCチェック用ライブラリクラス
|
||||
//
|
||||
#include "Crclib.h"
|
||||
|
||||
BOOL CRC::m_Init = FALSE;
|
||||
BOOL CRC::m_InitRev = FALSE;
|
||||
DWORD CRC::m_CrcTable[ UCHAR_MAX+1 ];
|
||||
DWORD CRC::m_CrcTableRev[ UCHAR_MAX+1 ];
|
||||
|
||||
#define CRCPOLY1 0x04C11DB7UL
|
||||
#define CRCPOLY2 0xEDB88320UL
|
||||
|
||||
DWORD CRC::Crc( INT size, LPBYTE c )
|
||||
{
|
||||
if( !m_Init ) {
|
||||
MakeTable();
|
||||
m_Init = TRUE;
|
||||
}
|
||||
|
||||
DWORD r = 0xFFFFFFFFUL;
|
||||
while( --size >= 0 ) {
|
||||
r = (r << CHAR_BIT) ^ m_CrcTable[(BYTE)(r >> (32 - CHAR_BIT)) ^ *c++];
|
||||
}
|
||||
return ~r & 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
DWORD CRC::CrcRev( INT size, LPBYTE c )
|
||||
{
|
||||
if( !m_InitRev ) {
|
||||
MakeTableRev();
|
||||
m_InitRev = TRUE;
|
||||
}
|
||||
|
||||
DWORD r = 0xFFFFFFFFUL;
|
||||
while( --size >= 0 ) {
|
||||
r = (r >> CHAR_BIT) ^ m_CrcTableRev[(BYTE)r ^ *c++];
|
||||
}
|
||||
return r ^ 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
void CRC::MakeTable()
|
||||
{
|
||||
INT i, j;
|
||||
DWORD r;
|
||||
|
||||
for( i = 0; i <= UCHAR_MAX; i++ ) {
|
||||
r = (DWORD)i << (32 - CHAR_BIT);
|
||||
for( j = 0; j < CHAR_BIT; j++ ) {
|
||||
if( r & 0x80000000UL ) r = (r << 1) ^ CRCPOLY1;
|
||||
else r <<= 1;
|
||||
}
|
||||
m_CrcTable[i] = r & 0xFFFFFFFFUL;
|
||||
}
|
||||
}
|
||||
|
||||
void CRC::MakeTableRev()
|
||||
{
|
||||
INT i, j;
|
||||
DWORD r;
|
||||
|
||||
for( i = 0; i <= UCHAR_MAX; i++ ) {
|
||||
r = i;
|
||||
for( j = 0; j < CHAR_BIT; j++ ) {
|
||||
if( r & 1 ) r = (r >> 1) ^ CRCPOLY2;
|
||||
else r >>= 1;
|
||||
}
|
||||
m_CrcTableRev[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
24
References/VirtuaNESex_src_191105/Crclib.h
Normal file
24
References/VirtuaNESex_src_191105/Crclib.h
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// CRCチェック用ライブラリクラス
|
||||
//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <limits.h>
|
||||
|
||||
class CRC
|
||||
{
|
||||
public:
|
||||
static DWORD Crc( INT size, LPBYTE c );
|
||||
static DWORD CrcRev( INT size, LPBYTE c ); // 逆順
|
||||
|
||||
protected:
|
||||
static void MakeTable();
|
||||
static void MakeTableRev(); // 逆順
|
||||
|
||||
static BOOL m_Init;
|
||||
static BOOL m_InitRev;
|
||||
static DWORD m_CrcTable[ UCHAR_MAX+1 ];
|
||||
static DWORD m_CrcTableRev[ UCHAR_MAX+1 ];
|
||||
private:
|
||||
};
|
||||
|
||||
173
References/VirtuaNESex_src_191105/DatachBarcodeDlg.cpp
Normal file
173
References/VirtuaNESex_src_191105/DatachBarcodeDlg.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
//
|
||||
// DATACHバーコードバトラーダイアログクラス
|
||||
//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "typedef.h"
|
||||
#include "macro.h"
|
||||
|
||||
#include "VirtuaNESres.h"
|
||||
#include "DebugOut.h"
|
||||
#include "App.h"
|
||||
#include "Pathlib.h"
|
||||
#include "Config.h"
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "DatachBarcodeDlg.h"
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "nes.h"
|
||||
#include "mapper.h"
|
||||
|
||||
// メッセージ
|
||||
DLG_MESSAGE_BEGIN(CDatachBarcodeDlg)
|
||||
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
|
||||
DLG_ON_MESSAGE( WM_ACTIVATE, OnActivate )
|
||||
DLG_ON_MESSAGE( WM_DESTROY, OnDestroy )
|
||||
DLG_ON_MESSAGE( WM_CLOSE, OnClose )
|
||||
// コマンド
|
||||
DLG_COMMAND_BEGIN()
|
||||
DLG_ON_COMMAND( IDCANCEL, OnCancel )
|
||||
//DLG_ON_COMMAND( IDC_EBB_CODE, OnCodeinput )
|
||||
DLG_ON_COMMAND( IDC_EBB_TRANSFER, OnCodeTransfer )
|
||||
DLG_ON_COMMAND( IDC_EBB_RANDOM, OnCodeCreate )
|
||||
|
||||
DLG_ON_COMMAND_NOTIFY( IDC_EBB_CODE, EN_CHANGE, OnCodeinput )
|
||||
|
||||
DLG_COMMAND_END()
|
||||
// Notify メッセージ
|
||||
DLG_NOTIFY_BEGIN()
|
||||
//DLG_ON_NOTIFY( IDC_LCH_LIST, LVN_KEYDOWN, OnKeyDownListView )
|
||||
DLG_NOTIFY_END()
|
||||
DLG_MESSAGE_END()
|
||||
|
||||
BOOL CDatachBarcodeDlg::Create( HWND hWndParent )
|
||||
{
|
||||
// 親はデスクトップにする
|
||||
m_hWnd = ::CreateDialogParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_EXT_BARCODEBATTLER),
|
||||
NULL, g_DlgProc, (LPARAM)this );
|
||||
if( !m_hWnd )
|
||||
return FALSE;
|
||||
|
||||
// モードレスダイアログリストに加える
|
||||
CWndList::Add( this );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CDatachBarcodeDlg::Destroy()
|
||||
{
|
||||
if( m_hWnd ) {
|
||||
// 位置保存
|
||||
::GetWindowRect( m_hWnd, &Config.general.rcBarcodePos );
|
||||
|
||||
// モードレスダイアログリストから削除
|
||||
CWndList::Del( this );
|
||||
::DestroyWindow( m_hWnd );
|
||||
m_hWnd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DLGMSG CDatachBarcodeDlg::OnInitDialog( DLGMSGPARAM )
|
||||
{
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnInitDialog\n" );
|
||||
|
||||
// 位置修正
|
||||
if( Config.general.rcBarcodePos.right-Config.general.rcBarcodePos.left != 0
|
||||
&& Config.general.rcBarcodePos.bottom-Config.general.rcBarcodePos.top != 0 ) {
|
||||
::SetWindowPos( m_hWnd, HWND_NOTOPMOST, Config.general.rcBarcodePos.left, Config.general.rcBarcodePos.top,
|
||||
0, 0, SWP_NOSIZE | SWP_NOZORDER );
|
||||
}
|
||||
|
||||
::SendDlgItemMessage( m_hWnd, IDC_EBB_CODE, EM_SETLIMITTEXT, 13, 0 );
|
||||
CTRLENABLE( IDC_EBB_TRANSFER, FALSE );
|
||||
|
||||
::srand( (unsigned)::time( NULL ) );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGMSG CDatachBarcodeDlg::OnActivate( DLGMSGPARAM )
|
||||
{
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnActivate\n" );
|
||||
|
||||
if( LOWORD(wParam) == WA_INACTIVE ) {
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnActivate:Inactive\n" );
|
||||
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)TRUE, 0 );
|
||||
} else {
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnActivate:Active\n" );
|
||||
::PostMessage( CApp::GetHWnd(), WM_VNS_SHORTCUTENABLE, (WPARAM)FALSE, 0 );
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DLGMSG CDatachBarcodeDlg::OnDestroy( DLGMSGPARAM )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGMSG CDatachBarcodeDlg::OnClose( DLGMSGPARAM )
|
||||
{
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnClose\n" );
|
||||
::ShowWindow( m_hWnd, SW_HIDE ); // 非表示にするだけ
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGCMD CDatachBarcodeDlg::OnCancel( DLGCMDPARAM )
|
||||
{
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnCancel\n" );
|
||||
::ShowWindow( m_hWnd, SW_HIDE ); // 非表示にするだけ
|
||||
}
|
||||
|
||||
DLGCMD CDatachBarcodeDlg::OnCodeinput( DLGCMDPARAM )
|
||||
{
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnCodeinput\n" );
|
||||
|
||||
INT len = ::SendDlgItemMessage( m_hWnd, IDC_EBB_CODE, WM_GETTEXTLENGTH, 0, 0 );
|
||||
CTRLENABLE( IDC_EBB_TRANSFER, ((len==8)||(len==13))?TRUE:FALSE );
|
||||
}
|
||||
|
||||
DLGCMD CDatachBarcodeDlg::OnCodeTransfer( DLGCMDPARAM )
|
||||
{
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnCodeTransfer\n" );
|
||||
|
||||
if( !Emu.IsRunning() )
|
||||
return;
|
||||
|
||||
BYTE code[14], *p;
|
||||
p = code;
|
||||
INT len = ::GetDlgItemText( m_hWnd, IDC_EBB_CODE, (LPTSTR)code, 14 );
|
||||
|
||||
Emu.EventParam2( CEmuThread::EV_BARCODE, (LONG)code, (LONG)len );
|
||||
}
|
||||
|
||||
DLGCMD CDatachBarcodeDlg::OnCodeCreate( DLGCMDPARAM )
|
||||
{
|
||||
DEBUGOUT( "CDatachBarcodeDlg::OnCodeCreate\n" );
|
||||
|
||||
BYTE code[14];
|
||||
INT digit, sum;
|
||||
|
||||
sum = 0;
|
||||
for( INT i = 0; i < 12; i++ ) {
|
||||
digit = ::rand()%10;
|
||||
code[i] = '0'+digit;
|
||||
sum += digit*((i&1)?3:1);
|
||||
}
|
||||
code[12] = '0'+((10-(sum%10))%10);
|
||||
code[13] = '\0';
|
||||
|
||||
::SetDlgItemText( m_hWnd, IDC_EBB_CODE, (LPCTSTR)code );
|
||||
}
|
||||
|
||||
40
References/VirtuaNESex_src_191105/DatachBarcodeDlg.h
Normal file
40
References/VirtuaNESex_src_191105/DatachBarcodeDlg.h
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// DATACHバーコードバトラーダイアログクラス
|
||||
//
|
||||
#ifndef __CDATACHBARCODEDLG_INCLUDED__
|
||||
#define __CDATACHBARCODEDLG_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "Wnd.h"
|
||||
|
||||
class CDatachBarcodeDlg : public CWnd
|
||||
{
|
||||
public:
|
||||
// Override from CWnd
|
||||
BOOL Create( HWND hWndParent );
|
||||
void Destroy();
|
||||
|
||||
protected:
|
||||
// Message map
|
||||
DLG_MESSAGE_MAP()
|
||||
DLGMSG OnInitDialog( DLGMSGPARAM );
|
||||
DLGMSG OnActivate( DLGMSGPARAM );
|
||||
DLGMSG OnDestroy( DLGMSGPARAM );
|
||||
DLGMSG OnClose( DLGMSGPARAM );
|
||||
DLGCMD OnCancel( DLGCMDPARAM );
|
||||
DLGCMD OnCodeinput( DLGCMDPARAM );
|
||||
DLGCMD OnCodeTransfer( DLGCMDPARAM );
|
||||
DLGCMD OnCodeCreate( DLGCMDPARAM );
|
||||
//
|
||||
private:
|
||||
};
|
||||
|
||||
#endif // !__CDATACHBARCODEDLG_INCLUDED__
|
||||
|
||||
BIN
References/VirtuaNESex_src_191105/Debug/Chinese.vlp
Normal file
BIN
References/VirtuaNESex_src_191105/Debug/Chinese.vlp
Normal file
Binary file not shown.
211
References/VirtuaNESex_src_191105/Debug/VirtuaNESex.ini
Normal file
211
References/VirtuaNESex_src_191105/Debug/VirtuaNESex.ini
Normal file
@ -0,0 +1,211 @@
|
||||
[Path]
|
||||
RomAutoRunPath=.\
|
||||
RomPathUse=1
|
||||
SavePathUse=1
|
||||
StatePathUse=1
|
||||
SnapshotPathUse=1
|
||||
MoviePathUse=1
|
||||
WavePathUse=1
|
||||
CheatPathUse=1
|
||||
RomPath=.\roms\
|
||||
SavePath=.\save\
|
||||
StatePath=.\state\
|
||||
SnapshotPath=.\snapshot\
|
||||
MoviePath=.\movie\
|
||||
WavePath=.\wave\
|
||||
CheatPath=.\cheatcode\
|
||||
[General]
|
||||
DoubleExecute=1
|
||||
StartupLauncher=0
|
||||
WindowZoom=0
|
||||
WindowPos=5B020000C10000006F040000E002000073
|
||||
ScreenZoom=1
|
||||
SearchDialogPos=0000000000000000000000000000000000
|
||||
PatternViewPos=0000000000000000000000000000000000
|
||||
NameTableViewPos=0000000000000000000000000000000000
|
||||
PaletteViewPos=0000000000000000000000000000000000
|
||||
MemoryViewPos=A50000009E00000078020000BC0200007B
|
||||
BarcodePos=0000000000000000000000000000000000
|
||||
PaletteEditPos=0000000000000000000000000000000000
|
||||
JoyAxisDisable=0
|
||||
JoyAxisSetting=000000000000000000000000000000000000000000000000000000000000000000
|
||||
[Emulation]
|
||||
IllegalOp=0
|
||||
AutoFrameSkip=1
|
||||
Throttle=1
|
||||
ThrottleFPS=120
|
||||
Background=0
|
||||
Priority=3
|
||||
FourPlayer=1
|
||||
CrcCheck=1
|
||||
DiskThrottle=1
|
||||
LoadFullscreen=0
|
||||
PNGsnapshot=0
|
||||
[Graphics]
|
||||
Aspect=0
|
||||
SpriteMax=1
|
||||
AllLine=1
|
||||
FPSDisp=0
|
||||
TVFrameMode=0
|
||||
ScanlineMode=0
|
||||
ScanlineColor=75
|
||||
SyncDraw=0
|
||||
MaxZoom=0
|
||||
LeftClip=1
|
||||
WindowVSync=0
|
||||
DiskAccessLamp=0
|
||||
DoubleSize=0
|
||||
SystemMemory=0
|
||||
UseHEL=0
|
||||
NoSquareList=0
|
||||
GraphicsFilter=0
|
||||
DisplayWidth=640
|
||||
DisplayHeight=480
|
||||
DisplayDepth=32
|
||||
DisplayRate=56
|
||||
PaletteUse=0
|
||||
PaletteFile=
|
||||
[Sound]
|
||||
Enable=1
|
||||
DisableVolumeEffect=0
|
||||
ExtraSoundEnable=1
|
||||
SamplingRate=22050
|
||||
SamplingBits=8
|
||||
BufferSize=4
|
||||
FilterType=0
|
||||
Volume=640064006400640064006400640064006400640064006400640064006400640040
|
||||
[ShortCut]
|
||||
TBL00=18402E402640314020401E400000000017401140000000000000000000002D4070
|
||||
TBL01=3B003C0019000F009C004E004A0039000E0000000000000000000000000000001A
|
||||
TBL02=0C000D003D003E0000000000000000000000000000000000000000000000000094
|
||||
TBL03=06000200030004000500000000000000198013801E801F8032800000000000002F
|
||||
TBL04=3F004000410042001C800000000000000E400240034004400540064007400840CF
|
||||
TBL05=09400A400B400C4090407D400000000000000000000000000000000000000000B7
|
||||
TBL06=19405700584057405800434043004400444000000000000000000000C740CF40DB
|
||||
TBL07=D200D30000000000000000000000000000000000000000000000000000000000A5
|
||||
TBL08=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL09=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL10=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL11=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL12=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL13=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL14=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL15=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL16=52404F40504051404B404C404D4047404840494052804F80508051804B804C8057
|
||||
TBL17=4D8047804880498000000000000000000000000000000000000000000000000025
|
||||
TBL18=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL19=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL20=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL21=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL22=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL23=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL24=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL25=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL26=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL27=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL28=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL29=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL30=000000000000000000000000000000000000000000000000000000000000000000
|
||||
TBL31=000000000000000000000000000000000000000000000000000000000000000000
|
||||
[Controller 1]
|
||||
Keys=120020001F0021002500240017001600220023000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002D
|
||||
Rapid=0000000000
|
||||
[Controller 2]
|
||||
Keys=480050004B004D00310030000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C3
|
||||
Rapid=0000000000
|
||||
[Controller 3]
|
||||
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
Rapid=0000000000
|
||||
[Controller 4]
|
||||
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
Rapid=0000000000
|
||||
[Crazy Climber]
|
||||
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
[Family Trainer]
|
||||
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
[Exciting Boxing]
|
||||
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
[Mahjang]
|
||||
Keys=000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
[NSF controller]
|
||||
Keys=C800D000CB00CD00C900D1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA
|
||||
[VS-Unisystem]
|
||||
Keys=2E000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E
|
||||
[Movie]
|
||||
UsePlayer=FF000000FF
|
||||
ResetRec=0
|
||||
Rerecord=1
|
||||
LoopPlay=0
|
||||
PadDisplay=0
|
||||
[Launcher]
|
||||
WindowPos=0000000000000000000000000000000000
|
||||
ColumnView=0101010101010101010101010101010110
|
||||
ColumnOrder=000102030405060708090A0B0C0D0E0F78
|
||||
ColumnWidth=A00030003000300030003000300030003000300030003000300030003000300070
|
||||
ListSelect=0
|
||||
SortDir=0
|
||||
SortType=0
|
||||
FolderUse=0000000000000000000000000000000000
|
||||
Folder00=
|
||||
Folder01=
|
||||
Folder02=
|
||||
Folder03=
|
||||
Folder04=
|
||||
Folder05=
|
||||
Folder06=
|
||||
Folder07=
|
||||
Folder08=
|
||||
Folder09=
|
||||
Folder10=
|
||||
Folder11=
|
||||
Folder12=
|
||||
Folder13=
|
||||
Folder14=
|
||||
Folder15=
|
||||
LastSelect=
|
||||
ActivePause=0
|
||||
[Netplay]
|
||||
ChatPos=0000000000000000000000000000000000
|
||||
NickName=NoName
|
||||
RecnetPortNum=1
|
||||
RecentPort00=10000
|
||||
RecentPort01=
|
||||
RecentPort02=
|
||||
RecentPort03=
|
||||
RecentPort04=
|
||||
RecentPort05=
|
||||
RecentPort06=
|
||||
RecentPort07=
|
||||
RecentPort08=
|
||||
RecentPort09=
|
||||
RecentPort10=
|
||||
RecentPort11=
|
||||
RecentPort12=
|
||||
RecentPort13=
|
||||
RecentPort14=
|
||||
RecentPort15=
|
||||
RecnetHostNum=1
|
||||
RecentHost00=localhost:10000
|
||||
RecentHost01=
|
||||
RecentHost02=
|
||||
RecentHost03=
|
||||
RecentHost04=
|
||||
RecentHost05=
|
||||
RecentHost06=
|
||||
RecentHost07=
|
||||
RecentHost08=
|
||||
RecentHost09=
|
||||
RecentHost10=
|
||||
RecentHost11=
|
||||
RecentHost12=
|
||||
RecentHost13=
|
||||
RecentHost14=
|
||||
RecentHost15=
|
||||
[Recent Path List]
|
||||
Path1=E:\Game\NES\ProgramStudy\[Subor]Karaoke(C)\
|
||||
Path2=E:\Game\NES\NSF\
|
||||
Path3=E:\Game\NES\Rom\
|
||||
[Recent File List]
|
||||
File1=E:\Game\NES\ProgramStudy\[Subor]Karaoke(C)\[Subor]Karaoke(C).nsf
|
||||
File2=E:\Game\NES\NSF\Contra.nsf
|
||||
File3=E:\Game\NES\Rom\Contra(U).nes
|
||||
62
References/VirtuaNESex_src_191105/DebugOut.cpp
Normal file
62
References/VirtuaNESex_src_191105/DebugOut.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Debug output
|
||||
//
|
||||
#include "DebugOut.h"
|
||||
|
||||
CDebugOut Dbg;
|
||||
|
||||
static const CHAR szClassName[] = "DebugWindow_wndclass";
|
||||
|
||||
CDebugOut::CDebugOut()
|
||||
{
|
||||
#if defined(_DEBUG) || defined(_DEBUGOUT)
|
||||
hWndDebugOutput = ::FindWindow( szClassName, NULL );
|
||||
if( !hWndDebugOutput ) {
|
||||
::OutputDebugString( "DebugWindow がありません\n" );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CDebugOut::Clear()
|
||||
{
|
||||
#if defined(_DEBUG) || defined(_DEBUGOUT)
|
||||
if( hWndDebugOutput ) {
|
||||
if( ::IsWindow( hWndDebugOutput ) ) {
|
||||
::SendMessage( hWndDebugOutput, WM_APP+1, (WPARAM)NULL, (LPARAM)NULL );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void __cdecl CDebugOut::Out( LPSTR fmt, ... )
|
||||
{
|
||||
#if defined(_DEBUG) || defined(_DEBUGOUT)
|
||||
CHAR buf[1000];
|
||||
va_list va;
|
||||
va_start( va, fmt );
|
||||
::vsprintf( buf, fmt, va );
|
||||
|
||||
if( hWndDebugOutput ) {
|
||||
if( ::IsWindow( hWndDebugOutput ) ) {
|
||||
COPYDATASTRUCT cds;
|
||||
cds.dwData = 0;
|
||||
cds.lpData = (void*)buf;
|
||||
cds.cbData = ::strlen(buf)+1; // 終端のNULLも送る
|
||||
// 文字列送信
|
||||
::SendMessage( hWndDebugOutput, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds );
|
||||
} else {
|
||||
::OutputDebugString( buf );
|
||||
}
|
||||
} else {
|
||||
::OutputDebugString( buf );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CDebugOut::Out( const string& str )
|
||||
{
|
||||
#if defined(_DEBUG) || defined(_DEBUGOUT)
|
||||
Out( (LPSTR)str.c_str() );
|
||||
#endif
|
||||
}
|
||||
|
||||
45
References/VirtuaNESex_src_191105/DebugOut.h
Normal file
45
References/VirtuaNESex_src_191105/DebugOut.h
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// Debug output
|
||||
//
|
||||
#ifndef __DEBUGOUT_INCLUDED__
|
||||
#define __DEBUGOUT_INCLUDED__
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
typedef void (__cdecl *DEBUGWINDOWOUTPUT)(LPCTSTR);
|
||||
|
||||
class CDebugOut {
|
||||
public:
|
||||
CDebugOut();
|
||||
|
||||
void Clear();
|
||||
|
||||
void __cdecl Out( LPSTR fmt, ... );
|
||||
void Out( const string& str );
|
||||
|
||||
protected:
|
||||
HWND hWndDebugOutput;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
extern CDebugOut Dbg;
|
||||
|
||||
#if defined(_DEBUG) || defined(_DEBUGOUT)
|
||||
#define DEBUGOUT Dbg.Out
|
||||
#else
|
||||
#define DEBUGOUT
|
||||
#endif // !_DEBUG
|
||||
|
||||
#if defined(_DEBUG) || defined(_DEBUGOUT)
|
||||
#define DEBUGCLR Dbg.Clear
|
||||
#else
|
||||
#define DEBUGCLR
|
||||
#endif // !_DEBUG
|
||||
|
||||
#endif // !__DEBUGOUT_INCLUDED__
|
||||
|
||||
130
References/VirtuaNESex_src_191105/DipSwitchDlg.cpp
Normal file
130
References/VirtuaNESex_src_191105/DipSwitchDlg.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
//
|
||||
// チャットダイアログクラス
|
||||
//
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <mbstring.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "typedef.h"
|
||||
#include "macro.h"
|
||||
|
||||
#include "VirtuaNESres.h"
|
||||
#include "DebugOut.h"
|
||||
#include "App.h"
|
||||
#include "Pathlib.h"
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "VsUnisystem.h"
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "DipSwitchDlg.h"
|
||||
|
||||
// メッセージ
|
||||
DLG_MESSAGE_BEGIN(CDipSwitchDlg)
|
||||
DLG_ON_MESSAGE( WM_INITDIALOG, OnInitDialog )
|
||||
|
||||
// コマンド
|
||||
DLG_COMMAND_BEGIN()
|
||||
DLG_ON_COMMAND( IDOK, OnOK )
|
||||
DLG_ON_COMMAND( IDCANCEL, OnCancel )
|
||||
DLG_COMMAND_END()
|
||||
// Notify メッセージ
|
||||
DLG_NOTIFY_BEGIN()
|
||||
DLG_NOTIFY_END()
|
||||
DLG_MESSAGE_END()
|
||||
|
||||
INT CDipSwitchDlg::DoModal( HWND hWndParent )
|
||||
{
|
||||
return ::DialogBoxParam( CApp::GetPlugin(), MAKEINTRESOURCE(IDD_EXT_VSUNISYSTEM),
|
||||
hWndParent, g_DlgProc, (LPARAM)this );
|
||||
}
|
||||
|
||||
|
||||
DLGMSG CDipSwitchDlg::OnInitDialog( DLGMSGPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CDipSwitchDlg::OnInitDialog\n" );
|
||||
|
||||
for( INT i = IDC_EVS_DIPCOMBO0; i <= IDC_EVS_DIPCOMBO7; i++ ) {
|
||||
::SendDlgItemMessage( m_hWnd, i, CB_RESETCONTENT, 0, 0 );
|
||||
}
|
||||
|
||||
BYTE val = Emu.GetNES()->GetVSDipSwitch();
|
||||
VSDIPSWITCH* dip = Emu.GetNES()->GetVSDipSwitchTable();
|
||||
|
||||
DEBUGOUT( "GET DIPSWITCH:%02X\n", val );
|
||||
|
||||
BYTE mask;
|
||||
|
||||
INT nStatic = IDC_EVS_DIPNAME0;
|
||||
INT nCombo = IDC_EVS_DIPCOMBO0;
|
||||
BOOL bFlag;
|
||||
INT nCount, nSelect;
|
||||
|
||||
bFlag = FALSE;
|
||||
nCount = nSelect = 0;
|
||||
for(;;) {
|
||||
if( dip->name == NULL && dip->value == 0x0000 ) {
|
||||
break;
|
||||
} else if( dip->value == 0x00FF ) {
|
||||
bFlag = FALSE;
|
||||
::SendDlgItemMessage( m_hWnd, nCombo, CB_SETCURSEL, (WPARAM)nSelect, 0 );
|
||||
nCombo++;
|
||||
} else if( !bFlag ) {
|
||||
bFlag = TRUE;
|
||||
::SetDlgItemText( m_hWnd, nStatic, (LPCTSTR)dip->name );
|
||||
mask = dip->value>>8;
|
||||
nCount = 0;
|
||||
nStatic++;
|
||||
} else {
|
||||
if( dip->value == (val & mask) )
|
||||
nSelect = nCount;
|
||||
::SendDlgItemMessage( m_hWnd, nCombo, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dip->name );
|
||||
::SendDlgItemMessage( m_hWnd, nCombo, CB_SETITEMDATA, (WPARAM)nCount, (LPARAM)(dip->value&0xFF) );
|
||||
nCount++;
|
||||
}
|
||||
dip++;
|
||||
}
|
||||
m_nDispCount = nStatic-IDC_EVS_DIPNAME0;
|
||||
|
||||
// 使わない奴は非表示にする
|
||||
for( ; nStatic <= IDC_EVS_DIPNAME7; nStatic++, nCombo++ ) {
|
||||
::ShowWindow( ::GetDlgItem( m_hWnd, nStatic ), SW_HIDE );
|
||||
::ShowWindow( ::GetDlgItem( m_hWnd, nCombo ), SW_HIDE );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DLGCMD CDipSwitchDlg::OnOK( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CDipSwitchDlg::OnOK\n" );
|
||||
|
||||
// 選択されている奴のItemDataを取得してDipSwitchデータを作り直す(OnInitDialogでItemDataを設定済み)
|
||||
BYTE dipval = 0;
|
||||
for( INT i = IDC_EVS_DIPCOMBO0; i < IDC_EVS_DIPCOMBO0+m_nDispCount; i++ ) {
|
||||
INT sel = ::SendDlgItemMessage( m_hWnd, i, CB_GETCURSEL, 0, 0 );
|
||||
DWORD val = (DWORD)::SendDlgItemMessage( m_hWnd, i, CB_GETITEMDATA, (WPARAM)sel, 0 );
|
||||
|
||||
dipval |= val & 0xFF;
|
||||
}
|
||||
|
||||
Emu.GetNES()->SetVSDipSwitch( dipval );
|
||||
|
||||
DEBUGOUT( "SET DIPSWITCH:%02X\n", dipval );
|
||||
|
||||
::EndDialog( m_hWnd, IDOK );
|
||||
}
|
||||
|
||||
DLGCMD CDipSwitchDlg::OnCancel( DLGCMDPARAM )
|
||||
{
|
||||
// DEBUGOUT( "CDipSwitchDlg::OnCancel\n" );
|
||||
::EndDialog( m_hWnd, IDCANCEL );
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user