Previous 199869 Revisions Next

r36140 Friday 27th February, 2015 at 23:21:44 UTC by Couriersud
Moved all renderers to osd/modules/render. (nw)
[3rdparty/bgfx]README.md
[3rdparty/bgfx/3rdparty/ocornut-imgui]imgui.cpp
[3rdparty/bgfx/examples/23-vectordisplay]vectordisplay.cpp
[3rdparty/bgfx/examples/common/imgui]fs_imgui_latlong.bin.h fs_imgui_latlong.sc imgui.cpp imgui.h ocornut_imgui.cpp
[3rdparty/bgfx/include]bgfx.c99.h bgfx.h
[3rdparty/bgfx/scripts]bgfx.lua example-common.lua genie.lua geometryc.lua makedisttex.lua shaderc.lua texturec.lua
[3rdparty/bgfx/src]bgfx.cpp bgfx_compute.sh bgfx_p.h bgfx_shader.sh config.h glimports.h renderer_d3d11.cpp renderer_d3d9.cpp renderer_gl.cpp renderer_gl.h
[3rdparty/bx/scripts]genie.lua toolchain.lua
[3rdparty/genie]README.md
[3rdparty/genie/src/actions/make]make_cpp.lua
[3rdparty/genie/src/base]api.lua bake.lua
[3rdparty/genie/src/host]scripts.c
[3rdparty/mongoose]mongoose.c
[3rdparty/mongoose/docs]API.md LuaSqlite.md*
[src/emu/bus]bus.mak
[src/emu/bus/a2bus]ezcgi.c ezcgi.h
[src/emu/video]tms34061.c
[src/mame/drivers]argus.c capbowl.c fgoal.c ssv.c tugboat.c
[src/mame/includes]argus.h capbowl.h fgoal.h ssv.h
[src/mame/video]argus.c capbowl.c fgoal.c ssv.c st0020.c
[src/mess]mess.mak
[src/mess/drivers]alnchase.c* apple2.c apple2e.c edracula.c* hh_tms1k.c hh_ucom4.c mbee.c tmtennis.c* wildfire.c
[src/mess/includes]mbee.h
[src/mess/layout]ebball.lay edracula.lay tmpacman.lay wildfire.lay
[src/mess/machine]mbee.c
[src/mess/video]mbee.c
[src/osd/modules/render]blit13.h* draw13.c* drawbgfx.c* drawd3d.c* drawd3d.h* drawdd.c* drawgdi.c* drawnone.c* drawogl.c* drawsdl.c*
[src/osd/modules/render/d3d]d3d9intf.c* d3dcomm.h* d3dhlsl.c* d3dhlsl.h* d3dintf.h*
[src/osd/modules/sync]osdsync.h
[src/osd/sdl]blit13.h draw13.c drawbgfx.c drawogl.c drawsdl.c sdl.mak
[src/osd/windows]d3d9intf.c d3dcomm.h d3dhlsl.c d3dhlsl.h d3dintf.h drawbgfx.c drawd3d.c drawd3d.h drawdd.c drawgdi.c drawnone.c windows.mak

trunk/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp
r244651r244652
18091809    g.CurrentWindowStack.resize(0);
18101810
18111811    // Create implicit window - we will only render it if the user has added something to it.
1812    ImGui::Begin("Debug", NULL, ImVec2(400,400), -1.0f, ImGuiWindowFlags_NoSavedSettings);
1812    ImGui::Begin("Debug", NULL, ImVec2(400,400));
18131813}
18141814
18151815// NB: behaviour of ImGui after Shutdown() is not tested/guaranteed at the moment. This function is merely here to free heap allocations.
trunk/3rdparty/bgfx/README.md
r244651r244652
6969how it currently looks. 
7070![mac_screenshot](https://raw.githubusercontent.com/emoon/ProDBG/master/data/screens/mac_screenshot.png)
7171
72
7273http://www.dogbytegames.com/ Dogbyte Games is an indie mobile developer studio
73focusing on racing games. 
74![ios](http://www.dogbytegames.com/bgfx/offroadlegends2_bgfx_ipad2.jpg)
74focusing on racing games.
7575
7676Examples
7777--------
trunk/3rdparty/bgfx/examples/23-vectordisplay/vectordisplay.cpp
r244651r244652
123123
124124void VectorDisplay::teardown()
125125{
126   for (size_t i = 0; i < m_vertexBuffers.size(); ++i)
127   {
128      bgfx::destroyDynamicVertexBuffer(m_vertexBuffers[i]);
129   }
130
131126   teardownResDependent();
132127
133128   bgfx::destroyProgram(m_drawToScreenShader);
r244651r244652
733728   {
734729      for (size_t i = 0; i < m_vertexBuffers.size(); ++i)
735730      {
736         bgfx::destroyDynamicVertexBuffer(m_vertexBuffers[i]);
731         destroyDynamicVertexBuffer(m_vertexBuffers[i]);
737732      }
738733
739734      m_vertexBuffers.clear();
trunk/3rdparty/bgfx/examples/common/imgui/fs_imgui_latlong.bin.h
r244651r244652
1static const uint8_t fs_imgui_latlong_glsl[649] =
1static const uint8_t fs_imgui_latlong_glsl[646] =
22{
33   0x46, 0x53, 0x48, 0x03, 0x6f, 0x1e, 0x3e, 0x3c, 0x02, 0x00, 0x11, 0x75, 0x5f, 0x69, 0x6d, 0x61, // FSH.o.><...u_ima
44   0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x07, 0x01, 0x00, 0x00, // geLodEnabled....
55   0x01, 0x00, 0x0a, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x00, // ...s_texColor...
6   0x00, 0x01, 0x00, 0x51, 0x02, 0x00, 0x00, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x68, // ...Q...varying h
6   0x00, 0x01, 0x00, 0x4e, 0x02, 0x00, 0x00, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x68, // ...N...varying h
77   0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, // ighp vec2 v_texc
88   0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x68, // oord0;.uniform h
99   0x69, 0x67, 0x68, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, // ighp vec4 u_imag
r244651r244652
2121   0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x20, 0x3d, 0x20, 0x28, 0x76, 0x5f, //   tmpvar_3 = (v_
2222   0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x33, 0x2e, // texcoord0.y * 3.
2323   0x31, 0x34, 0x31, 0x35, 0x39, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, // 14159);.  result
24   0x5f, 0x31, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x2d, 0x28, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x6d, // _1.x = (-(sin(tm
25   0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, 0x6e, 0x28, 0x74, // pvar_3)) * sin(t
26   0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, // mpvar_2));.  res
27   0x75, 0x6c, 0x74, 0x5f, 0x31, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x6d, // ult_1.y = cos(tm
28   0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, // pvar_3);.  resul
29   0x74, 0x5f, 0x31, 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x28, 0x2d, 0x28, 0x73, 0x69, 0x6e, 0x28, 0x74, // t_1.z = (-(sin(t
30   0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x33, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x63, 0x6f, 0x73, 0x28, // mpvar_3)) * cos(
31   0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6c, 0x6f, // tmpvar_2));.  lo
32   0x77, 0x70, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, // wp vec4 tmpvar_4
33   0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x2e, 0x78, 0x79, 0x7a, // ;.  tmpvar_4.xyz
34   0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x75, 0x62, 0x65, 0x4c, 0x6f, //  = textureCubeLo
35   0x64, 0x20, 0x20, 0x20, 0x20, 0x28, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, // d    (s_texColor
36   0x2c, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x2c, 0x20, 0x75, 0x5f, 0x69, 0x6d, // , result_1, u_im
37   0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x78, 0x29, // ageLodEnabled.x)
38   0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, // .xyz;.  tmpvar_4
39   0x2e, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x30, 0x2e, 0x32, 0x20, 0x2b, 0x20, 0x28, 0x30, 0x2e, 0x38, // .w = (0.2 + (0.8
40   0x20, 0x2a, 0x20, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, //  * u_imageLodEna
41   0x62, 0x6c, 0x65, 0x64, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, // bled.y));.  gl_F
42   0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, // ragColor = tmpva
43   0x72, 0x5f, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                           // r_4;.}...
24   0x5f, 0x31, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x6d, 0x70, 0x76, // _1.x = (sin(tmpv
25   0x61, 0x72, 0x5f, 0x33, 0x29, 0x20, 0x2a, 0x20, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x6d, 0x70, 0x76, // ar_3) * cos(tmpv
26   0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, // ar_2));.  result
27   0x5f, 0x31, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x6d, 0x70, 0x76, 0x61, // _1.y = cos(tmpva
28   0x72, 0x5f, 0x33, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, // r_3);.  result_1
29   0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x28, 0x2d, 0x28, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x6d, 0x70, 0x76, // .z = (-(sin(tmpv
30   0x61, 0x72, 0x5f, 0x33, 0x29, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x6d, 0x70, // ar_3)) * sin(tmp
31   0x76, 0x61, 0x72, 0x5f, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x77, 0x70, 0x20, // var_2));.  lowp
32   0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x3b, 0x0a, 0x20, // vec4 tmpvar_4;.
33   0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, //  tmpvar_4.xyz =
34   0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x43, 0x75, 0x62, 0x65, 0x4c, 0x6f, 0x64, 0x20, 0x20, // textureCubeLod
35   0x20, 0x20, 0x28, 0x73, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x72, //   (s_texColor, r
36   0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x31, 0x2c, 0x20, 0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, // esult_1, u_image
37   0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x78, 0x29, 0x2e, 0x78, 0x79, // LodEnabled.x).xy
38   0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, 0x2e, 0x77, 0x20, // z;.  tmpvar_4.w
39   0x3d, 0x20, 0x28, 0x30, 0x2e, 0x32, 0x20, 0x2b, 0x20, 0x28, 0x30, 0x2e, 0x38, 0x20, 0x2a, 0x20, // = (0.2 + (0.8 *
40   0x75, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, // u_imageLodEnable
41   0x64, 0x2e, 0x79, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, // d.y));.  gl_Frag
42   0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x34, // Color = tmpvar_4
43   0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00,                                                             // ;.}...
4444};
45static const uint8_t fs_imgui_latlong_dx9[537] =
45static const uint8_t fs_imgui_latlong_dx9[553] =
4646{
4747   0x46, 0x53, 0x48, 0x03, 0x6f, 0x1e, 0x3e, 0x3c, 0x01, 0x00, 0x11, 0x75, 0x5f, 0x69, 0x6d, 0x61, // FSH.o.><...u_ima
4848   0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x15, 0x01, 0x00, 0x00, // geLodEnabled....
49   0x01, 0x00, 0xf4, 0x01, 0x00, 0x03, 0xff, 0xff, 0xfe, 0xff, 0x30, 0x00, 0x43, 0x54, 0x41, 0x42, // ..........0.CTAB
49   0x01, 0x00, 0x04, 0x02, 0x00, 0x03, 0xff, 0xff, 0xfe, 0xff, 0x30, 0x00, 0x43, 0x54, 0x41, 0x42, // ..........0.CTAB
5050   0x1c, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, // ................
5151   0x1c, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, // ............D...
5252   0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........P.......
r244651r244652
7171   0x01, 0x00, 0x00, 0xa0, 0x13, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, // ................
7272   0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x55, 0xa0, // ..............U.
7373   0x01, 0x00, 0xaa, 0xa0, 0x25, 0x00, 0x00, 0x02, 0x02, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x80, // ....%...........
74   0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x05, 0x80, 0x01, 0x00, 0xc5, 0x80, 0x02, 0x00, 0x55, 0x81, // ..............U.
74   0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x80, 0x02, 0x00, 0x55, 0x80, // ..............U.
75   0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x80, 0x01, 0x00, 0x55, 0x80, 0x02, 0x00, 0x55, 0x81, // ..........U...U.
7576   0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x80, 0x02, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x02, // ................
7677   0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0xa0, 0x5f, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, // ........_.......
7778   0x00, 0x00, 0xe4, 0x80, 0x00, 0x08, 0xe4, 0xa0, 0x01, 0x00, 0x00, 0x02, 0x00, 0x08, 0x07, 0x80, // ................
r244651r244652
8384{
8485   0x46, 0x53, 0x48, 0x03, 0x6f, 0x1e, 0x3e, 0x3c, 0x01, 0x00, 0x11, 0x75, 0x5f, 0x69, 0x6d, 0x61, // FSH.o.><...u_ima
8586   0x67, 0x65, 0x4c, 0x6f, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x15, 0x00, 0x30, 0x0a, // geLodEnabled..0.
86   0x01, 0x00, 0x30, 0x02, 0x44, 0x58, 0x42, 0x43, 0xbb, 0x3e, 0xd7, 0x3a, 0x63, 0xc9, 0x70, 0x0b, // ..0.DXBC.>.:c.p.
87   0xa5, 0x2c, 0x7d, 0xb2, 0x3c, 0x0c, 0x75, 0x44, 0x01, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, // .,}.<.uD....0...
87   0x01, 0x00, 0x30, 0x02, 0x44, 0x58, 0x42, 0x43, 0x89, 0x11, 0x25, 0xa6, 0xf5, 0x66, 0x12, 0x3f, // ..0.DXBC..%..f.?
88   0xc0, 0x1f, 0x67, 0x9b, 0x6e, 0x4e, 0xac, 0x03, 0x01, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0x00, // ..g.nN......0...
8889   0x03, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, // ....,...........
8990   0x49, 0x53, 0x47, 0x4e, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // ISGNP...........
9091   0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // 8...............
r244651r244652
100101   0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x30, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, // .`......X0...p..
101102   0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, // ....UU..b...2...
102103   0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....e.... ......
103   0x68, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, // h.......8...2...
104   0x00, 0x00, 0x00, 0x00, 0x16, 0x15, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, // .............@..
105   0xdb, 0x0f, 0x49, 0x40, 0xdb, 0x0f, 0xc9, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..I@...@........
106   0x4d, 0x00, 0x00, 0x06, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, // M...B...........
107   0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x07, 0x82, 0x00, 0x10, 0x00, // ........M.......
108   0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, // ............A...
104   0x68, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, // h.......8...2...
105   0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, // ....F........@..
106   0xdb, 0x0f, 0xc9, 0x40, 0xdb, 0x0f, 0x49, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ...@..I@........
107   0x4d, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, // M...B...........
108   0x1a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x06, // ....A.......M...
109   0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x16, 0x05, 0x10, 0x00, // 2...............
109110   0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x06, 0x00, 0xd0, 0x00, 0x00, 0x62, 0x00, 0x10, 0x00, // ....M.......b...
110   0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, // ............8...
111   0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ........*.......
112   0x3a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x82, 0x00, 0x10, 0x00, // :.......8.......
113   0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, // ....:.......*...
114   0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0c, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....H...........
115   0x46, 0x03, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // F.......F~......
111   0x02, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, // ............8...
112   0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ........*.......
113   0x1a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, // ........8.......
114   0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, // ................
115   0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x0c, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....H...........
116   0x86, 0x03, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ........F~......
116117   0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, // .`........ .....
117118   0xa3, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....6...r ......
118119   0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x82, 0x20, 0x10, 0x00, // F.......2.... ..
trunk/3rdparty/bgfx/examples/common/imgui/fs_imgui_latlong.sc
r244651r244652
1818   float pi    = 3.14159265;
1919   float twoPi = 2.0*pi;
2020   float phi   = _uv.x * twoPi;
21   float theta = _uv.y * pi;
21   float theta = _uv.y *pi;
2222
2323   vec3 result;
24   result.x = -sin(theta)*sin(phi);
24   result.x = sin(theta)*cos(phi);
2525   result.y = cos(theta);
26   result.z = -sin(theta)*cos(phi);
26   result.z = -sin(theta)*sin(phi);
2727
2828   return result;
2929}
trunk/3rdparty/bgfx/examples/common/imgui/imgui.cpp
r244651r244652
387387      , m_textureHeight(512)
388388      , m_halfTexel(0.0f)
389389      , m_nvg(NULL)
390      , m_view(255)
390      , m_view(31)
391391      , m_viewWidth(0)
392392      , m_viewHeight(0)
393393      , m_currentFontIdx(0)
r244651r244652
20232023         xx = -borderSize;
20242024         yy = -1;
20252025         width = 2*borderSize+1;
2026         height = m_viewHeight+1;
2026         height = m_viewHeight;
20272027         triX = 0;
20282028         triY = (m_viewHeight-triSize)/2;
20292029         orientation = _checked ? TriangleOrientation::Left : TriangleOrientation::Right;
r244651r244652
20332033         xx = m_viewWidth - borderSize;
20342034         yy = -1;
20352035         width = 2*borderSize+1;
2036         height = m_viewHeight+1;
2036         height = m_viewHeight;
20372037         triX = m_viewWidth - triSize - 2;
20382038         triY = (m_viewHeight-width)/2;
20392039         orientation = _checked ? TriangleOrientation::Right : TriangleOrientation::Left;
trunk/3rdparty/bgfx/examples/common/imgui/imgui.h
r244651r244652
136136ImguiFontHandle imguiCreate(const void* _data = NULL, uint32_t _size = 0, float _fontSize = 15.0f);
137137void imguiDestroy();
138138
139void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, char _inputChar = 0, uint8_t _view = 255);
139void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, char _inputChar = 0, uint8_t _view = 31);
140140void imguiEndFrame();
141141
142142void imguiDrawText(int _x, int _y, ImguiTextAlign::Enum _align, const char* _text, uint32_t _argb);
trunk/3rdparty/bgfx/examples/common/imgui/ocornut_imgui.cpp
r244651r244652
8181
8282   void create(const void* _data, uint32_t _size, float _fontSize)
8383   {
84      m_viewId = 255;
84      m_viewId = 31;
8585
8686      ImGuiIO& io = ImGui::GetIO();
8787      io.DisplaySize = ImVec2(1280.0f, 720.0f);
trunk/3rdparty/bgfx/include/bgfx.c99.h
r244651r244652
287287    uint64_t supported;
288288
289289    uint16_t maxTextureSize;    /* < Maximum texture size.             */
290    uint16_t maxViews;          /* < Maximum views.                    */
291290    uint16_t maxDrawCalls;      /* < Maximum draw calls.               */
292291    uint8_t  maxFBAttachments;  /* < Maximum frame buffer attachments. */
293292
r244651r244652
13591358/**
13601359 *
13611360 */
1362BGFX_C_API void bgfx_set_image(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format);
1361BGFX_C_API void bgfx_set_image(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_texture_format_t _format, bgfx_access_t _access);
13631362
13641363/**
13651364 *
13661365 */
1367BGFX_C_API void bgfx_set_image_from_frame_buffer(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_frame_buffer_handle_t _handle, uint8_t _attachment, bgfx_access_t _access, bgfx_texture_format_t _format);
1366BGFX_C_API void bgfx_set_image_from_frame_buffer(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_frame_buffer_handle_t _handle, uint8_t _attachment, bgfx_texture_format_t _format, bgfx_access_t _access);
13681367
13691368/**
13701369 * Dispatch compute.
trunk/3rdparty/bgfx/include/bgfx.h
r244651r244652
310310      uint64_t supported;
311311
312312      uint16_t maxTextureSize;   ///< Maximum texture size.
313      uint16_t maxViews;         ///< Maximum views.
314313      uint16_t maxDrawCalls;     ///< Maximum draw calls.
315314      uint8_t  maxFBAttachments; ///< Maximum frame buffer attachments.
316315
r244651r244652
10991098   /// view will use these matrices.
11001099   void setViewTransform(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags = BGFX_VIEW_STEREO, const void* _projR = NULL);
11011100
1102   /// Post submit view reordering.
1103   ///
1104   /// @param _id First view id.
1105   /// @param _num Number of views to remap.
1106   /// @param _remap View remap id table. Passing `NULL` will reset view ids
1107   ///   to default state.
1108   ///
1109   void setViewRemap(uint8_t _id = 0, uint8_t _num = UINT8_MAX, const void* _remap = NULL);
1110
11111101   /// Sets debug marker.
11121102   void setMarker(const char* _marker);
11131103
r244651r244652
12831273   void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access);
12841274
12851275   ///
1286   void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format = TextureFormat::Count);
1276   void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, TextureFormat::Enum _format, Access::Enum _access);
12871277
12881278   ///
1289   void setImage(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, Access::Enum _access, TextureFormat::Enum _format = TextureFormat::Count);
1279   void setImage(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, TextureFormat::Enum _format, Access::Enum _access);
12901280
12911281   /// Dispatch compute.
12921282   void dispatch(uint8_t _id, ProgramHandle _handle, uint16_t _numX = 1, uint16_t _numY = 1, uint16_t _numZ = 1, uint8_t _flags = BGFX_SUBMIT_EYE_FIRST);
trunk/3rdparty/bgfx/scripts/bgfx.lua
r244651r244652
2929      end
3030
3131      includedirs {
32         path.join(BGFX_DIR, "3rdparty"),
33         path.join(BGFX_DIR, "../bx/include"),
32         BGFX_DIR .. "3rdparty",
33         BGFX_DIR .. "../bx/include",
3434      }
3535
3636      defines {
r244651r244652
6969
7070      configuration { "xcode4 or osx or ios*" }
7171         files {
72            path.join(BGFX_DIR, "src/**.mm"),
72            BGFX_DIR .. "src/**.mm",
7373         }
7474
7575      configuration { "osx" }
r244651r244652
8080      configuration { "not nacl" }
8181         includedirs {
8282            --nacl has GLES2 headers modified...
83            path.join(BGFX_DIR, "3rdparty/khronos"),
83            BGFX_DIR .. "3rdparty/khronos",
8484         }
8585
8686      configuration { "x64", "vs* or mingw*" }
r244651r244652
9191      configuration {}
9292
9393      includedirs {
94         path.join(BGFX_DIR, "include"),
94         BGFX_DIR .. "include",
9595      }
9696
9797      files {
98         path.join(BGFX_DIR, "include/**.h"),
99         path.join(BGFX_DIR, "src/**.cpp"),
100         path.join(BGFX_DIR, "src/**.h"),
98         BGFX_DIR .. "include/**.h",
99         BGFX_DIR .. "src/**.cpp",
100         BGFX_DIR .. "src/**.h",
101101      }
102102
103103      excludes {
104         path.join(BGFX_DIR, "src/**.bin.h"),
104         BGFX_DIR .. "src/**.bin.h",
105105      }
106106
107107      configuration {}
trunk/3rdparty/bgfx/scripts/example-common.lua
r244651r244652
88   kind "StaticLib"
99
1010   includedirs {
11      path.join(BX_DIR, "include"),
12      path.join(BGFX_DIR, "include"),
13      path.join(BGFX_DIR, "3rdparty"),
11      BX_DIR .. "include",
12      BGFX_DIR .. "include",
13      BGFX_DIR .. "3rdparty",
1414   }
1515
1616   files {
17      path.join(BGFX_DIR, "3rdparty/ib-compress/**.cpp"),
18      path.join(BGFX_DIR, "3rdparty/ib-compress/**.h"),
19      path.join(BGFX_DIR, "3rdparty/ocornut-imgui/**.cpp"),
20      path.join(BGFX_DIR, "3rdparty/ocornut-imgui/**.h"),
21      path.join(BGFX_DIR, "examples/common/**.cpp"),
22      path.join(BGFX_DIR, "examples/common/**.h"),
17      BGFX_DIR .. "3rdparty/ib-compress/**.cpp",
18      BGFX_DIR .. "3rdparty/ib-compress/**.h",
19      BGFX_DIR .. "3rdparty/ocornut-imgui/**.cpp",
20      BGFX_DIR .. "3rdparty/ocornut-imgui/**.h",
21      BGFX_DIR .. "examples/common/**.cpp",
22      BGFX_DIR .. "examples/common/**.h",
2323   }
2424
2525   if _OPTIONS["with-sdl"] then
trunk/3rdparty/bgfx/scripts/genie.lua
r244651r244652
4545   language "C++"
4646   startproject "example-00-helloworld"
4747
48BGFX_DIR = path.getabsolute("..")
49local BGFX_BUILD_DIR = path.join(BGFX_DIR, ".build")
50local BGFX_THIRD_PARTY_DIR = path.join(BGFX_DIR, "3rdparty")
51BX_DIR = path.getabsolute(path.join(BGFX_DIR, "../bx"))
48BGFX_DIR = (path.getabsolute("..") .. "/")
49local BGFX_BUILD_DIR = (BGFX_DIR .. ".build/")
50local BGFX_THIRD_PARTY_DIR = (BGFX_DIR .. "3rdparty/")
51BX_DIR = (BGFX_DIR .. "../bx/")
5252
5353defines {
5454   "BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS=1"
5555}
5656
57dofile (path.join(BX_DIR, "scripts/toolchain.lua"))
57dofile (BX_DIR .. "scripts/toolchain.lua")
5858if not toolchain(BGFX_BUILD_DIR, BGFX_THIRD_PARTY_DIR) then
5959   return -- no action specified
6060end
r244651r244652
8080
8181   -- don't output debugdir for winphone builds
8282   if "winphone81" ~= _OPTIONS["vs"] then
83      debugdir (path.join(BGFX_DIR, "examples/runtime"))
83      debugdir (BGFX_DIR .. "examples/runtime/")
8484   end
8585
8686   includedirs {
87      path.join(BX_DIR, "include"),
88      path.join(BGFX_DIR, "include"),
89      path.join(BGFX_DIR, "3rdparty"),
90      path.join(BGFX_DIR, "examples/common"),
87      BX_DIR .. "include",
88      BGFX_DIR .. "include",
89      BGFX_DIR .. "3rdparty",
90      BGFX_DIR .. "examples/common",
9191   }
9292
9393   files {
94      path.join(BGFX_DIR, "examples", _name, "**.cpp"),
95      path.join(BGFX_DIR, "examples", _name, "**.h"),
94      BGFX_DIR .. "examples/" .. _name .. "/**.cpp",
95      BGFX_DIR .. "examples/" .. _name .. "/**.h",
9696   }
9797
9898   links {
r244651r244652
120120      }
121121
122122      configuration { "x32" }
123         libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Win32", _ACTION) }
123         libdirs { "$(OVR_DIR)/LibOVR/Lib/Win32/" .. _ACTION }
124124
125125      configuration { "x64" }
126         libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/x64", _ACTION) }
126         libdirs { "$(OVR_DIR)/LibOVR/Lib/x64/" .. _ACTION }
127127
128128      configuration { "x32", "Debug" }
129129         links { "libovrd" }
r244651r244652
177177         "/ignore:4264" -- LNK4264: archiving object file compiled with /ZW into a static library; note that when authoring Windows Runtime types it is not recommended to link with a static library that contains Windows Runtime metadata
178178      }
179179      -- WinRT targets need their own output directories are build files stomp over each other
180      targetdir (path.join(BGFX_BUILD_DIR, "arm_" .. _ACTION, "bin", _name))
181      objdir (path.join(BGFX_BUILD_DIR, "arm_" .. _ACTION, "obj", _name))
180      targetdir (BGFX_BUILD_DIR .. "arm_" .. _ACTION .. "/bin/" .. _name)
181      objdir (BGFX_BUILD_DIR .. "arm_" .. _ACTION .. "/obj/" .. _name)
182182
183183   configuration { "mingw-clang" }
184184      kind "ConsoleApp"
r244651r244652
236236
237237   configuration { "osx" }
238238      files {
239         path.join(BGFX_DIR, "examples/common/**.mm"),
239         BGFX_DIR .. "examples/common/**.mm",
240240      }
241241      links {
242242         "Cocoa.framework",
r244651r244652
246246   configuration { "ios*" }
247247      kind "ConsoleApp"
248248      files {
249         path.join(BGFX_DIR, "examples/common/**.mm"),
249         BGFX_DIR .. "examples/common/**.mm",
250250      }
251251      linkoptions {
252252         "-framework CoreFoundation",
r244651r244652
259259   configuration { "xcode4", "ios" }
260260      kind "WindowedApp"
261261      files {
262         path.join(BGFX_DIR, "examples/runtime/iOS-Info.plist"),
262         BGFX_DIR .. "examples/runtime/iOS-Info.plist"
263263      }
264264
265265   configuration { "qnx*" }
trunk/3rdparty/bgfx/scripts/geometryc.lua
r244651r244652
88   kind "ConsoleApp"
99
1010   includedirs {
11      path.join(BX_DIR, "include"),
12      path.join(BGFX_DIR, "include"),
13      path.join(BGFX_DIR, "3rdparty"),
14      path.join(BGFX_DIR, "examples/common"),
11      BX_DIR   .. "include",
12      BGFX_DIR .. "include",
13      BGFX_DIR .. "3rdparty",
14      BGFX_DIR .. "examples/common",
1515   }
1616
1717   files {
18      path.join(BGFX_DIR, "3rdparty/forsyth-too/**.cpp"),
19      path.join(BGFX_DIR, "3rdparty/forsyth-too/**.h"),
20      path.join(BGFX_DIR, "3rdparty/ib-compress/**.cpp"),
21      path.join(BGFX_DIR, "3rdparty/ib-compress/**.h"),
22      path.join(BGFX_DIR, "src/vertexdecl.**"),
23      path.join(BGFX_DIR, "tools/geometryc/**.cpp"),
24      path.join(BGFX_DIR, "tools/geometryc/**.h"),
25      path.join(BGFX_DIR, "examples/common/bounds.**"),
18      BGFX_DIR .. "3rdparty/forsyth-too/**.cpp",
19      BGFX_DIR .. "3rdparty/forsyth-too/**.h",
20      BGFX_DIR .. "3rdparty/ib-compress/**.cpp",
21      BGFX_DIR .. "3rdparty/ib-compress/**.h",
22      BGFX_DIR .. "src/vertexdecl.**",
23      BGFX_DIR .. "tools/geometryc/**.cpp",
24      BGFX_DIR .. "tools/geometryc/**.h",
25      BGFX_DIR .. "examples/common/bounds.**",
2626   }
2727
2828   configuration { "osx" }
trunk/3rdparty/bgfx/scripts/makedisttex.lua
r244651r244652
88   kind "ConsoleApp"
99
1010   includedirs {
11      path.join(BX_DIR, "include"),
12      path.join(BGFX_DIR, "3rdparty"),
11      BX_DIR .. "include",
12      BGFX_DIR .. "3rdparty",
1313   }
1414
1515   files {
16      path.join(BGFX_DIR, "3rdparty/edtaa3/**.cpp"),
17      path.join(BGFX_DIR, "3rdparty/edtaa3/**.h"),
18      path.join(BGFX_DIR, "tools/makedisttex.cpp"),
16      BGFX_DIR .. "3rdparty/edtaa3/**.cpp",
17      BGFX_DIR .. "3rdparty/edtaa3/**.h",
18      BGFX_DIR .. "tools/makedisttex.cpp",
1919   }
trunk/3rdparty/bgfx/scripts/shaderc.lua
r244651r244652
77   uuid "f3cd2e90-52a4-11e1-b86c-0800200c9a66"
88   kind "ConsoleApp"
99
10   local GLSL_OPTIMIZER = path.join(BGFX_DIR, "3rdparty/glsl-optimizer")
11   local FCPP_DIR = path.join(BGFX_DIR, "3rdparty/fcpp")
10   local GLSL_OPTIMIZER = (BGFX_DIR .. "3rdparty/glsl-optimizer/")
11   local FCPP_DIR = (BGFX_DIR .. "3rdparty/fcpp/")
1212
1313   includedirs {
14      path.join(GLSL_OPTIMIZER, "src"),
14      GLSL_OPTIMIZER .. "src",
1515   }
1616
1717   configuration { "vs*" }
1818      includedirs {
19         path.join(GLSL_OPTIMIZER, "src/glsl/msvc"),
19         GLSL_OPTIMIZER .. "src/glsl/msvc",
2020      }
2121
2222      defines { -- glsl-optimizer
r244651r244652
4343
4444   configuration { "windows", "vs*" }
4545      includedirs {
46         path.join(GLSL_OPTIMIZER, "include/c99"),
46         GLSL_OPTIMIZER .. "include/c99",
4747      }
4848
4949   configuration { "windows" }
r244651r244652
6767   }
6868
6969   includedirs {
70      path.join(BX_DIR, "include"),
71      path.join(BGFX_DIR, "include"),
70      BX_DIR   .. "include",
71      BGFX_DIR .. "include",
7272
7373      FCPP_DIR,
7474
75      path.join(GLSL_OPTIMIZER, "include"),
76      path.join(GLSL_OPTIMIZER, "src/mesa"),
77      path.join(GLSL_OPTIMIZER, "src/mapi"),
78      path.join(GLSL_OPTIMIZER, "src/glsl"),
75      GLSL_OPTIMIZER .. "include",
76      GLSL_OPTIMIZER .. "src/mesa",
77      GLSL_OPTIMIZER .. "src/mapi",
78      GLSL_OPTIMIZER .. "src/glsl",
7979   }
8080
8181   files {
82      path.join(BGFX_DIR, "tools/shaderc/**.cpp"),
83      path.join(BGFX_DIR, "tools/shaderc/**.h"),
84      path.join(BGFX_DIR, "src/vertexdecl.**"),
82      BGFX_DIR .. "tools/shaderc/**.cpp",
83      BGFX_DIR .. "tools/shaderc/**.h",
84      BGFX_DIR .. "src/vertexdecl.**",
8585
86      path.join(FCPP_DIR, "**.h"),
87      path.join(FCPP_DIR, "cpp1.c"),
88      path.join(FCPP_DIR, "cpp2.c"),
89      path.join(FCPP_DIR, "cpp3.c"),
90      path.join(FCPP_DIR, "cpp4.c"),
91      path.join(FCPP_DIR, "cpp5.c"),
92      path.join(FCPP_DIR, "cpp6.c"),
93      path.join(FCPP_DIR, "cpp6.c"),
86      FCPP_DIR .. "**.h",
87      FCPP_DIR .. "cpp1.c",
88      FCPP_DIR .. "cpp2.c",
89      FCPP_DIR .. "cpp3.c",
90      FCPP_DIR .. "cpp4.c",
91      FCPP_DIR .. "cpp5.c",
92      FCPP_DIR .. "cpp6.c",
93      FCPP_DIR .. "cpp6.c",
9494
95      path.join(GLSL_OPTIMIZER, "src/mesa/**.c"),
96      path.join(GLSL_OPTIMIZER, "src/glsl/**.cpp"),
97      path.join(GLSL_OPTIMIZER, "src/mesa/**.h"),
98      path.join(GLSL_OPTIMIZER, "src/glsl/**.c"),
99      path.join(GLSL_OPTIMIZER, "src/glsl/**.cpp"),
100      path.join(GLSL_OPTIMIZER, "src/glsl/**.h"),
101      path.join(GLSL_OPTIMIZER, "src/util/**.c"),
102      path.join(GLSL_OPTIMIZER, "src/util/**.h"),
95      GLSL_OPTIMIZER .. "src/mesa/**.c",
96      GLSL_OPTIMIZER .. "src/glsl/**.cpp",
97      GLSL_OPTIMIZER .. "src/mesa/**.h",
98      GLSL_OPTIMIZER .. "src/glsl/**.c",
99      GLSL_OPTIMIZER .. "src/glsl/**.cpp",
100      GLSL_OPTIMIZER .. "src/glsl/**.h",
101      GLSL_OPTIMIZER .. "src/util/**.c",
102      GLSL_OPTIMIZER .. "src/util/**.h",
103103   }
104104
105105   excludes {
106      path.join(GLSL_OPTIMIZER, "src/glsl/glcpp/glcpp.c"),
107      path.join(GLSL_OPTIMIZER, "src/glsl/glcpp/tests/**"),
108      path.join(GLSL_OPTIMIZER, "src/glsl/glcpp/**.l"),
109      path.join(GLSL_OPTIMIZER, "src/glsl/glcpp/**.y"),
110      path.join(GLSL_OPTIMIZER, "src/glsl/ir_set_program_inouts.cpp"),
111      path.join(GLSL_OPTIMIZER, "src/glsl/main.cpp"),
112      path.join(GLSL_OPTIMIZER, "src/glsl/builtin_stubs.cpp"),
106      GLSL_OPTIMIZER .. "src/glsl/glcpp/glcpp.c",
107      GLSL_OPTIMIZER .. "src/glsl/glcpp/tests/**",
108      GLSL_OPTIMIZER .. "src/glsl/glcpp/**.l",
109      GLSL_OPTIMIZER .. "src/glsl/glcpp/**.y",
110      GLSL_OPTIMIZER .. "src/glsl/ir_set_program_inouts.cpp",
111      GLSL_OPTIMIZER .. "src/glsl/main.cpp",
112      GLSL_OPTIMIZER .. "src/glsl/builtin_stubs.cpp",
113113   }
114114
115115   strip()
trunk/3rdparty/bgfx/scripts/texturec.lua
r244651r244652
88   kind "ConsoleApp"
99
1010   includedirs {
11      path.join(BX_DIR, "include"),
12      path.join(BGFX_DIR, "include"),
13      path.join(BGFX_DIR, "src"),
11      BX_DIR .. "include",
12      BGFX_DIR .. "include",
13      BGFX_DIR .. "src",
1414   }
1515
1616   files {
17      path.join(BGFX_DIR, "src/image.*"),
18      path.join(BGFX_DIR, "tools/texturec/**.cpp"),
19      path.join(BGFX_DIR, "tools/texturec/**.h"),
17      BGFX_DIR .. "src/image.*",
18      BGFX_DIR .. "tools/texturec/**.cpp",
19      BGFX_DIR .. "tools/texturec/**.h",
2020   }
2121
2222   links {
trunk/3rdparty/bgfx/src/bgfx.cpp
r244651r244652
1919#   define BGFX_CHECK_RENDER_THREAD()
2020#endif // BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS
2121
22#define BGFX_CHECK_HANDLE(_handle, _max) \
23         BX_CHECK(isValid(_handle) \
24            && _handle.idx < _max \
25            , "Invalid handle. %d (< %d " #_max ")" \
26            , _handle.idx \
27            , _max \
28            );
29
3022#if BX_PLATFORM_ANDROID
3123   ::ANativeWindow* g_bgfxAndroidWindow = NULL;
3224
r244651r244652
805797
806798   void Frame::sort()
807799   {
808      for (uint32_t ii = 0, num = m_num; ii < num; ++ii)
809      {
810         m_sortKeys[ii] = SortKey::remapView(m_sortKeys[ii], m_viewRemap);
811      }
812800      bx::radixSort64(m_sortKeys, s_ctx->m_tempKeys, m_sortValues, s_ctx->m_tempValues, m_num);
813801   }
814802
r244651r244652
963951      BX_TRACE("Multithreaded renderer is disabled.");
964952#endif // BGFX_CONFIG_MULTITHREADED
965953
966      for (uint32_t ii = 0; ii < BX_COUNTOF(m_viewRemap); ++ii)
967      {
968         m_viewRemap[ii] = ii;
969      }
970
971954      memset(m_fb, 0xff, sizeof(m_fb) );
972955      memset(m_clear, 0, sizeof(m_clear) );
973956      memset(m_rect, 0, sizeof(m_rect) );
r244651r244652
11731156      freeDynamicBuffers();
11741157      m_submit->m_resolution = m_resolution;
11751158      m_submit->m_debug = m_debug;
1176
1177      memcpy(m_submit->m_viewRemap, m_viewRemap, sizeof(m_viewRemap) );
11781159      memcpy(m_submit->m_fb, m_fb, sizeof(m_fb) );
11791160      memcpy(m_submit->m_clear, m_clear, sizeof(m_clear) );
11801161      memcpy(m_submit->m_rect, m_rect, sizeof(m_rect) );
r244651r244652
19801961      g_caps.supported = 0
19811962         | (BGFX_CONFIG_MULTITHREADED ? BGFX_CAPS_RENDERER_MULTITHREADED : 0)
19821963         ;
1983      g_caps.maxViews     = BGFX_CONFIG_MAX_VIEWS;
19841964      g_caps.maxDrawCalls = BGFX_CONFIG_MAX_DRAW_CALLS;
19851965      g_caps.maxFBAttachments = 1;
19861966
r244651r244652
26372617      s_ctx->setClearColor(_index, _rgba);
26382618   }
26392619
2640   bool checkView(uint8_t _id)
2641   {
2642      // workaround GCC 4.9 type-limit check.
2643      const uint32_t id = _id;
2644      return id < BGFX_CONFIG_MAX_VIEWS;
2645   }
2646
26472620   void setViewName(uint8_t _id, const char* _name)
26482621   {
26492622      BGFX_CHECK_MAIN_THREAD();
2650      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2623      BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
26512624      s_ctx->setViewName(_id, _name);
26522625   }
26532626
26542627   void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
26552628   {
26562629      BGFX_CHECK_MAIN_THREAD();
2657      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2630      BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
26582631      s_ctx->setViewRect(_id, _x, _y, _width, _height);
26592632   }
26602633
26612634   void setViewScissor(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
26622635   {
26632636      BGFX_CHECK_MAIN_THREAD();
2664      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2637      BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
26652638      s_ctx->setViewScissor(_id, _x, _y, _width, _height);
26662639   }
26672640
26682641   void setViewClear(uint8_t _id, uint16_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
26692642   {
26702643      BGFX_CHECK_MAIN_THREAD();
2671      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2644      BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
26722645      s_ctx->setViewClear(_id, _flags, _rgba, _depth, _stencil);
26732646   }
26742647
26752648   void setViewClear(uint8_t _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7)
26762649   {
26772650      BGFX_CHECK_MAIN_THREAD();
2678      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2651      BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
26792652      s_ctx->setViewClear(_id, _flags, _depth, _stencil, _0, _1, _2, _3, _4, _5, _6, _7);
26802653   }
26812654
26822655   void setViewSeq(uint8_t _id, bool _enabled)
26832656   {
26842657      BGFX_CHECK_MAIN_THREAD();
2685      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2658      BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
26862659      s_ctx->setViewSeq(_id, _enabled);
26872660   }
26882661
26892662   void setViewFrameBuffer(uint8_t _id, FrameBufferHandle _handle)
26902663   {
26912664      BGFX_CHECK_MAIN_THREAD();
2692      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2665      BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
26932666      s_ctx->setViewFrameBuffer(_id, _handle);
26942667   }
26952668
26962669   void setViewTransform(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags, const void* _projR)
26972670   {
26982671      BGFX_CHECK_MAIN_THREAD();
2699      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2672      BX_CHECK(_id < BGFX_CONFIG_MAX_VIEWS, "Invalid view id: %d", _id);
27002673      s_ctx->setViewTransform(_id, _view, _projL, _flags, _projR);
27012674   }
27022675
2703   void setViewRemap(uint8_t _id, uint8_t _num, const void* _remap)
2704   {
2705      BGFX_CHECK_MAIN_THREAD();
2706      BX_CHECK(checkView(_id), "Invalid view id: %d", _id);
2707      s_ctx->setViewRemap(_id, _num, _remap);
2708   }
2709
27102676   void setMarker(const char* _marker)
27112677   {
27122678      BGFX_CHECK_MAIN_THREAD();
r244651r244652
27582724   void setUniform(UniformHandle _handle, const void* _value, uint16_t _num)
27592725   {
27602726      BGFX_CHECK_MAIN_THREAD();
2761      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_UNIFORMS);
27622727      s_ctx->setUniform(_handle, _value, _num);
27632728   }
27642729
27652730   void setIndexBuffer(IndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
27662731   {
27672732      BGFX_CHECK_MAIN_THREAD();
2768      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_INDEX_BUFFERS);
27692733      s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices);
27702734   }
27712735
27722736   void setIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _firstIndex, uint32_t _numIndices)
27732737   {
27742738      BGFX_CHECK_MAIN_THREAD();
2775      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS);
27762739      s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices);
27772740   }
27782741
r244651r244652
27972760   void setVertexBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices)
27982761   {
27992762      BGFX_CHECK_MAIN_THREAD();
2800      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_VERTEX_BUFFERS);
28012763      s_ctx->setVertexBuffer(_handle, _startVertex, _numVertices);
28022764   }
28032765
28042766   void setVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _numVertices)
28052767   {
28062768      BGFX_CHECK_MAIN_THREAD();
2807      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS);
28082769      s_ctx->setVertexBuffer(_handle, _numVertices);
28092770   }
28102771
r244651r244652
28232784   void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint32_t _num)
28242785   {
28252786      BGFX_CHECK_MAIN_THREAD();
2826      BX_CHECK(NULL != _idb, "_idb can't be NULL");
28272787      s_ctx->setInstanceDataBuffer(_idb, _num);
28282788   }
28292789
28302790   void setInstanceDataBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _num)
28312791   {
28322792      BGFX_CHECK_MAIN_THREAD();
2833      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_VERTEX_BUFFERS);
28342793      s_ctx->setInstanceDataBuffer(_handle, _startVertex, _num);
28352794   }
28362795
28372796   void setInstanceDataBuffer(DynamicVertexBufferHandle _handle, uint32_t _startVertex, uint32_t _num)
28382797   {
28392798      BGFX_CHECK_MAIN_THREAD();
2840      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS);
28412799      s_ctx->setInstanceDataBuffer(_handle, _startVertex, _num);
28422800   }
28432801
28442802   void setProgram(ProgramHandle _handle)
28452803   {
28462804      BGFX_CHECK_MAIN_THREAD();
2847      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_PROGRAMS);
28482805      s_ctx->setProgram(_handle);
28492806   }
28502807
r244651r244652
28692826   void setBuffer(uint8_t _stage, IndexBufferHandle _handle, Access::Enum _access)
28702827   {
28712828      BGFX_CHECK_MAIN_THREAD();
2872      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_INDEX_BUFFERS);
28732829      s_ctx->setBuffer(_stage, _handle, _access);
28742830   }
28752831
28762832   void setBuffer(uint8_t _stage, VertexBufferHandle _handle, Access::Enum _access)
28772833   {
28782834      BGFX_CHECK_MAIN_THREAD();
2879      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_VERTEX_BUFFERS);
28802835      s_ctx->setBuffer(_stage, _handle, _access);
28812836   }
28822837
28832838   void setBuffer(uint8_t _stage, DynamicIndexBufferHandle _handle, Access::Enum _access)
28842839   {
28852840      BGFX_CHECK_MAIN_THREAD();
2886      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_DYNAMIC_INDEX_BUFFERS);
28872841      s_ctx->setBuffer(_stage, _handle, _access);
28882842   }
28892843
28902844   void setBuffer(uint8_t _stage, DynamicVertexBufferHandle _handle, Access::Enum _access)
28912845   {
28922846      BGFX_CHECK_MAIN_THREAD();
2893      BGFX_CHECK_HANDLE(_handle, BGFX_CONFIG_MAX_DYNAMIC_VERTEX_BUFFERS);
28942847      s_ctx->setBuffer(_stage, _handle, _access);
28952848   }
28962849
2897   void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format)
2850   void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, TextureFormat::Enum _format, Access::Enum _access)
28982851   {
28992852      BGFX_CHECK_MAIN_THREAD();
2900      s_ctx->setImage(_stage, _sampler, _handle, _mip, _access, _format);
2853      s_ctx->setImage(_stage, _sampler, _handle, _mip, _format, _access);
29012854   }
29022855
2903   void setImage(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, Access::Enum _access, TextureFormat::Enum _format)
2856   void setImage(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, TextureFormat::Enum _format, Access::Enum _access)
29042857   {
29052858      BGFX_CHECK_MAIN_THREAD();
2906      s_ctx->setImage(_stage, _sampler, _handle, _attachment, _access, _format);
2859      s_ctx->setImage(_stage, _sampler, _handle, _attachment, _format, _access);
29072860   }
29082861
29092862   void dispatch(uint8_t _id, ProgramHandle _handle, uint16_t _numX, uint16_t _numY, uint16_t _numZ, uint8_t _flags)
r244651r244652
35133466   return bgfx::submit(_id, _depth);
35143467}
35153468
3516BGFX_C_API void bgfx_set_image(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_access_t _access, bgfx_texture_format_t _format)
3469BGFX_C_API void bgfx_set_image(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_texture_handle_t _handle, uint8_t _mip, bgfx_texture_format_t _format, bgfx_access_t _access)
35173470{
35183471   union { bgfx_uniform_handle_t c; bgfx::UniformHandle cpp; } sampler = { _sampler };
35193472   union { bgfx_texture_handle_t c; bgfx::TextureHandle cpp; } handle  = { _handle  };
3520   bgfx::setImage(_stage, sampler.cpp, handle.cpp, _mip, bgfx::Access::Enum(_access), bgfx::TextureFormat::Enum(_format) );
3473   bgfx::setImage(_stage, sampler.cpp, handle.cpp, _mip, bgfx::TextureFormat::Enum(_format), bgfx::Access::Enum(_access) );
35213474}
35223475
3523BGFX_C_API void bgfx_set_image_from_frame_buffer(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_frame_buffer_handle_t _handle, uint8_t _attachment, bgfx_access_t _access, bgfx_texture_format_t _format)
3476BGFX_C_API void bgfx_set_image_from_frame_buffer(uint8_t _stage, bgfx_uniform_handle_t _sampler, bgfx_frame_buffer_handle_t _handle, uint8_t _attachment, bgfx_texture_format_t _format, bgfx_access_t _access)
35243477{
35253478   union { bgfx_uniform_handle_t c;      bgfx::UniformHandle cpp;     } sampler = { _sampler };
35263479   union { bgfx_frame_buffer_handle_t c; bgfx::FrameBufferHandle cpp; } handle  = { _handle };
3527   bgfx::setImage(_stage, sampler.cpp, handle.cpp, _attachment, bgfx::Access::Enum(_access), bgfx::TextureFormat::Enum(_format) );
3480   bgfx::setImage(_stage, sampler.cpp, handle.cpp, _attachment, bgfx::TextureFormat::Enum(_format), bgfx::Access::Enum(_access) );
35283481}
35293482
35303483BGFX_C_API void bgfx_dispatch(uint8_t _id, bgfx_program_handle_t _handle, uint16_t _numX, uint16_t _numY, uint16_t _numZ, uint8_t _flags)
trunk/3rdparty/bgfx/src/bgfx_compute.sh
r244651r244652
1616vec2  uintBitsToFloat(uint2 _x) { return asfloat(_x); }
1717vec3  uintBitsToFloat(uint3 _x) { return asfloat(_x); }
1818vec4  uintBitsToFloat(uint4 _x) { return asfloat(_x); }
19uint  floatBitsToUint(float _x) { return asuint(_x);  }
20uvec2 floatBitsToUint(vec2  _x) { return asuint(_x);  }
21uvec3 floatBitsToUint(vec3  _x) { return asuint(_x);  }
22uvec4 floatBitsToUint(vec4  _x) { return asuint(_x);  }
23int   floatBitsToInt(float _x)  { return asint(_x);   }
24ivec2 floatBitsToInt(vec2  _x)  { return asint(_x);   }
25ivec3 floatBitsToInt(vec3  _x)  { return asint(_x);   }
26ivec4 floatBitsToInt(vec4  _x)  { return asint(_x);   }
1927
20uint  floatBitsToUint(float _x) { return asuint(_x); }
21uvec2 floatBitsToUint(vec2  _x) { return asuint(_x); }
22uvec3 floatBitsToUint(vec3  _x) { return asuint(_x); }
23uvec4 floatBitsToUint(vec4  _x) { return asuint(_x); }
24
25int   floatBitsToInt(float _x) { return asint(_x); }
26ivec2 floatBitsToInt(vec2  _x) { return asint(_x); }
27ivec3 floatBitsToInt(vec3  _x) { return asint(_x); }
28ivec4 floatBitsToInt(vec4  _x) { return asint(_x); }
29
30uint  bitfieldReverse(uint  _x) { return reversebits(_x); }
31uint2 bitfieldReverse(uint2 _x) { return reversebits(_x); }
32uint3 bitfieldReverse(uint3 _x) { return reversebits(_x); }
33uint4 bitfieldReverse(uint4 _x) { return reversebits(_x); }
34
35uint packHalf2x16(vec2 _x)
36{
37   return (f32tof16(_x.x)<<16) | f32tof16(_x.y);
38}
39
40vec2 unpackHalf2x16(uint _x)
41{
42   return vec2(f16tof32(_x >> 16), f16tof32(_x) );
43}
44
4528#define SHARED groupshared
4629
4730#define IMAGE2D_RO(_name, _reg) Texture2D           _name : register(t[_reg])
r244651r244652
5942   return _image.Load(uint3(_uv.xy, 0) );
6043}
6144
62uint4 imageLoad(Texture2D<uint> _image, ivec2 _uv)
45uint imageLoad(Texture2D<uint> _image, ivec2 _uv)
6346{
64   uint rr = _image.Load(uint3(_uv.xy, 0) );
65   return uint4(rr, rr, rr, rr);
47   return _image.Load(uint3(_uv.xy, 0) );
6648}
6749
68uint4 imageLoad(RWTexture2D<uint> _image, ivec2 _uv)
50uint imageLoad(RWTexture2D<uint> _image, ivec2 _uv)
6951{
70   uint rr = _image[_uv.xy];
71   return uint4(rr, rr, rr, rr);
52   return _image[_uv.xy];
7253}
7354
7455ivec2 imageSize(Texture2D _image)
trunk/3rdparty/bgfx/src/bgfx_p.h
r244651r244652
679679   };
680680
681681#define SORT_KEY_RENDER_DRAW (UINT64_C(1)<<0x2b)
682#define SORT_KEY_VIEW_SHIFT  UINT8_C(0x37)
683#define SORT_KEY_VIEW_MASK   ( (uint64_t(BGFX_CONFIG_MAX_VIEWS-1) )<<SORT_KEY_VIEW_SHIFT)
684682
685   BX_STATIC_ASSERT(BGFX_CONFIG_MAX_VIEWS <= 256);
683   BX_STATIC_ASSERT(BGFX_CONFIG_MAX_VIEWS   <= 32);
686684   BX_STATIC_ASSERT( (BGFX_CONFIG_MAX_PROGRAMS & (BGFX_CONFIG_MAX_PROGRAMS-1) ) == 0); // must be power of 2
687685
688686   struct SortKey
r244651r244652
691689      {
692690         // |               3               2               1               0|
693691         // |fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210|
694         // | vvvvvvvvsssssssssssdttpppppppppdddddddddddddddddddddddddddddddd|
692         // |    vvvvvsssssssssssdttpppppppppdddddddddddddddddddddddddddddddd|
695693         // |        ^          ^^ ^        ^                               ^|
696694         // |        |          || |        |                               ||
697695         // |   view-+      seq-+| +-trans  +-program                 depth-+|
r244651r244652
701699         const uint64_t program = uint64_t(m_program)<<0x20;
702700         const uint64_t trans   = uint64_t(m_trans  )<<0x29;
703701         const uint64_t seq     = uint64_t(m_seq    )<<0x2c;
704         const uint64_t view    = uint64_t(m_view   )<<SORT_KEY_VIEW_SHIFT;
702         const uint64_t view    = uint64_t(m_view   )<<0x37;
705703         const uint64_t key     = depth|program|trans|SORT_KEY_RENDER_DRAW|seq|view;
706704         return key;
707705      }
r244651r244652
710708      {
711709         // |               3               2               1               0|
712710         // |fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210|
713         // | vvvvvvvvsssssssssssdppppppppp                                  |
711         // |    vvvvvsssssssssssdppppppppp                                  |
714712         // |        ^          ^^        ^                                  |
715713         // |        |          ||        |                                  |
716714         // |   view-+      seq-+|        +-program                          |
r244651r244652
718716
719717         const uint64_t program = uint64_t(m_program)<<0x22;
720718         const uint64_t seq     = uint64_t(m_seq    )<<0x2c;
721         const uint64_t view    = uint64_t(m_view   )<<SORT_KEY_VIEW_SHIFT;
719         const uint64_t view    = uint64_t(m_view   )<<0x37;
722720         const uint64_t key     = program|seq|view;
723721         return key;
724722      }
r244651r244652
727725      bool decode(uint64_t _key)
728726      {
729727         m_seq     = (_key>>0x2c)& 0x7ff;
730         m_view    = uint8_t( (_key&SORT_KEY_VIEW_MASK)>>SORT_KEY_VIEW_SHIFT);
728         m_view    = (_key>>0x37)&(BGFX_CONFIG_MAX_VIEWS-1);
731729         if (_key & SORT_KEY_RENDER_DRAW)
732730         {
733731            m_depth   =  _key       & 0xffffffff;
r244651r244652
740738         return true; // compute
741739      }
742740
743      bool decode(uint64_t _key, uint8_t _viewRemap[BGFX_CONFIG_MAX_VIEWS])
744      {
745         bool compute = decode(_key);
746         m_view = _viewRemap[m_view];
747         return compute;
748      }
749
750      static uint64_t remapView(uint64_t _key, uint8_t _viewRemap[BGFX_CONFIG_MAX_VIEWS])
751      {
752         const uint8_t  oldView  = uint8_t( (_key & SORT_KEY_VIEW_MASK) >> SORT_KEY_VIEW_SHIFT);
753         const uint64_t view     = uint64_t(_viewRemap[oldView])        << SORT_KEY_VIEW_SHIFT;
754         const uint64_t key      = (_key & ~SORT_KEY_VIEW_MASK) | view;
755         return key;
756      }
757
758741      void reset()
759742      {
760743         m_depth   = 0;
r244651r244652
13701353
13711354      void setVertexBuffer(VertexBufferHandle _handle, uint32_t _startVertex, uint32_t _numVertices)
13721355      {
1356         BX_CHECK(_handle.idx < BGFX_CONFIG_MAX_VERTEX_BUFFERS, "Invalid vertex buffer handle. %d (< %d)", _handle.idx, BGFX_CONFIG_MAX_VERTEX_BUFFERS);
13731357         m_draw.m_startVertex  = _startVertex;
13741358         m_draw.m_numVertices  = _numVertices;
13751359         m_draw.m_vertexBuffer = _handle;
r244651r244652
14101394
14111395      void setProgram(ProgramHandle _handle)
14121396      {
1397         BX_CHECK(isValid(_handle), "Can't set program with invalid handle.");
14131398         m_key.m_program = _handle.idx;
14141399      }
14151400
r244651r244652
14471432         bind.m_un.m_compute.m_mip    = 0;
14481433      }
14491434
1450      void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format)
1435      void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, TextureFormat::Enum _format, Access::Enum _access)
14511436      {
14521437         Binding& bind = m_compute.m_bind[_stage];
14531438         bind.m_idx    = _handle.idx;
r244651r244652
15791564
15801565      SortKey m_key;
15811566
1582      uint8_t m_viewRemap[BGFX_CONFIG_MAX_VIEWS];
15831567      FrameBufferHandle m_fb[BGFX_CONFIG_MAX_VIEWS];
15841568      Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
15851569      float m_clearColor[BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE][4];
r244651r244652
17361720         m_free.push_back(Free(_ptr, _size) );
17371721      }
17381722
1739      uint64_t remove()
1740      {
1741         BX_CHECK(0 == m_used.size(), "");
1742
1743         if (0 < m_free.size() )
1744         {
1745            Free free = m_free.front();
1746            m_free.pop_front();
1747            return free.m_ptr;
1748         }
1749
1750         return 0;
1751      }
1752
17531723      uint64_t alloc(uint32_t _size)
17541724      {
17551725         for (FreeList::iterator it = m_free.begin(), itEnd = m_free.end(); it != itEnd; ++it)
r244651r244652
17881758         }
17891759      }
17901760
1791      bool compact()
1761      void compact()
17921762      {
17931763         m_free.sort();
17941764
r244651r244652
18051775               ++next;
18061776            }
18071777         }
1808
1809         return 0 == m_used.size();
18101778      }
18111779
18121780   private:
r244651r244652
21792147         else
21802148         {
21812149            m_dynIndexBufferAllocator.free(uint64_t(dib.m_handle.idx)<<32 | dib.m_offset);
2182            if (m_dynIndexBufferAllocator.compact() )
2183            {
2184               for (uint64_t ptr = m_dynIndexBufferAllocator.remove(); 0 != ptr; ptr = m_dynIndexBufferAllocator.remove() )
2185               {
2186                  IndexBufferHandle handle = { uint16_t(ptr>>32) };
2187                  destroyIndexBuffer(handle);
2188               }
2189            }
2150            m_dynIndexBufferAllocator.compact();
21902151         }
21912152
21922153         m_dynamicIndexBufferHandle.free(_handle.idx);
r244651r244652
23312292         else
23322293         {
23332294            m_dynVertexBufferAllocator.free(uint64_t(dvb.m_handle.idx)<<32 | dvb.m_offset);
2334            if (m_dynVertexBufferAllocator.compact() )
2335            {
2336               for (uint64_t ptr = m_dynVertexBufferAllocator.remove(); 0 != ptr; ptr = m_dynVertexBufferAllocator.remove() )
2337               {
2338                  VertexBufferHandle handle = { uint16_t(ptr>>32) };
2339                  destroyVertexBuffer(handle);
2340               }
2341            }
2295            m_dynVertexBufferAllocator.compact();
23422296         }
23432297
23442298         m_dynamicVertexBufferHandle.free(_handle.idx);
r244651r244652
27182672
27192673      BGFX_API_FUNC(TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info) )
27202674      {
2721         TextureInfo ti;
2722         if (NULL == _info)
2675         if (NULL != _info)
27232676         {
2724            _info = &ti;
2677            ImageContainer imageContainer;
2678            if (imageParse(imageContainer, _mem->data, _mem->size) )
2679            {
2680               calcTextureSize(*_info
2681                  , (uint16_t)imageContainer.m_width
2682                  , (uint16_t)imageContainer.m_height
2683                  , (uint16_t)imageContainer.m_depth
2684                  , imageContainer.m_cubeMap
2685                  , imageContainer.m_numMips
2686                  , TextureFormat::Enum(imageContainer.m_format)
2687                  );
2688            }
2689            else
2690            {
2691               _info->format = TextureFormat::Unknown;
2692               _info->storageSize = 0;
2693               _info->width   = 0;
2694               _info->height  = 0;
2695               _info->depth   = 0;
2696               _info->numMips = 0;
2697               _info->bitsPerPixel = 0;
2698               _info->cubeMap = false;
2699            }
27252700         }
27262701
2727         ImageContainer imageContainer;
2728         if (imageParse(imageContainer, _mem->data, _mem->size) )
2729         {
2730            calcTextureSize(*_info
2731               , (uint16_t)imageContainer.m_width
2732               , (uint16_t)imageContainer.m_height
2733               , (uint16_t)imageContainer.m_depth
2734               , imageContainer.m_cubeMap
2735               , imageContainer.m_numMips
2736               , TextureFormat::Enum(imageContainer.m_format)
2737               );
2738         }
2739         else
2740         {
2741            _info->format = TextureFormat::Unknown;
2742            _info->storageSize = 0;
2743            _info->width   = 0;
2744            _info->height  = 0;
2745            _info->depth   = 0;
2746            _info->numMips = 0;
2747            _info->bitsPerPixel = 0;
2748            _info->cubeMap = false;
2749         }
2750
27512702         TextureHandle handle = { m_textureHandle.alloc() };
27522703         BX_WARN(isValid(handle), "Failed to allocate texture handle.");
27532704         if (isValid(handle) )
27542705         {
27552706            TextureRef& ref = m_textureRef[handle.idx];
27562707            ref.m_refCount = 1;
2757            ref.m_format   = uint8_t(_info->format);
27582708
27592709            CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateTexture);
27602710            cmdbuf.write(handle);
r244651r244652
30883038         }
30893039      }
30903040
3091      BGFX_API_FUNC(void setViewRemap(uint8_t _id, uint8_t _num, const void* _remap) )
3092      {
3093         const uint32_t num = bx::uint32_min( (BGFX_CONFIG_MAX_VIEWS - _id) + _num, BGFX_CONFIG_MAX_VIEWS) - _id;
3094         if (NULL == _remap)
3095         {
3096            for (uint32_t ii = 0; ii < num; ++ii)
3097            {
3098               uint8_t id = uint8_t(ii+_id);
3099               m_viewRemap[id] = id;
3100            }
3101         }
3102         else
3103         {
3104            memcpy(&m_viewRemap[_id], _remap, num);
3105         }
3106      }
3107
31083041      BGFX_API_FUNC(void setMarker(const char* _marker) )
31093042      {
31103043         m_submit->setMarker(_marker);
r244651r244652
32573190         m_submit->setBuffer(_stage, dvb.m_handle, _access);
32583191      }
32593192
3260      BGFX_API_FUNC(void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, Access::Enum _access, TextureFormat::Enum _format) )
3193      BGFX_API_FUNC(void setImage(uint8_t _stage, UniformHandle _sampler, TextureHandle _handle, uint8_t _mip, TextureFormat::Enum _format, Access::Enum _access) )
32613194      {
3262         _format = TextureFormat::Count == _format ? TextureFormat::Enum(m_textureRef[_handle.idx].m_format) : _format;
3263         m_submit->setImage(_stage, _sampler, _handle, _mip, _access, _format);
3195         m_submit->setImage(_stage, _sampler, _handle, _mip, _format, _access);
32643196      }
32653197
3266      BGFX_API_FUNC(void setImage(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, Access::Enum _access, TextureFormat::Enum _format) )
3198      BGFX_API_FUNC(void setImage(uint8_t _stage, UniformHandle _sampler, FrameBufferHandle _handle, uint8_t _attachment, TextureFormat::Enum _format, Access::Enum _access) )
32673199      {
32683200         BX_CHECK(_attachment < g_caps.maxFBAttachments, "Frame buffer attachment index %d is invalid.", _attachment);
32693201         TextureHandle textureHandle = BGFX_INVALID_HANDLE;
r244651r244652
32753207            BX_CHECK(isValid(textureHandle), "Frame buffer texture %d is invalid.", _attachment);
32763208         }
32773209
3278         setImage(_stage, _sampler, textureHandle, 0, _access, _format);
3210         setImage(_stage, _sampler, textureHandle, 0, _format, _access);
32793211      }
32803212
32813213      BGFX_API_FUNC(uint32_t dispatch(uint8_t _id, ProgramHandle _handle, uint16_t _numX, uint16_t _numY, uint16_t _numZ, uint8_t _flags) )
r244651r244652
34053337      struct TextureRef
34063338      {
34073339         int16_t m_refCount;
3408         uint8_t m_format;
34093340      };
34103341
34113342      struct FrameBufferRef
r244651r244652
34273358      FrameBufferRef m_frameBufferRef[BGFX_CONFIG_MAX_FRAME_BUFFERS];
34283359      VertexDeclRef m_declRef;
34293360
3430      uint8_t m_viewRemap[BGFX_CONFIG_MAX_VIEWS];
34313361      FrameBufferHandle m_fb[BGFX_CONFIG_MAX_VIEWS];
34323362      Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
34333363
trunk/3rdparty/bgfx/src/bgfx_shader.sh
r244651r244652
189189vec3 vec3_splat(float _x) { return vec3(_x, _x, _x); }
190190vec4 vec4_splat(float _x) { return vec4(_x, _x, _x, _x); }
191191
192uvec2 uvec2_splat(uint _x) { return uvec2(_x, _x); }
193uvec3 uvec3_splat(uint _x) { return uvec3(_x, _x, _x); }
194uvec4 uvec4_splat(uint _x) { return uvec4(_x, _x, _x, _x); }
195
196192vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_mtx, _vec); }
197193vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_vec, _mtx); }
198194vec4 instMul(vec4 _vec, mat4 _mtx) { return mul(_mtx, _vec); }
r244651r244652
243239#   define vec2_splat(_x) vec2(_x)
244240#   define vec3_splat(_x) vec3(_x)
245241#   define vec4_splat(_x) vec4(_x)
246#   define uvec2_splat(_x) uvec2(_x)
247#   define uvec3_splat(_x) uvec3(_x)
248#   define uvec4_splat(_x) uvec4(_x)
249242
250243vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); }
251244vec3 instMul(mat3 _mtx, vec3 _vec) { return mul(_mtx, _vec); }
trunk/3rdparty/bgfx/src/config.h
r244651r244652
168168
169169#ifndef BGFX_CONFIG_MAX_VIEWS
170170// Do not change. Must be power of 2.
171#   define BGFX_CONFIG_MAX_VIEWS 256
171#   define BGFX_CONFIG_MAX_VIEWS 32
172172#endif // BGFX_CONFIG_MAX_VIEWS
173173
174174#define BGFX_CONFIG_MAX_VIEW_NAME_RESERVED 5
trunk/3rdparty/bgfx/src/glimports.h
r244651r244652
481481
482482GL_IMPORT      (true,  PFNGLINVALIDATEFRAMEBUFFERPROC,             glInvalidateFramebuffer, glDiscardFramebufferEXT);
483483
484#elif !BGFX_USE_GL_DYNAMIC_LIB
484#else
485485GL_IMPORT______(true,  PFNGLTEXIMAGE3DPROC,                        glTexImage3D);
486486GL_IMPORT______(true,  PFNGLTEXSUBIMAGE3DPROC,                     glTexSubImage3D);
487487GL_IMPORT______(true,  PFNGLCOMPRESSEDTEXIMAGE3DPROC,              glCompressedTexImage3D);
trunk/3rdparty/bgfx/src/renderer_d3d11.cpp
r244651r244652
665665#endif // BX_PLATFORM_WINRT
666666         BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");
667667
668         DX_CHECK(m_factory->MakeWindowAssociation(g_bgfxHwnd, 0
669            | DXGI_MWA_NO_WINDOW_CHANGES
670            | DXGI_MWA_NO_ALT_ENTER
671            ) );
672
673668         m_numWindows = 1;
674669
675670         if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
r244651r244652
731726         }
732727
733728         // Init reserved part of view name.
734         for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
729         for (uint8_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
735730         {
736731            char name[BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1];
737732            bx::snprintf(name, sizeof(name), "%3d  ", ii);
r244651r244652
30563051         int32_t numItems = _render->m_num;
30573052         for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;)
30583053         {
3059            const bool isCompute = key.decode(_render->m_sortKeys[item], _render->m_viewRemap);
3054            const bool isCompute = key.decode(_render->m_sortKeys[item]);
30603055            const bool viewChanged = 0
30613056               || key.m_view != view
30623057               || item == numItems
trunk/3rdparty/bgfx/src/renderer_d3d9.cpp
r244651r244652
570570         }
571571
572572         // Init reserved part of view name.
573         for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
573         for (uint8_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
574574         {
575575            char name[BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1];
576576            bx::snprintf(name, sizeof(name), "%3d  ", ii);
r244651r244652
28642864      {
28652865         for (uint32_t item = 0, numItems = _render->m_num; item < numItems; ++item)
28662866         {
2867            const bool isCompute = key.decode(_render->m_sortKeys[item], _render->m_viewRemap);
2867            const bool isCompute = key.decode(_render->m_sortKeys[item]);
28682868
28692869            if (isCompute)
28702870            {
trunk/3rdparty/bgfx/src/renderer_gl.cpp
r244651r244652
232232      { GL_DEPTH_COMPONENT32F,                       GL_DEPTH_COMPONENT,                          GL_FLOAT,                        false }, // D16F
233233      { GL_DEPTH_COMPONENT32F,                       GL_DEPTH_COMPONENT,                          GL_FLOAT,                        false }, // D24F
234234      { GL_DEPTH_COMPONENT32F,                       GL_DEPTH_COMPONENT,                          GL_FLOAT,                        false }, // D32F
235      { GL_STENCIL_INDEX8,                           GL_STENCIL_INDEX,                            GL_UNSIGNED_BYTE,                false }, // D0S8
235      { GL_STENCIL_INDEX8,                           GL_DEPTH_STENCIL,                            GL_UNSIGNED_BYTE,                false }, // D0S8
236236   };
237237   BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) );
238238
r244651r244652
430430         OES_texture_npot,
431431         OES_texture_half_float,
432432         OES_texture_half_float_linear,
433         OES_texture_stencil8,
434433         OES_vertex_array_object,
435434         OES_vertex_half_float,
436435         OES_vertex_type_10_10_10_2,
r244651r244652
591590      { "OES_texture_npot",                      false,                             true  },
592591      { "OES_texture_half_float",                false,                             true  },
593592      { "OES_texture_half_float_linear",         false,                             true  },
594      { "OES_texture_stencil8",                  false,                             true  },
595593      { "OES_vertex_array_object",               false,                             !BX_PLATFORM_IOS },
596594      { "OES_vertex_half_float",                 false,                             true  },
597595      { "OES_vertex_type_10_10_10_2",            false,                             true  },
r244651r244652
11671165            }
11681166         }
11691167
1170         if (BX_ENABLED(BX_PLATFORM_EMSCRIPTEN)
1171         ||  !isTextureFormatValid(TextureFormat::R8) )
1168         if (!isTextureFormatValid(TextureFormat::R8) )
11721169         {
11731170            // GL core has to use GL_R8 Issue#208, GLES2 has to use GL_LUMINANCE issue#226
11741171            s_textureFormat[TextureFormat::R8].m_internalFmt = GL_LUMINANCE;
r244651r244652
13881385         }
13891386
13901387         // Init reserved part of view name.
1391         for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
1388         for (uint8_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
13921389         {
13931390            bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d  ", ii);
13941391         }
r244651r244652
25572554         GLSL_TYPE(GL_IMAGE_2D);
25582555         GLSL_TYPE(GL_IMAGE_3D);
25592556         GLSL_TYPE(GL_IMAGE_CUBE);
2560         GLSL_TYPE(GL_UNSIGNED_INT_IMAGE_1D);
2561         GLSL_TYPE(GL_UNSIGNED_INT_IMAGE_2D);
2562         GLSL_TYPE(GL_UNSIGNED_INT_IMAGE_3D);
2563         GLSL_TYPE(GL_UNSIGNED_INT_IMAGE_CUBE);
25642557      }
25652558
25662559#undef GLSL_TYPE
r244651r244652
26432636      case GL_IMAGE_2D:
26442637      case GL_IMAGE_3D:
26452638      case GL_IMAGE_CUBE:
2646      case GL_UNSIGNED_INT_IMAGE_1D:
2647      case GL_UNSIGNED_INT_IMAGE_2D:
2648      case GL_UNSIGNED_INT_IMAGE_3D:
2649      case GL_UNSIGNED_INT_IMAGE_CUBE:
26502639         return UniformType::Uniform1iv;
26512640      };
26522641
r244651r244652
28442833         case GL_IMAGE_2D:
28452834         case GL_IMAGE_3D:
28462835         case GL_IMAGE_CUBE:
2847         case GL_UNSIGNED_INT_IMAGE_1D:
2848         case GL_UNSIGNED_INT_IMAGE_2D:
2849         case GL_UNSIGNED_INT_IMAGE_3D:
2850         case GL_UNSIGNED_INT_IMAGE_CUBE:
28512836            BX_TRACE("Sampler #%d at location %d.", m_numSamplers, loc);
28522837            m_sampler[m_numSamplers] = loc;
28532838            m_numSamplers++;
r244651r244652
42944279         int32_t numItems = _render->m_num;
42954280         for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;)
42964281         {
4297            const bool isCompute   = key.decode(_render->m_sortKeys[item], _render->m_viewRemap);
4282            const bool isCompute   = key.decode(_render->m_sortKeys[item]);
42984283            const bool viewChanged = 0
42994284               || key.m_view != view
43004285               || item == numItems
trunk/3rdparty/bgfx/src/renderer_gl.h
r244651r244652
167167#   define GL_RGBA32F 0x8814
168168#endif // GL_RGBA32F
169169
170#ifndef GL_STENCIL_INDEX
171#   define GL_STENCIL_INDEX 0x1901
172#endif // GL_STENCIL_INDEX
173
174170#ifndef GL_RED
175171#   define GL_RED 0x1903
176172#endif // GL_RED
r244651r244652
476472#   define GL_IMAGE_CUBE 0x9050
477473#endif // GL_IMAGE_CUBE
478474
479#ifndef GL_UNSIGNED_INT_IMAGE_1D
480#   define GL_UNSIGNED_INT_IMAGE_1D 0x9062
481#endif // GL_UNSIGNED_INT_IMAGE_1D
482
483#ifndef GL_UNSIGNED_INT_IMAGE_2D
484#   define GL_UNSIGNED_INT_IMAGE_2D 0x9063
485#endif // GL_UNSIGNED_INT_IMAGE_2D
486
487#ifndef GL_UNSIGNED_INT_IMAGE_3D
488#   define GL_UNSIGNED_INT_IMAGE_3D 0x9064
489#endif // GL_UNSIGNED_INT_IMAGE_3D
490
491#ifndef GL_UNSIGNED_INT_IMAGE_CUBE
492#   define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
493#endif // GL_UNSIGNED_INT_IMAGE_CUBE
494
495475#ifndef GL_PROGRAM_INPUT
496476#   define GL_PROGRAM_INPUT 0x92E3
497477#endif // GL_PROGRAM_INPUT
r244651r244652
912892      GLint m_attributes[Attrib::Count]; // sparse
913893      GLint m_instanceData[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
914894
915       GLint m_sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
895       GLint m_sampler[BGFX_CONFIG_MAX_TEXTURES];
916896       uint8_t m_numSamplers;
917897
918898      ConstantBuffer* m_constantBuffer;
trunk/3rdparty/bx/scripts/genie.lua
r244651r244652
1717
1818   language "C++"
1919
20BX_DIR = path.getabsolute("..")
21local BX_BUILD_DIR = path.join(BX_DIR, ".build")
22local BX_THIRD_PARTY_DIR = path.join(BX_DIR, "3rdparty")
20BX_DIR = (path.getabsolute("..") .. "/")
21local BX_BUILD_DIR = (BX_DIR .. ".build/")
22local BX_THIRD_PARTY_DIR = (BX_DIR .. "3rdparty/")
2323
2424defines {
2525   "BX_CONFIG_ENABLE_MSVC_LEVEL4_WARNINGS=1"
r244651r244652
3939   uuid "8a653da8-23d6-11e3-acb4-887628d43830"
4040   kind "ConsoleApp"
4141
42   debugdir (path.join(BX_DIR, "tests"))
42   debugdir (BX_DIR .. "tests")
4343
4444   removeflags {
4545      "NoExceptions",
4646   }
4747
4848   includedirs {
49      path.join(BX_DIR, "include"),
50      path.join(BX_THIRD_PARTY_DIR, "UnitTest++/src"),
49      BX_DIR .. "include",
50      BX_THIRD_PARTY_DIR .. "UnitTest++/src/",
5151   }
5252
5353   links {
r244651r244652
5555   }
5656
5757   files {
58      path.join(BX_DIR, "tests/**.cpp"),
59      path.join(BX_DIR, "tests/**.H"),
58      BX_DIR .. "tests/**.cpp",
59      BX_DIR .. "tests/**.H",
6060   }
6161
6262   configuration { "vs*" }
trunk/3rdparty/bx/scripts/toolchain.lua
r244651r244652
33-- License: https://github.com/bkaradzic/bx#license-bsd-2-clause
44--
55
6local bxDir = path.getabsolute("..")
6local bxDir = (path.getabsolute("..") .. "/")
77local naclToolchain = ""
88
99function toolchain(_buildDir, _libDir)
r244651r244652
7171   -- Avoid error when invoking genie --help.
7272   if (_ACTION == nil) then return false end
7373
74   location (path.join(_buildDir, "projects", _ACTION))
74   location (_buildDir .. "projects/" .. _ACTION)
7575
7676   if _ACTION == "clean" then
7777      os.rmdir(BUILD_DIR)
r244651r244652
107107         premake.gcc.cc  = "$(ANDROID_NDK_ARM)/bin/arm-linux-androideabi-gcc"
108108         premake.gcc.cxx = "$(ANDROID_NDK_ARM)/bin/arm-linux-androideabi-g++"
109109         premake.gcc.ar  = "$(ANDROID_NDK_ARM)/bin/arm-linux-androideabi-ar"
110         location (path.join(_buildDir, "projects", _ACTION .. "-android-arm"))
110         location (_buildDir .. "projects/" .. _ACTION .. "-android-arm")
111111      end
112112
113113      if "android-mips" == _OPTIONS["gcc"] then
r244651r244652
119119         premake.gcc.cc  = "$(ANDROID_NDK_MIPS)/bin/mipsel-linux-android-gcc"
120120         premake.gcc.cxx = "$(ANDROID_NDK_MIPS)/bin/mipsel-linux-android-g++"
121121         premake.gcc.ar  = "$(ANDROID_NDK_MIPS)/bin/mipsel-linux-android-ar"
122         location (path.join(_buildDir, "projects", _ACTION .. "-android-mips"))
122         location (_buildDir .. "projects/" .. _ACTION .. "-android-mips")
123123      end
124124
125125      if "android-x86" == _OPTIONS["gcc"] then
r244651r244652
131131         premake.gcc.cc  = "$(ANDROID_NDK_X86)/bin/i686-linux-android-gcc"
132132         premake.gcc.cxx = "$(ANDROID_NDK_X86)/bin/i686-linux-android-g++"
133133         premake.gcc.ar  = "$(ANDROID_NDK_X86)/bin/i686-linux-android-ar"
134         location (path.join(_buildDir, "projects", _ACTION .. "-android-x86"))
134         location (_buildDir .. "projects/" .. _ACTION .. "-android-x86")
135135      end
136136
137137      if "asmjs" == _OPTIONS["gcc"] then
r244651r244652
144144         premake.gcc.cxx  = "$(EMSCRIPTEN)/em++"
145145         premake.gcc.ar   = "$(EMSCRIPTEN)/emar"
146146         premake.gcc.llvm = true
147         location (path.join(_buildDir, "projects", _ACTION .. "-asmjs"))
147         location (_buildDir .. "projects/" .. _ACTION .. "-asmjs")
148148      end
149149
150150      if "freebsd" == _OPTIONS["gcc"] then
151         location (path.join(_buildDir, "projects", _ACTION .. "-freebsd"))
151         location (_buildDir .. "projects/" .. _ACTION .. "-freebsd")
152152      end
153153
154154      if "ios-arm" == _OPTIONS["gcc"] then
155155         premake.gcc.cc  = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
156156         premake.gcc.cxx = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++"
157157         premake.gcc.ar  = "ar"
158         location (path.join(_buildDir, "projects", _ACTION .. "-ios-arm"))
158         location (_buildDir .. "projects/" .. _ACTION .. "-ios-arm")
159159      end
160160
161161      if "ios-simulator" == _OPTIONS["gcc"] then
162162         premake.gcc.cc  = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
163163         premake.gcc.cxx = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++"
164164         premake.gcc.ar  = "ar"
165         location (path.join(_buildDir, "projects", _ACTION .. "-ios-simulator"))
165         location (_buildDir .. "projects/" .. _ACTION .. "-ios-simulator")
166166      end
167167
168168      if "linux-gcc" == _OPTIONS["gcc"] then
169         location (path.join(_buildDir, "projects", _ACTION .. "-linux"))
169         location (_buildDir .. "projects/" .. _ACTION .. "-linux")
170170      end
171171
172172      if "linux-clang" == _OPTIONS["gcc"] then
173173         premake.gcc.cc  = "clang"
174174         premake.gcc.cxx = "clang++"
175175         premake.gcc.ar  = "ar"
176         location (path.join(_buildDir, "projects", _ACTION .. "-linux-clang"))
176         location (_buildDir .. "projects/" .. _ACTION .. "-linux-clang")
177177      end
178178
179179      if "mingw-gcc" == _OPTIONS["gcc"] then
180180         premake.gcc.cc  = "$(MINGW)/bin/x86_64-w64-mingw32-gcc"
181181         premake.gcc.cxx = "$(MINGW)/bin/x86_64-w64-mingw32-g++"
182182         premake.gcc.ar  = "$(MINGW)/bin/ar"
183         location (path.join(_buildDir, "projects", _ACTION .. "-mingw-gcc"))
183         location (_buildDir .. "projects/" .. _ACTION .. "-mingw-gcc")
184184      end
185185
186186      if "mingw-clang" == _OPTIONS["gcc"] then
r244651r244652
189189         premake.gcc.ar   = "$(MINGW)/bin/ar"
190190--         premake.gcc.ar   = "$(CLANG)/bin/llvm-ar"
191191--         premake.gcc.llvm = true
192         location (path.join(_buildDir, "projects", _ACTION .. "-mingw-clang"))
192         location (_buildDir .. "projects/" .. _ACTION .. "-mingw-clang")
193193      end
194194
195195      if "nacl" == _OPTIONS["gcc"] then
r244651r244652
208208         premake.gcc.cc  = naclToolchain .. "gcc"
209209         premake.gcc.cxx = naclToolchain .. "g++"
210210         premake.gcc.ar  = naclToolchain .. "ar"
211         location (path.join(_buildDir, "projects", _ACTION .. "-nacl"))
211         location (_buildDir .. "projects/" .. _ACTION .. "-nacl")
212212      end
213213
214214      if "nacl-arm" == _OPTIONS["gcc"] then
r244651r244652
227227         premake.gcc.cc  = naclToolchain .. "gcc"
228228         premake.gcc.cxx = naclToolchain .. "g++"
229229         premake.gcc.ar  = naclToolchain .. "ar"
230         location (path.join(_buildDir, "projects", _ACTION .. "-nacl-arm"))
230         location (_buildDir .. "projects/" .. _ACTION .. "-nacl-arm")
231231      end
232232
233233      if "osx" == _OPTIONS["gcc"] then
r244651r244652
237237            premake.gcc.cxx = osxToolchain .. "clang++"
238238            premake.gcc.ar  = osxToolchain .. "ar"
239239         end
240         location (path.join(_buildDir, "projects", _ACTION .. "-osx"))
240         location (_buildDir .. "projects/" .. _ACTION .. "-osx")
241241      end
242242
243243      if "pnacl" == _OPTIONS["gcc"] then
r244651r244652
256256         premake.gcc.cc  = naclToolchain .. "clang"
257257         premake.gcc.cxx = naclToolchain .. "clang++"
258258         premake.gcc.ar  = naclToolchain .. "ar"
259         location (path.join(_buildDir, "projects", _ACTION .. "-pnacl"))
259         location (_buildDir .. "projects/" .. _ACTION .. "-pnacl")
260260      end
261261
262262      if "qnx-arm" == _OPTIONS["gcc"] then
r244651r244652
268268         premake.gcc.cc  = "$(QNX_HOST)/usr/bin/arm-unknown-nto-qnx8.0.0eabi-gcc"
269269         premake.gcc.cxx = "$(QNX_HOST)/usr/bin/arm-unknown-nto-qnx8.0.0eabi-g++"
270270         premake.gcc.ar  = "$(QNX_HOST)/usr/bin/arm-unknown-nto-qnx8.0.0eabi-ar"
271         location (path.join(_buildDir, "projects", _ACTION .. "-qnx-arm"))
271         location (_buildDir .. "projects/" .. _ACTION .. "-qnx-arm")
272272      end
273273
274274      if "rpi" == _OPTIONS["gcc"] then
275         location (path.join(_buildDir, "projects", _ACTION .. "-rpi"))
275         location (_buildDir .. "projects/" .. _ACTION .. "-rpi")
276276      end
277277   elseif _ACTION == "vs2012" or _ACTION == "vs2013" or _ACTION == "vs2015" then
278278
279279      if (_ACTION .. "-clang") == _OPTIONS["vs"] then
280280         premake.vstudio.toolset = ("LLVM-" .. _ACTION)
281         location (path.join(_buildDir, "projects", _ACTION .. "-clang"))
281         location (_buildDir .. "projects/" .. _ACTION .. "-clang")
282282      end
283283
284284      if "winphone8" == _OPTIONS["vs"] then
285285         premake.vstudio.toolset = "v110_wp80"
286         location (path.join(_buildDir, "projects", _ACTION .. "-winphone8"))
286         location (_buildDir .. "projects/" .. _ACTION .. "-winphone8")
287287      end
288288
289289      if "winphone81" == _OPTIONS["vs"] then
290290         premake.vstudio.toolset = "v120_wp81"
291291         platforms { "ARM" }
292         location (path.join(_buildDir, "projects", _ACTION .. "-winphone81"))
292         location (_buildDir .. "projects/" .. _ACTION .. "-winphone81")
293293      end
294294   elseif _ACTION == "xcode4" then
295295
296296      if "osx" == _OPTIONS["xcode"] then
297297         premake.xcode.toolset = "macosx"
298         location (path.join(_buildDir, "projects", _ACTION .. "-osx"))
298         location (_buildDir .. "projects/" .. _ACTION .. "-osx")
299299      end
300300      if "ios" == _OPTIONS["xcode"] then
301301         premake.xcode.toolset = "iphoneos"
302         location (path.join(_buildDir, "projects", _ACTION .. "-ios"))
302         location (_buildDir .. "projects/" .. _ACTION .. "-ios")
303303      end
304304   end
305305
r244651r244652
334334      }
335335
336336   configuration { "vs*" }
337      includedirs { path.join(bxDir, "include/compat/msvc") }
337      includedirs { bxDir .. "include/compat/msvc" }
338338      defines {
339339         "WIN32",
340340         "_WIN32",
r244651r244652
355355      }
356356
357357   configuration { "vs2008" }
358      includedirs { path.join(bxDir .. "include/compat/msvc/pre1600") }
358      includedirs { bxDir .. "include/compat/msvc/pre1600" }
359359
360360   configuration { "x32", "vs*" }
361      targetdir (path.join(_buildDir, "win32_" .. _ACTION, "bin"))
362      objdir (path.join(_buildDir, "win32_" .. _ACTION, "obj"))
361      targetdir (_buildDir .. "win32_" .. _ACTION .. "/bin")
362      objdir (_buildDir .. "win32_" .. _ACTION .. "/obj")
363363      libdirs {
364         path.join(_libDir, "lib/win32_" .. _ACTION),
364         _libDir .. "lib/win32_" .. _ACTION,
365365         "$(DXSDK_DIR)/lib/x86",
366366      }
367367
368368   configuration { "x64", "vs*" }
369369      defines { "_WIN64" }
370      targetdir (path.join(_buildDir, "win64_" .. _ACTION, "bin"))
371      objdir (path.join(_buildDir, "win64_" .. _ACTION, "obj"))
370      targetdir (_buildDir .. "win64_" .. _ACTION .. "/bin")
371      objdir (_buildDir .. "win64_" .. _ACTION .. "/obj")
372372      libdirs {
373         path.join(_libDir, "lib/win64_" .. _ACTION),
373         _libDir .. "lib/win64_" .. _ACTION,
374374         "$(DXSDK_DIR)/lib/x64",
375375      }
376376
377377   configuration { "ARM", "vs*" }
378      targetdir (path.join(_buildDir, "arm_" .. _ACTION, "bin"))
379      objdir (path.join(_buildDir, "arm_" .. _ACTION, "obj"))
378      targetdir (_buildDir .. "arm_" .. _ACTION .. "/bin")
379      objdir (_buildDir .. "arm_" .. _ACTION .. "/obj")
380380
381381   configuration { "vs*-clang" }
382382      buildoptions {
r244651r244652
384384      }
385385
386386   configuration { "x32", "vs*-clang" }
387      targetdir (path.join(_buildDir, "win32_" .. _ACTION .. "-clang/bin"))
388      objdir (path.join(_buildDir, "win32_" .. _ACTION .. "-clang/obj"))
387      targetdir (_buildDir .. "win32_" .. _ACTION .. "-clang/bin")
388      objdir (_buildDir .. "win32_" .. _ACTION .. "-clang/obj")
389389
390390   configuration { "x64", "vs*-clang" }
391      targetdir (path.join(_buildDir, "win64_" .. _ACTION .. "-clang/bin"))
392      objdir (path.join(_buildDir, "win64_" .. _ACTION .. "-clang/obj"))
391      targetdir (_buildDir .. "win64_" .. _ACTION .. "-clang/bin")
392      objdir (_buildDir .. "win64_" .. _ACTION .. "-clang/obj")
393393
394394   configuration { "winphone8*" }
395395      removeflags {
r244651r244652
399399
400400   configuration { "mingw-*" }
401401      defines { "WIN32" }
402      includedirs { path.join(bxDir, "include/compat/mingw") }
402      includedirs { bxDir .. "include/compat/mingw" }
403403      buildoptions {
404404         "-std=c++11",
405405         "-Wunused-value",
r244651r244652
416416      }
417417
418418   configuration { "x32", "mingw-gcc" }
419      targetdir (path.join(_buildDir, "win32_mingw-gcc/bin"))
420      objdir (path.join(_buildDir, "win32_mingw-gcc/obj"))
419      targetdir (_buildDir .. "win32_mingw-gcc" .. "/bin")
420      objdir (_buildDir .. "win32_mingw-gcc" .. "/obj")
421421      libdirs {
422         path.join(_libDir, "lib/win32_mingw-gcc"),
422         _libDir .. "lib/win32_mingw-gcc",
423423         "$(DXSDK_DIR)/lib/x86",
424424      }
425425      buildoptions { "-m32" }
426426
427427   configuration { "x64", "mingw-gcc" }
428      targetdir (path.join(_buildDir, "win64_mingw-gcc/bin"))
429      objdir (path.join(_buildDir, "win64_mingw-gcc/obj"))
428      targetdir (_buildDir .. "win64_mingw-gcc" .. "/bin")
429      objdir (_buildDir .. "win64_mingw-gcc" .. "/obj")
430430      libdirs {
431         path.join(_libDir, "lib/win64_mingw-gcc"),
431         _libDir .. "lib/win64_mingw-gcc",
432432         "$(DXSDK_DIR)/lib/x64",
433433         "$(GLES_X64_DIR)",
434434      }
r244651r244652
446446      }
447447
448448   configuration { "x32", "mingw-clang" }
449      targetdir (path.join(_buildDir, "win32_mingw-clang/bin"))
450      objdir (path.join(_buildDir, "win32_mingw-clang/obj"))
449      targetdir (_buildDir .. "win32_mingw-clang" .. "/bin")
450      objdir (_buildDir .. "win32_mingw-clang" .. "/obj")
451451      libdirs {
452         path.join(_libDir, "lib/win32_mingw-clang"),
452         _libDir .. "lib/win32_mingw-clang",
453453         "$(DXSDK_DIR)/lib/x86",
454454      }
455455      buildoptions { "-m32" }
456456
457457   configuration { "x64", "mingw-clang" }
458      targetdir (path.join(_buildDir, "win64_mingw-clang/bin"))
459      objdir (path.join(_buildDir, "win64_mingw-clang/obj"))
458      targetdir (_buildDir .. "win64_mingw-clang" .. "/bin")
459      objdir (_buildDir .. "win64_mingw-clang" .. "/obj")
460460      libdirs {
461         path.join(_libDir, "lib/win64_mingw-clang"),
461         _libDir .. "lib/win64_mingw-clang",
462462         "$(DXSDK_DIR)/lib/x64",
463463         "$(GLES_X64_DIR)",
464464      }
r244651r244652
487487      }
488488
489489   configuration { "linux-gcc", "x32" }
490      targetdir (path.join(_buildDir, "linux32_gcc/bin"))
491      objdir (path.join(_buildDir, "linux32_gcc/obj"))
492      libdirs { path.join(_libDir, "lib/linux32_gcc") }
490      targetdir (_buildDir .. "linux32_gcc" .. "/bin")
491      objdir (_buildDir .. "linux32_gcc" .. "/obj")
492      libdirs { _libDir .. "lib/linux32_gcc" }
493493      buildoptions {
494494         "-m32",
495495      }
496496
497497   configuration { "linux-gcc", "x64" }
498      targetdir (path.join(_buildDir, "linux64_gcc/bin"))
499      objdir (path.join(_buildDir, "linux64_gcc/obj"))
500      libdirs { path.join(_libDir, "lib/linux64_gcc") }
498      targetdir (_buildDir .. "linux64_gcc" .. "/bin")
499      objdir (_buildDir .. "linux64_gcc" .. "/obj")
500      libdirs { _libDir .. "lib/linux64_gcc" }
501501      buildoptions {
502502         "-m64",
503503      }
504504
505505   configuration { "linux-clang", "x32" }
506      targetdir (path.join(_buildDir, "linux32_clang/bin"))
507      objdir (path.join(_buildDir, "linux32_clang/obj"))
508      libdirs { path.join(_libDir, "lib/linux32_clang") }
506      targetdir (_buildDir .. "linux32_clang" .. "/bin")
507      objdir (_buildDir .. "linux32_clang" .. "/obj")
508      libdirs { _libDir .. "lib/linux32_clang" }
509509      buildoptions {
510510         "-m32",
511511      }
512512
513513   configuration { "linux-clang", "x64" }
514      targetdir (path.join(_buildDir, "linux64_clang/bin"))
515      objdir (path.join(_buildDir, "linux64_clang/obj"))
516      libdirs { path.join(_libDir, "lib/linux64_clang") }
514      targetdir (_buildDir .. "linux64_clang" .. "/bin")
515      objdir (_buildDir .. "linux64_clang" .. "/obj")
516      libdirs { _libDir .. "lib/linux64_clang" }
517517      buildoptions {
518518         "-m64",
519519      }
r244651r244652
559559      }
560560
561561   configuration { "android-arm" }
562      targetdir (path.join(_buildDir, "android-arm/bin"))
563      objdir (path.join(_buildDir, "android-arm/obj"))
562      targetdir (_buildDir .. "android-arm" .. "/bin")
563      objdir (_buildDir .. "android-arm" .. "/obj")
564564      libdirs {
565         path.join(_libDir, "lib/android-arm"),
565         _libDir .. "lib/android-arm",
566566         "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a",
567567      }
568568      includedirs {
569569         "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include",
570570      }
571571      buildoptions {
572         "--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-arm"),
572         "--sysroot=$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-arm",
573573         "-mthumb",
574574         "-march=armv7-a",
575575         "-mfloat-abi=softfp",
r244651r244652
578578         "-Wundef",
579579      }
580580      linkoptions {
581         "--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-arm"),
582         path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-arm/usr/lib/crtbegin_so.o"),
583         path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-arm/usr/lib/crtend_so.o"),
581         "--sysroot=$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-arm",
582         "$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-arm/usr/lib/crtbegin_so.o",
583         "$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-arm/usr/lib/crtend_so.o",
584584         "-march=armv7-a",
585585         "-Wl,--fix-cortex-a8",
586586      }
587587
588588   configuration { "android-mips" }
589      targetdir (path.join(_buildDir, "android-mips/bin"))
590      objdir (path.join(_buildDir, "android-mips/obj"))
589      targetdir (_buildDir .. "android-mips" .. "/bin")
590      objdir (_buildDir .. "android-mips" .. "/obj")
591591      libdirs {
592         path.join(_libDir, "lib/android-mips"),
592         _libDir .. "lib/android-mips",
593593         "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/mips",
594594      }
595595      includedirs {
596596         "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/mips/include",
597597      }
598598      buildoptions {
599         "--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-mips"),
599         "--sysroot=$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-mips",
600600         "-Wunused-value",
601601         "-Wundef",
602602      }
603603      linkoptions {
604         "--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-mips"),
605         path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-mips/usr/lib/crtbegin_so.o"),
606         path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-mips/usr/lib/crtend_so.o"),
604         "--sysroot=$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-mips",
605         "$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-mips/usr/lib/crtbegin_so.o",
606         "$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-mips/usr/lib/crtend_so.o",
607607      }
608608
609609   configuration { "android-x86" }
610      targetdir (path.join(_buildDir, "android-x86/bin"))
611      objdir (path.join(_buildDir, "android-x86/obj"))
610      targetdir (_buildDir .. "android-x86" .. "/bin")
611      objdir (_buildDir .. "android-x86" .. "/obj")
612612      libdirs {
613         path.join(_libDir, "lib/android-x86"),
613         _libDir .. "lib/android-x86",
614614         "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86",
615615      }
616616      includedirs {
617617         "$(ANDROID_NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86/include",
618618      }
619619      buildoptions {
620         "--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-x86"),
620         "--sysroot=$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-x86",
621621         "-march=i686",
622622         "-mtune=atom",
623623         "-mstackrealign",
r244651r244652
627627         "-Wundef",
628628      }
629629      linkoptions {
630         "--sysroot=" .. path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-x86"),
631         path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "arch-x86/usr/lib/crtbegin_so.o"),
632         path.join("$(ANDROID_NDK_ROOT)/platforms", androidPlatform, "/arch-x86/usr/lib/crtend_so.o"),
630         "--sysroot=$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-x86",
631         "$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-x86/usr/lib/crtbegin_so.o",
632         "$(ANDROID_NDK_ROOT)/platforms/" .. androidPlatform .. "/arch-x86/usr/lib/crtend_so.o",
633633      }
634634
635635   configuration { "asmjs" }
636      targetdir (path.join(_buildDir, "asmjs/bin"))
637      objdir (path.join(_buildDir, "asmjs/obj"))
638      libdirs { path.join(_libDir, "lib/asmjs") }
636      targetdir (_buildDir .. "asmjs" .. "/bin")
637      objdir (_buildDir .. "asmjs" .. "/obj")
638      libdirs { _libDir .. "lib/asmjs" }
639639      buildoptions {
640640         "-isystem$(EMSCRIPTEN)/system/include",
641641         "-isystem$(EMSCRIPTEN)/system/include/libc",
r244651r244652
644644      }
645645
646646   configuration { "freebsd" }
647      targetdir (path.join(_buildDir, "freebsd/bin"))
648      objdir (path.join(_buildDir, "freebsd/obj"))
649      libdirs { path.join(_libDir, "lib/freebsd") }
647      targetdir (_buildDir .. "freebsd" .. "/bin")
648      objdir (_buildDir .. "freebsd" .. "/obj")
649      libdirs { _libDir .. "lib/freebsd" }
650650      includedirs {
651         path.join(bxDir, "include/compat/freebsd"),
651         bxDir .. "include/compat/freebsd",
652652      }
653653
654654   configuration { "nacl or nacl-arm or pnacl" }
r244651r244652
664664      }
665665      includedirs {
666666         "$(NACL_SDK_ROOT)/include",
667         path.join(bxDir, "include/compat/nacl"),
667         bxDir .. "include/compat/nacl",
668668      }
669669
670670   configuration { "nacl" }
r244651r244652
678678      }
679679
680680   configuration { "x32", "nacl" }
681      targetdir (path.join(_buildDir, "nacl-x86/bin"))
682      objdir (path.join(_buildDir, "nacl-x86/obj"))
683      libdirs { path.join(_libDir, "lib/nacl-x86") }
681      targetdir (_buildDir .. "nacl-x86" .. "/bin")
682      objdir (_buildDir .. "nacl-x86" .. "/obj")
683      libdirs { _libDir .. "lib/nacl-x86" }
684684      linkoptions { "-melf32_nacl" }
685685
686686   configuration { "x32", "nacl", "Debug" }
r244651r244652
690690      libdirs { "$(NACL_SDK_ROOT)/lib/newlib_x86_32/Release" }
691691
692692   configuration { "x64", "nacl" }
693      targetdir (path.join(_buildDir, "nacl-x64/bin"))
694      objdir (path.join(_buildDir, "nacl-x64/obj"))
695      libdirs { path.join(_libDir, "lib/nacl-x64") }
693      targetdir (_buildDir .. "nacl-x64" .. "/bin")
694      objdir (_buildDir .. "nacl-x64" .. "/obj")
695      libdirs { _libDir .. "lib/nacl-x64" }
696696      linkoptions { "-melf64_nacl" }
697697
698698   configuration { "x64", "nacl", "Debug" }
r244651r244652
705705      buildoptions {
706706         "-Wno-psabi", -- note: the mangling of 'va_list' has changed in GCC 4.4.0
707707      }
708      targetdir (path.join(_buildDir, "nacl-arm/bin"))
709      objdir (path.join(_buildDir, "nacl-arm/obj"))
710      libdirs { path.join(_libDir, "lib/nacl-arm") }
708      targetdir (_buildDir .. "nacl-arm" .. "/bin")
709      objdir (_buildDir .. "nacl-arm" .. "/obj")
710      libdirs { _libDir .. "lib/nacl-arm" }
711711
712712   configuration { "nacl-arm", "Debug" }
713713      libdirs { "$(NACL_SDK_ROOT)/lib/newlib_arm/Debug" }
r244651r244652
716716      libdirs { "$(NACL_SDK_ROOT)/lib/newlib_arm/Release" }
717717
718718   configuration { "pnacl" }
719      targetdir (path.join(_buildDir, "pnacl/bin"))
720      objdir (path.join(_buildDir, "pnacl/obj"))
721      libdirs { path.join(_libDir, "lib/pnacl") }
719      targetdir (_buildDir .. "pnacl" .. "/bin")
720      objdir (_buildDir .. "pnacl" .. "/obj")
721      libdirs { _libDir .. "lib/pnacl" }
722722
723723   configuration { "pnacl", "Debug" }
724724      libdirs { "$(NACL_SDK_ROOT)/lib/pnacl/Debug" }
r244651r244652
727727      libdirs { "$(NACL_SDK_ROOT)/lib/pnacl/Release" }
728728
729729   configuration { "Xbox360" }
730      targetdir (path.join(_buildDir, "xbox360/bin"))
731      objdir (path.join(_buildDir, "xbox360/obj"))
732      includedirs { path.join(bxDir, "include/compat/msvc") }
733      libdirs { path.join(_libDir, "lib/xbox360") }
730      targetdir (_buildDir .. "xbox360" .. "/bin")
731      objdir (_buildDir .. "xbox360" .. "/obj")
732      includedirs { bxDir .. "include/compat/msvc" }
733      libdirs { _libDir .. "lib/xbox360" }
734734      defines {
735735         "NOMINMAX",
736736         "_XBOX",
737737      }
738738
739739   configuration { "osx", "x32" }
740      targetdir (path.join(_buildDir, "osx32_clang/bin"))
741      objdir (path.join(_buildDir, "osx32_clang/obj"))
742      libdirs { path.join(_libDir, "lib/osx32_clang") }
740      targetdir (_buildDir .. "osx32_clang" .. "/bin")
741      objdir (_buildDir .. "osx32_clang" .. "/obj")
742      libdirs { _libDir .. "lib/osx32_clang" }
743743      buildoptions {
744744         "-m32",
745745      }
746746
747747   configuration { "osx", "x64" }
748      targetdir (path.join(_buildDir, "osx64_clang/bin"))
749      objdir (path.join(_buildDir, "osx64_clang/obj"))
750      libdirs { path.join(_libDir, "lib/osx64_clang") }
748      targetdir (_buildDir .. "osx64_clang" .. "/bin")
749      objdir (_buildDir .. "osx64_clang" .. "/obj")
750      libdirs { _libDir .. "lib/osx64_clang" }
751751      buildoptions {
752752         "-m64",
753753      }
r244651r244652
759759         "-Wunused-value",
760760         "-Wundef",
761761      }
762      includedirs { path.join(bxDir, "include/compat/osx") }
762      includedirs { bxDir .. "include/compat/osx" }
763763
764764   configuration { "ios*" }
765765      linkoptions {
r244651r244652
770770         "-Wunused-value",
771771         "-Wundef",
772772      }
773      includedirs { path.join(bxDir, "include/compat/ios") }
773      includedirs { bxDir .. "include/compat/ios" }
774774
775775   configuration { "ios-arm" }
776      targetdir (path.join(_buildDir, "ios-arm/bin"))
777      objdir (path.join(_buildDir, "ios-arm/obj"))
778      libdirs { path.join(_libDir, "lib/ios-arm") }
776      targetdir (_buildDir .. "ios-arm" .. "/bin")
777      objdir (_buildDir .. "ios-arm" .. "/obj")
778      libdirs { _libDir .. "lib/ios-arm" }
779779      linkoptions {
780780         "-miphoneos-version-min=7.0",
781781         "-arch armv7",
r244651r244652
791791      }
792792
793793   configuration { "ios-simulator" }
794      targetdir (path.join(_buildDir, "ios-simulator/bin"))
795      objdir (path.join(_buildDir, "ios-simulator/obj"))
796      libdirs { path.join(_libDir, "lib/ios-simulator") }
794      targetdir (_buildDir .. "ios-simulator" .. "/bin")
795      objdir (_buildDir .. "ios-simulator" .. "/obj")
796      libdirs { _libDir .. "lib/ios-simulator" }
797797      linkoptions {
798798         "-mios-simulator-version-min=7.0",
799799         "-arch i386",
r244651r244652
809809      }
810810
811811   configuration { "qnx-arm" }
812      targetdir (path.join(_buildDir, "qnx-arm/bin"))
813      objdir (path.join(_buildDir, "qnx-arm/obj"))
814      libdirs { path.join(_libDir, "lib/qnx-arm") }
815--      includedirs { path.join(bxDir, "include/compat/qnx") }
812      targetdir (_buildDir .. "qnx-arm" .. "/bin")
813      objdir (_buildDir .. "qnx-arm" .. "/obj")
814      libdirs { _libDir .. "lib/qnx-arm" }
815--      includedirs { bxDir .. "include/compat/qnx" }
816816      buildoptions {
817817         "-std=c++0x",
818818         "-Wno-psabi", -- note: the mangling of 'va_list' has changed in GCC 4.4.0
r244651r244652
821821      }
822822
823823   configuration { "rpi" }
824      targetdir (path.join(_buildDir, "rpi/bin"))
825      objdir (path.join(_buildDir, "rpi/obj"))
824      targetdir (_buildDir .. "rpi" .. "/bin")
825      objdir (_buildDir .. "rpi" .. "/obj")
826826      libdirs {
827         path.join(_libDir, "lib/rpi"),
827         _libDir .. "lib/rpi",
828828         "/opt/vc/lib",
829829      }
830830      defines {
trunk/3rdparty/genie/README.md
r244651r244652
6161 - Added ability to configure Visual Studio toolset from GENie script.
6262 - Added `UnsignedChar` flag to force char to be unsigned.
6363 - Removed vs2002, vs2003, vs2005, Solaris, and Haiku support.
64 - Allow source files in the same project to have the same name. Added
65   `SingleOutputDir` flag to use single output directory (original behaviour).
64 - Allow source files in the same project to have the same name.
6665 - Added WinRT support.
6766 - Added `removeflags`, `removelinks`.
6867 - Added vs2015 support.
6968 - Added `targetsubdir`.
7069 - Added support for solution folders `group`.
71 - Added `options` section (and `ForceCpp` to enforce C++ compile even if
72   extension is for C files)
73 - Added `msgcompile`, `msgresource`, `msglinking` and `msgarchiving` as
74   overrides for make messages.
75 - Added `messageskip` list to disable some of compiler messages.
70 - Added `options` section (and `ForceCpp` to enforce C++ compile even if extension is for C files)
71 - Added `msgcompile`, `msgresource`, `msglinking` and `msgarchiving` as overrides for make messages
72 - Added `messageskip` list to disable some of compiler messages
7673
7774## Why fork?
7875
trunk/3rdparty/genie/src/actions/make/make_cpp.lua
r244651r244652
324324
325325      _p('  ALL_CPPFLAGS  += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), " "))
326326
327      _p('  ALL_CFLAGS    += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_c)))
328      _p('  ALL_CXXFLAGS  += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_cpp)))
327      _p('  ALL_CFLAGS    += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions)))
328      _p('  ALL_CXXFLAGS  += $(CXXFLAGS) $(ALL_CFLAGS)%s', make.list(table.join(cc.getcxxflags(cfg), cfg.buildoptions_cpp)))
329329
330330      _p('  ALL_RESFLAGS  += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s',
331331              make.list(table.join(cc.getdefines(cfg.resdefines),
trunk/3rdparty/genie/src/base/api.lua
r244651r244652
4242         scope = "config",
4343      },
4444
45      buildoptions_c =
46      {
47         kind  = "list",
48         scope = "config",
49      },
50     
5145      buildoptions_cpp =
5246      {
5347         kind  = "list",
r244651r244652
136130               NoNativeWChar = 1,
137131               NoPCH = 1,
138132               NoRTTI = 1,
139               SingleOutputDir = 1,
140133               Optimize = 1,
141134               OptimizeSize = 1,
142135               OptimizeSpeed = 1,
trunk/3rdparty/genie/src/base/bake.lua
r244651r244652
380380                  dir = cfg_dirs[cfg][v]
381381                  if hit_counts[dir] == 1 then break end
382382               end
383               if (cfg.flags.SingleOutputDir) then
384                  cfg.objectsdir = cfg.objdir or cfg.project.objdir or "obj"
385               else
386                  cfg.objectsdir = path.getrelative(cfg.location, dir)
387               end
383               cfg.objectsdir = path.getrelative(cfg.location, dir)
388384            end
389385         end
390386      end     
trunk/3rdparty/genie/src/host/scripts.c
r244651r244652
6969   "m)\ntbl[item] = item\nend\nend\nend\nreturn tbl\nend\nlocal function removevalues(tbl, removes)\nfor i=#tbl,1,-1 do\n            for _, pattern in ipairs(removes) do\n                if pattern == tbl[i] then\n                    table.remove(tbl, i)\n                    break\n                end\n            end\n        end\nend\nlocal function mergeobject(dest, src)\nif not src then \nreturn \nend\nfor fieldname, value in pairs(src) do\nif not nocopy[fieldname] then\nlocal field = premake.fields[fieldname]\nif field then\nif type(value) == \"table\" then\ndest[fieldname] = mergefield(field.kind, dest[fieldname], value)\nif src.removes then\nremoves = src.removes[fieldname]\nif removes then\nremovevalues(dest[fieldname], removes)\nend\nend\nelse\ndest[fieldname] = value\nend\nelse\ndest[fieldname] = value\nend\nend\nend\nend\nlocal function merge(dest, obj, basis, terms, cfgname, pltname)\nlocal key = cfgname or \"\"\npltname = pltname or \"Native\"\nif pltname ~= \"Native\" then\nkey = key .. pltname\nend"
7070   "\nterms.config = (cfgname or \"\"):lower()\nterms.platform = pltname:lower()\nlocal cfg = {}\nmergeobject(cfg, basis[key])\nadjustpaths(obj.location, cfg)\nmergeobject(cfg, obj)\nif (cfg.kind) then \nterms['kind']=cfg.kind:lower()\nend\nfor _, blk in ipairs(obj.blocks) do\nif (premake.iskeywordsmatch(blk.keywords, terms))then\nmergeobject(cfg, blk)\nif (cfg.kind and not cfg.terms.kind) then \ncfg.terms['kind'] = cfg.kind:lower()\nterms['kind'] = cfg.kind:lower()\nend\nend\nend\ncfg.name      = cfgname\ncfg.platform  = pltname\nfor k,v in pairs(terms) do\ncfg.terms[k] =v\nend\ndest[key] = cfg\nend\nlocal function collapse(obj, basis)\nlocal result = {}\nbasis = basis or {}\nlocal sln = obj.solution or obj\nlocal terms = premake.getactiveterms()\nmerge(result, obj, basis, terms)--this adjusts terms\nfor _, cfgname in ipairs(sln.configurations) do\nlocal terms_local = {}\nfor k,v in pairs(terms)do terms_local[k]=v end\nmerge(result, obj, basis, terms_local, cfgname, \"Native\")--terms cam also be adjusted here\nf"
7171   "or _, pltname in ipairs(sln.platforms or {}) do\nif pltname ~= \"Native\" then\nmerge(result, obj, basis,terms_local, cfgname, pltname)--terms also here\nend\nend\nend\nreturn result\nend\nlocal function builduniquedirs()\nlocal num_variations = 4\nlocal cfg_dirs = {}\nlocal hit_counts = {}\nfor sln in premake.solution.each() do\nfor _, prj in ipairs(sln.projects) do\nfor _, cfg in pairs(prj.__configs) do\nlocal dirs = { }\ndirs[1] = path.getabsolute(path.join(cfg.location, cfg.objdir or cfg.project.objdir or \"obj\"))\ndirs[2] = path.join(dirs[1], iif(cfg.platform == \"Native\", \"\", cfg.platform))\ndirs[3] = path.join(dirs[2], cfg.name)\ndirs[4] = path.join(dirs[3], cfg.project.name)\ncfg_dirs[cfg] = dirs\nlocal start = iif(cfg.name, 2, 1)\nfor v = start, num_variations do\nlocal d = dirs[v]\nhit_counts[d] = (hit_counts[d] or 0) + 1\nend\nend\nend\nend\nfor sln in premake.solution.each() do\nfor _, prj in ipairs(sln.projects) do\nfor _, cfg in pairs(prj.__configs) do\nlocal dir\nlocal start = iif(cfg.name, "
72   "2, 1)\nfor v = start, num_variations do\ndir = cfg_dirs[cfg][v]\nif hit_counts[dir] == 1 then break end\nend\nif (cfg.flags.SingleOutputDir) then\ncfg.objectsdir = cfg.objdir or cfg.project.objdir or \"obj\"\nelse\ncfg.objectsdir = path.getrelative(cfg.location, dir)\nend\nend\nend\nend\nend\nlocal function buildtargets()\nfor sln in premake.solution.each() do\nfor _, prj in ipairs(sln.projects) do\nfor _, cfg in pairs(prj.__configs) do\nlocal pathstyle = premake.getpathstyle(cfg)\nlocal namestyle = premake.getnamestyle(cfg)\ncfg.buildtarget = premake.gettarget(cfg, \"build\", pathstyle, namestyle, cfg.system)\ncfg.linktarget  = premake.gettarget(cfg, \"link\",  pathstyle, namestyle, cfg.system)\nif pathstyle == \"windows\" then\ncfg.objectsdir = path.translate(cfg.objectsdir, \"\\\\\")\nend\nend\nend\nend\nend\n  local function getCfgKind(cfg)\n  if(cfg.kind) then\n  return cfg.kind;\n  end\n  \n  if(cfg.project.__configs[\"\"] and cfg.project.__configs[\"\"].kind) then\n  return cfg.project.__configs[\"\"].k"
73   "ind;\n  end\n  \n  return nil\n  end\n  \n  local function getprojrec(dstArray, foundList, cfg, cfgname, searchField, bLinkage)\n  if(not cfg) then return end\n  \n  local foundUsePrjs = {};\n  for _, useName in ipairs(cfg[searchField]) do\n  local testName = useName:lower();\n  if((not foundList[testName])) then\n  local theProj = nil;\n  local theUseProj = nil;\n  for _, prj in ipairs(cfg.project.solution.projects) do\n  if (prj.name:lower() == testName) then\n  if(prj.usage) then\n  theUseProj = prj;\n  else\n  theProj = prj;\n  end\n  end\n  end\n  \n  --Must connect to a usage project.\n  if(theUseProj) then\n  foundList[testName] = true;\n  local prjEntry = {\n  name = testName,\n  proj = theProj,\n  usageProj = theUseProj,\n  bLinkageOnly = bLinkage,\n  };\n  dstArray[testName] = prjEntry;\n  table.insert(foundUsePrjs, theUseProj);\n  end\n  end\n  end\n  \n  for _, usePrj in ipairs(foundUsePrjs) do\n  --Links can only recurse through static libraries.\n  if((searchField ~= \"links\") or\n  (getCfgKind("
74   "usePrj.__configs[cfgname]) == \"StaticLib\")) then\n  getprojrec(dstArray, foundList, usePrj.__configs[cfgname],\n  cfgname, searchField, bLinkage);\n  end\n  end\n  end\n  \n  --\n  -- This function will recursively get all projects that the given configuration has in its \"uses\"\n  -- field. The return values are a list of tables. Each table in that list contains the following:\n  --name = The lowercase name of the project.\n  --proj = The project. Can be nil if it is usage-only.\n  --usageProj = The usage project. Can't be nil, as using a project that has no\n  -- usage project is not put into the list.\n  --bLinkageOnly = If this is true, then only the linkage information should be copied.\n  -- The recursion will only look at the \"uses\" field on *usage* projects.\n  -- This function will also add projects to the list that are mentioned in the \"links\"\n  -- field of usage projects. These will only copy linker information, but they will recurse.\n  -- through other \"links\" fields.\n  --\n  local func"
75   "tion getprojectsconnections(cfg, cfgname)\n  local dstArray = {};\n  local foundList = {};\n  foundList[cfg.project.name:lower()] = true;\n  \n  --First, follow the uses recursively.\n  getprojrec(dstArray, foundList, cfg, cfgname, \"uses\", false);\n  \n  --Next, go through all of the usage projects and recursively get their links.\n  --But only if they're not already there. Get the links as linkage-only.\n  local linkArray = {};\n  for prjName, prjEntry in pairs(dstArray) do\n  getprojrec(linkArray, foundList, prjEntry.usageProj.__configs[cfgname], cfgname, \n  \"links\", true);\n  end\n  \n  --Copy from linkArray into dstArray.\n  for prjName, prjEntry in pairs(linkArray) do\n  dstArray[prjName] = prjEntry;\n  end\n  \n  return dstArray;\n  end\n  \n  \n  local function isnameofproj(cfg, strName)\n  local sln = cfg.project.solution;\n  local strTest = strName:lower();\n  for prjIx, prj in ipairs(sln.projects) do\n  if (prj.name:lower() == strTest) then\n  return true;\n  end\n  end\n  \n  return false;\n  e"
76   "nd\n  --\n  -- Copies the field from dstCfg to srcCfg.\n  --\n  local function copydependentfield(srcCfg, dstCfg, strSrcField)\n  local srcField = premake.fields[strSrcField];\n  local strDstField = strSrcField;\n  \n  if type(srcCfg[strSrcField]) == \"table\" then\n  --handle paths.\n  if (srcField.kind == \"dirlist\" or srcField.kind == \"filelist\") and\n  (not keeprelative[strSrcField]) then\n  for i,p in ipairs(srcCfg[strSrcField]) do\n  table.insert(dstCfg[strDstField],\n  path.rebase(p, srcCfg.project.location, dstCfg.project.location))\n  end\n  else\n  if(strSrcField == \"links\") then\n  for i,p in ipairs(srcCfg[strSrcField]) do\n  if(not isnameofproj(dstCfg, p)) then\n  table.insert(dstCfg[strDstField], p)\n  else\n  printf(\"Failed to copy '%s' from proj '%s'.\",\n  p, srcCfg.project.name);\n  end\n  end\n  else\n  for i,p in ipairs(srcCfg[strSrcField]) do\n  table.insert(dstCfg[strDstField], p)\n  end\n  end\n  end\n  else\n  if(srcField.kind == \"path\" and (not keeprelative[strSrcField])) then\n"
77   "  dstCfg[strDstField] = path.rebase(srcCfg[strSrcField],\n  prj.location, dstCfg.project.location);\n  else\n  dstCfg[strDstField] = srcCfg[strSrcField];\n  end\n  end\n  end\n  \n  --\n  -- This function will take the list of project entries and apply their usage project data\n  -- to the given configuration. It will copy compiling information for the projects that are\n  -- not listed as linkage-only. It will copy the linking information for projects only if\n  -- the source project is not a static library. It won't copy linking information\n  -- if the project is in this solution; instead it will add that project to the configuration's\n  -- links field, expecting that Premake will handle the rest.\n  --\n  local function copyusagedata(cfg, cfgname, linkToProjs)\n  local myPrj = cfg.project;\n  local bIsStaticLib = (getCfgKind(cfg) == \"StaticLib\");\n  \n  for prjName, prjEntry in pairs(linkToProjs) do\n  local srcPrj = prjEntry.usageProj;\n  local srcCfg = srcPrj.__configs[cfgname];\n  \n  for name, field"
78   " in pairs(premake.fields) do\n  if(srcCfg[name]) then\n  if(field.usagecopy) then\n  if(not prjEntry.bLinkageOnly) then\n  copydependentfield(srcCfg, cfg, name)\n  end\n  elseif(field.linkagecopy) then\n  --Copy the linkage data if we're building a non-static thing\n  --and this is a pure usage project. If it's not pure-usage, then\n  --we will simply put the project's name in the links field later.\n  if((not bIsStaticLib) and (not prjEntry.proj)) then\n  copydependentfield(srcCfg, cfg, name)\n  end\n  end\n  end\n  end\n  \n  if((not bIsStaticLib) and prjEntry.proj) then\n  table.insert(cfg.links, prjEntry.proj.name);\n  end\n  end\n  end\nfunction premake.bake.buildconfigs()\nfor sln in premake.solution.each() do\nfor _, prj in ipairs(sln.projects) do\nprj.location = prj.location or sln.location or prj.basedir\nadjustpaths(prj.location, prj)\nfor _, blk in ipairs(prj.blocks) do\nadjustpaths(prj.location, blk)\nend\nend\nsln.location = sln.location or sln.basedir\nend\nfor sln in premake.solution.each() do\n"
79   "local basis = collapse(sln)\nfor _, prj in ipairs(sln.projects) do\nprj.__configs = collapse(prj, basis)\nfor _, cfg in pairs(prj.__configs) do\nbake.postprocess(prj, cfg)\nend\nend\nend\nfor sln in premake.solution.each() do\nfor prjIx, prj in ipairs(sln.projects) do\nif(not prj.usage) then\nfor cfgname, cfg in pairs(prj.__configs) do\nlocal usesPrjs = getprojectsconnections(cfg, cfgname);\ncopyusagedata(cfg, cfgname, usesPrjs)\nend\nend\nend\nend\nfor sln in premake.solution.each() do\nlocal removeList = {};\nfor index, prj in ipairs(sln.projects) do\nif(prj.usage) then\ntable.insert(removeList, 1, index); --Add in reverse order.\nend\nend\nfor _, index in ipairs(removeList) do\ntable.remove(sln.projects, index);\nend\nend\nbuilduniquedirs()\nbuildtargets(cfg)\nend\nfunction premake.bake.postprocess(prj, cfg)\ncfg.project   = prj\ncfg.shortname = premake.getconfigname(cfg.name, cfg.platform, true)\ncfg.longname  = premake.getconfigname(cfg.name, cfg.platform)\ncfg.location = cfg.location or cfg.basedir\nloca"
80   "l platform = premake.platforms[cfg.platform]\nif platform.iscrosscompiler then\ncfg.system = cfg.platform\nelse\ncfg.system = os.get()\nend\nif cfg.kind == \"SharedLib\" and platform.nosharedlibs then\ncfg.kind = \"StaticLib\"\nend\nlocal files = { }\nfor _, fname in ipairs(cfg.files) do\nlocal excluded = false\nfor _, exclude in ipairs(cfg.excludes) do\nexcluded = (fname == exclude)\nif (excluded) then break end\nend\nif (not excluded) then\ntable.insert(files, fname)\nend\nend\ncfg.files = files\nfor name, field in pairs(premake.fields) do\nif field.isflags then\nlocal values = cfg[name]\nfor _, flag in ipairs(values) do values[flag] = true end\nend\nend\ncfg.__fileconfigs = { }\nfor _, fname in ipairs(cfg.files) do\ncfg.terms.required = fname:lower()\nlocal fcfg = {}\nfor _, blk in ipairs(cfg.project.blocks) do\nif (premake.iskeywordsmatch(blk.keywords, cfg.terms)) then\nmergeobject(fcfg, blk)\nend\nend\nfcfg.name = fname\ncfg.__fileconfigs[fname] = fcfg\ntable.insert(cfg.__fileconfigs, fcfg)\nend\nend\n",
72   "2, 1)\nfor v = start, num_variations do\ndir = cfg_dirs[cfg][v]\nif hit_counts[dir] == 1 then break end\nend\ncfg.objectsdir = path.getrelative(cfg.location, dir)\nend\nend\nend\nend\nlocal function buildtargets()\nfor sln in premake.solution.each() do\nfor _, prj in ipairs(sln.projects) do\nfor _, cfg in pairs(prj.__configs) do\nlocal pathstyle = premake.getpathstyle(cfg)\nlocal namestyle = premake.getnamestyle(cfg)\ncfg.buildtarget = premake.gettarget(cfg, \"build\", pathstyle, namestyle, cfg.system)\ncfg.linktarget  = premake.gettarget(cfg, \"link\",  pathstyle, namestyle, cfg.system)\nif pathstyle == \"windows\" then\ncfg.objectsdir = path.translate(cfg.objectsdir, \"\\\\\")\nend\nend\nend\nend\nend\n  local function getCfgKind(cfg)\n  if(cfg.kind) then\n  return cfg.kind;\n  end\n  \n  if(cfg.project.__configs[\"\"] and cfg.project.__configs[\"\"].kind) then\n  return cfg.project.__configs[\"\"].kind;\n  end\n  \n  return nil\n  end\n  \n  local function getprojrec(dstArray, foundList, cfg, cfgname, searc"
73   "hField, bLinkage)\n  if(not cfg) then return end\n  \n  local foundUsePrjs = {};\n  for _, useName in ipairs(cfg[searchField]) do\n  local testName = useName:lower();\n  if((not foundList[testName])) then\n  local theProj = nil;\n  local theUseProj = nil;\n  for _, prj in ipairs(cfg.project.solution.projects) do\n  if (prj.name:lower() == testName) then\n  if(prj.usage) then\n  theUseProj = prj;\n  else\n  theProj = prj;\n  end\n  end\n  end\n  \n  --Must connect to a usage project.\n  if(theUseProj) then\n  foundList[testName] = true;\n  local prjEntry = {\n  name = testName,\n  proj = theProj,\n  usageProj = theUseProj,\n  bLinkageOnly = bLinkage,\n  };\n  dstArray[testName] = prjEntry;\n  table.insert(foundUsePrjs, theUseProj);\n  end\n  end\n  end\n  \n  for _, usePrj in ipairs(foundUsePrjs) do\n  --Links can only recurse through static libraries.\n  if((searchField ~= \"links\") or\n  (getCfgKind(usePrj.__configs[cfgname]) == \"StaticLib\")) then\n  getprojrec(dstArray, foundList, usePrj.__configs[cfgname"
74   "],\n  cfgname, searchField, bLinkage);\n  end\n  end\n  end\n  \n  --\n  -- This function will recursively get all projects that the given configuration has in its \"uses\"\n  -- field. The return values are a list of tables. Each table in that list contains the following:\n  --name = The lowercase name of the project.\n  --proj = The project. Can be nil if it is usage-only.\n  --usageProj = The usage project. Can't be nil, as using a project that has no\n  -- usage project is not put into the list.\n  --bLinkageOnly = If this is true, then only the linkage information should be copied.\n  -- The recursion will only look at the \"uses\" field on *usage* projects.\n  -- This function will also add projects to the list that are mentioned in the \"links\"\n  -- field of usage projects. These will only copy linker information, but they will recurse.\n  -- through other \"links\" fields.\n  --\n  local function getprojectsconnections(cfg, cfgname)\n  local dstArray = {};\n  local foundList = {};\n  foundList[cfg.pr"
75   "oject.name:lower()] = true;\n  \n  --First, follow the uses recursively.\n  getprojrec(dstArray, foundList, cfg, cfgname, \"uses\", false);\n  \n  --Next, go through all of the usage projects and recursively get their links.\n  --But only if they're not already there. Get the links as linkage-only.\n  local linkArray = {};\n  for prjName, prjEntry in pairs(dstArray) do\n  getprojrec(linkArray, foundList, prjEntry.usageProj.__configs[cfgname], cfgname, \n  \"links\", true);\n  end\n  \n  --Copy from linkArray into dstArray.\n  for prjName, prjEntry in pairs(linkArray) do\n  dstArray[prjName] = prjEntry;\n  end\n  \n  return dstArray;\n  end\n  \n  \n  local function isnameofproj(cfg, strName)\n  local sln = cfg.project.solution;\n  local strTest = strName:lower();\n  for prjIx, prj in ipairs(sln.projects) do\n  if (prj.name:lower() == strTest) then\n  return true;\n  end\n  end\n  \n  return false;\n  end\n  --\n  -- Copies the field from dstCfg to srcCfg.\n  --\n  local function copydependentfield(srcCfg, dstC"
76   "fg, strSrcField)\n  local srcField = premake.fields[strSrcField];\n  local strDstField = strSrcField;\n  \n  if type(srcCfg[strSrcField]) == \"table\" then\n  --handle paths.\n  if (srcField.kind == \"dirlist\" or srcField.kind == \"filelist\") and\n  (not keeprelative[strSrcField]) then\n  for i,p in ipairs(srcCfg[strSrcField]) do\n  table.insert(dstCfg[strDstField],\n  path.rebase(p, srcCfg.project.location, dstCfg.project.location))\n  end\n  else\n  if(strSrcField == \"links\") then\n  for i,p in ipairs(srcCfg[strSrcField]) do\n  if(not isnameofproj(dstCfg, p)) then\n  table.insert(dstCfg[strDstField], p)\n  else\n  printf(\"Failed to copy '%s' from proj '%s'.\",\n  p, srcCfg.project.name);\n  end\n  end\n  else\n  for i,p in ipairs(srcCfg[strSrcField]) do\n  table.insert(dstCfg[strDstField], p)\n  end\n  end\n  end\n  else\n  if(srcField.kind == \"path\" and (not keeprelative[strSrcField])) then\n  dstCfg[strDstField] = path.rebase(srcCfg[strSrcField],\n  prj.location, dstCfg.project.location);\n  else\n "
77   " dstCfg[strDstField] = srcCfg[strSrcField];\n  end\n  end\n  end\n  \n  --\n  -- This function will take the list of project entries and apply their usage project data\n  -- to the given configuration. It will copy compiling information for the projects that are\n  -- not listed as linkage-only. It will copy the linking information for projects only if\n  -- the source project is not a static library. It won't copy linking information\n  -- if the project is in this solution; instead it will add that project to the configuration's\n  -- links field, expecting that Premake will handle the rest.\n  --\n  local function copyusagedata(cfg, cfgname, linkToProjs)\n  local myPrj = cfg.project;\n  local bIsStaticLib = (getCfgKind(cfg) == \"StaticLib\");\n  \n  for prjName, prjEntry in pairs(linkToProjs) do\n  local srcPrj = prjEntry.usageProj;\n  local srcCfg = srcPrj.__configs[cfgname];\n  \n  for name, field in pairs(premake.fields) do\n  if(srcCfg[name]) then\n  if(field.usagecopy) then\n  if(not prjEntry.bLinkageO"
78   "nly) then\n  copydependentfield(srcCfg, cfg, name)\n  end\n  elseif(field.linkagecopy) then\n  --Copy the linkage data if we're building a non-static thing\n  --and this is a pure usage project. If it's not pure-usage, then\n  --we will simply put the project's name in the links field later.\n  if((not bIsStaticLib) and (not prjEntry.proj)) then\n  copydependentfield(srcCfg, cfg, name)\n  end\n  end\n  end\n  end\n  \n  if((not bIsStaticLib) and prjEntry.proj) then\n  table.insert(cfg.links, prjEntry.proj.name);\n  end\n  end\n  end\nfunction premake.bake.buildconfigs()\nfor sln in premake.solution.each() do\nfor _, prj in ipairs(sln.projects) do\nprj.location = prj.location or sln.location or prj.basedir\nadjustpaths(prj.location, prj)\nfor _, blk in ipairs(prj.blocks) do\nadjustpaths(prj.location, blk)\nend\nend\nsln.location = sln.location or sln.basedir\nend\nfor sln in premake.solution.each() do\nlocal basis = collapse(sln)\nfor _, prj in ipairs(sln.projects) do\nprj.__configs = collapse(prj, basis)\nfor "
79   "_, cfg in pairs(prj.__configs) do\nbake.postprocess(prj, cfg)\nend\nend\nend\nfor sln in premake.solution.each() do\nfor prjIx, prj in ipairs(sln.projects) do\nif(not prj.usage) then\nfor cfgname, cfg in pairs(prj.__configs) do\nlocal usesPrjs = getprojectsconnections(cfg, cfgname);\ncopyusagedata(cfg, cfgname, usesPrjs)\nend\nend\nend\nend\nfor sln in premake.solution.each() do\nlocal removeList = {};\nfor index, prj in ipairs(sln.projects) do\nif(prj.usage) then\ntable.insert(removeList, 1, index); --Add in reverse order.\nend\nend\nfor _, index in ipairs(removeList) do\ntable.remove(sln.projects, index);\nend\nend\nbuilduniquedirs()\nbuildtargets(cfg)\nend\nfunction premake.bake.postprocess(prj, cfg)\ncfg.project   = prj\ncfg.shortname = premake.getconfigname(cfg.name, cfg.platform, true)\ncfg.longname  = premake.getconfigname(cfg.name, cfg.platform)\ncfg.location = cfg.location or cfg.basedir\nlocal platform = premake.platforms[cfg.platform]\nif platform.iscrosscompiler then\ncfg.system = cfg.platform\nels"
80   "e\ncfg.system = os.get()\nend\nif cfg.kind == \"SharedLib\" and platform.nosharedlibs then\ncfg.kind = \"StaticLib\"\nend\nlocal files = { }\nfor _, fname in ipairs(cfg.files) do\nlocal excluded = false\nfor _, exclude in ipairs(cfg.excludes) do\nexcluded = (fname == exclude)\nif (excluded) then break end\nend\nif (not excluded) then\ntable.insert(files, fname)\nend\nend\ncfg.files = files\nfor name, field in pairs(premake.fields) do\nif field.isflags then\nlocal values = cfg[name]\nfor _, flag in ipairs(values) do values[flag] = true end\nend\nend\ncfg.__fileconfigs = { }\nfor _, fname in ipairs(cfg.files) do\ncfg.terms.required = fname:lower()\nlocal fcfg = {}\nfor _, blk in ipairs(cfg.project.blocks) do\nif (premake.iskeywordsmatch(blk.keywords, cfg.terms)) then\nmergeobject(fcfg, blk)\nend\nend\nfcfg.name = fname\ncfg.__fileconfigs[fname] = fcfg\ntable.insert(cfg.__fileconfigs, fcfg)\nend\nend\n",
8181
8282   /* base/api.lua */
83   "premake.fields =\n{\narchivesplit_size =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nbasedir =\n{\nkind  = \"path\",\nscope = \"container\",\n},\nbuildaction =\n{\nkind  = \"string\",\nscope = \"config\",\nallowed = {\n\"Compile\",\n\"Copy\",\n\"Embed\",\n\"None\"\n}\n},\nbuildoptions =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nbuildoptions_c =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nbuildoptions_cpp =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nconfigurations =\n{\nkind  = \"list\",\nscope = \"solution\",\n},\ndebugargs =\n{\nkind = \"list\",\nscope = \"config\",\n},\ndebugdir =\n{\nkind = \"path\",\nscope = \"config\",\n},\ndebugenvs  =\n{\nkind = \"list\",\nscope = \"config\",\n},\ndefines =\n{\nkind  = \"list\",\nscope = \"config\",\n},\ndeploymentoptions =\n{\nkind  = \"list\",\nscope = \"config\",\nusagecopy = true,\n},\nexcludes =\n{\nkind  = \"filelist\",\nscope = \"config\",\n},\nfiles =\n{\nkind  = \"filelist\",\nscope = \"config\",\n},\nflags =\n{\nkind  = \"list\",\nscope = "
84   "\"config\",\nisflags = true,\nusagecopy = true,\nallowed = function(value)\nlocal allowed_flags = {\nATL = 1,\nDebugEnvsDontMerge = 1,\nDebugEnvsInherit = 1,\nEnableMinimalRebuild = 1,\nEnableSSE = 1,\nEnableSSE2 = 1,\nExtraWarnings = 1,\nFatalWarnings = 1,\nFloatFast = 1,\nFloatStrict = 1,\nManaged = 1,\nMFC = 1,\nNativeWChar = 1,\nNo64BitChecks = 1,\nNoEditAndContinue = 1,\nNoExceptions = 1,\nNoFramePointer = 1,\nNoImportLib = 1,\nNoIncrementalLink = 1,\nNoManifest = 1,\nNoMultiProcessorCompilation = 1,\nNoNativeWChar = 1,\nNoPCH = 1,\nNoRTTI = 1,\nSingleOutputDir = 1,\nOptimize = 1,\nOptimizeSize = 1,\nOptimizeSpeed = 1,\nSEH = 1,\nStaticATL = 1,\nStaticRuntime = 1,\nSymbols = 1,\nUnicode = 1,\nUnsafe = 1,\nUnsignedChar = 1,\nWinMain = 1,\n}\nlocal englishToAmericanSpelling =\n{\noptimise = 'optimize',\noptimisesize = 'optimizesize',\noptimisespeed = 'optimizespeed',\n}\nlocal lowervalue = value:lower()\nlowervalue = englishToAmericanSpelling[lowervalue] or lowervalue\nfor v, _ in pairs(allowed_flags) do\ni"
85   "f v:lower() == lowervalue then\nreturn v\nend\nend\nreturn nil, \"invalid flag\"\nend,\n},\nframework =\n{\nkind = \"string\",\nscope = \"container\",\nallowed = {\n\"1.0\",\n\"1.1\",\n\"2.0\",\n\"3.0\",\n\"3.5\",\n\"4.0\",\n\"4.5\",\n}\n},\nforcedincludes = \n{\nkind  = \"absolutefilelist\",\nscope = \"config\",\n},\nimagepath =\n{\nkind = \"path\",\nscope = \"config\",\n},\nimageoptions =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nimplibdir =\n{\nkind  = \"path\",\nscope = \"config\",\n},\nimplibextension =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nimplibname =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nimplibprefix =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nimplibsuffix =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nincludedirs =\n{\nkind  = \"dirlist\",\nscope = \"config\",\nusagecopy = true,\n},\nkind =\n{\nkind  = \"string\",\nscope = \"config\",\nallowed = {\n\"ConsoleApp\",\n\"WindowedApp\",\n\"StaticLib\",\n\"SharedLib\"\n}\n},\nlanguage =\n{\nkind  = \"string\",\nsco"
86   "pe = \"container\",\nallowed = {\n\"C\",\n\"C++\",\n\"C#\"\n}\n},\nlibdirs =\n{\nkind  = \"dirlist\",\nscope = \"config\",\nlinkagecopy = true,\n},\nlinkoptions =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nlinks =\n{\nkind  = \"list\",\nscope = \"config\",\nallowed = function(value)\nif value:find('/', nil, true) then\nvalue = path.getabsolute(value)\nend\nreturn value\nend,\nlinkagecopy = true,\n},\nlocation =\n{\nkind  = \"path\",\nscope = \"container\",\n},\nmakesettings =\n{\nkind = \"list\",\nscope = \"config\",\n},\nmessageskip =\n{\nkind  = \"list\",\nscope = \"solution\",\nisflags = true,\nusagecopy = true,\nallowed = function(value)\nlocal allowed_messages = {\nSkipCreatingMessage = 1,\nSkipBuildingMessage = 1,\nSkipCleaningMessage = 1,\n}\nlocal lowervalue = value:lower()\nfor v, _ in pairs(allowed_messages) do\nif v:lower() == lowervalue then\nreturn v\nend\nend\nreturn nil, \"invalid message to skip\"\nend,\n},\nmsgarchiving =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nmsgcompile =\n{\n"
87   "kind  = \"string\",\nscope = \"config\",\n},\nmsgresource =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nmsglinking =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nobjdir =\n{\nkind  = \"path\",\nscope = \"config\",\n},\noptions =\n{\nkind  = \"list\",\nscope = \"container\",\nisflags = true,\nusagecopy = true,\nallowed = function(value)\nlocal allowed_options = {\nForceCPP = 1,\nArchiveSplit = 1\n}\nlocal lowervalue = value:lower()\nfor v, _ in pairs(allowed_options) do\nif v:lower() == lowervalue then\nreturn v\nend\nend\nreturn nil, \"invalid option\"\nend,\n},\npchheader =\n{\nkind  = \"string\",\nscope = \"config\",\n},\npchsource =\n{\nkind  = \"path\",\nscope = \"config\",\n},\nplatforms =\n{\nkind  = \"list\",\nscope = \"solution\",\nallowed = table.keys(premake.platforms),\n},\npostbuildcommands =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nprebuildcommands =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nprelinkcommands =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nresdefines =\n{\n"
88   "kind  = \"list\",\nscope = \"config\",\n},\nresincludedirs =\n{\nkind  = \"dirlist\",\nscope = \"config\",\n},\nresoptions =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nstartproject =\n{\nkind  = \"string\",\nscope = \"solution\",\n},\ntargetdir =\n{\nkind  = \"path\",\nscope = \"config\",\n},\ntargetsubdir =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntargetextension =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntargetname =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntargetprefix =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntargetsuffix =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntrimpaths =\n{\nkind = \"dirlist\",\nscope = \"config\",\n},\nuuid =\n{\nkind  = \"string\",\nscope = \"container\",\nallowed = function(value)\nlocal ok = true\nif (#value ~= 36) then ok = false end\nfor i=1,36 do\nlocal ch = value:sub(i,i)\nif (not ch:find(\"[ABCDEFabcdef0123456789-]\")) then ok = false end\nend\nif (value:sub(9,9) ~= \"-\")   then ok = false end\nif (value:sub(14,14) ~= \"-\")"
89   " then ok = false end\nif (value:sub(19,19) ~= \"-\") then ok = false end\nif (value:sub(24,24) ~= \"-\") then ok = false end\nif (not ok) then\nreturn nil, \"invalid UUID\"\nend\nreturn value:upper()\nend\n},\nuses =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nvpaths =\n{\nkind = \"keypath\",\nscope = \"container\",\n},\n}\nfunction premake.checkvalue(value, allowed)\nif (allowed) then\nif (type(allowed) == \"function\") then\nreturn allowed(value)\nelse\nfor _,v in ipairs(allowed) do\nif (value:lower() == v:lower()) then\nreturn v\nend\nend\nreturn nil, \"invalid value '\" .. value .. \"'\"\nend\nelse\nreturn value\nend\nend\nfunction premake.getobject(t)\nlocal container\nif (t == \"container\" or t == \"solution\") then\ncontainer = premake.CurrentContainer\nelse\ncontainer = premake.CurrentConfiguration\nend\nif t == \"solution\" then\nif type(container) == \"project\" then\ncontainer = container.solution\nend\nif type(container) ~= \"solution\" then\ncontainer = nil\nend\nend\nlocal msg\nif (not conta"
90   "iner) then\nif (t == \"container\") then\nmsg = \"no active solution or project\"\nelseif (t == \"solution\") then\nmsg = \"no active solution\"\nelse\nmsg = \"no active solution, project, or configuration\"\nend\nend\nreturn container, msg\nend\nfunction premake.setarray(obj, fieldname, value, allowed)\nobj[fieldname] = obj[fieldname] or {}\nlocal function add(value, depth)\nif type(value) == \"table\" then\nfor _,v in ipairs(value) do\nadd(v, depth + 1)\nend\nelse\nvalue, err = premake.checkvalue(value, allowed)\nif not value then\nerror(err, depth)\nend\ntable.insert(obj[fieldname], value)\nend\nend\nif value then\nadd(value, 5)\nend\nreturn obj[fieldname]\nend\nlocal function domatchedarray(ctype, fieldname, value, matchfunc)\nlocal result = { }\nfunction makeabsolute(value, depth)\nif (type(value) == \"table\") then\nfor _, item in ipairs(value) do\nmakeabsolute(item, depth + 1)\nend\nelseif type(value) == \"string\" then\nif value:find(\"*\") then\nmakeabsolute(matchfunc(value), depth + 1)\nelse\ntable.i"
91   "nsert(result, path.getabsolute(value))\nend\nelse\nerror(\"Invalid value in list: expected string, got \" .. type(value), depth)\nend\nend\nmakeabsolute(value, 3)\nreturn premake.setarray(ctype, fieldname, result)\nend\nfunction premake.setdirarray(ctype, fieldname, value)\nreturn domatchedarray(ctype, fieldname, value, os.matchdirs)\nend\nfunction premake.setfilearray(ctype, fieldname, value)\nreturn domatchedarray(ctype, fieldname, value, os.matchfiles)\nend\nfunction premake.setkeyvalue(ctype, fieldname, values)\nlocal container, err = premake.getobject(ctype)\nif not container then\nerror(err, 4)\nend\nif not container[fieldname] then\ncontainer[fieldname] = {}\nend\nif type(values) ~= \"table\" then\nerror(\"invalid value; table expected\", 4)\nend\nlocal field = container[fieldname]\nfor key,value in pairs(values) do\nif not field[key] then\nfield[key] = {}\nend\ntable.insertflat(field[key], value)\nend\nreturn field\nend\nfunction premake.setstring(ctype, fieldname, value, allowed)\nlocal container, err"
92   " = premake.getobject(ctype)\nif (not container) then\nerror(err, 4)\nend\nif (value) then\nvalue, err = premake.checkvalue(value, allowed)\nif (not value) then\nerror(err, 4)\nend\ncontainer[fieldname] = value\nend\nreturn container[fieldname]\nend\nfunction premake.remove(fieldname, value)\nlocal cfg = premake.CurrentConfiguration\ncfg.removes = cfg.removes or {}\ncfg.removes[fieldname] = premake.setarray(cfg.removes, fieldname, value)\nend\nlocal function accessor(name, value)\nlocal kind    = premake.fields[name].kind\nlocal scope   = premake.fields[name].scope\nlocal allowed = premake.fields[name].allowed\nif (kind == \"string\" or kind == \"path\") and value then\nif type(value) ~= \"string\" then\nerror(\"string value expected\", 3)\nend\nend\nlocal container, err = premake.getobject(scope)\nif (not container) then\nerror(err, 3)\nend\nif kind == \"string\" then\nreturn premake.setstring(scope, name, value, allowed)\nelseif kind == \"path\" then\nif value then value = path.getabsolute(value) end\nreturn "
93   "premake.setstring(scope, name, value)\nelseif kind == \"list\" then\nreturn premake.setarray(container, name, value, allowed)\nelseif kind == \"dirlist\" then\nreturn premake.setdirarray(container, name, value)\nelseif kind == \"filelist\" or kind == \"absolutefilelist\" then\nreturn premake.setfilearray(container, name, value)\nelseif kind == \"keyvalue\" or kind == \"keypath\" then\nreturn premake.setkeyvalue(scope, name, value)\nend\nend\nfor name, info in pairs(premake.fields) do\n_G[name] = function(value)\nreturn accessor(name, value)\nend\nif info.kind == \"list\" or \n   info.kind == \"dirlist\" or \n   info.kind == \"filelist\" or\n   info.kind == \"absolutefilelist\" \nthen\n_G[\"remove\"..name] = function(value)\npremake.remove(name, value)\nend\nend\nend\nfunction configuration(terms)\nif not terms then\nreturn premake.CurrentConfiguration\nend\nlocal container, err = premake.getobject(\"container\")\nif (not container) then\nerror(err, 2)\nend\nlocal cfg = { }\ncfg.terms = table.flatten({terms})\n"
94   "table.insert(container.blocks, cfg)\npremake.CurrentConfiguration = cfg\ncfg.keywords = { }\nfor _, word in ipairs(cfg.terms) do\ntable.insert(cfg.keywords, path.wildcards(word):lower())\nend\nfor name, field in pairs(premake.fields) do\nif (field.kind ~= \"string\" and field.kind ~= \"path\") then\ncfg[name] = { }\nend\nend\nreturn cfg\nend\nlocal function creategroup(name, sln, parent, inpath)\nlocal group = {}\nsetmetatable(group, {\n__type = \"group\"\n})\ntable.insert(sln.groups, group)\nsln.groups[inpath] = group\ngroup.solution = sln\ngroup.name = name\ngroup.uuid = os.uuid(group.name)\ngroup.parent = parent\nreturn group\nend\nlocal function creategroupsfrompath(inpath, sln)\nif inpath == nil then return nil end\ninpath = path.translate(inpath, \"/\")\nlocal groups = string.explode(inpath, \"/\")\nlocal curpath = \"\"\nlocal lastgroup = nil\nfor i, v in ipairs(groups) do\ncurpath = curpath .. \"/\" .. v:lower()\nlocal group = sln.groups[curpath]\nif group == nil then\ngroup = creategroup(v, sln, lastgr"
95   "oup, curpath)\nend\nlastgroup = group\nend\nreturn lastgroup\nend\nlocal function createproject(name, sln, isUsage)\nlocal prj = {}\nsetmetatable(prj, {\n__type = \"project\",\n})\ntable.insert(sln.projects, prj)\nif(isUsage) then\nif(sln.projects[name]) then\nsln.projects[name].usageProj = prj;\nelse\nsln.projects[name] = prj\nend\nelse\nif(sln.projects[name]) then\nprj.usageProj = sln.projects[name];\nend\nsln.projects[name] = prj\nend\nlocal group = creategroupsfrompath(premake.CurrentGroup, sln)\nprj.solution       = sln\nprj.name           = name\nprj.basedir        = os.getcwd()\nprj.uuid           = os.uuid(prj.name)\nprj.blocks         = { }\nprj.usage   = isUsage\nprj.group          = group\nreturn prj;\nend\nfunction usage(name)\nif (not name) then\nif(type(premake.CurrentContainer) ~= \"project\") then return nil end\nif(not premake.CurrentContainer.usage) then return nil end\nreturn premake.CurrentContainer\nend\nlocal sln\nif (type(premake.CurrentContainer) == \"project\") then\nsln = premake.Curr"
96   "entContainer.solution\nelse\nsln = premake.CurrentContainer\nend\nif (type(sln) ~= \"solution\") then\nerror(\"no active solution\", 2)\nend\n  -- if this is a new project, or the project in that slot doesn't have a usage, create it\n  if((not sln.projects[name]) or\n  ((not sln.projects[name].usage) and (not sln.projects[name].usageProj))) then\n  premake.CurrentContainer = createproject(name, sln, true)\n  else\n  premake.CurrentContainer = iff(sln.projects[name].usage,\n  sln.projects[name], sln.projects[name].usageProj)\n  end\n  -- add an empty, global configuration to the project\n  configuration { }\n  return premake.CurrentContainer\n  end\n  function project(name)\n  if (not name) then\n  --Only return non-usage projects\n  if(type(premake.CurrentContainer) ~= \"project\") then return nil end\n  if(premake.CurrentContainer.usage) then return nil end\n  return premake.CurrentContainer\nend\n  -- identify the parent solution\n  local sln\n  if (type(premake.CurrentContainer) == \"project\") then\n  sln "
97   "= premake.CurrentContainer.solution\n  else\n  sln = premake.CurrentContainer\n  end\n  if (type(sln) ~= \"solution\") then\n  error(\"no active solution\", 2)\n  end\n  -- if this is a new project, or the old project is a usage project, create it\n  if((not sln.projects[name]) or sln.projects[name].usage) then\n  premake.CurrentContainer = createproject(name, sln)\n  else\n  premake.CurrentContainer = sln.projects[name];\n  end\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction solution(name)\nif not name then\nif type(premake.CurrentContainer) == \"project\" then\nreturn premake.CurrentContainer.solution\nelse\nreturn premake.CurrentContainer\nend\nend\npremake.CurrentContainer = premake.solution.get(name)\nif (not premake.CurrentContainer) then\npremake.CurrentContainer = premake.solution.new(name)\nend\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction group(name)\nif not name then \nreturn premake.CurrentGroup\nend\npremake.CurrentGroup = name\nreturn premake.CurrentGroup\n"
98   "end\nfunction newaction(a)\npremake.action.add(a)\nend\nfunction newoption(opt)\npremake.option.add(opt)\nend\n",
83   "premake.fields =\n{\narchivesplit_size =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nbasedir =\n{\nkind  = \"path\",\nscope = \"container\",\n},\nbuildaction =\n{\nkind  = \"string\",\nscope = \"config\",\nallowed = {\n\"Compile\",\n\"Copy\",\n\"Embed\",\n\"None\"\n}\n},\nbuildoptions =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nbuildoptions_cpp =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nconfigurations =\n{\nkind  = \"list\",\nscope = \"solution\",\n},\ndebugargs =\n{\nkind = \"list\",\nscope = \"config\",\n},\ndebugdir =\n{\nkind = \"path\",\nscope = \"config\",\n},\ndebugenvs  =\n{\nkind = \"list\",\nscope = \"config\",\n},\ndefines =\n{\nkind  = \"list\",\nscope = \"config\",\n},\ndeploymentoptions =\n{\nkind  = \"list\",\nscope = \"config\",\nusagecopy = true,\n},\nexcludes =\n{\nkind  = \"filelist\",\nscope = \"config\",\n},\nfiles =\n{\nkind  = \"filelist\",\nscope = \"config\",\n},\nflags =\n{\nkind  = \"list\",\nscope = \"config\",\nisflags = true,\nusagecopy = true,\nallowed = functi"
84   "on(value)\nlocal allowed_flags = {\nATL = 1,\nDebugEnvsDontMerge = 1,\nDebugEnvsInherit = 1,\nEnableMinimalRebuild = 1,\nEnableSSE = 1,\nEnableSSE2 = 1,\nExtraWarnings = 1,\nFatalWarnings = 1,\nFloatFast = 1,\nFloatStrict = 1,\nManaged = 1,\nMFC = 1,\nNativeWChar = 1,\nNo64BitChecks = 1,\nNoEditAndContinue = 1,\nNoExceptions = 1,\nNoFramePointer = 1,\nNoImportLib = 1,\nNoIncrementalLink = 1,\nNoManifest = 1,\nNoMultiProcessorCompilation = 1,\nNoNativeWChar = 1,\nNoPCH = 1,\nNoRTTI = 1,\nOptimize = 1,\nOptimizeSize = 1,\nOptimizeSpeed = 1,\nSEH = 1,\nStaticATL = 1,\nStaticRuntime = 1,\nSymbols = 1,\nUnicode = 1,\nUnsafe = 1,\nUnsignedChar = 1,\nWinMain = 1,\n}\nlocal englishToAmericanSpelling =\n{\noptimise = 'optimize',\noptimisesize = 'optimizesize',\noptimisespeed = 'optimizespeed',\n}\nlocal lowervalue = value:lower()\nlowervalue = englishToAmericanSpelling[lowervalue] or lowervalue\nfor v, _ in pairs(allowed_flags) do\nif v:lower() == lowervalue then\nreturn v\nend\nend\nreturn nil, \"invalid flag\"\nend,"
85   "\n},\nframework =\n{\nkind = \"string\",\nscope = \"container\",\nallowed = {\n\"1.0\",\n\"1.1\",\n\"2.0\",\n\"3.0\",\n\"3.5\",\n\"4.0\",\n\"4.5\",\n}\n},\nforcedincludes = \n{\nkind  = \"absolutefilelist\",\nscope = \"config\",\n},\nimagepath =\n{\nkind = \"path\",\nscope = \"config\",\n},\nimageoptions =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nimplibdir =\n{\nkind  = \"path\",\nscope = \"config\",\n},\nimplibextension =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nimplibname =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nimplibprefix =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nimplibsuffix =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nincludedirs =\n{\nkind  = \"dirlist\",\nscope = \"config\",\nusagecopy = true,\n},\nkind =\n{\nkind  = \"string\",\nscope = \"config\",\nallowed = {\n\"ConsoleApp\",\n\"WindowedApp\",\n\"StaticLib\",\n\"SharedLib\"\n}\n},\nlanguage =\n{\nkind  = \"string\",\nscope = \"container\",\nallowed = {\n\"C\",\n\"C++\",\n\"C#\"\n}\n},\nlibdirs =\n{\nkind "
86   " = \"dirlist\",\nscope = \"config\",\nlinkagecopy = true,\n},\nlinkoptions =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nlinks =\n{\nkind  = \"list\",\nscope = \"config\",\nallowed = function(value)\nif value:find('/', nil, true) then\nvalue = path.getabsolute(value)\nend\nreturn value\nend,\nlinkagecopy = true,\n},\nlocation =\n{\nkind  = \"path\",\nscope = \"container\",\n},\nmakesettings =\n{\nkind = \"list\",\nscope = \"config\",\n},\nmessageskip =\n{\nkind  = \"list\",\nscope = \"solution\",\nisflags = true,\nusagecopy = true,\nallowed = function(value)\nlocal allowed_messages = {\nSkipCreatingMessage = 1,\nSkipBuildingMessage = 1,\nSkipCleaningMessage = 1,\n}\nlocal lowervalue = value:lower()\nfor v, _ in pairs(allowed_messages) do\nif v:lower() == lowervalue then\nreturn v\nend\nend\nreturn nil, \"invalid message to skip\"\nend,\n},\nmsgarchiving =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nmsgcompile =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nmsgresource =\n{\nkind  = \"string\",\ns"
87   "cope = \"config\",\n},\nmsglinking =\n{\nkind  = \"string\",\nscope = \"config\",\n},\nobjdir =\n{\nkind  = \"path\",\nscope = \"config\",\n},\noptions =\n{\nkind  = \"list\",\nscope = \"container\",\nisflags = true,\nusagecopy = true,\nallowed = function(value)\nlocal allowed_options = {\nForceCPP = 1,\nArchiveSplit = 1\n}\nlocal lowervalue = value:lower()\nfor v, _ in pairs(allowed_options) do\nif v:lower() == lowervalue then\nreturn v\nend\nend\nreturn nil, \"invalid option\"\nend,\n},\npchheader =\n{\nkind  = \"string\",\nscope = \"config\",\n},\npchsource =\n{\nkind  = \"path\",\nscope = \"config\",\n},\nplatforms =\n{\nkind  = \"list\",\nscope = \"solution\",\nallowed = table.keys(premake.platforms),\n},\npostbuildcommands =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nprebuildcommands =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nprelinkcommands =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nresdefines =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nresincludedirs =\n{\nkind  = \"dirlist\","
88   "\nscope = \"config\",\n},\nresoptions =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nstartproject =\n{\nkind  = \"string\",\nscope = \"solution\",\n},\ntargetdir =\n{\nkind  = \"path\",\nscope = \"config\",\n},\ntargetsubdir =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntargetextension =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntargetname =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntargetprefix =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntargetsuffix =\n{\nkind  = \"string\",\nscope = \"config\",\n},\ntrimpaths =\n{\nkind = \"dirlist\",\nscope = \"config\",\n},\nuuid =\n{\nkind  = \"string\",\nscope = \"container\",\nallowed = function(value)\nlocal ok = true\nif (#value ~= 36) then ok = false end\nfor i=1,36 do\nlocal ch = value:sub(i,i)\nif (not ch:find(\"[ABCDEFabcdef0123456789-]\")) then ok = false end\nend\nif (value:sub(9,9) ~= \"-\")   then ok = false end\nif (value:sub(14,14) ~= \"-\") then ok = false end\nif (value:sub(19,19) ~= \"-\") then ok = false end\nif (value:s"
89   "ub(24,24) ~= \"-\") then ok = false end\nif (not ok) then\nreturn nil, \"invalid UUID\"\nend\nreturn value:upper()\nend\n},\nuses =\n{\nkind  = \"list\",\nscope = \"config\",\n},\nvpaths =\n{\nkind = \"keypath\",\nscope = \"container\",\n},\n}\nfunction premake.checkvalue(value, allowed)\nif (allowed) then\nif (type(allowed) == \"function\") then\nreturn allowed(value)\nelse\nfor _,v in ipairs(allowed) do\nif (value:lower() == v:lower()) then\nreturn v\nend\nend\nreturn nil, \"invalid value '\" .. value .. \"'\"\nend\nelse\nreturn value\nend\nend\nfunction premake.getobject(t)\nlocal container\nif (t == \"container\" or t == \"solution\") then\ncontainer = premake.CurrentContainer\nelse\ncontainer = premake.CurrentConfiguration\nend\nif t == \"solution\" then\nif type(container) == \"project\" then\ncontainer = container.solution\nend\nif type(container) ~= \"solution\" then\ncontainer = nil\nend\nend\nlocal msg\nif (not container) then\nif (t == \"container\") then\nmsg = \"no active solution or project\"\nel"
90   "seif (t == \"solution\") then\nmsg = \"no active solution\"\nelse\nmsg = \"no active solution, project, or configuration\"\nend\nend\nreturn container, msg\nend\nfunction premake.setarray(obj, fieldname, value, allowed)\nobj[fieldname] = obj[fieldname] or {}\nlocal function add(value, depth)\nif type(value) == \"table\" then\nfor _,v in ipairs(value) do\nadd(v, depth + 1)\nend\nelse\nvalue, err = premake.checkvalue(value, allowed)\nif not value then\nerror(err, depth)\nend\ntable.insert(obj[fieldname], value)\nend\nend\nif value then\nadd(value, 5)\nend\nreturn obj[fieldname]\nend\nlocal function domatchedarray(ctype, fieldname, value, matchfunc)\nlocal result = { }\nfunction makeabsolute(value, depth)\nif (type(value) == \"table\") then\nfor _, item in ipairs(value) do\nmakeabsolute(item, depth + 1)\nend\nelseif type(value) == \"string\" then\nif value:find(\"*\") then\nmakeabsolute(matchfunc(value), depth + 1)\nelse\ntable.insert(result, path.getabsolute(value))\nend\nelse\nerror(\"Invalid value in list: exp"
91   "ected string, got \" .. type(value), depth)\nend\nend\nmakeabsolute(value, 3)\nreturn premake.setarray(ctype, fieldname, result)\nend\nfunction premake.setdirarray(ctype, fieldname, value)\nreturn domatchedarray(ctype, fieldname, value, os.matchdirs)\nend\nfunction premake.setfilearray(ctype, fieldname, value)\nreturn domatchedarray(ctype, fieldname, value, os.matchfiles)\nend\nfunction premake.setkeyvalue(ctype, fieldname, values)\nlocal container, err = premake.getobject(ctype)\nif not container then\nerror(err, 4)\nend\nif not container[fieldname] then\ncontainer[fieldname] = {}\nend\nif type(values) ~= \"table\" then\nerror(\"invalid value; table expected\", 4)\nend\nlocal field = container[fieldname]\nfor key,value in pairs(values) do\nif not field[key] then\nfield[key] = {}\nend\ntable.insertflat(field[key], value)\nend\nreturn field\nend\nfunction premake.setstring(ctype, fieldname, value, allowed)\nlocal container, err = premake.getobject(ctype)\nif (not container) then\nerror(err, 4)\nend\nif (value) "
92   "then\nvalue, err = premake.checkvalue(value, allowed)\nif (not value) then\nerror(err, 4)\nend\ncontainer[fieldname] = value\nend\nreturn container[fieldname]\nend\nfunction premake.remove(fieldname, value)\nlocal cfg = premake.CurrentConfiguration\ncfg.removes = cfg.removes or {}\ncfg.removes[fieldname] = premake.setarray(cfg.removes, fieldname, value)\nend\nlocal function accessor(name, value)\nlocal kind    = premake.fields[name].kind\nlocal scope   = premake.fields[name].scope\nlocal allowed = premake.fields[name].allowed\nif (kind == \"string\" or kind == \"path\") and value then\nif type(value) ~= \"string\" then\nerror(\"string value expected\", 3)\nend\nend\nlocal container, err = premake.getobject(scope)\nif (not container) then\nerror(err, 3)\nend\nif kind == \"string\" then\nreturn premake.setstring(scope, name, value, allowed)\nelseif kind == \"path\" then\nif value then value = path.getabsolute(value) end\nreturn premake.setstring(scope, name, value)\nelseif kind == \"list\" then\nreturn premake.s"
93   "etarray(container, name, value, allowed)\nelseif kind == \"dirlist\" then\nreturn premake.setdirarray(container, name, value)\nelseif kind == \"filelist\" or kind == \"absolutefilelist\" then\nreturn premake.setfilearray(container, name, value)\nelseif kind == \"keyvalue\" or kind == \"keypath\" then\nreturn premake.setkeyvalue(scope, name, value)\nend\nend\nfor name, info in pairs(premake.fields) do\n_G[name] = function(value)\nreturn accessor(name, value)\nend\nif info.kind == \"list\" or \n   info.kind == \"dirlist\" or \n   info.kind == \"filelist\" or\n   info.kind == \"absolutefilelist\" \nthen\n_G[\"remove\"..name] = function(value)\npremake.remove(name, value)\nend\nend\nend\nfunction configuration(terms)\nif not terms then\nreturn premake.CurrentConfiguration\nend\nlocal container, err = premake.getobject(\"container\")\nif (not container) then\nerror(err, 2)\nend\nlocal cfg = { }\ncfg.terms = table.flatten({terms})\ntable.insert(container.blocks, cfg)\npremake.CurrentConfiguration = cfg\ncfg.keywords"
94   " = { }\nfor _, word in ipairs(cfg.terms) do\ntable.insert(cfg.keywords, path.wildcards(word):lower())\nend\nfor name, field in pairs(premake.fields) do\nif (field.kind ~= \"string\" and field.kind ~= \"path\") then\ncfg[name] = { }\nend\nend\nreturn cfg\nend\nlocal function creategroup(name, sln, parent, inpath)\nlocal group = {}\nsetmetatable(group, {\n__type = \"group\"\n})\ntable.insert(sln.groups, group)\nsln.groups[inpath] = group\ngroup.solution = sln\ngroup.name = name\ngroup.uuid = os.uuid(group.name)\ngroup.parent = parent\nreturn group\nend\nlocal function creategroupsfrompath(inpath, sln)\nif inpath == nil then return nil end\ninpath = path.translate(inpath, \"/\")\nlocal groups = string.explode(inpath, \"/\")\nlocal curpath = \"\"\nlocal lastgroup = nil\nfor i, v in ipairs(groups) do\ncurpath = curpath .. \"/\" .. v:lower()\nlocal group = sln.groups[curpath]\nif group == nil then\ngroup = creategroup(v, sln, lastgroup, curpath)\nend\nlastgroup = group\nend\nreturn lastgroup\nend\nlocal function cre"
95   "ateproject(name, sln, isUsage)\nlocal prj = {}\nsetmetatable(prj, {\n__type = \"project\",\n})\ntable.insert(sln.projects, prj)\nif(isUsage) then\nif(sln.projects[name]) then\nsln.projects[name].usageProj = prj;\nelse\nsln.projects[name] = prj\nend\nelse\nif(sln.projects[name]) then\nprj.usageProj = sln.projects[name];\nend\nsln.projects[name] = prj\nend\nlocal group = creategroupsfrompath(premake.CurrentGroup, sln)\nprj.solution       = sln\nprj.name           = name\nprj.basedir        = os.getcwd()\nprj.uuid           = os.uuid(prj.name)\nprj.blocks         = { }\nprj.usage   = isUsage\nprj.group          = group\nreturn prj;\nend\nfunction usage(name)\nif (not name) then\nif(type(premake.CurrentContainer) ~= \"project\") then return nil end\nif(not premake.CurrentContainer.usage) then return nil end\nreturn premake.CurrentContainer\nend\nlocal sln\nif (type(premake.CurrentContainer) == \"project\") then\nsln = premake.CurrentContainer.solution\nelse\nsln = premake.CurrentContainer\nend\nif (type(sln) ~= \""
96   "solution\") then\nerror(\"no active solution\", 2)\nend\n  -- if this is a new project, or the project in that slot doesn't have a usage, create it\n  if((not sln.projects[name]) or\n  ((not sln.projects[name].usage) and (not sln.projects[name].usageProj))) then\n  premake.CurrentContainer = createproject(name, sln, true)\n  else\n  premake.CurrentContainer = iff(sln.projects[name].usage,\n  sln.projects[name], sln.projects[name].usageProj)\n  end\n  -- add an empty, global configuration to the project\n  configuration { }\n  return premake.CurrentContainer\n  end\n  function project(name)\n  if (not name) then\n  --Only return non-usage projects\n  if(type(premake.CurrentContainer) ~= \"project\") then return nil end\n  if(premake.CurrentContainer.usage) then return nil end\n  return premake.CurrentContainer\nend\n  -- identify the parent solution\n  local sln\n  if (type(premake.CurrentContainer) == \"project\") then\n  sln = premake.CurrentContainer.solution\n  else\n  sln = premake.CurrentContainer\n  end"
97   "\n  if (type(sln) ~= \"solution\") then\n  error(\"no active solution\", 2)\n  end\n  -- if this is a new project, or the old project is a usage project, create it\n  if((not sln.projects[name]) or sln.projects[name].usage) then\n  premake.CurrentContainer = createproject(name, sln)\n  else\n  premake.CurrentContainer = sln.projects[name];\n  end\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction solution(name)\nif not name then\nif type(premake.CurrentContainer) == \"project\" then\nreturn premake.CurrentContainer.solution\nelse\nreturn premake.CurrentContainer\nend\nend\npremake.CurrentContainer = premake.solution.get(name)\nif (not premake.CurrentContainer) then\npremake.CurrentContainer = premake.solution.new(name)\nend\nconfiguration { }\nreturn premake.CurrentContainer\nend\nfunction group(name)\nif not name then \nreturn premake.CurrentGroup\nend\npremake.CurrentGroup = name\nreturn premake.CurrentGroup\nend\nfunction newaction(a)\npremake.action.add(a)\nend\nfunction newoption(opt)\npre"
98   "make.option.add(opt)\nend\n",
9999
100100   /* base/cmdline.lua */
101101   "newoption \n{\ntrigger     = \"cc\",\nvalue       = \"VALUE\",\ndescription = \"Choose a C/C++ compiler set\",\nallowed = {\n{ \"gcc\", \"GNU GCC (gcc/g++)\" },\n{ \"ow\",  \"OpenWatcom\"        },\n}\n}\nnewoption\n{\ntrigger     = \"dotnet\",\nvalue       = \"VALUE\",\ndescription = \"Choose a .NET compiler set\",\nallowed = {\n{ \"msnet\",   \"Microsoft .NET (csc)\" },\n{ \"mono\",    \"Novell Mono (mcs)\"    },\n{ \"pnet\",    \"Portable.NET (cscc)\"  },\n}\n}\nnewoption\n{\ntrigger     = \"file\",\nvalue       = \"FILE\",\ndescription = \"Read FILE as a Premake script; default is 'premake4.lua'\"\n}\nnewoption\n{\ntrigger     = \"help\",\ndescription = \"Display this information\"\n}\nnewoption\n{\ntrigger     = \"os\",\nvalue       = \"VALUE\",\ndescription = \"Generate files for a different operating system\",\nallowed = {\n{ \"bsd\",      \"OpenBSD, NetBSD, or FreeBSD\" },\n{ \"linux\",    \"Linux\" },\n{ \"macosx\",   \"Apple Mac OS X\" },\n{ \"windows\",  \"Microsoft Windows\" },\n}\n}\nnewoption\n{"
r244651r244652
185185   "$(SILENT) if exist $(subst /,\\\\\\\\,$(OBJDIR)) rmdir /s /q $(subst /,\\\\\\\\,$(OBJDIR))')\n_p('endif')\n_p('')\n_p('prebuild:')\n_p('\\t$(PREBUILDCMDS)')\n_p('')\n_p('prelink:')\n_p('\\t$(PRELINKCMDS)')\n_p('')\ncpp.pchrules(prj)\ncpp.fileRules(prj)\n_p('-include $(OBJECTS:%%.o=%%.d)')\n_p('ifneq (,$(PCH))')\n_p('  -include $(OBJDIR)/$(notdir $(PCH)).d')\n_p('endif')\nend\nfunction premake.gmake_cpp_header(prj, cc, platforms)\n_p('# %s project makefile autogenerated by GENie', premake.action.current().shortname)\n_p('ifndef config')\n_p('  config=%s', _MAKE.esc(premake.getconfigname(prj.solution.configurations[1], platforms[1], true)))\n_p('endif')\n_p('')\n_p('ifndef verbose')\n_p('  SILENT = @')\n_p('endif')\n_p('')\n_p('SHELLTYPE := msdos')\n_p('ifeq (,$(ComSpec)$(COMSPEC))')\n_p('  SHELLTYPE := posix')\n_p('endif')\n_p('ifeq (/bin,$(findstring /bin,$(SHELL)))')\n_p('  SHELLTYPE := posix')\n_p('endif')\n_p('')\n_p('ifeq (posix,$(SHELLTYPE))')\n_p('  MKDIR = $(SILENT) mkdir -p \"$(1)\"')\n_p('  COPY  = $("
186186   "SILENT) cp -fR \"$(1)\" \"$(2)\"')\n_p('else')\n_p('  MKDIR = $(SILENT) mkdir \"$(subst /,\\\\\\\\,$(1))\" 2> nul || exit 0')\n_p('  COPY  = $(SILENT) copy /Y \"$(subst /,\\\\\\\\,$(1))\" \"$(subst /,\\\\\\\\,$(2))\"')\n_p('endif')\n_p('')\n_p('CC  = %s', cc.cc)\n_p('CXX = %s', cc.cxx)\n_p('AR  = %s', cc.ar)\n_p('')\n_p('ifndef RESCOMP')\n_p('  ifdef WINDRES')\n_p('    RESCOMP = $(WINDRES)')\n_p('  else')\n_p('    RESCOMP = windres')\n_p('  endif')\n_p('endif')\n_p('')\nend\nfunction premake.gmake_cpp_config(prj, cfg, cc)\n_p('ifeq ($(config),%s)', _MAKE.esc(cfg.shortname))\ncpp.platformtools(cfg, cc)\n_p('  OBJDIR     = %s', _MAKE.esc(cfg.objectsdir))\n_p('  TARGETDIR  = %s', _MAKE.esc(cfg.buildtarget.directory))\n_p('  TARGET     = $(TARGETDIR)/%s', _MAKE.esc(cfg.buildtarget.name))\n_p('  DEFINES   +=%s', make.list(cc.getdefines(cfg.defines)))\n_p('  INCLUDES  +=%s', make.list(cc.getincludedirs(cfg.includedirs)))\ncpp.pchconfig(cfg)\ncpp.flags(cfg, cc)\ncpp.linker(cfg, cc)\n_p('  OBJECTS := \\\\')\nfor _, fi"
187187   "le in ipairs(prj.files) do\nif path.iscppfile(file) then\nlocal excluded = false\nfor _, exclude in ipairs(cfg.excludes) do\nexcluded = (exclude == file)\nif (excluded) then break end\nend\nif excluded == false then\n_p('\\t$(OBJDIR)/%s.o \\\\'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n)\nend\nend\nend\n_p('')\n_p('  define PREBUILDCMDS')\nif #cfg.prebuildcommands > 0 then\n_p('\\t@echo Running pre-build commands')\n_p('\\t%s', table.implode(cfg.prebuildcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p('  endef')\n_p('  define PRELINKCMDS')\nif #cfg.prelinkcommands > 0 then\n_p('\\t@echo Running pre-link commands')\n_p('\\t%s', table.implode(cfg.prelinkcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p('  endef')\n_p('  define POSTBUILDCMDS')\nif #cfg.postbuildcommands > 0 then\n_p('\\t@echo Running post-build commands')\n_p('\\t%s', table.implode(cfg.postbuildcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p('  endef')\nmake.settings(cfg, cc)\n_p('endif')\n_p('')\nend\nfunction cpp.platformtools(cfg, cc)\nlocal platfor"
188   "m = cc.platforms[cfg.platform]\nif platform.cc then\n_p('  CC         = %s', platform.cc)\nend\nif platform.cxx then\n_p('  CXX        = %s', platform.cxx)\nend\nif platform.ar then\n_p('  AR         = %s', platform.ar)\nend\nend\nfunction cpp.flags(cfg, cc)\nif cfg.pchheader and not cfg.flags.NoPCH then\n_p('  FORCE_INCLUDE += -include $(OBJDIR)/$(notdir $(PCH))')\nend\nif #cfg.forcedincludes > 0 then\n_p('  FORCE_INCLUDE += -include %s'\n,premake.esc(table.concat(cfg.forcedincludes, \";\")))\nend\n_p('  ALL_CPPFLAGS  += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), \" \"))\n_p('  ALL_CFLAGS    += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_c)))\n_p('  ALL_CXXFLAGS  += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_cpp)))\n_p('  ALL_RESFLAGS  += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s',\n        make.list(table.join(cc.getdefines(cfg.resd"
189   "efines),\n                                cc.getincludedirs(cfg.resincludedirs), cfg.resoptions)))\nend\nfunction cpp.linker(cfg, cc)\n_p('  ALL_LDFLAGS   += $(LDFLAGS)%s', make.list(table.join(cc.getlibdirflags(cfg), cc.getldflags(cfg), cfg.linkoptions)))\n_p('  LDDEPS    +=%s', make.list(_MAKE.esc(premake.getlinks(cfg, \"siblings\", \"fullpath\"))))\n_p('  LIBS      += $(LDDEPS)%s', make.list(cc.getlinkflags(cfg)))\nif cfg.kind == \"StaticLib\" then\nif cfg.platform:startswith(\"Universal\") then\n_p('  LINKCMD    = libtool -o $(TARGET)')\nelse\nif cc.llvm then\n_p('  LINKCMD    = $(AR) rcs $(TARGET)')\nelse\n_p('  LINKCMD    = $(AR) -rcs $(TARGET)')\nend\nend\nelse\nlocal tool = iif(cfg.language == \"C\", \"CC\", \"CXX\")\n_p('  LINKCMD    = $(%s) -o $(TARGET) $(OBJECTS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)', tool)\nend\nend\nfunction cpp.pchconfig(cfg)\nif not cfg.pchheader or cfg.flags.NoPCH then\nreturn\nend\nlocal pch = cfg.pchheader\nfor _, incdir in ipairs(cfg.includedirs) do\nlocal abspath = p"
190   "ath.getabsolute(path.join(cfg.project.location, incdir))\nlocal testname = path.join(abspath, pch)\nif os.isfile(testname) then\npch = path.getrelative(cfg.location, testname)\nbreak\nend\nend\n_p('  PCH        = %s', _MAKE.esc(pch))\n_p('  GCH        = $(OBJDIR)/$(notdir $(PCH)).gch')\nend\nfunction cpp.pchrules(prj)\n_p('ifneq (,$(PCH))')\n_p('$(GCH): $(PCH)')\n_p('\\t@echo $(notdir $<)')\nlocal cmd = iif(prj.language == \"C\", \"$(CC) -x c-header $(ALL_CFLAGS)\", \"$(CXX) -x c++-header $(ALL_CXXFLAGS)\")\n_p('\\t$(SILENT) %s -MMD -MP $(DEFINES) $(INCLUDES) -o \"$@\" -MF \"$(@:%%.gch=%%.d)\" -c \"$<\"', cmd)\n_p('endif')\n_p('')\nend\nfunction cpp.fileRules(prj)\nfor _, file in ipairs(prj.files or {}) do\nif path.iscppfile(file) then\n_p('$(OBJDIR)/%s.o: %s'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n, _MAKE.esc(file)\n)\nif prj.msgcompile then\n_p('\\t@echo ' .. prj.msgcompile)\nelse\n_p('\\t@echo $(notdir $<)')\nend\ncpp.buildcommand(path.iscfile(file) and not prj.options.ForceCPP, \"o\")\n_p('')\n"
191   "elseif (path.getextension(file) == \".rc\") then\n_p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))\nif prj.msgresource then\n_p('\\t@echo ' .. prj.msgresource)\nelse\n_p('\\t@echo $(notdir $<)')\nend\n_p('\\t$(SILENT) $(RESCOMP) $< -O coff -o \"$@\" $(ALL_RESFLAGS)')\n_p('')\nend\nend\nend\nfunction cpp.buildcommand(iscfile, objext)\nlocal flags = iif(iscfile, '$(CC) $(ALL_CFLAGS)', '$(CXX) $(ALL_CXXFLAGS)')\n_p('\\t$(SILENT) %s $(FORCE_INCLUDE) -o \"$@\" -MF $(@:%%.%s=%%.d) -c \"$<\"', flags, objext)\nend\n",
188   "m = cc.platforms[cfg.platform]\nif platform.cc then\n_p('  CC         = %s', platform.cc)\nend\nif platform.cxx then\n_p('  CXX        = %s', platform.cxx)\nend\nif platform.ar then\n_p('  AR         = %s', platform.ar)\nend\nend\nfunction cpp.flags(cfg, cc)\nif cfg.pchheader and not cfg.flags.NoPCH then\n_p('  FORCE_INCLUDE += -include $(OBJDIR)/$(notdir $(PCH))')\nend\nif #cfg.forcedincludes > 0 then\n_p('  FORCE_INCLUDE += -include %s'\n,premake.esc(table.concat(cfg.forcedincludes, \";\")))\nend\n_p('  ALL_CPPFLAGS  += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), \" \"))\n_p('  ALL_CFLAGS    += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions)))\n_p('  ALL_CXXFLAGS  += $(CXXFLAGS) $(ALL_CFLAGS)%s', make.list(table.join(cc.getcxxflags(cfg), cfg.buildoptions_cpp)))\n_p('  ALL_RESFLAGS  += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s',\n        make.list(table.join(cc.getdefines(cfg.resdefines),\n                                cc.getincludedir"
189   "s(cfg.resincludedirs), cfg.resoptions)))\nend\nfunction cpp.linker(cfg, cc)\n_p('  ALL_LDFLAGS   += $(LDFLAGS)%s', make.list(table.join(cc.getlibdirflags(cfg), cc.getldflags(cfg), cfg.linkoptions)))\n_p('  LDDEPS    +=%s', make.list(_MAKE.esc(premake.getlinks(cfg, \"siblings\", \"fullpath\"))))\n_p('  LIBS      += $(LDDEPS)%s', make.list(cc.getlinkflags(cfg)))\nif cfg.kind == \"StaticLib\" then\nif cfg.platform:startswith(\"Universal\") then\n_p('  LINKCMD    = libtool -o $(TARGET)')\nelse\nif cc.llvm then\n_p('  LINKCMD    = $(AR) rcs $(TARGET)')\nelse\n_p('  LINKCMD    = $(AR) -rcs $(TARGET)')\nend\nend\nelse\nlocal tool = iif(cfg.language == \"C\", \"CC\", \"CXX\")\n_p('  LINKCMD    = $(%s) -o $(TARGET) $(OBJECTS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)', tool)\nend\nend\nfunction cpp.pchconfig(cfg)\nif not cfg.pchheader or cfg.flags.NoPCH then\nreturn\nend\nlocal pch = cfg.pchheader\nfor _, incdir in ipairs(cfg.includedirs) do\nlocal abspath = path.getabsolute(path.join(cfg.project.location, incdir))\n"
190   "local testname = path.join(abspath, pch)\nif os.isfile(testname) then\npch = path.getrelative(cfg.location, testname)\nbreak\nend\nend\n_p('  PCH        = %s', _MAKE.esc(pch))\n_p('  GCH        = $(OBJDIR)/$(notdir $(PCH)).gch')\nend\nfunction cpp.pchrules(prj)\n_p('ifneq (,$(PCH))')\n_p('$(GCH): $(PCH)')\n_p('\\t@echo $(notdir $<)')\nlocal cmd = iif(prj.language == \"C\", \"$(CC) -x c-header $(ALL_CFLAGS)\", \"$(CXX) -x c++-header $(ALL_CXXFLAGS)\")\n_p('\\t$(SILENT) %s -MMD -MP $(DEFINES) $(INCLUDES) -o \"$@\" -MF \"$(@:%%.gch=%%.d)\" -c \"$<\"', cmd)\n_p('endif')\n_p('')\nend\nfunction cpp.fileRules(prj)\nfor _, file in ipairs(prj.files or {}) do\nif path.iscppfile(file) then\n_p('$(OBJDIR)/%s.o: %s'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n, _MAKE.esc(file)\n)\nif prj.msgcompile then\n_p('\\t@echo ' .. prj.msgcompile)\nelse\n_p('\\t@echo $(notdir $<)')\nend\ncpp.buildcommand(path.iscfile(file) and not prj.options.ForceCPP, \"o\")\n_p('')\nelseif (path.getextension(file) == \".rc\") then\n_p('$(OB"
191   "JDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))\nif prj.msgresource then\n_p('\\t@echo ' .. prj.msgresource)\nelse\n_p('\\t@echo $(notdir $<)')\nend\n_p('\\t$(SILENT) $(RESCOMP) $< -O coff -o \"$@\" $(ALL_RESFLAGS)')\n_p('')\nend\nend\nend\nfunction cpp.buildcommand(iscfile, objext)\nlocal flags = iif(iscfile, '$(CC) $(ALL_CFLAGS)', '$(CXX) $(ALL_CXXFLAGS)')\n_p('\\t$(SILENT) %s $(FORCE_INCLUDE) -o \"$@\" -MF $(@:%%.%s=%%.d) -c \"$<\"', flags, objext)\nend\n",
192192
193193   /* actions/make/make_csharp.lua */
194194   "local function getresourcefilename(cfg, fname)\nif path.getextension(fname) == \".resx\" then\n    local name = cfg.buildtarget.basename .. \".\"\n    local dir = path.getdirectory(fname)\n    if dir ~= \".\" then \nname = name .. path.translate(dir, \".\") .. \".\"\nend\nreturn \"$(OBJDIR)/\" .. _MAKE.esc(name .. path.getbasename(fname)) .. \".resources\"\nelse\nreturn fname\nend\nend\nfunction premake.make_csharp(prj)\nlocal csc = premake.dotnet\nlocal cfglibs = { }\nlocal cfgpairs = { }\nlocal anycfg\nfor cfg in premake.eachconfig(prj) do\nanycfg = cfg\ncfglibs[cfg] = premake.getlinks(cfg, \"siblings\", \"fullpath\")\ncfgpairs[cfg] = { }\nfor _, fname in ipairs(cfglibs[cfg]) do\nif path.getdirectory(fname) ~= cfg.buildtarget.directory then\ncfgpairs[cfg][\"$(TARGETDIR)/\" .. _MAKE.esc(path.getname(fname))] = _MAKE.esc(fname)\nend\nend\nend\nlocal sources = {}\nlocal embedded = { }\nlocal copypairs = { }\nfor fcfg in premake.project.eachfile(prj) do\nlocal action = csc.getbuildaction(fcfg)\nif action == \"Co"
trunk/3rdparty/mongoose/docs/API.md
r244651r244652
11# Mongoose API Reference
22
3    struct mg_server *mg_create_server(void *server_param, mg_handler_t handler);
3    struct mg_server *mg_create_server(void *server_param);
44
55Creates web server instance. Returns opaque instance pointer, or NULL if
66there is not enough memory. `server_param`: Could be any pointer, or NULL.
r244651r244652
173173     Mongoose will call a handler repeatedly after each socket write.
174174
175175<!-- -->
176
176     
177177     void mg_send_file(struct mg_connection *, const char *path);
178178
179179Tells Mongoose to serve given file. Mongoose handles file according to
r244651r244652
187187                           const char *data, size_t data_len);
188188
189189Similar to `mg_write()`, but wraps the data into a websocket frame with a
190given websocket `opcode`.
190given websocket `opcode`. 
191191
192192    const char *mg_get_header(const struct mg_connection *, const char *name);
193193
r244651r244652
219219                                 const char *user,
220220                                 const char *password);
221221
222Add, edit or delete the entry in the passwords file.
222Add, edit or delete the entry in the passwords file. 
223223This function allows an application to manipulate .htpasswd files on the
224224fly by adding, deleting and changing user records. This is one of the
225several ways of implementing authentication on the server side.
225several ways of implementing authentication on the server side. 
226226If password is not NULL, entry is added (or modified if already exists).
227If password is NULL, entry is deleted.
227If password is NULL, entry is deleted. 
228228Return: 1 on success, 0 on error.
229229
230
230   
231231    int mg_parse_multipart(const char *buf, int buf_len,
232232                           char *var_name, int var_name_len,
233233                           char *file_name, int file_name_len,
trunk/3rdparty/mongoose/docs/LuaSqlite.md
r0r244652
1# Mongoose Lua Server Pages
2
3Pre-built Windows and Mac mongoose binaries support Lua Server Pages
4functionality.
5That means it is possible to write PHP-like scripts with mongoose
6using Lua programming language instead of PHP. Lua is known
7for it's speed and small size. Mongoose uses Lua version 5.2.3, the
8documentation for it can be found at
9[Lua 5.2 reference manual](http://www.lua.org/manual/5.2/).
10
11To create a Lua Page, make a file that is called `ANY_NAME.lp`. For example,
12`my_page.lp`. It is important to have a file
13name that ends up with `.lp`, cause this is the way mongoose recognises
14Lua Page file. The contents of the file, just like
15with PHP, is HTML with embedded Lua code. Lua code must be enclosed within
16`&lt;?  ?&gt;` blocks, and can appear anywhere on the page.
17
18Mongoose does not send HTTP headers for Lua pages. Therefore,
19every Lua Page must begin with HTTP status line and headers, like this:
20
21    <? mg.write('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n') ?>
22    <html><body>
23      <span>Today is:</span> <? mg.write(os.date("%A")) ?>
24    </body></html>
25
26Note that this example uses function `mg.write()`, which prints data to the
27web page. Using function `mg.write()` is the way to generate web content from
28inside Lua code. In addition to `mg.write()`, all standard library functions
29are accessible from the Lua code (please check reference manual for details).
30Information about the request is available via the `mg.request_info` object.
31I contains request method, all headers, etcetera. Please refer to
32`struct mg_request_info` definition in
33[mongoose.h](https://github.com/cesanta/mongoose/blob/master/mongoose.h)
34to see what is available via the `mg.request_info` object.
35Check out [prime_numbers.lp](https://github.com/cesanta/mongoose/blob/master/examples/lua/prime_numbers.lp) for some example.
36
37Mongoose exports the following to the Lua Server Page:
38
39    mg.write(str)     -- writes string to the client
40    mg.onerror(msg)   -- error handler, can be overridden
41    mg.request_info   -- a table with request information
42
43Using Lua scripting it is easy to emulate SSI functionality. For example,
44to include the content of another file, one can write:
45
46    <? mg.write(io.open('MY_FILE.TXT'):read('*all')) ?>
47
48To serve a Lua Page, mongoose creates Lua context. That context is used for
49all Lua blocks within the page. That means, all Lua blocks on the same page
50share the same context. If one block defines a variable, for example, that
51variable is visible in all following blocks.
trunk/3rdparty/mongoose/mongoose.c
r244651r244652
124124#include <sys/socket.h>
125125#include <sys/select.h>
126126#define closesocket(x) close(x)
127#ifndef __OS2__
127128#define __cdecl
129#else
130#include <sys/time.h>
131typedef int socklen_t;
132#endif
128133#define INVALID_SOCKET (-1)
129134#define to64(x) strtoll(x, NULL, 10)
130135typedef int sock_t;
r244651r244652
601606
602607// TODO(lsm): use non-blocking resolver
603608static int ns_resolve2(const char *host, struct in_addr *ina) {
604#ifdef NS_ENABLE_GETADDRINFO
605  int rv = 0;
606  struct addrinfo hints, *servinfo, *p;
607  struct sockaddr_in *h = NULL;
608  char *ip = NS_MALLOC(17);
609  memset(ip, '\0', 17);
610
611  memset(&hints, 0, sizeof hints);
612  hints.ai_family = AF_INET;
613  hints.ai_socktype = SOCK_STREAM;
614
615  if((rv = getaddrinfo(host, NULL , NULL, &servinfo)) != 0) {
616    DBG(("getaddrinfo(%s) failed: %s", host, strerror(errno)));
617    return 0;
618  }
619
620  for(p = servinfo; p != NULL; p = p->ai_next) {
621    memcpy(&h, &p->ai_addr, sizeof(struct sockaddr_in *));
622    memcpy(ina, &h->sin_addr, sizeof(ina));
623  }
624
625  freeaddrinfo(servinfo);
626  return 1;
627#else
628609  struct hostent *he;
629610  if ((he = gethostbyname(host)) == NULL) {
630611    DBG(("gethostbyname(%s) failed: %s", host, strerror(errno)));
r244651r244652
633614    return 1;
634615  }
635616  return 0;
636#endif
637617}
638618
639619// Resolve FDQN "host", store IP address in the "ip".
r244651r244652
15791559#define MAP_FAILED NULL
15801560#define MAP_PRIVATE 0
15811561#define PROT_READ 0
1562#elif defined(__OS2__)
1563static void *mmap(void *addr, int64_t len, int prot, int flags, int fd,
1564                  int offset) {
1565  void *p;
1566
1567  int pos = lseek( fd, 0, SEEK_CUR ); /* Get a current position */
1568
1569  if (pos == -1)
1570    return NULL;
1571
1572  /* Seek to offset offset */
1573  if (lseek( fd, offset, SEEK_SET) == -1)
1574    return NULL;
1575
1576  p = malloc(len);
1577
1578  /* Read in a file */
1579  if (!p || read(fd, p, len) == -1) {
1580    free(p);
1581    p = NULL;
1582  }
1583
1584  /* Restore the position */
1585  lseek(fd, pos, SEEK_SET);
1586
1587  return p;
1588}
1589#define munmap(x, y)  free(x)
1590#define MAP_FAILED NULL
1591#define MAP_PRIVATE 0
1592#define PROT_READ 0
15821593#else
15831594#include <sys/mman.h>
15841595#endif
r244651r244652
29983009      copy_len = 4 + data_len;
29993010    } else {
30003011      // 64-bit length field
3012      copy[1] = 127;
30013013      const uint32_t hi = htonl((uint32_t) ((uint64_t) data_len >> 32));
30023014      const uint32_t lo = htonl(data_len & 0xffffffff);
3003      copy[1] = 127;
30043015      memcpy(copy+2,&hi,sizeof(hi));
30053016      memcpy(copy+6,&lo,sizeof(lo));
30063017      memcpy(copy + 10, data, data_len);
trunk/src/emu/bus/a2bus/ezcgi.c
r244651r244652
1/*********************************************************************
2
3    ezcgi.c
4
5    "E-Z Color Graphics Interface" by Steve Ciarcia
6    from BYTE Magazine, August, 1982
7    https://archive.org/details/byte-magazine-1982-08-rescan
8
9*********************************************************************/
10
11#include "emu.h"
12#include "ezcgi.h"
13
14
15/***************************************************************************
16    PARAMETERS
17***************************************************************************/
18
19#define TMS_TAG "ezcgi_tms"
20#define SCREEN_TAG "screen"
21
22//**************************************************************************
23//  GLOBAL VARIABLES
24//**************************************************************************
25
26const device_type A2BUS_EZCGI = &device_creator<a2bus_ezcgi_device>;
27const device_type A2BUS_EZCGI_9938 = &device_creator<a2bus_ezcgi_9938_device>;
28const device_type A2BUS_EZCGI_9958 = &device_creator<a2bus_ezcgi_9958_device>;
29
30MACHINE_CONFIG_FRAGMENT( ezcgi )
31   MCFG_DEVICE_ADD( TMS_TAG, TMS9918A, XTAL_10_738635MHz / 2 )
32   MCFG_TMS9928A_VRAM_SIZE(0x4000) // 16k of VRAM
33   MCFG_TMS9928A_OUT_INT_LINE_CB(WRITELINE(a2bus_ezcgi_device, tms_irq_w))
34   MCFG_TMS9928A_SCREEN_ADD_NTSC( SCREEN_TAG )
35   MCFG_SCREEN_UPDATE_DEVICE( TMS_TAG, tms9918a_device, screen_update )
36MACHINE_CONFIG_END
37
38#define MSX2_XBORDER_PIXELS     16
39#define MSX2_YBORDER_PIXELS     28
40#define MSX2_TOTAL_XRES_PIXELS      256 * 2 + (MSX2_XBORDER_PIXELS * 2)
41#define MSX2_TOTAL_YRES_PIXELS      212 * 2 + (MSX2_YBORDER_PIXELS * 2)
42#define MSX2_VISIBLE_XBORDER_PIXELS 8 * 2
43#define MSX2_VISIBLE_YBORDER_PIXELS 14 * 2
44
45MACHINE_CONFIG_FRAGMENT( ezcgi9938 )
46   MCFG_V9938_ADD(TMS_TAG, SCREEN_TAG, 0x30000)   // 192K of VRAM
47   MCFG_V99X8_INTERRUPT_CALLBACK(WRITELINE(a2bus_ezcgi_9938_device, tms_irq_w))
48
49   MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
50   MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
51   MCFG_SCREEN_REFRESH_RATE(60)
52   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
53   MCFG_SCREEN_UPDATE_DEVICE(TMS_TAG, v9938_device, screen_update)
54   MCFG_SCREEN_SIZE(MSX2_TOTAL_XRES_PIXELS, 262*2)
55   MCFG_SCREEN_VISIBLE_AREA(MSX2_XBORDER_PIXELS - MSX2_VISIBLE_XBORDER_PIXELS, MSX2_TOTAL_XRES_PIXELS - MSX2_XBORDER_PIXELS + MSX2_VISIBLE_XBORDER_PIXELS - 1, MSX2_YBORDER_PIXELS - MSX2_VISIBLE_YBORDER_PIXELS, MSX2_TOTAL_YRES_PIXELS - MSX2_YBORDER_PIXELS + MSX2_VISIBLE_YBORDER_PIXELS - 1)
56   MCFG_SCREEN_PALETTE("ezcgi_tms:palette")
57MACHINE_CONFIG_END
58
59MACHINE_CONFIG_FRAGMENT( ezcgi9958 )
60   MCFG_V9958_ADD(TMS_TAG, SCREEN_TAG, 0x30000)   // 192K of VRAM
61   MCFG_V99X8_INTERRUPT_CALLBACK(WRITELINE(a2bus_ezcgi_9958_device, tms_irq_w))
62
63   MCFG_SCREEN_ADD(SCREEN_TAG, RASTER)
64   MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK)
65   MCFG_SCREEN_REFRESH_RATE(60)
66   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
67   MCFG_SCREEN_UPDATE_DEVICE(TMS_TAG, v9938_device, screen_update)
68   MCFG_SCREEN_SIZE(MSX2_TOTAL_XRES_PIXELS, 262*2)
69   MCFG_SCREEN_VISIBLE_AREA(MSX2_XBORDER_PIXELS - MSX2_VISIBLE_XBORDER_PIXELS, MSX2_TOTAL_XRES_PIXELS - MSX2_XBORDER_PIXELS + MSX2_VISIBLE_XBORDER_PIXELS - 1, MSX2_YBORDER_PIXELS - MSX2_VISIBLE_YBORDER_PIXELS, MSX2_TOTAL_YRES_PIXELS - MSX2_YBORDER_PIXELS + MSX2_VISIBLE_YBORDER_PIXELS - 1)
70   MCFG_SCREEN_PALETTE("ezcgi_tms:palette")
71MACHINE_CONFIG_END
72
73//-------------------------------------------------
74//  machine_config_additions - device-specific
75//  machine configurations
76//-------------------------------------------------
77
78machine_config_constructor a2bus_ezcgi_device::device_mconfig_additions() const
79{
80   return MACHINE_CONFIG_NAME( ezcgi );
81}
82
83machine_config_constructor a2bus_ezcgi_9938_device::device_mconfig_additions() const
84{
85   return MACHINE_CONFIG_NAME( ezcgi9938 );
86}
87
88machine_config_constructor a2bus_ezcgi_9958_device::device_mconfig_additions() const
89{
90   return MACHINE_CONFIG_NAME( ezcgi9958 );
91}
92
93//**************************************************************************
94//  LIVE DEVICE
95//**************************************************************************
96
97a2bus_ezcgi_device::a2bus_ezcgi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
98   device_t(mconfig, A2BUS_EZCGI, "E-Z Color Graphics Interface", tag, owner, clock, "a2ezcgi", __FILE__),
99   device_a2bus_card_interface(mconfig, *this),
100   m_tms(*this, TMS_TAG)
101{
102}
103
104a2bus_ezcgi_device::a2bus_ezcgi_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
105   device_t(mconfig, type, name, tag, owner, clock, shortname, source),
106   device_a2bus_card_interface(mconfig, *this),
107   m_tms(*this, TMS_TAG)
108{
109}
110
111a2bus_ezcgi_9938_device::a2bus_ezcgi_9938_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
112   device_t(mconfig, A2BUS_EZCGI_9938, "E-Z Color Graphics Interface (TMS9938)", tag, owner, clock, "a2ezcgi3", __FILE__),
113   device_a2bus_card_interface(mconfig, *this),
114   m_tms(*this, TMS_TAG)
115{
116}
117
118a2bus_ezcgi_9938_device::a2bus_ezcgi_9938_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
119   device_t(mconfig, type, name, tag, owner, clock, shortname, source),
120   device_a2bus_card_interface(mconfig, *this),
121   m_tms(*this, TMS_TAG)
122{
123}
124
125a2bus_ezcgi_9958_device::a2bus_ezcgi_9958_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
126   device_t(mconfig, A2BUS_EZCGI_9958, "E-Z Color Graphics Interface (TMS9958)", tag, owner, clock, "a2ezcgi5", __FILE__),
127   device_a2bus_card_interface(mconfig, *this),
128   m_tms(*this, TMS_TAG)
129{
130}
131
132a2bus_ezcgi_9958_device::a2bus_ezcgi_9958_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
133   device_t(mconfig, type, name, tag, owner, clock, shortname, source),
134   device_a2bus_card_interface(mconfig, *this),
135   m_tms(*this, TMS_TAG)
136{
137}
138
139//-------------------------------------------------
140//  device_start - device-specific startup
141//-------------------------------------------------
142
143void a2bus_ezcgi_device::device_start()
144{
145   // set_a2bus_device makes m_slot valid
146   set_a2bus_device();
147}
148
149void a2bus_ezcgi_device::device_reset()
150{
151}
152
153void a2bus_ezcgi_9938_device::device_start()
154{
155   // set_a2bus_device makes m_slot valid
156   set_a2bus_device();
157}
158
159void a2bus_ezcgi_9938_device::device_reset()
160{
161}
162
163void a2bus_ezcgi_9958_device::device_start()
164{
165   // set_a2bus_device makes m_slot valid
166   set_a2bus_device();
167}
168
169void a2bus_ezcgi_9958_device::device_reset()
170{
171}
172
173/*
174    C0nx map:
175    0 - TMS read
176    1 - TMS write
177*/
178
179UINT8 a2bus_ezcgi_device::read_c0nx(address_space &space, UINT8 offset)
180{
181   switch (offset)
182   {
183      case 0:
184         return m_tms->vram_read(space, 0);
185
186      case 1:
187         return m_tms->register_read(space, 0);
188   }
189
190   return 0xff;
191}
192
193void a2bus_ezcgi_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data)
194{
195   switch (offset)
196   {
197      case 0:
198         m_tms->vram_write(space, 0, data);
199         break;
200
201      case 1:
202         m_tms->register_write(space, 0, data);
203         break;
204   }
205}
206
207UINT8 a2bus_ezcgi_9938_device::read_c0nx(address_space &space, UINT8 offset)
208{
209   switch (offset)
210   {
211      case 0:
212         return m_tms->vram_r();
213
214      case 1:
215         return m_tms->status_r();
216   }
217
218   return 0xff;
219}
220
221void a2bus_ezcgi_9938_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data)
222{
223   switch (offset)
224   {
225      case 0:
226         m_tms->vram_w(data);
227         break;
228
229      case 1:
230         m_tms->command_w(data);
231         break;
232
233      case 2:
234         m_tms->palette_w(data);
235         break;
236
237      case 3:
238         m_tms->register_w(data);
239         break;
240   }
241}
242
243UINT8 a2bus_ezcgi_9958_device::read_c0nx(address_space &space, UINT8 offset)
244{
245   switch (offset)
246   {
247      case 0:
248         return m_tms->vram_r();
249
250      case 1:
251         return m_tms->status_r();
252   }
253
254   return 0xff;
255}
256
257void a2bus_ezcgi_9958_device::write_c0nx(address_space &space, UINT8 offset, UINT8 data)
258{
259   switch (offset)
260   {
261      case 0:
262         m_tms->vram_w(data);
263         break;
264
265      case 1:
266         m_tms->command_w(data);
267         break;
268
269      case 2:
270         m_tms->palette_w(data);
271         break;
272
273      case 3:
274         m_tms->register_w(data);
275         break;
276   }
277}
278
279WRITE_LINE_MEMBER( a2bus_ezcgi_device::tms_irq_w )
280{
281   if (state)
282   {
283      raise_slot_irq();
284   }
285   else
286   {
287      lower_slot_irq();
288   }
289}
290
291WRITE_LINE_MEMBER( a2bus_ezcgi_9938_device::tms_irq_w )
292{
293   if (state)
294   {
295      raise_slot_irq();
296   }
297   else
298   {
299      lower_slot_irq();
300   }
301}
302
303WRITE_LINE_MEMBER( a2bus_ezcgi_9958_device::tms_irq_w )
304{
305   if (state)
306   {
307      raise_slot_irq();
308   }
309   else
310   {
311      lower_slot_irq();
312   }
313}
314
trunk/src/emu/bus/a2bus/ezcgi.h
r244651r244652
1/*********************************************************************
2
3    ezcgi.h
4
5    "E-Z Color Graphics Interface" by Steve Ciarcia
6    from BYTE Magazine, August, 1982
7    https://archive.org/details/byte-magazine-1982-08-rescan
8
9*********************************************************************/
10
11#ifndef __A2BUS_EZCGI__
12#define __A2BUS_EZCGI__
13
14#include "emu.h"
15#include "a2bus.h"
16#include "video/tms9928a.h"
17#include "video/v9938.h"
18
19//**************************************************************************
20//  TYPE DEFINITIONS
21//**************************************************************************
22
23class a2bus_ezcgi_device:
24   public device_t,
25   public device_a2bus_card_interface
26{
27public:
28   // construction/destruction
29   a2bus_ezcgi_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
30   a2bus_ezcgi_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
31
32   // optional information overrides
33   virtual machine_config_constructor device_mconfig_additions() const;
34
35   DECLARE_WRITE_LINE_MEMBER( tms_irq_w );
36
37protected:
38   virtual void device_start();
39   virtual void device_reset();
40
41   // overrides of standard a2bus slot functions
42   virtual UINT8 read_c0nx(address_space &space, UINT8 offset);
43   virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data);
44
45   required_device<tms9918a_device> m_tms;
46
47private:
48};
49
50class a2bus_ezcgi_9938_device:
51   public device_t,
52   public device_a2bus_card_interface
53{
54public:
55   // construction/destruction
56   a2bus_ezcgi_9938_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
57   a2bus_ezcgi_9938_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
58
59   // optional information overrides
60   virtual machine_config_constructor device_mconfig_additions() const;
61
62   DECLARE_WRITE_LINE_MEMBER( tms_irq_w );
63
64protected:
65   virtual void device_start();
66   virtual void device_reset();
67
68   // overrides of standard a2bus slot functions
69   virtual UINT8 read_c0nx(address_space &space, UINT8 offset);
70   virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data);
71
72   required_device<v9938_device> m_tms;
73
74private:
75};
76
77class a2bus_ezcgi_9958_device:
78   public device_t,
79   public device_a2bus_card_interface
80{
81public:
82   // construction/destruction
83   a2bus_ezcgi_9958_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
84   a2bus_ezcgi_9958_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
85
86   // optional information overrides
87   virtual machine_config_constructor device_mconfig_additions() const;
88
89   DECLARE_WRITE_LINE_MEMBER( tms_irq_w );
90
91protected:
92   virtual void device_start();
93   virtual void device_reset();
94
95   // overrides of standard a2bus slot functions
96   virtual UINT8 read_c0nx(address_space &space, UINT8 offset);
97   virtual void write_c0nx(address_space &space, UINT8 offset, UINT8 data);
98
99   required_device<v9958_device> m_tms;
100
101private:
102};
103
104// device type definition
105extern const device_type A2BUS_EZCGI;
106extern const device_type A2BUS_EZCGI_9938;
107extern const device_type A2BUS_EZCGI_9958;
108
109#endif  /* __A2BUS_EZCGI__ */
trunk/src/emu/bus/bus.mak
r244651r244652
931931BUSOBJS += $(BUSOBJ)/a2bus/corvfdc02.o
932932BUSOBJS += $(BUSOBJ)/a2bus/ramcard16k.o
933933BUSOBJS += $(BUSOBJ)/a2bus/ramcard128k.o
934BUSOBJS += $(BUSOBJ)/a2bus/ezcgi.o
935934endif
936935
937936#-------------------------------------------------
trunk/src/emu/video/tms34061.c
r244651r244652
6060
6161   /* allocate memory for VRAM */
6262   m_vram = auto_alloc_array_clear(machine(), UINT8, m_vramsize + 256 * 2);
63   
63   /* not really a save state, just there for debugging purposes */
64   save_pointer(NAME(m_vram), m_vramsize);
65
6466   /* allocate memory for latch RAM */
6567   m_latchram = auto_alloc_array_clear(machine(), UINT8, m_vramsize + 256 * 2);
6668
r244651r244652
9395
9496   /* start vertical interrupt timer */
9597   m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tms34061_device::interrupt), this));
96   
97   save_item(NAME(m_regs));
98   save_item(NAME(m_xmask));
99   save_item(NAME(m_yshift));
100   save_pointer(NAME(m_vram), m_vramsize);
101   save_pointer(NAME(m_latchram), m_vramsize);
102   save_item(NAME(m_latchdata));
10398}
10499
105100//-------------------------------------------------
trunk/src/mame/drivers/argus.c
r244651r244652
107107===============
108108 - Half transparent color (50% alpha blending) is not emulated.
109109 - Sprite priority switch of Butasan is shown in test mode. What will be
110   happened when set it ? JFF is not implemented this mystery switch too.
110   happened when set it ? JFF is not implemented this mistery switch too.
111111 - Data proms of Butasan does exist. But I don't know what is used for.
112112 - Though clock speed of Argus is actually 4 MHz, major sprite problems
113113   are broken out in the middle of slowdown. So, it is set 5 MHz now.
r244651r244652
123123#include "includes/argus.h"
124124
125125
126void argus_state::machine_start()
127{
128   membank("mainbank")->configure_entries(0, 8, memregion("maincpu")->base() + 0x10000, 0x4000);
129}
130
131126/***************************************************************************
132127
133128  Interrupt(s)
134129
135130***************************************************************************/
136131
137TIMER_DEVICE_CALLBACK_MEMBER(argus_state::scanline)
132TIMER_DEVICE_CALLBACK_MEMBER(argus_state::argus_scanline)
138133{
139134   int scanline = param;
140135
r244651r244652
156151      m_maincpu->set_input_line_and_vector(0, HOLD_LINE,0xcf); /* RST 08h */
157152}
158153
154/* Handler called by the YM2203 emulator when the internal timers cause an IRQ */
155WRITE_LINE_MEMBER(argus_state::irqhandler)
156{
157   m_audiocpu->set_input_line(0, state ? ASSERT_LINE : CLEAR_LINE);
158}
159159
160160/***************************************************************************
161161
r244651r244652
163163
164164***************************************************************************/
165165
166WRITE8_MEMBER(argus_state::bankselect_w)
166WRITE8_MEMBER(argus_state::argus_bankselect_w)
167167{
168   membank("mainbank")->set_entry(data & 7);   /* Select 8 banks of 16k */
168   UINT8 *RAM = memregion("maincpu")->base();
169   int bankaddress;
170
171   bankaddress = 0x10000 + ((data & 7) * 0x4000);
172   membank("bank1")->set_base(&RAM[bankaddress]);   /* Select 8 banks of 16k */
169173}
170174
171175
r244651r244652
177181
178182static ADDRESS_MAP_START( argus_map, AS_PROGRAM, 8, argus_state )
179183   AM_RANGE(0x0000, 0x7fff) AM_ROM
180   AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("mainbank")
184   AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank1")
181185   AM_RANGE(0xc000, 0xc000) AM_READ_PORT("SYSTEM")
182186   AM_RANGE(0xc001, 0xc001) AM_READ_PORT("P1")
183187   AM_RANGE(0xc002, 0xc002) AM_READ_PORT("P2")
184188   AM_RANGE(0xc003, 0xc003) AM_READ_PORT("DSW1")
185189   AM_RANGE(0xc004, 0xc004) AM_READ_PORT("DSW2")
186190   AM_RANGE(0xc200, 0xc200) AM_WRITE(soundlatch_byte_w)
187   AM_RANGE(0xc201, 0xc201) AM_WRITE(flipscreen_w)
188   AM_RANGE(0xc202, 0xc202) AM_WRITE(bankselect_w)
191   AM_RANGE(0xc201, 0xc201) AM_WRITE(argus_flipscreen_w)
192   AM_RANGE(0xc202, 0xc202) AM_WRITE(argus_bankselect_w)
189193   AM_RANGE(0xc300, 0xc301) AM_RAM AM_SHARE("bg0_scrollx")
190194   AM_RANGE(0xc302, 0xc303) AM_RAM AM_SHARE("bg0_scrolly")
191195   AM_RANGE(0xc308, 0xc309) AM_RAM AM_SHARE("bg1_scrollx")
192196   AM_RANGE(0xc30a, 0xc30b) AM_RAM AM_SHARE("bg1_scrolly")
193197   AM_RANGE(0xc30c, 0xc30c) AM_WRITE(argus_bg_status_w)
194   AM_RANGE(0xc400, 0xcfff) AM_RAM_WRITE(argus_paletteram_w) AM_SHARE("paletteram")
195   AM_RANGE(0xd000, 0xd7ff) AM_RAM_WRITE(txram_w) AM_SHARE("txram")
196   AM_RANGE(0xd800, 0xdfff) AM_RAM_WRITE(bg1ram_w) AM_SHARE("bg1ram")
198   AM_RANGE(0xc400, 0xcfff) AM_READWRITE(argus_paletteram_r, argus_paletteram_w) AM_SHARE("paletteram")
199   AM_RANGE(0xd000, 0xd7ff) AM_READWRITE(argus_txram_r, argus_txram_w) AM_SHARE("txram")
200   AM_RANGE(0xd800, 0xdfff) AM_READWRITE(argus_bg1ram_r, argus_bg1ram_w) AM_SHARE("bg1ram")
197201   AM_RANGE(0xe000, 0xf1ff) AM_RAM
198202   AM_RANGE(0xf200, 0xf7ff) AM_RAM AM_SHARE("spriteram")
199203   AM_RANGE(0xf800, 0xffff) AM_RAM
r244651r244652
201205
202206static ADDRESS_MAP_START( valtric_map, AS_PROGRAM, 8, argus_state )
203207   AM_RANGE(0x0000, 0x7fff) AM_ROM
204   AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("mainbank")
208   AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank1")
205209   AM_RANGE(0xc000, 0xc000) AM_READ_PORT("SYSTEM")
206210   AM_RANGE(0xc001, 0xc001) AM_READ_PORT("P1")
207211   AM_RANGE(0xc002, 0xc002) AM_READ_PORT("P2")
208212   AM_RANGE(0xc003, 0xc003) AM_READ_PORT("DSW1")
209213   AM_RANGE(0xc004, 0xc004) AM_READ_PORT("DSW2")
210214   AM_RANGE(0xc200, 0xc200) AM_WRITE(soundlatch_byte_w)
211   AM_RANGE(0xc201, 0xc201) AM_WRITE(flipscreen_w)
212   AM_RANGE(0xc202, 0xc202) AM_WRITE(bankselect_w)
215   AM_RANGE(0xc201, 0xc201) AM_WRITE(argus_flipscreen_w)
216   AM_RANGE(0xc202, 0xc202) AM_WRITE(argus_bankselect_w)
213217   AM_RANGE(0xc300, 0xc300) AM_WRITE(valtric_unknown_w)
214218   AM_RANGE(0xc308, 0xc309) AM_RAM AM_SHARE("bg1_scrollx")
215219   AM_RANGE(0xc30a, 0xc30b) AM_RAM AM_SHARE("bg1_scrolly")
216220   AM_RANGE(0xc30c, 0xc30c) AM_WRITE(valtric_bg_status_w)
217221   AM_RANGE(0xc30d, 0xc30d) AM_WRITE(valtric_mosaic_w)
218   AM_RANGE(0xc400, 0xcfff) AM_RAM_WRITE(valtric_paletteram_w) AM_SHARE("paletteram")
219   AM_RANGE(0xd000, 0xd7ff) AM_RAM_WRITE(txram_w) AM_SHARE("txram")
220   AM_RANGE(0xd800, 0xdfff) AM_RAM_WRITE(bg1ram_w) AM_SHARE("bg1ram")
222   AM_RANGE(0xc400, 0xcfff) AM_READWRITE(argus_paletteram_r, valtric_paletteram_w) AM_SHARE("paletteram")
223   AM_RANGE(0xd000, 0xd7ff) AM_READWRITE(argus_txram_r, argus_txram_w) AM_SHARE("txram")
224   AM_RANGE(0xd800, 0xdfff) AM_READWRITE(argus_bg1ram_r, argus_bg1ram_w) AM_SHARE("bg1ram")
221225   AM_RANGE(0xe000, 0xf1ff) AM_RAM
222226   AM_RANGE(0xf200, 0xf7ff) AM_RAM AM_SHARE("spriteram")
223227   AM_RANGE(0xf800, 0xffff) AM_RAM
r244651r244652
225229
226230static ADDRESS_MAP_START( butasan_map, AS_PROGRAM, 8, argus_state )
227231   AM_RANGE(0x0000, 0x7fff) AM_ROM
228   AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("mainbank")
232   AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank1")
229233   AM_RANGE(0xc000, 0xc000) AM_READ_PORT("SYSTEM")
230234   AM_RANGE(0xc001, 0xc001) AM_READ_PORT("P1")
231235   AM_RANGE(0xc002, 0xc002) AM_READ_PORT("P2")
r244651r244652
233237   AM_RANGE(0xc004, 0xc004) AM_READ_PORT("DSW2")
234238   AM_RANGE(0xc100, 0xc100) AM_WRITE(butasan_unknown_w)
235239   AM_RANGE(0xc200, 0xc200) AM_WRITE(soundlatch_byte_w)
236   AM_RANGE(0xc201, 0xc201) AM_WRITE(flipscreen_w)
237   AM_RANGE(0xc202, 0xc202) AM_WRITE(bankselect_w)
240   AM_RANGE(0xc201, 0xc201) AM_WRITE(argus_flipscreen_w)
241   AM_RANGE(0xc202, 0xc202) AM_WRITE(argus_bankselect_w)
238242   AM_RANGE(0xc203, 0xc203) AM_WRITE(butasan_pageselect_w)
239243   AM_RANGE(0xc300, 0xc301) AM_RAM AM_SHARE("bg0_scrollx")
240244   AM_RANGE(0xc302, 0xc303) AM_RAM AM_SHARE("bg0_scrolly")
r244651r244652
242246   AM_RANGE(0xc308, 0xc309) AM_RAM AM_SHARE("bg1_scrollx")
243247   AM_RANGE(0xc30a, 0xc30b) AM_RAM AM_SHARE("bg1_scrolly")
244248   AM_RANGE(0xc30c, 0xc30c) AM_WRITE(butasan_bg1_status_w)
245   AM_RANGE(0xc400, 0xc7ff) AM_RAM_WRITE(butasan_bg1ram_w) AM_SHARE("butasan_bg1ram")
246   AM_RANGE(0xc800, 0xcfff) AM_RAM_WRITE(butasan_paletteram_w) AM_SHARE("paletteram")
249   AM_RANGE(0xc400, 0xc7ff) AM_READWRITE(butasan_bg1ram_r, butasan_bg1ram_w) AM_SHARE("butasan_bg1ram")
250   AM_RANGE(0xc800, 0xcfff) AM_READWRITE(argus_paletteram_r, butasan_paletteram_w) AM_SHARE("paletteram")
247251   AM_RANGE(0xd000, 0xdfff) AM_READWRITE(butasan_pagedram_r, butasan_pagedram_w)
248252   AM_RANGE(0xe000, 0xefff) AM_RAM
249253   AM_RANGE(0xf000, 0xf67f) AM_RAM AM_SHARE("spriteram")
r244651r244652
530534   /* basic machine hardware */
531535   MCFG_CPU_ADD("maincpu", Z80, 5000000)           /* 4 MHz */
532536   MCFG_CPU_PROGRAM_MAP(argus_map)
533   MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", argus_state, scanline, "screen", 0, 1)
537   MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", argus_state, argus_scanline, "screen", 0, 1)
534538
535539   MCFG_CPU_ADD("audiocpu", Z80, 5000000)
536540   MCFG_CPU_PROGRAM_MAP(sound_map_a)
r244651r244652
556560   MCFG_SPEAKER_STANDARD_MONO("mono")
557561
558562   MCFG_SOUND_ADD("ym1", YM2203, 6000000 / 4)
559   MCFG_YM2203_IRQ_HANDLER(INPUTLINE("audiocpu", 0))
563   MCFG_YM2203_IRQ_HANDLER(WRITELINE(argus_state, irqhandler))
560564   MCFG_SOUND_ROUTE(0, "mono", 0.15)
561565   MCFG_SOUND_ROUTE(1, "mono", 0.15)
562566   MCFG_SOUND_ROUTE(2, "mono", 0.15)
r244651r244652
574578   /* basic machine hardware */
575579   MCFG_CPU_ADD("maincpu", Z80, 5000000)           /* 5 MHz */
576580   MCFG_CPU_PROGRAM_MAP(valtric_map)
577   MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", argus_state, scanline, "screen", 0, 1)
581   MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", argus_state, argus_scanline, "screen", 0, 1)
578582
579583   MCFG_CPU_ADD("audiocpu", Z80, 5000000)
580584   MCFG_CPU_PROGRAM_MAP(sound_map_a)
r244651r244652
600604   MCFG_SPEAKER_STANDARD_MONO("mono")
601605
602606   MCFG_SOUND_ADD("ym1", YM2203, 6000000 / 4)
603   MCFG_YM2203_IRQ_HANDLER(INPUTLINE("audiocpu", 0))
607   MCFG_YM2203_IRQ_HANDLER(WRITELINE(argus_state, irqhandler))
604608   MCFG_SOUND_ROUTE(0, "mono", 0.15)
605609   MCFG_SOUND_ROUTE(1, "mono", 0.15)
606610   MCFG_SOUND_ROUTE(2, "mono", 0.15)
r244651r244652
644648   MCFG_SPEAKER_STANDARD_MONO("mono")
645649
646650   MCFG_SOUND_ADD("ym1", YM2203, 6000000 / 4)
647   MCFG_YM2203_IRQ_HANDLER(INPUTLINE("audiocpu", 0))
651   MCFG_YM2203_IRQ_HANDLER(WRITELINE(argus_state, irqhandler))
648652   MCFG_SOUND_ROUTE(0, "mono", 0.30)
649653   MCFG_SOUND_ROUTE(1, "mono", 0.30)
650654   MCFG_SOUND_ROUTE(2, "mono", 0.30)
r244651r244652
792796
793797
794798/*  ( YEAR   NAME     PARENT  MACHINE   INPUT     INIT  MONITOR  COMPANY                  FULLNAME ) */
795GAME( 1986, argus,    0,      argus,    argus, driver_device,    0,    ROT270,  "NMK (Jaleco license)", "Argus",                                       GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
796GAME( 1986, valtric,  0,      valtric,  valtric, driver_device,  0,    ROT270,  "NMK (Jaleco license)", "Valtric",                                     GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
797GAME( 1987, butasan,  0,      butasan,  butasan, driver_device,  0,    ROT0,    "NMK (Jaleco license)", "Butasan - Pig's & Bomber's (Japan, English)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
798GAME( 1987, butasanj, butasan,butasan,  butasan, driver_device,  0,    ROT0,    "NMK (Jaleco license)", "Butasan (Japan, Japanese)",                   GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
799GAME( 1986, argus,    0,      argus,    argus, driver_device,    0,    ROT270,  "NMK (Jaleco license)", "Argus",                                       GAME_IMPERFECT_GRAPHICS )
800GAME( 1986, valtric,  0,      valtric,  valtric, driver_device,  0,    ROT270,  "NMK (Jaleco license)", "Valtric",                                     GAME_IMPERFECT_GRAPHICS )
801GAME( 1987, butasan,  0,      butasan,  butasan, driver_device,  0,    ROT0,    "NMK (Jaleco license)", "Butasan - Pig's & Bomber's (Japan, English)", GAME_IMPERFECT_GRAPHICS )
802GAME( 1987, butasanj, butasan,butasan,  butasan, driver_device,  0,    ROT0,    "NMK (Jaleco license)", "Butasan (Japan, Japanese)",                   GAME_IMPERFECT_GRAPHICS )
trunk/src/mame/drivers/capbowl.c
r244651r244652
103103 *
104104 *************************************/
105105
106INTERRUPT_GEN_MEMBER(capbowl_state::interrupt)
106INTERRUPT_GEN_MEMBER(capbowl_state::capbowl_interrupt)
107107{
108108   if (ioport("SERVICE")->read() & 1)                      /* get status of the F2 key */
109109      device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);    /* trigger self test */
r244651r244652
121121{
122122   switch (id)
123123   {
124   case TIMER_UPDATE:
125      update(ptr, param);
124   case TIMER_CAPBOWL_UPDATE:
125      capbowl_update(ptr, param);
126126      break;
127127   default:
128128      assert_always(FALSE, "Unknown id in capbowl_state::device_timer");
r244651r244652
130130}
131131
132132
133TIMER_CALLBACK_MEMBER(capbowl_state::update)
133TIMER_CALLBACK_MEMBER(capbowl_state::capbowl_update)
134134{
135135   int scanline = param;
136136
137137   m_screen->update_partial(scanline - 1);
138138   scanline += 32;
139139   if (scanline > 240) scanline = 32;
140   m_update_timer->adjust(m_screen->time_until_pos(scanline), scanline);
140   timer_set(m_screen->time_until_pos(scanline), TIMER_CAPBOWL_UPDATE, scanline);
141141}
142142
143143
r244651r244652
190190 *
191191 *************************************/
192192
193WRITE8_MEMBER(capbowl_state::sndcmd_w)
193WRITE8_MEMBER(capbowl_state::capbowl_sndcmd_w)
194194{
195195   m_audiocpu->set_input_line(M6809_IRQ_LINE, HOLD_LINE);
196196   soundlatch_byte_w(space, offset, data);
197197}
198198
199199
200
200201/*************************************
201202 *
203 *  Handler called by the 2203 emulator
204 *  when the internal timers cause an IRQ
205 *
206 *************************************/
207
208WRITE_LINE_MEMBER(capbowl_state::firqhandler)
209{
210   m_audiocpu->set_input_line(M6809_FIRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
211}
212
213
214
215/*************************************
216 *
202217 *  Main CPU memory handlers
203218 *
204219 *************************************/
r244651r244652
208223   AM_RANGE(0x4000, 0x4000) AM_WRITEONLY AM_SHARE("rowaddress")
209224   AM_RANGE(0x4800, 0x4800) AM_WRITE(capbowl_rom_select_w)
210225   AM_RANGE(0x5000, 0x57ff) AM_RAM AM_SHARE("nvram")
211   AM_RANGE(0x5800, 0x5fff) AM_READWRITE(tms34061_r, tms34061_w)
212   AM_RANGE(0x6000, 0x6000) AM_WRITE(sndcmd_w)
226   AM_RANGE(0x5800, 0x5fff) AM_READWRITE(capbowl_tms34061_r, capbowl_tms34061_w)
227   AM_RANGE(0x6000, 0x6000) AM_WRITE(capbowl_sndcmd_w)
213228   AM_RANGE(0x6800, 0x6800) AM_WRITE(track_reset_w) AM_READNOP   /* + watchdog */
214229   AM_RANGE(0x7000, 0x7000) AM_READ(track_0_r)         /* + other inputs */
215230   AM_RANGE(0x7800, 0x7800) AM_READ(track_1_r)         /* + other inputs */
r244651r244652
221236   AM_RANGE(0x0000, 0x001f) AM_READWRITE(bowlrama_blitter_r, bowlrama_blitter_w)
222237   AM_RANGE(0x4000, 0x4000) AM_WRITEONLY AM_SHARE("rowaddress")
223238   AM_RANGE(0x5000, 0x57ff) AM_RAM AM_SHARE("nvram")
224   AM_RANGE(0x5800, 0x5fff) AM_READWRITE(tms34061_r, tms34061_w)
225   AM_RANGE(0x6000, 0x6000) AM_WRITE(sndcmd_w)
239   AM_RANGE(0x5800, 0x5fff) AM_READWRITE(capbowl_tms34061_r, capbowl_tms34061_w)
240   AM_RANGE(0x6000, 0x6000) AM_WRITE(capbowl_sndcmd_w)
226241   AM_RANGE(0x6800, 0x6800) AM_WRITE(track_reset_w) AM_READNOP    /* + watchdog */
227242   AM_RANGE(0x7000, 0x7000) AM_READ(track_0_r)         /* + other inputs */
228243   AM_RANGE(0x7800, 0x7800) AM_READ(track_1_r)         /* + other inputs */
r244651r244652
286301
287302/*************************************
288303 *
304 *  TMS34061 interfacing
305 *
306 *************************************/
307
308WRITE_LINE_MEMBER(capbowl_state::generate_tms34061_interrupt)
309{
310   m_maincpu->set_input_line(M6809_FIRQ_LINE, state);
311}
312
313/*************************************
314 *
289315 *  Machine driver
290316 *
291317 *************************************/
292318
293319void capbowl_state::machine_start()
294320{
295   m_update_timer = timer_alloc(TIMER_UPDATE);
296   
297321   save_item(NAME(m_blitter_addr));
298   save_item(NAME(m_last_trackball_val));
322   save_item(NAME(m_last_trackball_val[0]));
323   save_item(NAME(m_last_trackball_val[1]));
299324}
300325
301326void capbowl_state::machine_reset()
302327{
303   m_update_timer->adjust(m_screen->time_until_pos(32), 32);
328   timer_set(m_screen->time_until_pos(32), TIMER_CAPBOWL_UPDATE, 32);
304329
305330   m_blitter_addr = 0;
306331   m_last_trackball_val[0] = 0;
r244651r244652
313338   /* basic machine hardware */
314339   MCFG_CPU_ADD("maincpu", M6809E, MASTER_CLOCK)
315340   MCFG_CPU_PROGRAM_MAP(capbowl_map)
316   MCFG_CPU_VBLANK_INT_DRIVER("screen", capbowl_state,  interrupt)
341   MCFG_CPU_VBLANK_INT_DRIVER("screen", capbowl_state,  capbowl_interrupt)
317342   MCFG_WATCHDOG_TIME_INIT(PERIOD_OF_555_ASTABLE(100000.0, 100000.0, 0.1e-6) * 15.5) // ~0.3s
318343
319344   MCFG_CPU_ADD("audiocpu", M6809E, MASTER_CLOCK)
r244651r244652
329354   MCFG_SCREEN_SIZE(360, 256)
330355   MCFG_SCREEN_VISIBLE_AREA(0, 359, 0, 244)
331356   MCFG_SCREEN_REFRESH_RATE(57)
332   MCFG_SCREEN_UPDATE_DRIVER(capbowl_state, screen_update)
357   MCFG_SCREEN_UPDATE_DRIVER(capbowl_state, screen_update_capbowl)
333358
334359   MCFG_DEVICE_ADD("tms34061", TMS34061, 0)
335360   MCFG_TMS34061_ROWSHIFT(8)  /* VRAM address is (row << rowshift) | col */
336361   MCFG_TMS34061_VRAM_SIZE(0x10000) /* size of video RAM */
337   MCFG_TMS34061_INTERRUPT_CB(INPUTLINE("maincpu", M6809_FIRQ_LINE))      /* interrupt gen callback */
362   MCFG_TMS34061_INTERRUPT_CB(WRITELINE(capbowl_state, generate_tms34061_interrupt))      /* interrupt gen callback */
338363
339364   /* sound hardware */
340365   MCFG_SPEAKER_STANDARD_MONO("mono")
341366
342367   MCFG_SOUND_ADD("ymsnd", YM2203, MASTER_CLOCK/2)
343   MCFG_YM2203_IRQ_HANDLER(INPUTLINE("audiocpu", M6809_FIRQ_LINE))
368   MCFG_YM2203_IRQ_HANDLER(WRITELINE(capbowl_state, firqhandler))
344369   MCFG_AY8910_PORT_A_READ_CB(DEVREAD8("ticket", ticket_dispenser_device, read))
345370   MCFG_AY8910_PORT_B_WRITE_CB(DEVWRITE8("ticket", ticket_dispenser_device, write))  /* Also a status LED. See memory map above */
346371   MCFG_SOUND_ROUTE(0, "mono", 0.07)
r244651r244652
467492 *
468493 *************************************/
469494
470GAME( 1988, capbowl,  0,       capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Capcom Bowling (set 1)", GAME_SUPPORTS_SAVE )
471GAME( 1988, capbowl2, capbowl, capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Capcom Bowling (set 2)", GAME_SUPPORTS_SAVE )
472GAME( 1988, capbowl3, capbowl, capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Capcom Bowling (set 3)", GAME_SUPPORTS_SAVE )
473GAME( 1988, capbowl4, capbowl, capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Capcom Bowling (set 4)", GAME_SUPPORTS_SAVE )
474GAME( 1989, clbowl,   capbowl, capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Coors Light Bowling", GAME_SUPPORTS_SAVE )
475GAME( 1991, bowlrama, 0,       bowlrama, capbowl, driver_device, 0,        ROT270, "P&P Marketing", "Bowl-O-Rama", GAME_SUPPORTS_SAVE )
495GAME( 1988, capbowl,  0,       capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Capcom Bowling (set 1)", 0 )
496GAME( 1988, capbowl2, capbowl, capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Capcom Bowling (set 2)", 0 )
497GAME( 1988, capbowl3, capbowl, capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Capcom Bowling (set 3)", 0 )
498GAME( 1988, capbowl4, capbowl, capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Capcom Bowling (set 4)", 0 )
499GAME( 1989, clbowl,   capbowl, capbowl,  capbowl, capbowl_state, capbowl,  ROT270, "Incredible Technologies / Capcom", "Coors Light Bowling", 0 )
500GAME( 1991, bowlrama, 0,       bowlrama, capbowl, driver_device, 0,        ROT270, "P&P Marketing", "Bowl-O-Rama", 0 )
trunk/src/mame/drivers/fgoal.c
r244651r244652
9898   if (scanline > 256)
9999      scanline = 0;
100100
101   m_interrupt_timer->adjust(m_screen->time_until_pos(scanline));
101   timer_set(m_screen->time_until_pos(scanline), TIMER_INTERRUPT);
102102}
103103
104104
105unsigned fgoal_state::video_ram_address( )
105unsigned fgoal_state::video_ram_address( )
106106{
107107   return 0x4000 | (m_row << 5) | (m_col >> 3);
108108}
109109
110110
111READ8_MEMBER(fgoal_state::analog_r)
111READ8_MEMBER(fgoal_state::fgoal_analog_r)
112112{
113   return ioport(m_player ? "PADDLE1" : "PADDLE0")->read(); /* PCB can be jumpered to use a single dial */
113   return ioport(m_fgoal_player ? "PADDLE1" : "PADDLE0")->read(); /* PCB can be jumpered to use a single dial */
114114}
115115
116116
117CUSTOM_INPUT_MEMBER(fgoal_state::_80_r)
117CUSTOM_INPUT_MEMBER(fgoal_state::fgoal_80_r)
118118{
119119   UINT8 ret = (m_screen->vpos() & 0x80) ? 1 : 0;
120120
121121   return ret;
122122}
123123
124READ8_MEMBER(fgoal_state::nmi_reset_r)
124READ8_MEMBER(fgoal_state::fgoal_nmi_reset_r)
125125{
126126   m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
127127
r244651r244652
129129}
130130
131131
132READ8_MEMBER(fgoal_state::irq_reset_r)
132READ8_MEMBER(fgoal_state::fgoal_irq_reset_r)
133133{
134134   m_maincpu->set_input_line(0, CLEAR_LINE);
135135
r244651r244652
137137}
138138
139139
140READ8_MEMBER(fgoal_state::row_r)
140READ8_MEMBER(fgoal_state::fgoal_row_r)
141141{
142142   return m_row;
143143}
144144
145145
146WRITE8_MEMBER(fgoal_state::row_w)
146WRITE8_MEMBER(fgoal_state::fgoal_row_w)
147147{
148148   m_row = data;
149149   m_mb14241->shift_data_w(space, 0, 0);
150150}
151151
152WRITE8_MEMBER(fgoal_state::col_w)
152WRITE8_MEMBER(fgoal_state::fgoal_col_w)
153153{
154154   m_col = data;
155155   m_mb14241->shift_count_w(space, 0, data);
156156}
157157
158READ8_MEMBER(fgoal_state::address_hi_r)
158READ8_MEMBER(fgoal_state::fgoal_address_hi_r)
159159{
160160   return video_ram_address() >> 8;
161161}
162162
163READ8_MEMBER(fgoal_state::address_lo_r)
163READ8_MEMBER(fgoal_state::fgoal_address_lo_r)
164164{
165165   return video_ram_address() & 0xff;
166166}
167167
168READ8_MEMBER(fgoal_state::shifter_r)
168READ8_MEMBER(fgoal_state::fgoal_shifter_r)
169169{
170170   UINT8 v = m_mb14241->shift_result_r(space, 0);
171171
172172   return BITSWAP8(v, 7, 6, 5, 4, 3, 2, 1, 0);
173173}
174174
175READ8_MEMBER(fgoal_state::shifter_reverse_r)
175READ8_MEMBER(fgoal_state::fgoal_shifter_reverse_r)
176176{
177177   UINT8 v = m_mb14241->shift_result_r(space, 0);
178178
r244651r244652
180180}
181181
182182
183WRITE8_MEMBER(fgoal_state::sound1_w)
183WRITE8_MEMBER(fgoal_state::fgoal_sound1_w)
184184{
185185   /* BIT0 => SX2 */
186186   /* BIT1 => SX1 */
r244651r244652
193193}
194194
195195
196WRITE8_MEMBER(fgoal_state::sound2_w)
196WRITE8_MEMBER(fgoal_state::fgoal_sound2_w)
197197{
198198   /* BIT0 => CX0 */
199199   /* BIT1 => SX6 */
r244651r244652
201201   /* BIT3 => SX5 */
202202   /* BIT4 => SX4 */
203203   /* BIT5 => SX3 */
204   m_player = data & 1;
204   m_fgoal_player = data & 1;
205205}
206206
207207
r244651r244652
209209
210210   AM_RANGE(0x0000, 0x00ef) AM_RAM
211211
212   AM_RANGE(0x00f0, 0x00f0) AM_READ(row_r)
213   AM_RANGE(0x00f1, 0x00f1) AM_READ(analog_r)
212   AM_RANGE(0x00f0, 0x00f0) AM_READ(fgoal_row_r)
213   AM_RANGE(0x00f1, 0x00f1) AM_READ(fgoal_analog_r)
214214   AM_RANGE(0x00f2, 0x00f2) AM_READ_PORT("IN0")
215215   AM_RANGE(0x00f3, 0x00f3) AM_READ_PORT("IN1")
216   AM_RANGE(0x00f4, 0x00f4) AM_READ(address_hi_r)
217   AM_RANGE(0x00f5, 0x00f5) AM_READ(address_lo_r)
218   AM_RANGE(0x00f6, 0x00f6) AM_READ(shifter_r)
219   AM_RANGE(0x00f7, 0x00f7) AM_READ(shifter_reverse_r)
220   AM_RANGE(0x00f8, 0x00fb) AM_READ(nmi_reset_r)
221   AM_RANGE(0x00fc, 0x00ff) AM_READ(irq_reset_r)
216   AM_RANGE(0x00f4, 0x00f4) AM_READ(fgoal_address_hi_r)
217   AM_RANGE(0x00f5, 0x00f5) AM_READ(fgoal_address_lo_r)
218   AM_RANGE(0x00f6, 0x00f6) AM_READ(fgoal_shifter_r)
219   AM_RANGE(0x00f7, 0x00f7) AM_READ(fgoal_shifter_reverse_r)
220   AM_RANGE(0x00f8, 0x00fb) AM_READ(fgoal_nmi_reset_r)
221   AM_RANGE(0x00fc, 0x00ff) AM_READ(fgoal_irq_reset_r)
222222
223   AM_RANGE(0x00f0, 0x00f0) AM_WRITE(row_w)
224   AM_RANGE(0x00f1, 0x00f1) AM_WRITE(col_w)
225   AM_RANGE(0x00f2, 0x00f2) AM_WRITE(row_w)
226   AM_RANGE(0x00f3, 0x00f3) AM_WRITE(col_w)
223   AM_RANGE(0x00f0, 0x00f0) AM_WRITE(fgoal_row_w)
224   AM_RANGE(0x00f1, 0x00f1) AM_WRITE(fgoal_col_w)
225   AM_RANGE(0x00f2, 0x00f2) AM_WRITE(fgoal_row_w)
226   AM_RANGE(0x00f3, 0x00f3) AM_WRITE(fgoal_col_w)
227227   AM_RANGE(0x00f4, 0x00f7) AM_DEVWRITE("mb14241", mb14241_device, shift_data_w)
228   AM_RANGE(0x00f8, 0x00fb) AM_WRITE(sound1_w)
229   AM_RANGE(0x00fc, 0x00ff) AM_WRITE(sound2_w)
228   AM_RANGE(0x00f8, 0x00fb) AM_WRITE(fgoal_sound1_w)
229   AM_RANGE(0x00fc, 0x00ff) AM_WRITE(fgoal_sound2_w)
230230
231231   AM_RANGE(0x0100, 0x03ff) AM_RAM
232232   AM_RANGE(0x4000, 0x7fff) AM_RAM AM_SHARE("video_ram")
233233
234   AM_RANGE(0x8000, 0x8000) AM_WRITE(ypos_w)
235   AM_RANGE(0x8001, 0x8001) AM_WRITE(xpos_w)
236   AM_RANGE(0x8002, 0x8002) AM_WRITE(color_w)
234   AM_RANGE(0x8000, 0x8000) AM_WRITE(fgoal_ypos_w)
235   AM_RANGE(0x8001, 0x8001) AM_WRITE(fgoal_xpos_w)
236   AM_RANGE(0x8002, 0x8002) AM_WRITE(fgoal_color_w)
237237
238238   AM_RANGE(0xa000, 0xbfff) AM_ROM
239239   AM_RANGE(0xd000, 0xffff) AM_ROM
r244651r244652
266266   /* extra credit score changes depending on player's performance */
267267
268268   PORT_START("IN1")
269   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, fgoal_state, _80_r, NULL) /* 128V */
269   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, fgoal_state,fgoal_80_r, NULL) /* 128V */
270270   PORT_DIPNAME( 0x40, 0x00, DEF_STR( Cabinet ))
271271   PORT_DIPSETTING(    0x00, DEF_STR( Upright ))
272272   PORT_DIPSETTING(    0x40, DEF_STR( Cocktail ))
r244651r244652
338338
339339void fgoal_state::machine_start()
340340{
341   m_interrupt_timer = timer_alloc(TIMER_INTERRUPT);
342   
343341   save_item(NAME(m_xpos));
344342   save_item(NAME(m_ypos));
345343   save_item(NAME(m_current_color));
346   save_item(NAME(m_player));
344   save_item(NAME(m_fgoal_player));
347345   save_item(NAME(m_row));
348346   save_item(NAME(m_col));
349347   save_item(NAME(m_prev_coin));
r244651r244652
351349
352350void fgoal_state::machine_reset()
353351{
354   m_interrupt_timer->adjust(m_screen->time_until_pos(0));
352   timer_set(m_screen->time_until_pos(0), TIMER_INTERRUPT);
355353
356354   m_xpos = 0;
357355   m_ypos = 0;
358356   m_current_color = 0;
359   m_player = 0;
357   m_fgoal_player = 0;
360358   m_row = 0;
361359   m_col = 0;
362360   m_prev_coin = 0;
r244651r244652
377375   MCFG_SCREEN_REFRESH_RATE(60)
378376   MCFG_SCREEN_SIZE(256, 263)
379377   MCFG_SCREEN_VISIBLE_AREA(0, 255, 16, 255)
380   MCFG_SCREEN_UPDATE_DRIVER(fgoal_state, screen_update)
378   MCFG_SCREEN_UPDATE_DRIVER(fgoal_state, screen_update_fgoal)
381379   MCFG_SCREEN_PALETTE("palette")
382380
383381   MCFG_GFXDECODE_ADD("gfxdecode", "palette", fgoal)
r244651r244652
435433ROM_END
436434
437435
438GAME( 1979, fgoal,  0,     fgoal, fgoal, driver_device, 0, ROT90, "Taito", "Field Goal (set 1)", GAME_NO_SOUND | GAME_SUPPORTS_SAVE )
439GAME( 1979, fgoala, fgoal, fgoal, fgoal, driver_device, 0, ROT90, "Taito", "Field Goal (set 2)", GAME_NO_SOUND | GAME_SUPPORTS_SAVE )
436GAME( 1979, fgoal,  0,     fgoal, fgoal, driver_device, 0, ROT90, "Taito", "Field Goal (set 1)", GAME_NO_SOUND )
437GAME( 1979, fgoala, fgoal, fgoal, fgoal, driver_device, 0, ROT90, "Taito", "Field Goal (set 2)", GAME_NO_SOUND )
trunk/src/mame/drivers/ssv.c
r244651r244652
179179   m_maincpu->set_input_line(0, (m_requested_int & m_irq_enable)? ASSERT_LINE : CLEAR_LINE);
180180}
181181
182IRQ_CALLBACK_MEMBER(ssv_state::irq_callback)
182IRQ_CALLBACK_MEMBER(ssv_state::ssv_irq_callback)
183183{
184184   int i;
185185   for ( i = 0; i <= 7; i++ )
r244651r244652
193193   return 0;
194194}
195195
196WRITE16_MEMBER(ssv_state::irq_ack_w)
196WRITE16_MEMBER(ssv_state::ssv_irq_ack_w)
197197{
198198   int level = ((offset * 2) & 0x70) >> 4;
199199
r244651r244652
220220    ultrax:     40,00 at the start then 42,4a
221221    twineag2:   40,00 at the start then 42,4a
222222*/
223WRITE16_MEMBER(ssv_state::irq_enable_w)
223WRITE16_MEMBER(ssv_state::ssv_irq_enable_w)
224224{
225225   COMBINE_DATA(&m_irq_enable);
226226}
227227
228TIMER_DEVICE_CALLBACK_MEMBER(ssv_state::interrupt)
228TIMER_DEVICE_CALLBACK_MEMBER(ssv_state::ssv_interrupt)
229229{
230230   int scanline = param;
231231
r244651r244652
283283    survarts:   83
284284    sxyreact:   80
285285*/
286WRITE16_MEMBER(ssv_state::lockout_w)
286WRITE16_MEMBER(ssv_state::ssv_lockout_w)
287287{
288288//  popmessage("%02X",data & 0xff);
289289   if (ACCESSING_BITS_0_7)
r244651r244652
293293      coin_counter_w(machine(), 1, data & 0x04);
294294      coin_counter_w(machine(), 0, data & 0x08);
295295//                        data & 0x40?
296      enable_video(data & 0x80);
296      ssv_enable_video(data & 0x80);
297297   }
298298}
299299
300300/* Same as above but with inverted lockout lines */
301WRITE16_MEMBER(ssv_state::lockout_inv_w)
301WRITE16_MEMBER(ssv_state::ssv_lockout_inv_w)
302302{
303303//  popmessage("%02X",data & 0xff);
304304   if (ACCESSING_BITS_0_7)
r244651r244652
308308      coin_counter_w(machine(), 1, data & 0x04);
309309      coin_counter_w(machine(), 0, data & 0x08);
310310//                        data & 0x40?
311      enable_video(data & 0x80);
311      ssv_enable_video(data & 0x80);
312312   }
313313}
314314
r244651r244652
396396   AM_RANGE(0x100000, 0x13ffff) AM_RAM AM_SHARE("spriteram")                                       /*  Sprites */  \
397397   AM_RANGE(0x140000, 0x15ffff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") /* Palette */\
398398   AM_RANGE(0x160000, 0x17ffff) AM_RAM                                                             /*          */  \
399   AM_RANGE(0x1c0000, 0x1c0001) AM_READ(vblank_r           )                                   /*  Vblank? */  \
399   AM_RANGE(0x1c0000, 0x1c0001) AM_READ(ssv_vblank_r           )                                   /*  Vblank? */  \
400400/**/AM_RANGE(0x1c0002, 0x1c007f) AM_READONLY                                    /*  Scroll  */  \
401   AM_RANGE(0x1c0000, 0x1c007f) AM_WRITE(scroll_w) AM_SHARE("scroll")                  /*  Scroll  */  \
401   AM_RANGE(0x1c0000, 0x1c007f) AM_WRITE(ssv_scroll_w) AM_SHARE("scroll")                  /*  Scroll  */  \
402402   AM_RANGE(0x210002, 0x210003) AM_READ_PORT("DSW1")                                                               \
403403   AM_RANGE(0x210004, 0x210005) AM_READ_PORT("DSW2")                                                               \
404404   AM_RANGE(0x210008, 0x210009) AM_READ_PORT("P1")                                                                 \
405405   AM_RANGE(0x21000a, 0x21000b) AM_READ_PORT("P2")                                                                 \
406406   AM_RANGE(0x21000c, 0x21000d) AM_READ_PORT("SYSTEM")                                                             \
407   AM_RANGE(0x21000e, 0x21000f) AM_READNOP AM_WRITE(lockout_w)                             /*  Lockout */  \
407   AM_RANGE(0x21000e, 0x21000f) AM_READNOP AM_WRITE(ssv_lockout_w)                             /*  Lockout */  \
408408   AM_RANGE(0x210010, 0x210011) AM_WRITENOP                                                                        \
409409   AM_RANGE(0x230000, 0x230071) AM_WRITEONLY AM_SHARE("irq_vectors")                       /*  IRQ Vec */  \
410   AM_RANGE(0x240000, 0x240071) AM_WRITE(irq_ack_w )                                           /*  IRQ Ack */  \
411   AM_RANGE(0x260000, 0x260001) AM_WRITE(irq_enable_w)                                         /*  IRQ En  */  \
410   AM_RANGE(0x240000, 0x240071) AM_WRITE(ssv_irq_ack_w )                                           /*  IRQ Ack */  \
411   AM_RANGE(0x260000, 0x260001) AM_WRITE(ssv_irq_enable_w)                                         /*  IRQ En  */  \
412412   AM_RANGE(0x300000, 0x30007f) AM_DEVREADWRITE8("ensoniq", es5506_device, read, write, 0x00ff)    /*  Sound   */  \
413413   AM_RANGE(_ROM, 0xffffff) AM_ROM AM_REGION("maincpu", 0)                                         /*  ROM     */
414414/***************************************************************************
r244651r244652
513513static ADDRESS_MAP_START( hypreact_map, AS_PROGRAM, 16, ssv_state )
514514   AM_RANGE(0x210000, 0x210001) AM_READ(watchdog_reset16_r)            // Watchdog
515515//  AM_RANGE(0x210002, 0x210003) AM_WRITENOP                      // ? 5 at the start
516   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(lockout_inv_w)            // Inverted lockout lines
516   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(ssv_lockout_inv_w)            // Inverted lockout lines
517517//  AM_RANGE(0x280000, 0x280001) AM_READNOP                       // ? read at the start, value not used
518518   AM_RANGE(0xc00000, 0xc00001) AM_READ(hypreact_input_r)              // Inputs
519519   AM_RANGE(0xc00006, 0xc00007) AM_RAM AM_SHARE("input_sel")           //
r244651r244652
529529static ADDRESS_MAP_START( hypreac2_map, AS_PROGRAM, 16, ssv_state )
530530   AM_RANGE(0x210000, 0x210001) AM_READ(watchdog_reset16_r)                // Watchdog
531531//  AM_RANGE(0x210002, 0x210003) AM_WRITENOP                          // ? 5 at the start
532   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(lockout_inv_w)                // Inverted lockout lines
532   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(ssv_lockout_inv_w)                // Inverted lockout lines
533533//  AM_RANGE(0x280000, 0x280001) AM_READNOP                           // ? read at the start, value not used
534534   AM_RANGE(0x500000, 0x500001) AM_READ(hypreact_input_r)                  // Inputs
535535   AM_RANGE(0x500002, 0x500003) AM_READ(hypreact_input_r)                  // (again?)
r244651r244652
587587
588588/* Monster Slider needs the RAM mirrored for the gameplay logic to work correctly */
589589
590READ16_MEMBER(ssv_state::mainram_r)
590READ16_MEMBER(ssv_state::ssv_mainram_r)
591591{
592592   return m_mainram[offset];
593593}
594594
595WRITE16_MEMBER(ssv_state::mainram_w)
595WRITE16_MEMBER(ssv_state::ssv_mainram_w)
596596{
597597   COMBINE_DATA(&m_mainram[offset]);
598598}
599599
600600static ADDRESS_MAP_START( mslider_map, AS_PROGRAM, 16, ssv_state )
601   AM_RANGE(0x010000, 0x01ffff) AM_READWRITE(mainram_r, mainram_w) // RAM Mirror
601   AM_RANGE(0x010000, 0x01ffff) AM_READWRITE(ssv_mainram_r, ssv_mainram_w) // RAM Mirror
602602//  AM_RANGE(0x210002, 0x210003) AM_WRITENOP                          // ? 1 at the start
603603   AM_RANGE(0x400000, 0x47ffff) AM_WRITEONLY                           // ?
604604//  AM_RANGE(0x500000, 0x500001) AM_WRITENOP                          // ? ff at the start
r244651r244652
684684   AM_RANGE(0x010000, 0x050faf) AM_RAM                                     // More RAM
685685   AM_RANGE(0x210000, 0x210001) AM_READ(watchdog_reset16_r)                // Watchdog
686686//  AM_RANGE(0x210002, 0x210003) AM_WRITENOP                          // ? 0,4 at the start
687   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(lockout_inv_w)                // Coin Counters / Lockouts
687   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(ssv_lockout_inv_w)                // Coin Counters / Lockouts
688688   AM_RANGE(0x300076, 0x300077) AM_READ(srmp7_irqv_r)                      // Sound
689689//  0x540000, 0x540003, related to lev 5 irq?
690690   AM_RANGE(0x580000, 0x580001) AM_WRITE(srmp7_sound_bank_w)               // Sound Bank
r244651r244652
751751}
752752
753753static ADDRESS_MAP_START( sxyreact_map, AS_PROGRAM, 16, ssv_state )
754//  AM_RANGE(0x020000, 0x03ffff) AM_READWRITE(mainram_r, mainram_w)             // sxyreac2 reads / writes here, why?
754//  AM_RANGE(0x020000, 0x03ffff) AM_READWRITE(ssv_mainram_r, ssv_mainram_w)             // sxyreac2 reads / writes here, why?
755755   AM_RANGE(0x210000, 0x210001) AM_READ(watchdog_reset16_r)                            // Watchdog
756756//  AM_RANGE(0x210002, 0x210003) AM_WRITENOP                                      // ? 1 at the start
757   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(lockout_inv_w)                            // Inverted lockout lines
757   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(ssv_lockout_inv_w)                            // Inverted lockout lines
758758   AM_RANGE(0x500002, 0x500003) AM_READ(sxyreact_ballswitch_r)                         // ?
759759   AM_RANGE(0x500004, 0x500005) AM_READWRITE(sxyreact_dial_r, sxyreact_motor_w)        // Dial Value (serial)
760760   AM_RANGE(0x520000, 0x520001) AM_WRITE(sxyreact_dial_w)                              // Dial Value (advance 1 bit)
r244651r244652
828828}
829829
830830static ADDRESS_MAP_START( jsk_map, AS_PROGRAM, 16, ssv_state )
831   AM_RANGE(0x050000, 0x05ffff) AM_READWRITE(mainram_r, mainram_w) // RAM Mirror?
831   AM_RANGE(0x050000, 0x05ffff) AM_READWRITE(ssv_mainram_r, ssv_mainram_w) // RAM Mirror?
832832   AM_RANGE(0x210000, 0x210001) AM_WRITE(watchdog_reset16_w)               // Watchdog
833833   AM_RANGE(0x400000, 0x47ffff) AM_RAM                                     // RAM?
834834   AM_RANGE(0x900000, 0x900007) AM_READWRITE(latch16_r, latch16_w)
r244651r244652
898898   AM_RANGE(0x180000, 0x1bffff) AM_READWRITE(eaglshot_gfxram_r, eaglshot_gfxram_w)
899899   AM_RANGE(0x210000, 0x210001) AM_READNOP /*AM_READ(watchdog_reset16_r)*/                 // Watchdog
900900//  AM_RANGE(0x210002, 0x210003) AM_WRITENOP                                      // ? 0,4 at the start
901   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(lockout_inv_w)                            // Inverted lockout lines
901   AM_RANGE(0x21000e, 0x21000f) AM_WRITE(ssv_lockout_inv_w)                            // Inverted lockout lines
902902   AM_RANGE(0x800000, 0x800001) AM_WRITE(eaglshot_gfxrom_bank_w)
903903   AM_RANGE(0x900000, 0x900001) AM_WRITE(eaglshot_trackball_w)
904904   AM_RANGE(0xa00000, 0xbfffff) AM_ROMBANK("gfxrom")
r244651r244652
24812481
24822482***************************************************************************/
24832483
2484void ssv_state::init(int interrupt_ultrax)
2484void ssv_state::init_ssv(int interrupt_ultrax)
24852485{
24862486   int i;
24872487   for (i = 0; i < 16; i++)
r244651r244652
24892489                        ( (i & 4) ? (2 << 16) : 0 ) +
24902490                        ( (i & 2) ? (4 << 16) : 0 ) +
24912491                        ( (i & 1) ? (8 << 16) : 0 ) ;
2492   enable_video(1);
2492   ssv_enable_video(1);
24932493   m_interrupt_ultrax = interrupt_ultrax;
2494   
2495   save_item(NAME(m_requested_int));
2496   save_item(NAME(m_irq_enable));
24972494}
24982495
24992496void ssv_state::init_hypreac2_common()
r244651r244652
25312528   }
25322529}
25332530
2534DRIVER_INIT_MEMBER(ssv_state,drifto94)     {    init(0); init_st010();  }
2535DRIVER_INIT_MEMBER(ssv_state,eaglshot)     {    init(0); init_eaglshot_banking(); save_item(NAME(m_trackball_select)); }
2536DRIVER_INIT_MEMBER(ssv_state,gdfs)         {    init(0); save_item(NAME(m_gdfs_lightgun_select)); save_item(NAME(m_gdfs_eeprom_old)); }
2537DRIVER_INIT_MEMBER(ssv_state,hypreact)     {    init(0); }
2538DRIVER_INIT_MEMBER(ssv_state,hypreac2)     {    init(0); init_hypreac2_common();    }
2539DRIVER_INIT_MEMBER(ssv_state,janjans1)     {    init(0); }
2540DRIVER_INIT_MEMBER(ssv_state,keithlcy)     {    init(0); }
2541DRIVER_INIT_MEMBER(ssv_state,meosism)       {   init(0); }
2542DRIVER_INIT_MEMBER(ssv_state,mslider)       {   init(0); }
2543DRIVER_INIT_MEMBER(ssv_state,ryorioh)       {   init(0); }
2544DRIVER_INIT_MEMBER(ssv_state,srmp4)        {    init(0);
2531DRIVER_INIT_MEMBER(ssv_state,drifto94)     {    init_ssv(0); init_st010();  }
2532DRIVER_INIT_MEMBER(ssv_state,eaglshot)     {    init_ssv(0); init_eaglshot_banking();    }
2533DRIVER_INIT_MEMBER(ssv_state,gdfs)         {    init_ssv(0); }
2534DRIVER_INIT_MEMBER(ssv_state,hypreact)     {    init_ssv(0); }
2535DRIVER_INIT_MEMBER(ssv_state,hypreac2)     {    init_ssv(0); init_hypreac2_common();    }
2536DRIVER_INIT_MEMBER(ssv_state,janjans1)     {    init_ssv(0); }
2537DRIVER_INIT_MEMBER(ssv_state,keithlcy)     {    init_ssv(0); }
2538DRIVER_INIT_MEMBER(ssv_state,meosism)       {   init_ssv(0); }
2539DRIVER_INIT_MEMBER(ssv_state,mslider)       {   init_ssv(0); }
2540DRIVER_INIT_MEMBER(ssv_state,ryorioh)       {   init_ssv(0); }
2541DRIVER_INIT_MEMBER(ssv_state,srmp4)        {    init_ssv(0);
25452542//  ((UINT16 *)memregion("maincpu")->base())[0x2b38/2] = 0x037a;   /* patch to see gal test mode */
25462543}
2547DRIVER_INIT_MEMBER(ssv_state,srmp7)        {    init(0); }
2548DRIVER_INIT_MEMBER(ssv_state,stmblade)     {    init(0); init_st010(); }
2549DRIVER_INIT_MEMBER(ssv_state,survarts)     {    init(0); }
2550DRIVER_INIT_MEMBER(ssv_state,dynagear)     {    init(0); }
2551DRIVER_INIT_MEMBER(ssv_state,sxyreact)     {    init(0); init_hypreac2_common();  save_item(NAME(m_sxyreact_serial)); save_item(NAME(m_sxyreact_dial)); }
2552DRIVER_INIT_MEMBER(ssv_state,cairblad)     {    init(0); init_hypreac2_common();    }
2553DRIVER_INIT_MEMBER(ssv_state,sxyreac2)     {    init(0); init_hypreac2_common();  save_item(NAME(m_sxyreact_serial)); save_item(NAME(m_sxyreact_dial)); }
2554DRIVER_INIT_MEMBER(ssv_state,twineag2)     {    init(1); init_st010();  }
2555DRIVER_INIT_MEMBER(ssv_state,ultrax)        {   init(1); }
2556DRIVER_INIT_MEMBER(ssv_state,vasara)        {   init(0); }
2557DRIVER_INIT_MEMBER(ssv_state,jsk)          {    init(0); save_item(NAME(m_latches)); }
2544DRIVER_INIT_MEMBER(ssv_state,srmp7)        {    init_ssv(0); }
2545DRIVER_INIT_MEMBER(ssv_state,stmblade)     {    init_ssv(0); init_st010(); }
2546DRIVER_INIT_MEMBER(ssv_state,survarts)     {    init_ssv(0); }
2547DRIVER_INIT_MEMBER(ssv_state,dynagear)     {    init_ssv(0); }
2548DRIVER_INIT_MEMBER(ssv_state,sxyreact)     {    init_ssv(0); init_hypreac2_common();    }
2549DRIVER_INIT_MEMBER(ssv_state,cairblad)     {    init_ssv(0); init_hypreac2_common();    }
2550DRIVER_INIT_MEMBER(ssv_state,sxyreac2)     {    init_ssv(0); init_hypreac2_common();    }
2551DRIVER_INIT_MEMBER(ssv_state,twineag2)     {    init_ssv(1); init_st010();  }
2552DRIVER_INIT_MEMBER(ssv_state,ultrax)        {   init_ssv(1); }
2553DRIVER_INIT_MEMBER(ssv_state,vasara)        {   init_ssv(0); }
2554DRIVER_INIT_MEMBER(ssv_state,jsk)          {    init_ssv(0); }
25582555
25592556#define SSV_MASTER_CLOCK XTAL_48MHz/3
25602557
r244651r244652
25702567
25712568   /* basic machine hardware */
25722569   MCFG_CPU_ADD("maincpu", V60, SSV_MASTER_CLOCK) /* Based on STA-0001 & STA-0001B System boards */
2573   MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(ssv_state,irq_callback)
2570   MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(ssv_state,ssv_irq_callback)
25742571
2575   MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", ssv_state, interrupt, "screen", 0, 1)
2572   MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", ssv_state, ssv_interrupt, "screen", 0, 1)
25762573
25772574   /* video hardware */
25782575   MCFG_SCREEN_ADD("screen", RASTER)
25792576   MCFG_SCREEN_RAW_PARAMS(SSV_PIXEL_CLOCK,SSV_HTOTAL,SSV_HBEND,SSV_HBSTART,SSV_VTOTAL,SSV_VBEND,SSV_VBSTART)
2580   MCFG_SCREEN_UPDATE_DRIVER(ssv_state, screen_update)
2577   MCFG_SCREEN_UPDATE_DRIVER(ssv_state, screen_update_ssv)
25812578   MCFG_SCREEN_PALETTE("palette")
25822579
25832580   MCFG_GFXDECODE_ADD("gfxdecode", "palette", ssv)
r244651r244652
47094706
47104707//     year   rom       clone     machine   inputs    init      monitor manufacturer          title                                               flags
47114708
4712GAME( 1993,  dynagear,  0,        dynagear, dynagear, ssv_state, dynagear, ROT0,   "Sammy",              "Dyna Gear",                                                              GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
4709GAME( 1993,  dynagear,  0,        dynagear, dynagear, ssv_state, dynagear, ROT0,   "Sammy",              "Dyna Gear",                                                              GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS )
47134710
4714GAME( 1993,  keithlcy,  0,        keithlcy, keithlcy, ssv_state, keithlcy, ROT0,   "Visco",              "Dramatic Adventure Quiz Keith & Lucy (Japan)",                           GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4711GAME( 1993,  keithlcy,  0,        keithlcy, keithlcy, ssv_state, keithlcy, ROT0,   "Visco",              "Dramatic Adventure Quiz Keith & Lucy (Japan)",                           GAME_NO_COCKTAIL )
47154712
4716GAME( 1993,  srmp4,     0,        srmp4,    srmp4,    ssv_state, srmp4,    ROT0,   "Seta",               "Super Real Mahjong PIV (Japan)",                                         GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4717GAME( 1993,  srmp4o,    srmp4,    srmp4,    srmp4,    ssv_state, srmp4,    ROT0,   "Seta",               "Super Real Mahjong PIV (Japan, older set)",                              GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE ) // by the numbering of the program roms this should be older
4713GAME( 1993,  srmp4,     0,        srmp4,    srmp4,    ssv_state, srmp4,    ROT0,   "Seta",               "Super Real Mahjong PIV (Japan)",                                         GAME_NO_COCKTAIL )
4714GAME( 1993,  srmp4o,    srmp4,    srmp4,    srmp4,    ssv_state, srmp4,    ROT0,   "Seta",               "Super Real Mahjong PIV (Japan, older set)",                              GAME_NO_COCKTAIL ) // by the numbering of the program roms this should be older
47184715
4719GAME( 1993,  survarts,  0,        survarts, survarts, ssv_state, survarts, ROT0,   "Sammy",              "Survival Arts (World)",                                                  GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4720GAME( 1993,  survartsu, survarts, survarts, survarts, ssv_state, survarts, ROT0,   "American Sammy",     "Survival Arts (USA)",                                                    GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4721GAME( 1993,  survartsj, survarts, survarts, survarts, ssv_state, survarts, ROT0,   "Sammy",              "Survival Arts (Japan)",                                                  GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4716GAME( 1993,  survarts,  0,        survarts, survarts, ssv_state, survarts, ROT0,   "Sammy",              "Survival Arts (World)",                                                  GAME_NO_COCKTAIL )
4717GAME( 1993,  survartsu, survarts, survarts, survarts, ssv_state, survarts, ROT0,   "American Sammy",     "Survival Arts (USA)",                                                    GAME_NO_COCKTAIL )
4718GAME( 1993,  survartsj, survarts, survarts, survarts, ssv_state, survarts, ROT0,   "Sammy",              "Survival Arts (Japan)",                                                  GAME_NO_COCKTAIL )
47224719
4723GAME( 1994,  drifto94,  0,        drifto94, drifto94, ssv_state, drifto94, ROT0,   "Visco",              "Drift Out '94 - The Hard Order (Japan)",                                 GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4720GAME( 1994,  drifto94,  0,        drifto94, drifto94, ssv_state, drifto94, ROT0,   "Visco",              "Drift Out '94 - The Hard Order (Japan)",                                 GAME_NO_COCKTAIL )
47244721
4725GAME( 1994,  eaglshot,  0,        eaglshot, eaglshot, ssv_state, eaglshot, ROT0,   "Sammy",              "Eagle Shot Golf",                                                        GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
4722GAME( 1994,  eaglshot,  0,        eaglshot, eaglshot, ssv_state, eaglshot, ROT0,   "Sammy",              "Eagle Shot Golf",                                                        GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS )
47264723
4727GAME( 1995,  hypreact,  0,        hypreact, hypreact, ssv_state, hypreact, ROT0,   "Sammy",              "Mahjong Hyper Reaction (Japan)",                                         GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4724GAME( 1995,  hypreact,  0,        hypreact, hypreact, ssv_state, hypreact, ROT0,   "Sammy",              "Mahjong Hyper Reaction (Japan)",                                         GAME_NO_COCKTAIL )
47284725
4729GAME( 1994,  twineag2,  0,        twineag2, twineag2, ssv_state, twineag2, ROT270, "Seta",               "Twin Eagle II - The Rescue Mission",                                     GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4726GAME( 1994,  twineag2,  0,        twineag2, twineag2, ssv_state, twineag2, ROT270, "Seta",               "Twin Eagle II - The Rescue Mission",                                     GAME_NO_COCKTAIL )
47304727
4731GAME( 1995,  gdfs,      0,        gdfs,     gdfs,     ssv_state, gdfs,     ROT0,   "Banpresto",          "Mobil Suit Gundam Final Shooting (Japan)",                               GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4728GAME( 1995,  gdfs,      0,        gdfs,     gdfs,     ssv_state, gdfs,     ROT0,   "Banpresto",          "Mobil Suit Gundam Final Shooting (Japan)",                               GAME_NO_COCKTAIL )
47324729
4733GAME( 1995,  ultrax,    0,        ultrax,   ultrax,   ssv_state, ultrax,   ROT270, "Banpresto / Tsuburaya Productions", "Ultra X Weapons / Ultra Keibitai",                        GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE ) // 95-01-30 13:27:15 on startup
4734GAME( 1995,  ultraxg,   ultrax,   ultrax,   ultrax,   ssv_state, ultrax,   ROT270, "Banpresto / Tsuburaya Productions", "Ultra X Weapons / Ultra Keibitai (GAMEST review build)",  GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE ) // 95-02-16 15:30:24 on startup (newer, but could have pause functionality due to being a review build so left as clone)
4730GAME( 1995,  ultrax,    0,        ultrax,   ultrax,   ssv_state, ultrax,   ROT270, "Banpresto / Tsuburaya Productions", "Ultra X Weapons / Ultra Keibitai",                        GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS ) // 95-01-30 13:27:15 on startup
4731GAME( 1995,  ultraxg,   ultrax,   ultrax,   ultrax,   ssv_state, ultrax,   ROT270, "Banpresto / Tsuburaya Productions", "Ultra X Weapons / Ultra Keibitai (GAMEST review build)",  GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS ) // 95-02-16 15:30:24 on startup (newer, but could have pause functionality due to being a review build so left as clone)
47354732
4736GAME( 1996,  janjans1,  0,        janjans1, janjans1, ssv_state, janjans1, ROT0,   "Visco",              "Lovely Pop Mahjong JangJang Shimasho (Japan)",                           GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
4733GAME( 1996,  janjans1,  0,        janjans1, janjans1, ssv_state, janjans1, ROT0,   "Visco",              "Lovely Pop Mahjong JangJang Shimasho (Japan)",                           GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS )
47374734
4738GAME( 1996?, meosism,   0,        meosism,  meosism,  ssv_state, meosism,  ROT0,   "Sammy",              "Meosis Magic (Japan)",                                                   GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4735GAME( 1996?, meosism,   0,        meosism,  meosism,  ssv_state, meosism,  ROT0,   "Sammy",              "Meosis Magic (Japan)",                                                   GAME_NO_COCKTAIL )
47394736
4740GAME( 1996,  stmblade,  0,        stmblade, stmblade, ssv_state, stmblade, ROT270, "Visco",              "Storm Blade (US)",                                                       GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
4741GAME( 1996,  stmbladej, stmblade, stmblade, stmblade, ssv_state, stmblade, ROT270, "Visco",              "Storm Blade (Japan)",                                                    GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
4737GAME( 1996,  stmblade,  0,        stmblade, stmblade, ssv_state, stmblade, ROT270, "Visco",              "Storm Blade (US)",                                                       GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS )
4738GAME( 1996,  stmbladej, stmblade, stmblade, stmblade, ssv_state, stmblade, ROT270, "Visco",              "Storm Blade (Japan)",                                                    GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS )
47424739
4743GAME( 1997,  hypreac2,  0,        hypreac2, hypreac2, ssv_state, hypreac2, ROT0,   "Sammy",              "Mahjong Hyper Reaction 2 (Japan)",                                       GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4740GAME( 1997,  hypreac2,  0,        hypreac2, hypreac2, ssv_state, hypreac2, ROT0,   "Sammy",              "Mahjong Hyper Reaction 2 (Japan)",                                       GAME_NO_COCKTAIL )
47444741
4745GAME( 1997,  jsk,       0,        jsk,      jsk,      ssv_state, jsk,      ROT0,   "Visco",              "Joryuu Syougi Kyoushitsu (Japan)",                                       GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4742GAME( 1997,  jsk,       0,        jsk,      jsk,      ssv_state, jsk,      ROT0,   "Visco",              "Joryuu Syougi Kyoushitsu (Japan)",                                       GAME_NO_COCKTAIL )
47464743
4747GAME( 1997,  koikois2,  0,        janjans1, koikois2, ssv_state, janjans1, ROT0,   "Visco",              "Koi Koi Shimasho 2 - Super Real Hanafuda (Japan)",                       GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4744GAME( 1997,  koikois2,  0,        janjans1, koikois2, ssv_state, janjans1, ROT0,   "Visco",              "Koi Koi Shimasho 2 - Super Real Hanafuda (Japan)",                       GAME_NO_COCKTAIL )
47484745
4749GAME( 1997,  mslider,   0,        mslider,  mslider,  ssv_state, mslider,  ROT0,   "Visco / Datt Japan", "Monster Slider (Japan)",                                                 GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4746GAME( 1997,  mslider,   0,        mslider,  mslider,  ssv_state, mslider,  ROT0,   "Visco / Datt Japan", "Monster Slider (Japan)",                                                 GAME_NO_COCKTAIL )
47504747
4751GAME( 1997,  srmp7,     0,        srmp7,    srmp7,    ssv_state, srmp7,    ROT0,   "Seta",               "Super Real Mahjong P7 (Japan)",                                          GAME_NO_COCKTAIL | GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
4748GAME( 1997,  srmp7,     0,        srmp7,    srmp7,    ssv_state, srmp7,    ROT0,   "Seta",               "Super Real Mahjong P7 (Japan)",                                          GAME_NO_COCKTAIL | GAME_IMPERFECT_SOUND )
47524749
4753GAME( 1998,  ryorioh,   0,        ryorioh,  ryorioh,  ssv_state, ryorioh,  ROT0,   "Visco",              "Gourmet Battle Quiz Ryohrioh CooKing (Japan)",                           GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4750GAME( 1998,  ryorioh,   0,        ryorioh,  ryorioh,  ssv_state, ryorioh,  ROT0,   "Visco",              "Gourmet Battle Quiz Ryohrioh CooKing (Japan)",                           GAME_NO_COCKTAIL )
47544751
4755GAME( 1998,  sxyreact,  0,        sxyreact, sxyreact, ssv_state, sxyreact, ROT0,   "Sammy",              "Pachinko Sexy Reaction (Japan)",                                         GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4752GAME( 1998,  sxyreact,  0,        sxyreact, sxyreact, ssv_state, sxyreact, ROT0,   "Sammy",              "Pachinko Sexy Reaction (Japan)",                                         GAME_NO_COCKTAIL )
47564753
4757GAME( 1999,  sxyreac2,  0,        sxyreac2, sxyreact, ssv_state, sxyreac2, ROT0,   "Sammy",              "Pachinko Sexy Reaction 2 (Japan)",                                       GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4754GAME( 1999,  sxyreac2,  0,        sxyreac2, sxyreact, ssv_state, sxyreac2, ROT0,   "Sammy",              "Pachinko Sexy Reaction 2 (Japan)",                                       GAME_NO_COCKTAIL )
47584755
4759GAME( 1999,  cairblad,  0,        cairblad, cairblad, ssv_state, cairblad, ROT270, "Sammy",              "Change Air Blade (Japan)",                                               GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4756GAME( 1999,  cairblad,  0,        cairblad, cairblad, ssv_state, cairblad, ROT270, "Sammy",              "Change Air Blade (Japan)",                                               GAME_NO_COCKTAIL )
47604757
4761GAME( 2000,  janjans2,  0,        janjans1, janjans2, ssv_state, janjans1, ROT0,   "Visco",              "Lovely Pop Mahjong JangJang Shimasho 2 (Japan)",                         GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
4758GAME( 2000,  janjans2,  0,        janjans1, janjans2, ssv_state, janjans1, ROT0,   "Visco",              "Lovely Pop Mahjong JangJang Shimasho 2 (Japan)",                         GAME_NO_COCKTAIL | GAME_IMPERFECT_GRAPHICS )
47624759
4763GAME( 2000,  vasara,    0,        vasara,   vasara,   ssv_state, vasara,   ROT270, "Visco",              "Vasara",                                                                 GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4760GAME( 2000,  vasara,    0,        vasara,   vasara,   ssv_state, vasara,   ROT270, "Visco",              "Vasara",                                                                 GAME_NO_COCKTAIL )
47644761
4765GAME( 2001,  vasara2,   0,        vasara,   vasara2,  ssv_state, vasara,   ROT270, "Visco",              "Vasara 2 (set 1)",                                                       GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4766GAME( 2001,  vasara2a,  vasara2,  vasara,   vasara2,  ssv_state, vasara,   ROT270, "Visco",              "Vasara 2 (set 2)",                                                       GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
4762GAME( 2001,  vasara2,   0,        vasara,   vasara2,  ssv_state, vasara,   ROT270, "Visco",              "Vasara 2 (set 1)",                                                       GAME_NO_COCKTAIL )
4763GAME( 2001,  vasara2a,  vasara2,  vasara,   vasara2,  ssv_state, vasara,   ROT270, "Visco",              "Vasara 2 (set 2)",                                                       GAME_NO_COCKTAIL )
trunk/src/mame/drivers/tugboat.c
r244651r244652
1111  but the current implementation is a big kludge, and it still looks wrong.
1212- colors might not be entirely accurate
1313  Suspect berenstn is using the wrong color PROM.
14- convert to use the H46505 device.
1514
1615the problem which caused the controls not to work
1716---
r244651r244652
4039   tugboat_state(const machine_config &mconfig, device_type type, const char *tag)
4140      : driver_device(mconfig, type, tag),
4241      m_maincpu(*this, "maincpu"),
42      m_ram(*this, "ram"),
4343      m_gfxdecode(*this, "gfxdecode"),
4444      m_screen(*this, "screen"),
45      m_palette(*this, "palette"),
46      m_ram(*this, "ram") { }
45      m_palette(*this, "palette") { }
4746
4847   required_device<cpu_device> m_maincpu;
48   required_shared_ptr<UINT8> m_ram;
4949   required_device<gfxdecode_device> m_gfxdecode;
5050   required_device<screen_device> m_screen;
5151   required_device<palette_device> m_palette;
52   
53   required_shared_ptr<UINT8> m_ram;
5452
5553   UINT8 m_hd46505_0_reg[18];
5654   UINT8 m_hd46505_1_reg[18];
5755   int m_reg0;
5856   int m_reg1;
5957   int m_ctrl;
60   emu_timer *m_interrupt_timer;
61   
62   DECLARE_WRITE8_MEMBER(hd46505_0_w);
63   DECLARE_WRITE8_MEMBER(hd46505_1_w);
64   DECLARE_WRITE8_MEMBER(score_w);
65   DECLARE_READ8_MEMBER(input_r);
66   DECLARE_WRITE8_MEMBER(ctrl_w);
67   
58   DECLARE_WRITE8_MEMBER(tugboat_hd46505_0_w);
59   DECLARE_WRITE8_MEMBER(tugboat_hd46505_1_w);
60   DECLARE_WRITE8_MEMBER(tugboat_score_w);
61   DECLARE_READ8_MEMBER(tugboat_input_r);
62   DECLARE_WRITE8_MEMBER(tugboat_ctrl_w);
6863   virtual void machine_start();
6964   virtual void video_start();
7065   virtual void machine_reset();
7166   DECLARE_PALETTE_INIT(tugboat);
72   
73   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
67   UINT32 screen_update_tugboat(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
7468   void draw_tilemap(bitmap_ind16 &bitmap,const rectangle &cliprect,
7569      int addr,int gfx0,int gfx1,int transparency);
7670
r244651r244652
8175
8276void tugboat_state::machine_start()
8377{
84   m_interrupt_timer = timer_alloc(TIMER_INTERRUPT);
85   
78   /*save_item(NAME(m_hd46505_0_reg));
8679   save_item(NAME(m_hd46505_0_reg));
87   save_item(NAME(m_hd46505_1_reg));
8880   save_item(NAME(m_reg0));
8981   save_item(NAME(m_reg1));
90   save_item(NAME(m_ctrl));
82   save_item(NAME(m_ctrl));*/
9183}
9284
9385void tugboat_state::video_start()
r244651r244652
121113
122114/* see mc6845.c. That file is only a placeholder, I process the writes here
123115   because I need the start_addr register to handle scrolling */
124WRITE8_MEMBER(tugboat_state::hd46505_0_w)
116WRITE8_MEMBER(tugboat_state::tugboat_hd46505_0_w)
125117{
126118   if (offset == 0) m_reg0 = data & 0x0f;
127119   else if (m_reg0 < 18) m_hd46505_0_reg[m_reg0] = data;
128120}
129WRITE8_MEMBER(tugboat_state::hd46505_1_w)
121WRITE8_MEMBER(tugboat_state::tugboat_hd46505_1_w)
130122{
131123   if (offset == 0) m_reg1 = data & 0x0f;
132124   else if (m_reg1 < 18) m_hd46505_1_reg[m_reg1] = data;
133125}
134126
135127
136WRITE8_MEMBER(tugboat_state::score_w)
128WRITE8_MEMBER(tugboat_state::tugboat_score_w)
137129{
138130      if (offset>=0x8) m_ram[0x291d + 32*offset + 32*(1-8)] = data ^ 0x0f;
139131      if (offset<0x8 ) m_ram[0x291d + 32*offset + 32*9] = data ^ 0x0f;
r244651r244652
176168   }
177169}
178170
179UINT32 tugboat_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
171UINT32 tugboat_state::screen_update_tugboat(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
180172{
181173   int startaddr0 = m_hd46505_0_reg[0x0c]*256 + m_hd46505_0_reg[0x0d];
182174   int startaddr1 = m_hd46505_1_reg[0x0c]*256 + m_hd46505_1_reg[0x0d];
r244651r244652
189181
190182
191183
192READ8_MEMBER(tugboat_state::input_r)
184READ8_MEMBER(tugboat_state::tugboat_input_r)
193185{
194186   if (~m_ctrl & 0x80)
195187      return ioport("IN0")->read();
r244651r244652
203195      return ioport("IN4")->read();
204196}
205197
206WRITE8_MEMBER(tugboat_state::ctrl_w)
198WRITE8_MEMBER(tugboat_state::tugboat_ctrl_w)
207199{
208200   m_ctrl = data;
209201}
r244651r244652
214206   {
215207   case TIMER_INTERRUPT:
216208      m_maincpu->set_input_line(0, HOLD_LINE);
217      m_interrupt_timer->adjust(m_screen->frame_period());
209      timer_set(m_screen->frame_period(), TIMER_INTERRUPT);
218210      break;
219211   default:
220212      assert_always(FALSE, "Unknown id in tugboat_state::device_timer");
r244651r244652
223215
224216void tugboat_state::machine_reset()
225217{
226   m_interrupt_timer->adjust(m_screen->time_until_pos(0));
218   timer_set(m_screen->time_until_pos(0), TIMER_INTERRUPT);
227219}
228220
229221
r244651r244652
231223   ADDRESS_MAP_GLOBAL_MASK(0x7fff)
232224   AM_RANGE(0x0000, 0x01ff) AM_RAM AM_SHARE("ram")
233225   AM_RANGE(0x1060, 0x1061) AM_DEVWRITE("aysnd", ay8910_device, address_data_w)
234   AM_RANGE(0x10a0, 0x10a1) AM_WRITE(hd46505_0_w)  /* scrolling is performed changing the start_addr register (0C/0D) */
235   AM_RANGE(0x10c0, 0x10c1) AM_WRITE(hd46505_1_w)
226   AM_RANGE(0x10a0, 0x10a1) AM_WRITE(tugboat_hd46505_0_w)  /* scrolling is performed changing the start_addr register (0C/0D) */
227   AM_RANGE(0x10c0, 0x10c1) AM_WRITE(tugboat_hd46505_1_w)
236228   AM_RANGE(0x11e4, 0x11e7) AM_DEVREADWRITE("pia0", pia6821_device, read, write)
237229   AM_RANGE(0x11e8, 0x11eb) AM_DEVREADWRITE("pia1", pia6821_device, read, write)
238230   //AM_RANGE(0x1700, 0x1fff) AM_RAM
239   AM_RANGE(0x18e0, 0x18ef) AM_WRITE(score_w)
231   AM_RANGE(0x18e0, 0x18ef) AM_WRITE(tugboat_score_w)
240232   AM_RANGE(0x2000, 0x2fff) AM_RAM /* tilemap RAM */
241233   AM_RANGE(0x4000, 0x7fff) AM_ROM
242234ADDRESS_MAP_END
r244651r244652
360352   MCFG_CPU_VBLANK_INT_DRIVER("screen", tugboat_state,  nmi_line_pulse)
361353
362354   MCFG_DEVICE_ADD("pia0", PIA6821, 0)
363   MCFG_PIA_READPA_HANDLER(READ8(tugboat_state,input_r))
355   MCFG_PIA_READPA_HANDLER(READ8(tugboat_state,tugboat_input_r))
364356
365357   MCFG_DEVICE_ADD("pia1", PIA6821, 0)
366358   MCFG_PIA_READPA_HANDLER(IOPORT("DSW"))
367   MCFG_PIA_WRITEPB_HANDLER(WRITE8(tugboat_state, ctrl_w))
359   MCFG_PIA_WRITEPB_HANDLER(WRITE8(tugboat_state, tugboat_ctrl_w))
368360
369361   MCFG_SCREEN_ADD("screen", RASTER)
370362   MCFG_SCREEN_REFRESH_RATE(60)
371363   MCFG_SCREEN_SIZE(32*8,32*8)
372364   MCFG_SCREEN_VISIBLE_AREA(1*8,31*8-1,2*8,30*8-1)
373   MCFG_SCREEN_UPDATE_DRIVER(tugboat_state, screen_update)
365   MCFG_SCREEN_UPDATE_DRIVER(tugboat_state, screen_update_tugboat)
374366   MCFG_SCREEN_PALETTE("palette")
375367
376368   MCFG_GFXDECODE_ADD("gfxdecode", "palette", tugboat)
r244651r244652
468460ROM_END
469461
470462
471GAME( 1982, tugboat,  0, tugboat, tugboat, driver_device,  0, ROT90, "Enter-Tech, Ltd.", "Tugboat",    GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
472GAME( 1983, noahsark, 0, tugboat, noahsark, driver_device, 0, ROT90, "Enter-Tech, Ltd.", "Noah's Ark", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
473GAME( 1984, berenstn, 0, tugboat, noahsark, driver_device, 0, ROT90, "Enter-Tech, Ltd.", "The Berenstain Bears in Big Paw's Cave", GAME_IMPERFECT_GRAPHICS | GAME_WRONG_COLORS | GAME_SUPPORTS_SAVE )
463GAME( 1982, tugboat,  0, tugboat, tugboat, driver_device,  0, ROT90, "Enter-Tech, Ltd.", "Tugboat",    GAME_IMPERFECT_GRAPHICS )
464GAME( 1983, noahsark, 0, tugboat, noahsark, driver_device, 0, ROT90, "Enter-Tech, Ltd.", "Noah's Ark", GAME_IMPERFECT_GRAPHICS )
465GAME( 1984, berenstn, 0, tugboat, noahsark, driver_device, 0, ROT90, "Enter-Tech, Ltd.", "The Berenstain Bears in Big Paw's Cave", GAME_IMPERFECT_GRAPHICS | GAME_WRONG_COLORS )
trunk/src/mame/includes/argus.h
r244651r244652
33public:
44   argus_state(const machine_config &mconfig, device_type type, const char *tag)
55      : driver_device(mconfig, type, tag),
6      m_maincpu(*this, "maincpu"),
7      m_audiocpu(*this, "audiocpu"),
8      m_gfxdecode(*this, "gfxdecode"),
9      m_screen(*this, "screen"),
10      m_palette(*this, "palette"),
116      m_bg0_scrollx(*this, "bg0_scrollx"),
127      m_bg0_scrolly(*this, "bg0_scrolly"),
138      m_bg1_scrollx(*this, "bg1_scrollx"),
r244651r244652
1611      m_txram(*this, "txram"),
1712      m_bg1ram(*this, "bg1ram"),
1813      m_spriteram(*this, "spriteram"),
19      m_butasan_bg1ram(*this, "butasan_bg1ram")  { }
14      m_butasan_bg1ram(*this, "butasan_bg1ram"),
15      m_maincpu(*this, "maincpu"),
16      m_audiocpu(*this, "audiocpu"),
17      m_gfxdecode(*this, "gfxdecode"),
18      m_screen(*this, "screen"),
19      m_palette(*this, "palette")  { }
2020
21   required_device<cpu_device> m_maincpu;
22   required_device<cpu_device> m_audiocpu;
23   required_device<gfxdecode_device> m_gfxdecode;
24   required_device<screen_device> m_screen;
25   required_device<palette_device> m_palette;
26
2721   optional_shared_ptr<UINT8> m_bg0_scrollx;
2822   optional_shared_ptr<UINT8> m_bg0_scrolly;
2923   required_shared_ptr<UINT8> m_bg1_scrollx;
r244651r244652
3428   required_shared_ptr<UINT8> m_spriteram;
3529   optional_shared_ptr<UINT8> m_butasan_bg1ram;
3630
37   // common
38   UINT8 m_bg_status;
39   UINT8 m_flipscreen;
40   UINT16 m_palette_intensity;
41   
42   // argus specific
4331   UINT8 *m_dummy_bg0ram;
44   int m_lowbitscroll;
45   int m_prvscrollx;
46   
47   // butasan specific
4832   UINT8 *m_butasan_txram;
4933   UINT8 *m_butasan_bg0ram;
5034   UINT8 *m_butasan_bg0backram;
5135   UINT8 *m_butasan_txbackram;
5236   UINT8 *m_butasan_pagedram[2];
5337   UINT8 m_butasan_page_latch;
38   tilemap_t *m_tx_tilemap;
39   tilemap_t *m_bg0_tilemap;
40   tilemap_t *m_bg1_tilemap;
41   UINT8 m_bg_status;
5442   UINT8 m_butasan_bg1_status;
55   UINT8 m_butasan_unknown;
56   
57   // valtric specific
43   UINT8 m_flipscreen;
44   UINT16 m_palette_intensity;
45   int m_lowbitscroll;
46   int m_prvscrollx;
5847   UINT8 m_valtric_mosaic;
5948   bitmap_rgb32 m_mosaicbitmap;
6049   UINT8 m_valtric_unknown;
50   UINT8 m_butasan_unknown;
6151   int m_mosaic;
62   
63   tilemap_t *m_tx_tilemap;
64   tilemap_t *m_bg0_tilemap;
65   tilemap_t *m_bg1_tilemap;
66   
67   // common
68   DECLARE_WRITE8_MEMBER(bankselect_w);
52   DECLARE_WRITE8_MEMBER(argus_bankselect_w);
6953   DECLARE_WRITE8_MEMBER(valtric_mosaic_w);
70   DECLARE_WRITE8_MEMBER(txram_w);
71   DECLARE_WRITE8_MEMBER(bg1ram_w);
72   DECLARE_WRITE8_MEMBER(flipscreen_w);
73
74   // argus specific
54   DECLARE_READ8_MEMBER(argus_txram_r);
55   DECLARE_WRITE8_MEMBER(argus_txram_w);
56   DECLARE_READ8_MEMBER(argus_bg1ram_r);
57   DECLARE_WRITE8_MEMBER(argus_bg1ram_w);
7558   DECLARE_WRITE8_MEMBER(argus_bg_status_w);
76   DECLARE_WRITE8_MEMBER(argus_paletteram_w);
77
78   // butasan specific
59   DECLARE_WRITE8_MEMBER(valtric_bg_status_w);
7960   DECLARE_WRITE8_MEMBER(butasan_bg0_status_w);
8061   DECLARE_WRITE8_MEMBER(butasan_bg1_status_w);
62   DECLARE_WRITE8_MEMBER(argus_flipscreen_w);
63   DECLARE_READ8_MEMBER(argus_paletteram_r);
64   DECLARE_WRITE8_MEMBER(argus_paletteram_w);
65   DECLARE_WRITE8_MEMBER(valtric_paletteram_w);
8166   DECLARE_WRITE8_MEMBER(butasan_paletteram_w);
8267   DECLARE_READ8_MEMBER(butasan_bg1ram_r);
8368   DECLARE_WRITE8_MEMBER(butasan_bg1ram_w);
8469   DECLARE_WRITE8_MEMBER(butasan_pageselect_w);
8570   DECLARE_READ8_MEMBER(butasan_pagedram_r);
8671   DECLARE_WRITE8_MEMBER(butasan_pagedram_w);
87   DECLARE_WRITE8_MEMBER(butasan_unknown_w);
88
89   // valtric specific
90   DECLARE_WRITE8_MEMBER(valtric_bg_status_w);
91   DECLARE_WRITE8_MEMBER(valtric_paletteram_w);
9272   DECLARE_WRITE8_MEMBER(valtric_unknown_w);
93   
73   DECLARE_WRITE8_MEMBER(butasan_unknown_w);
9474   TILE_GET_INFO_MEMBER(argus_get_tx_tile_info);
9575   TILE_GET_INFO_MEMBER(argus_get_bg0_tile_info);
9676   TILE_GET_INFO_MEMBER(argus_get_bg1_tile_info);
r244651r244652
9979   TILE_GET_INFO_MEMBER(butasan_get_tx_tile_info);
10080   TILE_GET_INFO_MEMBER(butasan_get_bg0_tile_info);
10181   TILE_GET_INFO_MEMBER(butasan_get_bg1_tile_info);
102   
103   virtual void machine_start();
10482   DECLARE_VIDEO_START(argus);
10583   DECLARE_VIDEO_RESET(argus);
10684   DECLARE_VIDEO_START(valtric);
10785   DECLARE_VIDEO_RESET(valtric);
10886   DECLARE_VIDEO_START(butasan);
10987   DECLARE_VIDEO_RESET(butasan);
110   
11188   UINT32 screen_update_argus(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
11289   UINT32 screen_update_valtric(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
11390   UINT32 screen_update_butasan(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
114   
115   TIMER_DEVICE_CALLBACK_MEMBER(scanline);
91   TIMER_DEVICE_CALLBACK_MEMBER(argus_scanline);
11692   TIMER_DEVICE_CALLBACK_MEMBER(butasan_scanline);
117   
11893   void reset_common();
119   void change_palette(int color, int lo_offs, int hi_offs);
120   void change_bg_palette(int color, int lo_offs, int hi_offs);
94   void argus_write_dummy_rams(int dramoffs, int vromoffs);
95   void argus_change_palette(int color, int lo_offs, int hi_offs);
96   void argus_change_bg_palette(int color, int lo_offs, int hi_offs);
12197   void bg_setting();
122   
123   // argus specific
12498   void argus_bg0_scroll_handle();
125   void argus_write_dummy_rams(int dramoffs, int vromoffs);
12699   void argus_draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int priority);
127   
128   // butasan specific
129   void butasan_draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect);
130   void butasan_log_vram();
131   
132   // valtric specific
133100   void valtric_draw_mosaic(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
134101   void valtric_draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect);
102   void butasan_draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect);
103   void butasan_log_vram();
104   DECLARE_WRITE_LINE_MEMBER(irqhandler);
105   required_device<cpu_device> m_maincpu;
106   required_device<cpu_device> m_audiocpu;
107   required_device<gfxdecode_device> m_gfxdecode;
108   required_device<screen_device> m_screen;
109   required_device<palette_device> m_palette;
135110};
trunk/src/mame/includes/capbowl.h
r244651r244652
1212public:
1313   enum
1414   {
15      TIMER_UPDATE
15      TIMER_CAPBOWL_UPDATE
1616   };
1717
1818   capbowl_state(const machine_config &mconfig, device_type type, const char *tag)
1919      : driver_device(mconfig, type, tag),
20      m_rowaddress(*this, "rowaddress"),
2021      m_maincpu(*this, "maincpu"),
2122      m_audiocpu(*this, "audiocpu"),
2223      m_tms34061(*this, "tms34061"),
23      m_screen(*this, "screen"),
24      m_rowaddress(*this, "rowaddress") { }
24      m_screen(*this, "screen") { }
2525
26   /* devices */
27   required_device<cpu_device> m_maincpu;
28   required_device<cpu_device> m_audiocpu;
29   required_device<tms34061_device> m_tms34061;
30   required_device<screen_device> m_screen;
31
3226   /* memory pointers */
3327   required_shared_ptr<UINT8> m_rowaddress;
3428
r244651r244652
3731
3832   /* input-related */
3933   UINT8 m_last_trackball_val[2];
40   
41   emu_timer *m_update_timer;
4234
43   // common
35   /* devices */
36   required_device<cpu_device> m_maincpu;
37   required_device<cpu_device> m_audiocpu;
38   required_device<tms34061_device> m_tms34061;
39   required_device<screen_device> m_screen;
40
41   DECLARE_WRITE8_MEMBER(capbowl_rom_select_w);
4442   DECLARE_READ8_MEMBER(track_0_r);
4543   DECLARE_READ8_MEMBER(track_1_r);
4644   DECLARE_WRITE8_MEMBER(track_reset_w);
47   DECLARE_WRITE8_MEMBER(sndcmd_w);
48   DECLARE_WRITE8_MEMBER(tms34061_w);
49   DECLARE_READ8_MEMBER(tms34061_r);
50   
51   // capbowl specific
52   DECLARE_WRITE8_MEMBER(capbowl_rom_select_w);
53   
54   // bowlrama specific
45   DECLARE_WRITE8_MEMBER(capbowl_sndcmd_w);
46   DECLARE_WRITE8_MEMBER(capbowl_tms34061_w);
47   DECLARE_READ8_MEMBER(capbowl_tms34061_r);
5548   DECLARE_WRITE8_MEMBER(bowlrama_blitter_w);
5649   DECLARE_READ8_MEMBER(bowlrama_blitter_r);
57   
5850   DECLARE_DRIVER_INIT(capbowl);
5951   virtual void machine_start();
6052   virtual void machine_reset();
61   
62   INTERRUPT_GEN_MEMBER(interrupt);
63   TIMER_CALLBACK_MEMBER(update);
64   
65   UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
53   UINT32 screen_update_capbowl(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
54   INTERRUPT_GEN_MEMBER(capbowl_interrupt);
55   TIMER_CALLBACK_MEMBER(capbowl_update);
6656   inline rgb_t pen_for_pixel( UINT8 *src, UINT8 pix );
57   DECLARE_WRITE_LINE_MEMBER(firqhandler);
58   DECLARE_WRITE_LINE_MEMBER(generate_tms34061_interrupt);
6759
6860protected:
6961   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
trunk/src/mame/includes/fgoal.h
r244651r244652
1010
1111   fgoal_state(const machine_config &mconfig, device_type type, const char *tag)
1212      : driver_device(mconfig, type, tag),
13      m_video_ram(*this, "video_ram"),
1314      m_maincpu(*this, "maincpu"),
1415      m_mb14241(*this, "mb14241"),
1516      m_gfxdecode(*this, "gfxdecode"),
1617      m_screen(*this, "screen"),
17      m_palette(*this, "palette"),
18      m_video_ram(*this, "video_ram")   { }
18      m_palette(*this, "palette")
19      { }
1920
20   /* devices */
21   required_device<cpu_device> m_maincpu;
22   required_device<mb14241_device> m_mb14241;
23   required_device<gfxdecode_device> m_gfxdecode;
24   required_device<screen_device> m_screen;
25   required_device<palette_device> m_palette;
26
2721   /* memory pointers */
2822   required_shared_ptr<UINT8> m_video_ram;
2923
r244651r244652
3529   int        m_current_color;
3630
3731   /* misc */
38   int        m_player;
32   int        m_fgoal_player;
3933   UINT8      m_row;
4034   UINT8      m_col;
4135   int        m_prev_coin;
42   emu_timer  *m_interrupt_timer;
4336
44   DECLARE_READ8_MEMBER(analog_r);
45   DECLARE_READ8_MEMBER(nmi_reset_r);
46   DECLARE_READ8_MEMBER(irq_reset_r);
47   DECLARE_READ8_MEMBER(row_r);
48   DECLARE_WRITE8_MEMBER(row_w);
49   DECLARE_WRITE8_MEMBER(col_w);
50   DECLARE_READ8_MEMBER(address_hi_r);
51   DECLARE_READ8_MEMBER(address_lo_r);
52   DECLARE_READ8_MEMBER(shifter_r);
53   DECLARE_READ8_MEMBER(shifter_reverse_r);
54   DECLARE_WRITE8_MEMBER(sound1_w);
55   DECLARE_WRITE8_MEMBER(sound2_w);
56   DECLARE_WRITE8_MEMBER(color_w);
57   DECLARE_WRITE8_MEMBER(ypos_w);
58   DECLARE_WRITE8_MEMBER(xpos_w);
37   /* devices */
38   required_device<cpu_device> m_maincpu;
39   required_device<mb14241_device> m_mb14241;
40   required_device<gfxdecode_device> m_gfxdecode;
41   required_device<screen_device> m_screen;
42   required_device<palette_device> m_palette;
5943
60   DECLARE_CUSTOM_INPUT_MEMBER(_80_r);
61   
62   TIMER_CALLBACK_MEMBER(interrupt_callback);
63
44   DECLARE_READ8_MEMBER(fgoal_analog_r);
45   DECLARE_READ8_MEMBER(fgoal_nmi_reset_r);
46   DECLARE_READ8_MEMBER(fgoal_irq_reset_r);
47   DECLARE_READ8_MEMBER(fgoal_row_r);
48   DECLARE_WRITE8_MEMBER(fgoal_row_w);
49   DECLARE_WRITE8_MEMBER(fgoal_col_w);
50   DECLARE_READ8_MEMBER(fgoal_address_hi_r);
51   DECLARE_READ8_MEMBER(fgoal_address_lo_r);
52   DECLARE_READ8_MEMBER(fgoal_shifter_r);
53   DECLARE_READ8_MEMBER(fgoal_shifter_reverse_r);
54   DECLARE_WRITE8_MEMBER(fgoal_sound1_w);
55   DECLARE_WRITE8_MEMBER(fgoal_sound2_w);
56   DECLARE_WRITE8_MEMBER(fgoal_color_w);
57   DECLARE_WRITE8_MEMBER(fgoal_ypos_w);
58   DECLARE_WRITE8_MEMBER(fgoal_xpos_w);
59   DECLARE_CUSTOM_INPUT_MEMBER(fgoal_80_r);
6460   virtual void machine_start();
6561   virtual void machine_reset();
6662   virtual void video_start();
6763   DECLARE_PALETTE_INIT(fgoal);
68
69   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
64   UINT32 screen_update_fgoal(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
65   TIMER_CALLBACK_MEMBER(interrupt_callback);
7066   int intensity(int bits);
71   unsigned video_ram_address( );
67   unsigned video_ram_address( );
7268
7369protected:
7470   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
trunk/src/mame/includes/ssv.h
r244651r244652
5252   optional_shared_ptr<UINT16> m_input_sel;
5353
5454   int m_tile_code[16];
55
5556   int m_enable_video;
5657   int m_shadow_pen_mask;
5758   int m_shadow_pen_shift;
59
5860   UINT8 m_requested_int;
5961   UINT16 m_irq_enable;
62
6063   UINT16 *m_eaglshot_gfxram;
64
6165   tilemap_t *m_gdfs_tmap;
66
6267   int m_interrupt_ultrax;
68
6369   int m_gdfs_lightgun_select;
70
6471   UINT16 m_sxyreact_serial;
6572   int m_sxyreact_dial;
6673   UINT16 m_gdfs_eeprom_old;
74
6775   UINT32 m_latches[8];
76
6877   UINT8 m_trackball_select;
69
70   DECLARE_WRITE16_MEMBER(irq_ack_w);
71   DECLARE_WRITE16_MEMBER(irq_enable_w);
72   DECLARE_WRITE16_MEMBER(lockout_w);
73   DECLARE_WRITE16_MEMBER(lockout_inv_w);
78   DECLARE_WRITE16_MEMBER(ssv_irq_ack_w);
79   DECLARE_WRITE16_MEMBER(ssv_irq_enable_w);
80   DECLARE_WRITE16_MEMBER(ssv_lockout_w);
81   DECLARE_WRITE16_MEMBER(ssv_lockout_inv_w);
7482   DECLARE_READ16_MEMBER(dsp_dr_r);
7583   DECLARE_WRITE16_MEMBER(dsp_dr_w);
7684   DECLARE_READ16_MEMBER(dsp_r);
r244651r244652
8290   DECLARE_READ16_MEMBER(gdfs_blitram_r);
8391   DECLARE_WRITE16_MEMBER(gdfs_blitram_w);
8492   DECLARE_READ16_MEMBER(hypreact_input_r);
85   DECLARE_READ16_MEMBER(mainram_r);
86   DECLARE_WRITE16_MEMBER(mainram_w);
93   DECLARE_READ16_MEMBER(ssv_mainram_r);
94   DECLARE_WRITE16_MEMBER(ssv_mainram_w);
8795   DECLARE_READ16_MEMBER(srmp4_input_r);
8896   DECLARE_READ16_MEMBER(srmp7_irqv_r);
8997   DECLARE_WRITE16_MEMBER(srmp7_sound_bank_w);
r244651r244652
102110   DECLARE_READ16_MEMBER(eaglshot_gfxram_r);
103111   DECLARE_WRITE16_MEMBER(eaglshot_gfxram_w);
104112   DECLARE_WRITE16_MEMBER(gdfs_tmapram_w);
105   DECLARE_READ16_MEMBER(vblank_r);
106   DECLARE_WRITE16_MEMBER(scroll_w);
113   DECLARE_READ16_MEMBER(ssv_vblank_r);
114   DECLARE_WRITE16_MEMBER(ssv_scroll_w);
107115   DECLARE_READ16_MEMBER(gdfs_eeprom_r);
108116   DECLARE_WRITE16_MEMBER(gdfs_eeprom_w);
109   
110   TILE_GET_INFO_MEMBER(get_tile_info_0);
111   
112117   DECLARE_DRIVER_INIT(gdfs);
113118   DECLARE_DRIVER_INIT(sxyreac2);
114119   DECLARE_DRIVER_INIT(hypreac2);
r244651r244652
131136   DECLARE_DRIVER_INIT(jsk);
132137   DECLARE_DRIVER_INIT(twineag2);
133138   DECLARE_DRIVER_INIT(mslider);
139   TILE_GET_INFO_MEMBER(get_tile_info_0);
134140   virtual void machine_reset();
135141   virtual void video_start();
136142   DECLARE_VIDEO_START(gdfs);
137143   DECLARE_VIDEO_START(eaglshot);
138   
139   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
144   UINT32 screen_update_ssv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
140145   UINT32 screen_update_gdfs(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
141146   UINT32 screen_update_eaglshot(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
142   
143   TIMER_DEVICE_CALLBACK_MEMBER(interrupt);
147   TIMER_DEVICE_CALLBACK_MEMBER(ssv_interrupt);
144148   TIMER_DEVICE_CALLBACK_MEMBER(gdfs_interrupt);
145149   void update_irq_state();
146   IRQ_CALLBACK_MEMBER(irq_callback);
147   
148   void drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx,UINT32 code,UINT32 color,int flipx,int flipy,int x0,int y0,int shadow);
150   IRQ_CALLBACK_MEMBER(ssv_irq_callback);
151   void ssv_drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx,UINT32 code,UINT32 color,int flipx,int flipy,int x0,int y0,int shadow);
149152   void draw_row(bitmap_ind16 &bitmap, const rectangle &cliprect, int sx, int sy, int scroll);
150153   void draw_layer(bitmap_ind16 &bitmap, const rectangle &cliprect, int  nr);
151154   void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
152   void enable_video(int enable);
153   void init(int interrupt_ultrax);
155   void ssv_enable_video(int enable);
156   void init_ssv(int interrupt_ultrax);
154157   void init_hypreac2_common();
155158   void init_eaglshot_banking();
156159   void init_st010();
trunk/src/mame/video/argus.c
r244651r244652
8989-----------------------------------------------------------------------------
9090 +0
9191 ---- ---x  = BG enable bit
92 ---- --x-  = grey scale effect or tile bank select.
92 ---- --x-  = gray scale effect or tile bank select.
9393
9494
9595Flip screen controller
r244651r244652
109109(*) Things which are not emulated.
110110 - Color $000 - 00f, $01e, $02e ... are half transparent color.
111111 - Sprite priority bit may be present in Butasan. But I don't know
112   what happens when it is set.
112   what is happened when it is set.
113113
114114***************************************************************************/
115115
r244651r244652
272272   m_dummy_bg0ram = auto_alloc_array(machine(), UINT8, 0x800);
273273
274274   jal_blend_init(machine(), 1);
275   
276   save_item(NAME(m_bg_status));
277   save_item(NAME(m_flipscreen));
278   save_item(NAME(m_palette_intensity));
279   save_pointer(NAME(m_dummy_bg0ram), 0x800);
280   save_item(NAME(m_lowbitscroll));
281   save_item(NAME(m_prvscrollx));
282275}
283276
284277VIDEO_RESET_MEMBER(argus_state,argus)
r244651r244652
302295   m_screen->register_screen_bitmap(m_mosaicbitmap);
303296
304297   jal_blend_init(machine(), 1);
305   
306   save_item(NAME(m_bg_status));
307   save_item(NAME(m_flipscreen));
308   save_item(NAME(m_palette_intensity));
309   save_item(NAME(m_valtric_mosaic));
310   save_item(NAME(m_valtric_unknown));
311   save_item(NAME(m_mosaic));
312298}
313299
314300VIDEO_RESET_MEMBER(argus_state,valtric)
r244651r244652
336322   m_butasan_txbackram  = &m_butasan_pagedram[1][0x800];
337323
338324   jal_blend_init(machine(), 1);
339   
340   save_item(NAME(m_bg_status));
341   save_item(NAME(m_flipscreen));
342   save_item(NAME(m_palette_intensity));
343   save_pointer(NAME(m_butasan_pagedram[0]), 0x1000);
344   save_pointer(NAME(m_butasan_pagedram[1]), 0x1000);
345   save_item(NAME(m_butasan_page_latch));
346   save_item(NAME(m_butasan_bg1_status));
347   save_item(NAME(m_butasan_unknown));
348325}
349326
350327VIDEO_RESET_MEMBER(argus_state,butasan)
r244651r244652
386363   }
387364}
388365
389void argus_state::change_palette(int color, int lo_offs, int hi_offs)
366void argus_state::argus_change_palette(int color, int lo_offs, int hi_offs)
390367{
391368   UINT8 lo = m_paletteram[lo_offs];
392369   UINT8 hi = m_paletteram[hi_offs];
r244651r244652
394371   m_palette->set_pen_color(color, pal4bit(lo >> 4), pal4bit(lo), pal4bit(hi >> 4));
395372}
396373
397void argus_state::change_bg_palette(int color, int lo_offs, int hi_offs)
374void argus_state::argus_change_bg_palette(int color, int lo_offs, int hi_offs)
398375{
399376   UINT8 r,g,b,lo,hi,ir,ig,ib,ix;
400377   rgb_t rgb,irgb;
r244651r244652
441418   m_valtric_mosaic = data;
442419}
443420
444WRITE8_MEMBER(argus_state::txram_w)
421READ8_MEMBER(argus_state::argus_txram_r)
445422{
423   return m_txram[offset];
424}
425
426WRITE8_MEMBER(argus_state::argus_txram_w)
427{
446428   m_txram[offset] = data;
447429   m_tx_tilemap->mark_tile_dirty(offset >> 1);
448430}
449431
450WRITE8_MEMBER(argus_state::bg1ram_w)
432READ8_MEMBER(argus_state::argus_bg1ram_r)
451433{
434   return m_bg1ram[offset];
435}
436
437WRITE8_MEMBER(argus_state::argus_bg1ram_w)
438{
452439   m_bg1ram[offset] = data;
453440   m_bg1_tilemap->mark_tile_dirty(offset >> 1);
454441}
r244651r244652
466453
467454         for (offs = 0x400; offs < 0x500; offs++)
468455         {
469            change_bg_palette((offs - 0x400) + 0x080, offs, offs + 0x400);
456            argus_change_bg_palette((offs - 0x400) + 0x080, offs, offs + 0x400);
470457         }
471458      }
472459   }
r244651r244652
485472
486473         for (offs = 0x400; offs < 0x600; offs += 2)
487474         {
488            change_bg_palette(((offs - 0x400) >> 1) + 0x100, offs & ~1, offs | 1);
475            argus_change_bg_palette(((offs - 0x400) >> 1) + 0x100, offs & ~1, offs | 1);
489476         }
490477      }
491478   }
r244651r244652
507494   }
508495}
509496
510WRITE8_MEMBER(argus_state::flipscreen_w)
497WRITE8_MEMBER(argus_state::argus_flipscreen_w)
511498{
512499   m_flipscreen = data & 0x80;
513500}
514501
502READ8_MEMBER(argus_state::argus_paletteram_r)
503{
504   return m_paletteram[offset];
505}
506
515507WRITE8_MEMBER(argus_state::argus_paletteram_w)
516508{
517509   int offs;
r244651r244652
522514   {
523515      offset &= 0x07f;
524516
525      change_palette(offset, offset, offset + 0x080);
517      argus_change_palette(offset, offset, offset + 0x080);
526518
527519      if (offset == 0x07f || offset == 0x0ff)
528520      {
529521         m_palette_intensity = m_paletteram[0x0ff] | (m_paletteram[0x07f] << 8);
530522
531523         for (offs = 0x400; offs < 0x500; offs++)
532            change_bg_palette((offs & 0xff) + 0x080, offs, offs + 0x400);
524            argus_change_bg_palette((offs & 0xff) + 0x080, offs, offs + 0x400);
533525      }
534526   }
535527   else if ((offset >= 0x400 && offset <= 0x4ff) ||
r244651r244652
538530      offs = offset & 0xff;
539531      offset = offs | 0x400;
540532
541      change_bg_palette(offs + 0x080, offset, offset + 0x400);
533      argus_change_bg_palette(offs + 0x080, offset, offset + 0x400);
542534   }
543535   else if ((offset >= 0x500 && offset <= 0x5ff) ||
544536            (offset >= 0x900 && offset <= 0x9ff))       /* BG1 color */
r244651r244652
546538      offs = offset & 0xff;
547539      offset = offs | 0x500;
548540
549      change_palette(offs + 0x180, offset, offset + 0x400);
541      argus_change_palette(offs + 0x180, offset, offset + 0x400);
550542   }
551543   else if ((offset >= 0x700 && offset <= 0x7ff) ||
552544            (offset >= 0xb00 && offset <= 0xbff))       /* text color */
r244651r244652
554546      offs = offset & 0xff;
555547      offset = offs | 0x700;
556548
557      change_palette(offs + 0x280, offset, offset + 0x400);
549      argus_change_palette(offs + 0x280, offset, offset + 0x400);
558550   }
559551}
560552
r244651r244652
564556
565557   if (offset <= 0x1ff)                            /* Sprite color */
566558   {
567      change_palette(offset >> 1, offset & ~1, offset | 1);
559      argus_change_palette(offset >> 1, offset & ~1, offset | 1);
568560
569561      if (offset == 0x1fe || offset == 0x1ff)
570562      {
r244651r244652
573565         m_palette_intensity = m_paletteram[0x1ff] | (m_paletteram[0x1fe] << 8);
574566
575567         for (offs = 0x400; offs < 0x600; offs += 2)
576            change_bg_palette(((offs & 0x1ff) >> 1) + 0x100, offs & ~1, offs | 1);
568            argus_change_bg_palette(((offs & 0x1ff) >> 1) + 0x100, offs & ~1, offs | 1);
577569      }
578570   }
579571   else if (offset >= 0x400 && offset <= 0x5ff)        /* BG color */
580572   {
581      change_bg_palette(((offset & 0x1ff) >> 1) + 0x100, offset & ~1, offset | 1);
573      argus_change_bg_palette(((offset & 0x1ff) >> 1) + 0x100, offset & ~1, offset | 1);
582574   }
583575   else if (offset >= 0x600 && offset <= 0x7ff)        /* Text color */
584576   {
585      change_palette(((offset & 0x1ff) >> 1) + 0x200, offset & ~1, offset | 1);
577      argus_change_palette(((offset & 0x1ff) >> 1) + 0x200, offset & ~1, offset | 1);
586578   }
587579}
588580
r244651r244652
592584
593585   if (offset <= 0x1ff)                            /* BG0 color */
594586   {
595      change_palette((offset >> 1) + 0x100, offset & ~1, offset | 1);
587      argus_change_palette((offset >> 1) + 0x100, offset & ~1, offset | 1);
596588   }
597589   else if (offset <= 0x23f)                       /* BG1 color */
598590   {
599      change_palette(((offset & 0x3f) >> 1) + 0x0c0, offset & ~1, offset | 1);
591      argus_change_palette(((offset & 0x3f) >> 1) + 0x0c0, offset & ~1, offset | 1);
600592   }
601593   else if (offset >= 0x400 && offset <= 0x47f)    /* Sprite color */
602594   {                                               /* 16 colors */
603      change_palette((offset & 0x7f) >> 1, offset & ~1, offset | 1);
595      argus_change_palette((offset & 0x7f) >> 1, offset & ~1, offset | 1);
604596   }
605597   else if (offset >= 0x480 && offset <= 0x4ff)    /* Sprite color */
606598   {                                               /* 8  colors */
607599      int offs = (offset & 0x070) | ((offset & 0x00f) >> 1);
608600
609      change_palette(offs + 0x040, offset & ~1, offset | 1);
610      change_palette(offs + 0x048, offset & ~1, offset | 1);
601      argus_change_palette(offs + 0x040, offset & ~1, offset | 1);
602      argus_change_palette(offs + 0x048, offset & ~1, offset | 1);
611603   }
612604   else if (offset >= 0x600 && offset <= 0x7ff)    /* Text color */
613605   {
614      change_palette(((offset & 0x1ff) >> 1) + 0x200, offset & ~1, offset | 1);
606      argus_change_palette(((offset & 0x1ff) >> 1) + 0x200, offset & ~1, offset | 1);
615607   }
616608   else if (offset >= 0x240 && offset <= 0x25f)    // dummy
617      change_palette(((offset & 0x1f) >> 1) + 0xe0, offset & ~1, offset | 1);
609      argus_change_palette(((offset & 0x1f) >> 1) + 0xe0, offset & ~1, offset | 1);
618610   else if (offset >= 0x500 && offset <= 0x51f)    // dummy
619      change_palette(((offset & 0x1f) >> 1) + 0xf0, offset & ~1, offset | 1);
611      argus_change_palette(((offset & 0x1f) >> 1) + 0xf0, offset & ~1, offset | 1);
620612}
621613
614READ8_MEMBER(argus_state::butasan_bg1ram_r)
615{
616   return m_butasan_bg1ram[offset];
617}
618
622619WRITE8_MEMBER(argus_state::butasan_bg1ram_w)
623620{
624621   int idx;
r244651r244652
807804
808805void argus_state::argus_draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int priority)
809806{
807   UINT8 *spriteram = m_spriteram;
808   int offs;
809
810810   /* Draw the sprites */
811   for (int offs = 0; offs < m_spriteram.bytes(); offs += 16)
811   for (offs = 0; offs < m_spriteram.bytes(); offs += 16)
812812   {
813      if (!(m_spriteram[offs+15] == 0 && m_spriteram[offs+11] == 0xf0))
813      if (!(spriteram[offs+15] == 0 && spriteram[offs+11] == 0xf0))
814814      {
815815         int sx, sy, tile, flipx, flipy, color, pri;
816816
817         sx = m_spriteram[offs+12]; if (m_spriteram[offs+13] & 0x01) sx -= 256;
818         sy = m_spriteram[offs+11]; if (!(m_spriteram[offs+13] & 0x02)) sy -= 256;
817         sx = spriteram[offs+12]; if (spriteram[offs+13] & 0x01) sx -= 256;
818         sy = spriteram[offs+11]; if (!(spriteram[offs+13] & 0x02)) sy -= 256;
819819
820         tile  = m_spriteram[offs+14] | ((m_spriteram[offs+13] & 0xc0) << 2);
821         flipx = m_spriteram[offs+13] & 0x10;
822         flipy = m_spriteram[offs+13] & 0x20;
823         color = m_spriteram[offs+15] & 0x07;
824         pri   = (m_spriteram[offs+15] & 0x08) >> 3;
820         tile  = spriteram[offs+14] | ((spriteram[offs+13] & 0xc0) << 2);
821         flipx = spriteram[offs+13] & 0x10;
822         flipy = spriteram[offs+13] & 0x20;
823         color = spriteram[offs+15] & 0x07;
824         pri   = (spriteram[offs+15] & 0x08) >> 3;
825825
826826         if (m_flipscreen)
827827         {
r244651r244652
933933
934934void argus_state::valtric_draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect)
935935{
936   UINT8 *spriteram = m_spriteram;
937   int offs;
938
936939   /* Draw the sprites */
937   for (int offs = 0; offs < m_spriteram.bytes(); offs += 16)
940   for (offs = 0; offs < m_spriteram.bytes(); offs += 16)
938941   {
939      if (!(m_spriteram[offs+15] == 0 && m_spriteram[offs+11] == 0xf0))
942      if (!(spriteram[offs+15] == 0 && spriteram[offs+11] == 0xf0))
940943      {
941944         int sx, sy, tile, flipx, flipy, color;
942945
943         sx = m_spriteram[offs+12]; if (m_spriteram[offs+13] & 0x01) sx -= 256;
944         sy = m_spriteram[offs+11]; if (!(m_spriteram[offs+13] & 0x02)) sy -= 256;
946         sx = spriteram[offs+12]; if (spriteram[offs+13] & 0x01) sx -= 256;
947         sy = spriteram[offs+11]; if (!(spriteram[offs+13] & 0x02)) sy -= 256;
945948
946         tile  = m_spriteram[offs+14] | ((m_spriteram[offs+13] & 0xc0) << 2);
947         flipx = m_spriteram[offs+13] & 0x10;
948         flipy = m_spriteram[offs+13] & 0x20;
949         color = m_spriteram[offs+15] & 0x0f;
949         tile  = spriteram[offs+14] | ((spriteram[offs+13] & 0xc0) << 2);
950         flipx = spriteram[offs+13] & 0x10;
951         flipy = spriteram[offs+13] & 0x20;
952         color = spriteram[offs+15] & 0x0f;
950953
951954         if (m_flipscreen)
952955         {
r244651r244652
969972
970973void argus_state::butasan_draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect)
971974{
975   UINT8 *spriteram = m_spriteram;
976   int offs;
977
972978   /* Draw the sprites */
973   for (int offs = 0; offs < m_spriteram.bytes(); offs += 16)
979   for (offs = 0; offs < m_spriteram.bytes(); offs += 16)
974980   {
975981      int sx, sy, tile, flipx, flipy, color;
976982      int fx, fy;
977983
978      tile  = m_spriteram[offs+14] | ((m_spriteram[offs+15] & 0x0f) << 8);
979      flipx = m_spriteram[offs+8] & 0x01;
980      flipy = m_spriteram[offs+8] & 0x04;
981      color = m_spriteram[offs+9] & 0x0f;
984      tile  = spriteram[offs+14] | ((spriteram[offs+15] & 0x0f) << 8);
985      flipx = spriteram[offs+8] & 0x01;
986      flipy = spriteram[offs+8] & 0x04;
987      color = spriteram[offs+9] & 0x0f;
982988
983      sx = m_spriteram[offs+10];
984      sy = m_spriteram[offs+12];
989      sx = spriteram[offs+10];
990      sy = spriteram[offs+12];
985991
986      if (m_spriteram[offs+11] & 0x01) sx-=256;
987      if (m_spriteram[offs+13] & 0x01) sy-=256;
992      if (spriteram[offs+11] & 0x01) sx-=256;
993      if (spriteram[offs+13] & 0x01) sy-=256;
988994
989995      sy = 240 - sy;
990996
trunk/src/mame/video/capbowl.c
r244651r244652
1515 *
1616 *************************************/
1717
18WRITE8_MEMBER(capbowl_state::tms34061_w)
18WRITE8_MEMBER(capbowl_state::capbowl_tms34061_w)
1919{
2020   int func = (offset >> 8) & 3;
2121   int col = offset & 0xff;
r244651r244652
3030}
3131
3232
33READ8_MEMBER(capbowl_state::tms34061_r)
33READ8_MEMBER(capbowl_state::capbowl_tms34061_r)
3434{
3535   int func = (offset >> 8) & 3;
3636   int col = offset & 0xff;
r244651r244652
123123}
124124
125125
126UINT32 capbowl_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
126UINT32 capbowl_state::screen_update_capbowl(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
127127{
128   int x, y;
129
128130   /* first get the current display state */
129131   m_tms34061->get_display_state();
130132
r244651r244652
136138   }
137139
138140   /* now regenerate the bitmap */
139   for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
141   for (y = cliprect.min_y; y <= cliprect.max_y; y++)
140142   {
141143      UINT8 *src = &m_tms34061->m_display.vram[256 * y];
142144      UINT32 *dest = &bitmap.pix32(y);
143145
144      for (int x = cliprect.min_x & ~1; x <= cliprect.max_x; x += 2)
146      for (x = cliprect.min_x & ~1; x <= cliprect.max_x; x += 2)
145147      {
146148         UINT8 pix = src[32 + (x / 2)];
147149         *dest++ = pen_for_pixel(src, pix >> 4);
trunk/src/mame/video/fgoal.c
r244651r244652
88#include "includes/fgoal.h"
99
1010
11WRITE8_MEMBER(fgoal_state::color_w)
11WRITE8_MEMBER(fgoal_state::fgoal_color_w)
1212{
1313   m_current_color = data & 3;
1414}
1515
1616
17WRITE8_MEMBER(fgoal_state::ypos_w)
17WRITE8_MEMBER(fgoal_state::fgoal_ypos_w)
1818{
1919   m_ypos = data;
2020}
2121
2222
23WRITE8_MEMBER(fgoal_state::xpos_w)
23WRITE8_MEMBER(fgoal_state::fgoal_xpos_w)
2424{
2525   m_xpos = data;
2626}
r244651r244652
3636}
3737
3838
39UINT32 fgoal_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
39UINT32 fgoal_state::screen_update_fgoal(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
4040{
4141   const UINT8* VRAM = m_video_ram;
4242
r244651r244652
4646
4747   /* draw color overlay foreground and background */
4848
49   if (m_player == 1 && (ioport("IN1")->read() & 0x40))
49   if (m_fgoal_player == 1 && (ioport("IN1")->read() & 0x40))
5050   {
5151      m_gfxdecode->gfx(0)->zoom_opaque(m_fgbitmap,cliprect,
52         0, (m_player << 2) | m_current_color,
52         0, (m_fgoal_player << 2) | m_current_color,
5353         1, 1,
5454         0, 16,
5555         0x40000,
r244651r244652
6565   else
6666   {
6767      m_gfxdecode->gfx(0)->zoom_opaque(m_fgbitmap,cliprect,
68         0, (m_player << 2) | m_current_color,
68         0, (m_fgoal_player << 2) | m_current_color,
6969         0, 0,
7070         0, 0,
7171         0x40000,
trunk/src/mame/video/ssv.c
r244651r244652
141141#endif
142142
143143
144void ssv_state::drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx,
144void ssv_state::ssv_drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx,
145145               UINT32 code,UINT32 color,int flipx,int flipy,int x0,int y0,
146146               int shadow )
147147{
r244651r244652
194194void ssv_state::video_start()
195195{
196196   m_gfxdecode->gfx(0)->set_granularity(64); /* 256 colour sprites with palette selectable on 64 colour boundaries */
197   
198   save_item(NAME(m_enable_video));
199   save_item(NAME(m_shadow_pen_mask));
200   save_item(NAME(m_shadow_pen_shift));
201197}
202198
203199VIDEO_START_MEMBER(ssv_state,eaglshot)
r244651r244652
208204
209205   m_gfxdecode->gfx(0)->set_source((UINT8 *)m_eaglshot_gfxram);
210206   m_gfxdecode->gfx(1)->set_source((UINT8 *)m_eaglshot_gfxram);
211   
212   save_pointer(NAME(m_eaglshot_gfxram), 16 * 0x40000 / 2);
213207}
214208
215209TILE_GET_INFO_MEMBER(ssv_state::get_tile_info_0)
r244651r244652
374368
375369***************************************************************************/
376370
377READ16_MEMBER(ssv_state::vblank_r)
371READ16_MEMBER(ssv_state::ssv_vblank_r)
378372{
379373   if (m_screen->vblank())
380374      return 0x2000 | 0x1000;
r244651r244652
382376      return 0x0000;
383377}
384378
385WRITE16_MEMBER(ssv_state::scroll_w)
379WRITE16_MEMBER(ssv_state::ssv_scroll_w)
386380{
387381   COMBINE_DATA(m_scroll + offset);
388382
r244651r244652
694688         {
695689            for (ty = ystart; ty != yend; ty += yinc)
696690            {
697               drawgfx( bitmap, clip, m_gfxdecode->gfx(gfx),
691               ssv_drawgfx( bitmap, clip, m_gfxdecode->gfx(gfx),
698692                                 code++,
699693                                 color,
700694                                 flipx, flipy,
r244651r244652
919913            {
920914               for (y = ystart; y != yend; y += yinc)
921915               {
922                  drawgfx( bitmap, cliprect, m_gfxdecode->gfx(gfx),
916                  ssv_drawgfx( bitmap, cliprect, m_gfxdecode->gfx(gfx),
923917                                    code++,
924918                                    color,
925919                                    flipx, flipy,
r244651r244652
954948
955949UINT32 ssv_state::screen_update_eaglshot(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
956950{
957   return screen_update(screen, bitmap, cliprect);
951   return screen_update_ssv(screen, bitmap, cliprect);
958952}
959953
960954UINT32 ssv_state::screen_update_gdfs(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
961955{
962   screen_update(screen, bitmap, cliprect);
956   screen_update_ssv(screen, bitmap, cliprect);
963957
964958   // draw zooming sprites
965959   m_gdfs_st0020->st0020_draw_all(bitmap, cliprect);
r244651r244652
971965   return 0;
972966}
973967
974void ssv_state::enable_video(int enable)
968void ssv_state::ssv_enable_video(int enable)
975969{
976970   m_enable_video = enable;
977971}
978972
979UINT32 ssv_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
973UINT32 ssv_state::screen_update_ssv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
980974{
981975   rectangle clip;
982976
trunk/src/mame/video/st0020.c
r244651r244652
8585   save_pointer(NAME(m_st0020_gfxram), 4 * 0x100000/2);
8686   save_pointer(NAME(m_st0020_spriteram), 0x80000/2);
8787   save_pointer(NAME(m_st0020_blitram), 0x100/2);
88   save_item(NAME(m_st0020_gfxram_bank));
8988}
9089
9190void st0020_device::device_reset()
trunk/src/mess/drivers/alnchase.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:hap
3/***************************************************************************
4
5  Tomy Alien Chase (manufactured in Japan)
6  * boards are labeled TN-16
7  * NEC uCOM-43 MCU, labeled D553C 258
8  * red/green VFD display with color overlay, 2-sided*
9
10  *Player one views the VFD from the front (grid+filament side) while the
11  opposite player views it from the back side (through the conductive traces),
12  basically a mirror-image.
13
14  This is a space-themed tabletop VFD electronic game. To start, simply
15  press [UP]. Hold a joystick direction to move around.
16
17  NOTE!: MESS external artwork is required to be able to play
18
19
20  TODO:
21  - display should go off when sound is played, needs decay simulation?
22
23***************************************************************************/
24
25#include "emu.h"
26#include "cpu/ucom4/ucom4.h"
27#include "sound/speaker.h"
28
29#include "alnchase.lh" // this is a test layout, external artwork is necessary
30
31
32class alnchase_state : public driver_device
33{
34public:
35   alnchase_state(const machine_config &mconfig, device_type type, const char *tag)
36      : driver_device(mconfig, type, tag),
37      m_maincpu(*this, "maincpu"),
38      m_button_matrix(*this, "IN"),
39      m_speaker(*this, "speaker")
40   { }
41
42   required_device<cpu_device> m_maincpu;
43   required_ioport_array<2> m_button_matrix;
44   required_device<speaker_sound_device> m_speaker;
45
46   UINT8 m_input_mux;
47   UINT32 m_plate;
48   UINT16 m_grid;
49
50   DECLARE_READ8_MEMBER(input_r);
51   DECLARE_WRITE8_MEMBER(display_w);
52   DECLARE_WRITE8_MEMBER(port_e_w);
53
54   UINT32 m_vfd_state[0x10];
55   void update_vfd();
56
57   virtual void machine_start();
58};
59
60
61
62/***************************************************************************
63
64  Display
65
66***************************************************************************/
67
68void alnchase_state::update_vfd()
69{
70   for (int i = 0; i < 9; i++)
71      if (m_grid & (1 << i) && m_vfd_state[i] != m_plate)
72      {
73         // on difference, send to output
74         for (int j = 0; j < 17; j++)
75            output_set_lamp_value(i*100 + j, m_plate >> j & 1);
76
77         m_vfd_state[i] = m_plate;
78      }
79}
80
81
82
83/***************************************************************************
84
85  I/O
86
87***************************************************************************/
88
89READ8_MEMBER(alnchase_state::input_r)
90{
91   UINT8 inp = 0;
92
93   // read selected button rows
94   for (int i = 0; i < 2; i++)
95      if (m_input_mux >> i & 1)
96         inp |= m_button_matrix[i]->read();
97
98   return inp;
99}
100
101WRITE8_MEMBER(alnchase_state::display_w)
102{
103   int shift;
104
105   if (offset <= NEC_UCOM4_PORTE)
106   {
107      // C/D/E0: vfd matrix grid
108      shift = (offset - NEC_UCOM4_PORTC) * 4;
109      m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
110
111      // C0(grid 0): input enable PL1
112      // D0(grid 4): input enable PL2
113      m_input_mux = (m_grid & 1) | (m_grid >> 3 & 2);
114   }
115
116   if (offset >= NEC_UCOM4_PORTE)
117   {
118      // E23/F/G/H/I: vfd matrix plate
119      shift = (offset - NEC_UCOM4_PORTE) * 4;
120      m_plate = ((m_plate << 2 & ~(0xf << shift)) | (data << shift)) >> 2;
121   }
122
123   update_vfd();
124}
125
126WRITE8_MEMBER(alnchase_state::port_e_w)
127{
128   display_w(space, offset, data);
129
130   // E1: speaker out
131   m_speaker->level_w(data >> 1 & 1);
132}
133
134
135
136/***************************************************************************
137
138  Inputs
139
140***************************************************************************/
141
142/* physical button layout and labels is like this:
143
144    POWER SOUND LEVEL PLAYER
145     ON    ON    PRO   TWO        START
146      o     o     |     |
147      |     |     |     |       [joystick]
148      |     |     o     o
149     OFF   OFF   AMA   ONE     GAME 0,1,2,3
150
151    1 PLAYER SIDE
152
153    other player side only has a joystick
154*/
155
156static INPUT_PORTS_START( alnchase )
157   PORT_START("IN.0") // C0 port A
158   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
159   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
160   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
161   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
162
163   PORT_START("IN.1") // D0 port A
164   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) // on non-mirrored view, swap P2 left/right
165   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) // "
166   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
167   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
168
169   PORT_START("SW") // port B
170   PORT_CONFNAME( 0x01, 0x01, "Players" )
171   PORT_CONFSETTING(    0x01, "1" )
172   PORT_CONFSETTING(    0x00, "2" )
173   PORT_CONFNAME( 0x02, 0x00, DEF_STR( Difficulty ) )
174   PORT_CONFSETTING(    0x00, "Amateur" )
175   PORT_CONFSETTING(    0x02, "Professional" )
176   PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
177INPUT_PORTS_END
178
179
180
181/***************************************************************************
182
183  Machine Config
184
185***************************************************************************/
186
187void alnchase_state::machine_start()
188{
189   // zerofill
190   memset(m_vfd_state, 0, sizeof(m_vfd_state));
191   m_input_mux = 0;
192   m_plate = 0;
193   m_grid = 0;
194
195   // register for savestates
196   save_item(NAME(m_vfd_state));
197   save_item(NAME(m_input_mux));
198   save_item(NAME(m_plate));
199   save_item(NAME(m_grid));
200}
201
202
203static MACHINE_CONFIG_START( alnchase, alnchase_state )
204
205   /* basic machine hardware */
206   MCFG_CPU_ADD("maincpu", NEC_D553, XTAL_400kHz)
207   MCFG_UCOM4_READ_A_CB(READ8(alnchase_state, input_r))
208   MCFG_UCOM4_READ_B_CB(IOPORT("SW"))
209   MCFG_UCOM4_WRITE_C_CB(WRITE8(alnchase_state, display_w))
210   MCFG_UCOM4_WRITE_D_CB(WRITE8(alnchase_state, display_w))
211   MCFG_UCOM4_WRITE_E_CB(WRITE8(alnchase_state, port_e_w))
212   MCFG_UCOM4_WRITE_F_CB(WRITE8(alnchase_state, display_w))
213   MCFG_UCOM4_WRITE_G_CB(WRITE8(alnchase_state, display_w))
214   MCFG_UCOM4_WRITE_H_CB(WRITE8(alnchase_state, display_w))
215   MCFG_UCOM4_WRITE_I_CB(WRITE8(alnchase_state, display_w))
216
217   MCFG_DEFAULT_LAYOUT(layout_alnchase)
218
219   /* no video! */
220
221   /* sound hardware */
222   MCFG_SPEAKER_STANDARD_MONO("mono")
223   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
224   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
225MACHINE_CONFIG_END
226
227
228
229/***************************************************************************
230
231  Game driver(s)
232
233***************************************************************************/
234
235ROM_START( alnchase )
236   ROM_REGION( 0x0800, "maincpu", 0 )
237   ROM_LOAD( "d553c-258", 0x0000, 0x0800, CRC(c5284ff5) SHA1(6a20aaacc9748f0e0335958f3cea482e36153704) )
238ROM_END
239
240
241CONS( 1984, alnchase, 0, 0, alnchase, alnchase, driver_device, 0, "Tomy", "Alien Chase", GAME_SUPPORTS_SAVE | GAME_REQUIRES_ARTWORK )
trunk/src/mess/drivers/apple2.c
r244651r244652
7979#include "bus/a2bus/mouse.h"
8080#include "bus/a2bus/ramcard16k.h"
8181#include "bus/a2bus/ramcard128k.h"
82#include "bus/a2bus/ezcgi.h"
8382
8483#define A2_CPU_TAG "maincpu"
8584#define A2_KBDC_TAG "ay3600"
r244651r244652
12291228   SLOT_INTERFACE("dx1", A2BUS_DX1)    /* Decillonix DX-1 sampler card */
12301229   SLOT_INTERFACE("tm2ho", A2BUS_TIMEMASTERHO) /* Applied Engineering TimeMaster II H.O. */
12311230   SLOT_INTERFACE("mouse", A2BUS_MOUSE)    /* Apple II Mouse Card */
1232   SLOT_INTERFACE("ezcgi", A2BUS_EZCGI)   /* E-Z Color Graphics Interface */
1233   SLOT_INTERFACE("ezcgi9938", A2BUS_EZCGI_9938)   /* E-Z Color Graphics Interface (TMS9938) */
1234   SLOT_INTERFACE("ezcgi9958", A2BUS_EZCGI_9958)   /* E-Z Color Graphics Interface (TMS9958) */
12351231//  SLOT_INTERFACE("magicmusician", A2BUS_MAGICMUSICIAN)    /* Magic Musician Card */
12361232SLOT_INTERFACE_END
12371233
trunk/src/mess/drivers/apple2e.c
r244651r244652
143143#include "bus/a2bus/a2dx1.h"
144144#include "bus/a2bus/timemasterho.h"
145145#include "bus/a2bus/mouse.h"
146#include "bus/a2bus/ezcgi.h"
147146#include "bus/a2bus/a2eauxslot.h"
148147#include "bus/a2bus/a2estd80col.h"
149148#include "bus/a2bus/a2eext80col.h"
r244651r244652
30363035   SLOT_INTERFACE("dx1", A2BUS_DX1)    /* Decillonix DX-1 sampler card */
30373036   SLOT_INTERFACE("tm2ho", A2BUS_TIMEMASTERHO) /* Applied Engineering TimeMaster II H.O. */
30383037   SLOT_INTERFACE("mouse", A2BUS_MOUSE)    /* Apple II Mouse Card */
3039   SLOT_INTERFACE("ezcgi", A2BUS_EZCGI)   /* E-Z Color Graphics Interface */
3040   SLOT_INTERFACE("ezcgi9938", A2BUS_EZCGI_9938)   /* E-Z Color Graphics Interface (TMS9938) */
3041   SLOT_INTERFACE("ezcgi9958", A2BUS_EZCGI_9958)   /* E-Z Color Graphics Interface (TMS9958) */
30423038//  SLOT_INTERFACE("magicmusician", A2BUS_MAGICMUSICIAN)    /* Magic Musician Card */
30433039SLOT_INTERFACE_END
30443040
trunk/src/mess/drivers/edracula.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:hap
3/***************************************************************************
4
5  Epoch Dracula (manufactured in Japan)
6  * NEC uCOM-43 MCU, labeled D553C 206
7  * cyan/red/green VFD display NEC FIP8BM20T
8
9  known releases:
10  - Japan: Dracula House, yellow case
11  - USA: Dracula, red case
12  - Other: Dracula, yellow case, published by Hales
13
14  NOTE!: MESS external artwork is required to be able to play
15
16
17  TODO:
18  - display should go off when sound is played, needs decay simulation?
19
20***************************************************************************/
21
22#include "emu.h"
23#include "cpu/ucom4/ucom4.h"
24#include "sound/speaker.h"
25
26#include "edracula.lh" // this is a test layout, external artwork is necessary
27
28
29class edracula_state : public driver_device
30{
31public:
32   edracula_state(const machine_config &mconfig, device_type type, const char *tag)
33      : driver_device(mconfig, type, tag),
34      m_maincpu(*this, "maincpu"),
35      m_speaker(*this, "speaker")
36   { }
37
38   required_device<cpu_device> m_maincpu;
39   required_device<speaker_sound_device> m_speaker;
40
41   UINT32 m_plate;
42   UINT16 m_grid;
43
44   DECLARE_WRITE8_MEMBER(grid_w);
45   DECLARE_WRITE8_MEMBER(plate_w);
46   DECLARE_WRITE8_MEMBER(port_i_w);
47
48   UINT32 m_vfd_state[0x10];
49   void update_vfd();
50
51   virtual void machine_start();
52};
53
54
55
56/***************************************************************************
57
58  Display
59
60***************************************************************************/
61
62void edracula_state::update_vfd()
63{
64   for (int i = 0; i < 8; i++)
65      if (m_grid & (1 << i) && m_vfd_state[i] != m_plate)
66      {
67         // on difference, send to output
68         for (int j = 0; j < 18; j++)
69            output_set_lamp_value(i*100 + j, m_plate >> j & 1);
70
71         m_vfd_state[i] = m_plate;
72      }
73}
74
75
76
77/***************************************************************************
78
79  I/O
80
81***************************************************************************/
82
83WRITE8_MEMBER(edracula_state::grid_w)
84{
85   // port C/D: vfd matrix grid
86   int shift = (offset - NEC_UCOM4_PORTC) * 4;
87   m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
88
89   update_vfd();
90}
91
92WRITE8_MEMBER(edracula_state::plate_w)
93{
94   // port E/F/G/H/I01: vfd matrix plate
95   int shift = (offset - NEC_UCOM4_PORTE) * 4;
96   m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
97
98   update_vfd();
99}
100
101WRITE8_MEMBER(edracula_state::port_i_w)
102{
103   plate_w(space, offset, data & 3);
104
105   // I2: speaker out
106   m_speaker->level_w(data >> 2 & 1);
107}
108
109
110
111/***************************************************************************
112
113  Inputs
114
115***************************************************************************/
116
117static INPUT_PORTS_START( edracula )
118   PORT_START("IN0")
119   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT )
120   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START )
121   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
122   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
123
124   PORT_START("IN1")
125   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
126   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
127   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
128   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
129INPUT_PORTS_END
130
131
132
133/***************************************************************************
134
135  Machine Config
136
137***************************************************************************/
138
139void edracula_state::machine_start()
140{
141   // zerofill
142   memset(m_vfd_state, 0, sizeof(m_vfd_state));
143   m_plate = 0;
144   m_grid = 0;
145
146   // register for savestates
147   save_item(NAME(m_vfd_state));
148   save_item(NAME(m_plate));
149   save_item(NAME(m_grid));
150}
151
152
153static MACHINE_CONFIG_START( edracula, edracula_state )
154
155   /* basic machine hardware */
156   MCFG_CPU_ADD("maincpu", NEC_D553, XTAL_400kHz)
157   MCFG_UCOM4_READ_A_CB(IOPORT("IN0"))
158   MCFG_UCOM4_READ_B_CB(IOPORT("IN1"))
159   MCFG_UCOM4_WRITE_C_CB(WRITE8(edracula_state, grid_w))
160   MCFG_UCOM4_WRITE_D_CB(WRITE8(edracula_state, grid_w))
161   MCFG_UCOM4_WRITE_E_CB(WRITE8(edracula_state, plate_w))
162   MCFG_UCOM4_WRITE_F_CB(WRITE8(edracula_state, plate_w))
163   MCFG_UCOM4_WRITE_G_CB(WRITE8(edracula_state, plate_w))
164   MCFG_UCOM4_WRITE_H_CB(WRITE8(edracula_state, plate_w))
165   MCFG_UCOM4_WRITE_I_CB(WRITE8(edracula_state, port_i_w))
166
167   MCFG_DEFAULT_LAYOUT(layout_edracula)
168
169   /* no video! */
170
171   /* sound hardware */
172   MCFG_SPEAKER_STANDARD_MONO("mono")
173   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
174   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
175MACHINE_CONFIG_END
176
177
178
179/***************************************************************************
180
181  Game driver(s)
182
183***************************************************************************/
184
185ROM_START( edracula )
186   ROM_REGION( 0x0800, "maincpu", 0 )
187   ROM_LOAD( "d553c-206", 0x0000, 0x0800, CRC(b524857b) SHA1(c1c89ed5dd4bb1e6e98462dc8fa5af2aa48d8ede) )
188ROM_END
189
190
191CONS( 1982, edracula, 0, 0, edracula, edracula, driver_device, 0, "Epoch", "Dracula (Epoch)", GAME_SUPPORTS_SAVE | GAME_REQUIRES_ARTWORK )
trunk/src/mess/drivers/hh_tms1k.c
r244651r244652
55  This driver is a collection of simple dedicated handheld and tabletop
66  toys based around the TMS1000 MCU series. Anything more complex or clearly
77  part of a series is (or will be) in its own driver.
8 
9  Let's use this driver for a list of known devices and their serials,
10  excluding TI's own products (see for example ticalc1x.c, tispeak.c)
118
12  serial   device   etc.
13--------------------------------------------------------------------
14 @MP0904A  TMS0970  1977, Milton Bradley Comp IV
15 @MP0905B  TMS0970  1977, Parker Brothers Codename Sector
16 @MP0914   TMS1000  1979, Entex Baseball
17 @MP1030   TMS1100  1980, APF Mathemagician
18 @MP3226   TMS1000  1978, Milton Bradley Simon
19 @MP3403   TMS1100  1978, unknown
20 @MP3404   TMS1100  1978, Parker Brothers Merlin
21 @MP3405   TMS1100  1979, Coleco Amaze-A-Tron
22 @MP3438A  TMS1100  1979, Kenner Star Wars Electronic Battle Command
23  MP3450A  TMS1100  1979, MicroVision cartridge: Blockbuster
24  MP3454   TMS1100  1979, MicroVision cartridge: Star Trek Phaser Strike
25  MP3455   TMS1100  1980, MicroVision cartridge: Pinball
26  MP3457   TMS1100  1979, MicroVision cartridge: Mindbuster
27  MP3474   TMS1100  1979, MicroVision cartridge: Vegas Slots
28  MP3475   TMS1100  1979, MicroVision cartridge: Bowling
29  MP3479   TMS1100  1980, MicroVision cartridge: Baseball
30  MP3481   TMS1100  1979, MicroVision cartridge: Connect Four
31  MP3496   TMS1100  1980, MicroVision cartridge: Sea Duel
32 @MP6100A  TMS0980  1979, Ideal Electronic Detective
33 @MP6101B  TMS0980  1979, Parker Brothers Stop Thief
34 @MP7313   TMS1400  1980, Parker Brothers Bank Shot
35 @MP7314   TMS1400  1980, Parker Brothers Split Second
36 *MP7332   TMS1400  1981, Milton Bradley Dark Tower
37 @MP7334   TMS1400  1981, Coleco Total Control 4
389
39  inconsistent:
40 
41  M34009   TMS1100  1981, MicroVision cartridge: Alien Raiders
42  M34017   TMS1100  1981, MicroVision cartridge: Cosmic Hunter
43  M34047   TMS1100  1982, MicroVision cartridge: Super Blockbuster
44
45  CD7282SL TMS1100  1981, Tandy-12 (serial is similar to TI Speak & Spell series?)
46
47  (* denotes not yet emulated by MESS, @ denotes it's in this driver)
48
4910***************************************************************************/
5011
5112#include "emu.h"
5213#include "cpu/tms0980/tms0980.h"
5314#include "sound/speaker.h"
5415
55// internal artwork
5616#include "amaztron.lh"
5717#include "bankshot.lh"
5818#include "cnsector.lh"
19#include "ebball.lh"
5920#include "elecdet.lh"
6021#include "comp4.lh"
6122#include "mathmagi.lh"
62#include "merlin.lh" // clickable
63#include "simon.lh" // clickable
23#include "merlin.lh"
24#include "simon.lh"
6425#include "splitsec.lh"
6526#include "starwbc.lh"
6627#include "stopthie.lh"
67#include "tandy12.lh" // clickable
28#include "tandy12.lh"
6829#include "tc4.lh"
6930
70// test-layouts - use external artwork
71#include "ebball.lh"
7231
73
7432class hh_tms1k_state : public driver_device
7533{
7634public:
r244651r244652
11472
11573   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
11674   void display_update();
117   void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety);
11875   
11976   // game-specific handlers
12077   void mathmagi_display();
r244651r244652
13289   DECLARE_WRITE16_MEMBER(tc4_write_r);
13390   DECLARE_WRITE16_MEMBER(tc4_write_o);
13491
135   void ebball_display();
136   DECLARE_READ8_MEMBER(ebball_read_k);
137   DECLARE_WRITE16_MEMBER(ebball_write_r);
138   DECLARE_WRITE16_MEMBER(ebball_write_o);
139
14092   DECLARE_READ8_MEMBER(elecdet_read_k);
14193   DECLARE_WRITE16_MEMBER(elecdet_write_r);
14294   DECLARE_WRITE16_MEMBER(elecdet_write_o);
r244651r244652
166118   DECLARE_WRITE16_MEMBER(stopthief_write_r);
167119   DECLARE_WRITE16_MEMBER(stopthief_write_o);
168120
121   void bankshot_display();
169122   DECLARE_READ8_MEMBER(bankshot_read_k);
170123   DECLARE_WRITE16_MEMBER(bankshot_write_r);
171124   DECLARE_WRITE16_MEMBER(bankshot_write_o);
172125
126   void splitsec_display();
173127   DECLARE_READ8_MEMBER(splitsec_read_k);
174128   DECLARE_WRITE16_MEMBER(splitsec_write_r);
175129   DECLARE_WRITE16_MEMBER(splitsec_write_o);
r244651r244652
185139};
186140
187141
188// machine_start/reset
189
190142void hh_tms1k_state::machine_start()
191143{
192144   // zerofill
r244651r244652
216168   save_item(NAME(m_power_on));
217169}
218170
171
219172void hh_tms1k_state::machine_reset()
220173{
221174   m_power_on = true;
222175}
223176
224
225
226177/***************************************************************************
227178
228179  Helper Functions
r244651r244652
292243   display_update();
293244}
294245
295void hh_tms1k_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
296{
297   m_display_maxx = maxx;
298   m_display_maxy = maxy;
299246
300   // update current state
301   for (int y = 0; y < maxy; y++)
302      m_display_state[y] = (sety >> y & 1) ? setx : 0;
303   
304   display_update();
305}
306
307
308247UINT8 hh_tms1k_state::read_inputs(int columns)
309248{
310   UINT8 ret = 0;
249   UINT8 k = 0;
311250
312251   // read selected input rows
313252   for (int i = 0; i < columns; i++)
314253      if (m_inp_mux >> i & 1)
315         ret |= m_inp_matrix[i]->read();
254         k |= m_inp_matrix[i]->read();
316255
317   return ret;
256   return k;
318257}
319258
259INPUT_CHANGED_MEMBER(hh_tms1k_state::tms0980_power_button)
260{
261   m_power_on = (bool)(FPTR)param;
262   m_maincpu->set_input_line(INPUT_LINE_RESET, m_power_on ? CLEAR_LINE : ASSERT_LINE);
263}
320264
321// devices with a TMS0980 can auto power-off
322
323265WRITE_LINE_MEMBER(hh_tms1k_state::tms0980_auto_power_off)
324266{
267   // TMS0980 auto power-off opcode
325268   if (state)
326269   {
327270      m_power_on = false;
r244651r244652
329272   }
330273}
331274
332INPUT_CHANGED_MEMBER(hh_tms1k_state::tms0980_power_button)
333{
334   m_power_on = (bool)(FPTR)param;
335   m_maincpu->set_input_line(INPUT_LINE_RESET, m_power_on ? CLEAR_LINE : ASSERT_LINE);
336}
337
338
339
340275/***************************************************************************
341276
342277  Minidrivers (I/O, Inputs, Machine Config)
r244651r244652
396331   return read_inputs(6);
397332}
398333
334
399335WRITE16_MEMBER(hh_tms1k_state::mathmagi_write_r)
400336{
401337   // R3,R5-R7,R9,R10: input mux
r244651r244652
414350   m_o = data;
415351}
416352
417
418353/* physical button layout and labels is like this:
419354
420355    ON     ONE       [SEL] [NXT] [?]   [/]
r244651r244652
464399   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
465400INPUT_PORTS_END
466401
467// output PLA is not dumped
468402static const UINT16 mathmagi_output_pla[0x20] =
469403{
470404   lA+lB+lC+lD+lE+lF,      // 0
r244651r244652
501435   lA+lF+lE+lD+lC          // G
502436};
503437
438
504439static MACHINE_CONFIG_START( mathmagi, hh_tms1k_state )
505440
506441   /* basic machine hardware */
r244651r244652
691626void hh_tms1k_state::tc4_display()
692627{
693628   m_display_wait = 50;
629   m_display_maxy = 10;
630   m_display_maxx = 9;
694631   
695632   // R5,7,8,9 are 7segs
696   for (int y = 0; y < 10; y++)
633   for (int y = 0; y < m_display_maxy; y++)
697634      if (y >= 5 && y <= 9 && y != 6)
698635         m_7seg_mask[y] = 0x7f;
699636   
700637   // update current state (note: R6 as extra column!)
701   display_matrix(9, 10, (m_o | (m_r << 2 & 0x100)), m_r);
638   for (int y = 0; y < m_display_maxy; y++)
639      m_display_state[y] = (m_r >> y & 1) ? (m_o | (m_r << 2 & 0x100)) : 0;
640   
641   display_update();
702642}
703643
704644READ8_MEMBER(hh_tms1k_state::tc4_read_k)
r244651r244652
722662   m_inp_mux = data & 0x23f;
723663   
724664   // R6: led column 8
725   // +other columns
665   // +other: select leds
726666   m_r = data;
727667   tc4_display();
728668}
729669
730670WRITE16_MEMBER(hh_tms1k_state::tc4_write_o)
731671{
732   // O0-O7: led row
672   // O0-O7: leds/7segment
733673   m_o = data;
734674   tc4_display();
735675}
r244651r244652
805745  Entex Baseball
806746  * TMS1000NLP MP0914 (die labeled MP0914A)
807747
808  NOTE!: MESS external artwork is recommended
809
810  lamp translation table: led LDzz from game PCB = MESS lampyx:
811
812    LD0  = -        LD10 = lamp12   LD20 = lamp42   LD30 = lamp60
813    LD1  = lamp23   LD11 = lamp4    LD21 = lamp41   LD31 = lamp61
814    LD2  = lamp0    LD12 = lamp15   LD22 = lamp40   LD32 = lamp62
815    LD3  = lamp1    LD13 = lamp22   LD23 = lamp43   LD33 = lamp70
816    LD4  = lamp2    LD14 = lamp33   LD24 = lamp53   LD34 = lamp71
817    LD5  = lamp10   LD15 = lamp32   LD25 = lamp52
818    LD6  = lamp13   LD16 = lamp21   LD26 = lamp51
819    LD7  = lamp11   LD17 = lamp31   LD27 = lamp50
820    LD8  = lamp3    LD18 = lamp30   LD28 = lamp72
821    LD9  = lamp14   LD19 = lamp20   LD29 = lamp73
822
823748***************************************************************************/
824749
825void hh_tms1k_state::ebball_display()
826{
827   // R8 is a 7seg
828   m_7seg_mask[8] = 0x7f;
829   
830   display_matrix(7, 9, m_o, m_r);
831}
832
833READ8_MEMBER(hh_tms1k_state::ebball_read_k)
834{
835   // note: K8(Vss row) is always on
836   return m_inp_matrix[5]->read() | read_inputs(5);
837}
838
839WRITE16_MEMBER(hh_tms1k_state::ebball_write_r)
840{
841   // R1-R5: input mux
842   m_inp_mux = data >> 1 & 0x1f;
843   
844   // R9: speaker out
845   m_speaker->level_w(data >> 9 & 1);
846   
847   // R0-R8: led columns
848   m_r = data;
849   ebball_display();
850}
851
852WRITE16_MEMBER(hh_tms1k_state::ebball_write_o)
853{
854   // O0-O6: led row
855   // O7: N/C
856   m_o = data;
857   ebball_display();
858}
859
750// inputs
860751static INPUT_PORTS_START( ebball )
861   PORT_START("IN.0") // R1
862   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
863   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 )
864   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 )
865   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
866
867   PORT_START("IN.1") // R2
868   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON4 )
869   PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
870
871   PORT_START("IN.2") // R3
872   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 )
873   PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
874
875   PORT_START("IN.3") // R4
876   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON6 )
877   PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
878
879   PORT_START("IN.4") // R5
880   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON7 )
881   PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
882
883   PORT_START("IN.5") // Vss!
884   PORT_BIT( 0x07, IP_ACTIVE_HIGH, IPT_UNUSED )
885   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 )
886752INPUT_PORTS_END
887753
754// machine config
888755static MACHINE_CONFIG_START( ebball, hh_tms1k_state )
889756
890757   /* basic machine hardware */
891758   MCFG_CPU_ADD("maincpu", TMS1000, 350000) // RC osc. R=43K, C=47pf -> ~350kHz
892   MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, ebball_read_k))
893   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, ebball_write_r))
894   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, ebball_write_o))
895759
896   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
897760   MCFG_DEFAULT_LAYOUT(layout_ebball)
898761
899762   /* no video! */
r244651r244652
932795
933796WRITE16_MEMBER(hh_tms1k_state::elecdet_write_r)
934797{
935   // R7,R8: speaker on
936   m_speaker->level_w((data & 0x180 && m_o & 0x80) ? 1 : 0);
798   m_display_maxy = 7;
799   m_display_maxx = 7;
937800
938801   // R0-R6: select digit
939   for (int y = 0; y < 7; y++)
802   UINT8 o = BITSWAP8(m_o,7,5,2,1,4,0,6,3);
803   for (int y = 0; y < m_display_maxy; y++)
804   {
940805      m_7seg_mask[y] = 0x7f;
806      m_display_state[y] = (data >> y & 1) ? o : 0;
807   }
941808
942   display_matrix(7, 7, BITSWAP8(m_o,7,5,2,1,4,0,6,3), data);
809   display_update();
810
811   // R7,R8: speaker on
812   m_speaker->level_w((data & 0x180 && m_o & 0x80) ? 1 : 0);
943813}
944814
945815WRITE16_MEMBER(hh_tms1k_state::elecdet_write_o)
r244651r244652
963833*/
964834
965835static INPUT_PORTS_START( elecdet )
966   PORT_START("IN.0") // O0
836   PORT_START("IN.0") // O0 pin18
967837   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("4")
968838   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
969839   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("6")
970840   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) PORT_NAME("Private Question")
971841   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("5")
972842
973   PORT_START("IN.1") // O1
843   PORT_START("IN.1") // O1 pin17
974844   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
975845   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
976846   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("0")
977847   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_ENTER) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Enter")
978848   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
979849
980   PORT_START("IN.2") // O4
850   PORT_START("IN.2") // O4 pin14
981851   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("7")
982852   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
983853   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
984854   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_NAME("I Accuse")
985855   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("8")
986856
987   PORT_START("IN.3") // O6
857   PORT_START("IN.3") // O6 pin12
988858   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("1")
989859   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
990860   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("3")
r244651r244652
1038908
1039909void hh_tms1k_state::starwbc_display()
1040910{
1041   // R6,R8 are 7segs
1042   m_7seg_mask[6] = m_7seg_mask[8] = 0x7f;
1043   
1044   display_matrix(8, 10, m_o, m_r);
911   m_display_maxy = 10;
912   m_display_maxx = 8;
913
914   UINT8 o = (m_o << 4 & 0xf0) | (m_o >> 4 & 0x0f);
915   for (int y = 0; y < m_display_maxy; y+=2)
916   {
917      m_display_state[y] = (m_r >> y & 1) ? o : 0;
918     
919      // R6,R8 are 7segs
920      if (y == 6 || y == 8)
921         m_7seg_mask[y] = 0x7f;
922   }
923
924   display_update();
1045925}
1046926
1047927READ8_MEMBER(hh_tms1k_state::starwbc_read_k)
r244651r244652
1054934   // R0,R1,R3,R5,R7: input mux
1055935   m_inp_mux = (data & 3) | (data >> 1 & 4) | (data >> 2 & 8) | (data >> 3 & 0x10);
1056936
1057   // R9: speaker out
937   // R9: piezo speaker
1058938   m_speaker->level_w(data >> 9 & 1);
1059939
1060   // R0,R2,R4,R6,R8: led columns
1061   m_r = data & 0x155;
940   // R0,R2,R4,R6,R8: leds
941   m_r = data;
1062942   starwbc_display();
1063943}
1064944
1065945WRITE16_MEMBER(hh_tms1k_state::starwbc_write_o)
1066946{
1067   // O0-O7: led row
1068   m_o = (data << 4 & 0xf0) | (data >> 4 & 0x0f);
947   // O0-O7: leds state
948   m_o = data;
1069949   starwbc_display();
1070950}
1071951
1072952
953
1073954/* physical button layout and labels is like this:
1074955
1075956    (reconnnaissance=yellow)        (tactical reaction=green)
r244651r244652
1115996static MACHINE_CONFIG_START( starwbc, hh_tms1k_state )
1116997
1117998   /* basic machine hardware */
1118   MCFG_CPU_ADD("maincpu", TMS1100, 325000) // RC osc. R=51K, C=47pf -> ~325kHz
999   MCFG_CPU_ADD("maincpu", TMS1100, 300000) // RC osc. R=51K, C=47pf -> ~300kHz
11191000   MCFG_TMS1XXX_READ_K_CB(READ8(hh_tms1k_state, starwbc_read_k))
11201001   MCFG_TMS1XXX_WRITE_R_CB(WRITE16(hh_tms1k_state, starwbc_write_r))
11211002   MCFG_TMS1XXX_WRITE_O_CB(WRITE16(hh_tms1k_state, starwbc_write_o))
r244651r244652
11481029  Refer to the official manual for more information.
11491030
11501031
1032  TODO:
1033  - MCU clock is unknown
1034
11511035***************************************************************************/
11521036
11531037READ8_MEMBER(hh_tms1k_state::comp4_read_k)
r244651r244652
11631047   // R2    R7
11641048   // R1    R6
11651049   // R0    R5
1166   m_r = data;
1167   display_matrix(11, 1, m_r, m_o);
1050   m_display_maxx = 11;
1051   m_display_state[0] = data;
1052   display_update();
11681053}
11691054
11701055WRITE16_MEMBER(hh_tms1k_state::comp4_write_o)
11711056{
1057   // O0: leds common (always writes 1)
11721058   // O1-O3: input mux
1173   m_inp_mux = data >> 1 & 7;
1174
1175   // O0: leds common
11761059   // other bits: N/C
1177   m_o = data;
1178   display_matrix(11, 1, m_r, m_o);
1060   m_inp_mux = data >> 1 & 7;
11791061}
11801062
11811063
r244651r244652
12231105  Milton Bradley Simon, created by Ralph Baer
12241106
12251107  Revision A hardware:
1226  * TMS1000 (die labeled MP3226), DS75494 lamp driver
1108  * TMS1000 (has internal ROM), DS75494 lamp driver
12271109
12281110  Newer revisions have a smaller 16-pin MB4850 chip instead of the TMS1000.
12291111  This one has been decapped too, but we couldn't find an internal ROM.
r244651r244652
12471129   // R5 -> 75494 IN3 -> red lamp
12481130   // R6 -> 75494 IN5 -> yellow lamp
12491131   // R7 -> 75494 IN2 -> blue lamp
1250   display_matrix(4, 1, data >> 4, 1);
1132   m_display_maxx = 4;
1133   m_display_state[0] = data >> 4 & 0xf;
1134   display_update();
12511135
12521136   // R8 -> 75494 IN0 -> speaker
12531137   m_speaker->level_w(data >> 8 & 1);
r244651r244652
14541338   R7   R8   R9
14551339        R10
14561340   */
1457   display_matrix(11, 1, data, 1);
1341   m_display_maxx = 11;
1342   m_display_state[0] = data;
1343   display_update();
14581344}
14591345
14601346WRITE16_MEMBER(hh_tms1k_state::merlin_write_o)
r244651r244652
16511537
16521538***************************************************************************/
16531539
1540void hh_tms1k_state::bankshot_display()
1541{
1542   m_display_maxy = 11;
1543   m_display_maxx = 7;
1544   
1545   // update current state
1546   for (int y = 0; y < m_display_maxy; y++)
1547      m_display_state[y] = (m_r >> y & 1) ? m_o : 0;
1548   
1549   display_update();
1550}
1551
16541552READ8_MEMBER(hh_tms1k_state::bankshot_read_k)
16551553{
16561554   return read_inputs(2);
16571555}
16581556
1557
16591558WRITE16_MEMBER(hh_tms1k_state::bankshot_write_r)
16601559{
16611560   // R0: speaker out
r244651r244652
16641563   // R2,R3: input mux
16651564   m_inp_mux = data >> 2 & 3;
16661565
1667   // R2-R10: led columns
1566   // R2-R10: led rows
16681567   m_r = data & ~3;
1669   display_matrix(7, 11, m_o, m_r);
1568   bankshot_display();
16701569}
16711570
16721571WRITE16_MEMBER(hh_tms1k_state::bankshot_write_o)
16731572{
1674   // O0-O6: led row
1573   // O0-O6: led columns
16751574   // O7: N/C
16761575   m_o = data;
1677   display_matrix(7, 11, m_o, m_r);
1576   bankshot_display();
16781577}
16791578
16801579
r244651r244652
17441643
17451644  *: higher number indicates higher difficulty
17461645
1747  display layout, where number xy is lamp R(x),O(y)
1646***************************************************************************/
17481647
1648
1649/* display layout, where number xy is lamp R(x),O(y)
1650
17491651       00    02    04
17501652    10 01 12 03 14 05 16
17511653       11    13    15
r244651r244652
17571659       71    73    75
17581660    50 60 52 62 54 64 56
17591661       70    72    74
1662*/
17601663
1761***************************************************************************/
1664void hh_tms1k_state::splitsec_display()
1665{
1666   m_display_maxy = 8;
1667   m_display_maxx = 7;
1668   
1669   // update current state
1670   for (int y = 0; y < m_display_maxy; y++)
1671      m_display_state[y] = (m_r >> y & 1) ? m_o : 0;
1672   
1673   display_update();
1674}
17621675
17631676READ8_MEMBER(hh_tms1k_state::splitsec_read_k)
17641677{
r244651r244652
17731686   // R9,R10: input mux
17741687   m_inp_mux = data >> 9 & 3;
17751688
1776   // R0-R7: led columns
1689   // R0-R7: led rows
17771690   m_r = data;
1778   display_matrix(7, 8, m_o, m_r);
1691   display_update();
17791692}
17801693
17811694WRITE16_MEMBER(hh_tms1k_state::splitsec_write_o)
17821695{
1783   // O0-O6: led row
1696   // O0-O6: led columns
17841697   // O7: N/C
17851698   m_o = data;
1786   display_matrix(7, 8, m_o, m_r);
1699   splitsec_display();
17871700}
17881701
17891702static INPUT_PORTS_START( splitsec )
r244651r244652
17951708
17961709   PORT_START("IN.1") // R10
17971710   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
1798   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SELECT )
1799   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START )
1711   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Select")
1712   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Start")
18001713   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
18011714INPUT_PORTS_END
18021715
r244651r244652
18531766
18541767void hh_tms1k_state::tandy12_display()
18551768{
1769   m_display_maxx = 13;
1770   
18561771   // O0-O7: button lamps 1-8, R0-R3: button lamps 9-12
1857   display_matrix(13, 1, (m_o << 1 & 0x1fe) | (m_r << 9 & 0x1e00), 1);
1772   m_display_state[0] = (m_o << 1 & 0x1fe) | (m_r << 9 & 0x1e00);
1773   display_update();
18581774}
18591775
18601776READ8_MEMBER(hh_tms1k_state::tandy12_read_k)
r244651r244652
20811997
20821998ROM_START( amaztron )
20831999   ROM_REGION( 0x0800, "maincpu", 0 )
2084   ROM_LOAD( "mp3405", 0x0000, 0x0800, CRC(9cbc0009) SHA1(17772681271b59280687492f37fa0859998f041d) )
2000   ROM_LOAD( "tms1100nll_mp3405", 0x0000, 0x0800, CRC(9cbc0009) SHA1(17772681271b59280687492f37fa0859998f041d) )
20852001
20862002   ROM_REGION( 867, "maincpu:mpla", 0 )
20872003   ROM_LOAD( "tms1100_amaztron_mpla.pla", 0, 867, CRC(03574895) SHA1(04407cabfb3adee2ee5e4218612cb06c12c540f4) )
r244651r244652
20942010
20952011ROM_START( tc4 )
20962012   ROM_REGION( 0x1000, "maincpu", 0 )
2097   ROM_LOAD( "mp7334", 0x0000, 0x1000, CRC(923f3821) SHA1(a9ae342d7ff8dae1dedcd1e4984bcfae68586581) )
2013   ROM_LOAD( "tms1400nll_mp7334", 0x0000, 0x1000, CRC(923f3821) SHA1(a9ae342d7ff8dae1dedcd1e4984bcfae68586581) )
20982014
20992015   ROM_REGION( 867, "maincpu:mpla", 0 )
21002016   ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) )
r244651r244652
21162032
21172033ROM_START( elecdet )
21182034   ROM_REGION( 0x1000, "maincpu", 0 )
2119   ROM_LOAD( "mp6100a", 0x0000, 0x1000, CRC(6f396bb8) SHA1(1f104d4ca9bee0d4572be4779b7551dfe20c4f04) )
2035   ROM_LOAD( "tms0980nll_mp6100a", 0x0000, 0x1000, CRC(6f396bb8) SHA1(1f104d4ca9bee0d4572be4779b7551dfe20c4f04) )
21202036
21212037   ROM_REGION( 1246, "maincpu:ipla", 0 )
21222038   ROM_LOAD( "tms0980_default_ipla.pla", 0, 1246, CRC(42db9a38) SHA1(2d127d98028ec8ec6ea10c179c25e447b14ba4d0) )
r244651r244652
22042120
22052121ROM_START( stopthie )
22062122   ROM_REGION( 0x1000, "maincpu", 0 )
2207   ROM_LOAD( "mp6101b", 0x0000, 0x1000, CRC(8bde5bb4) SHA1(8c318fcce67acc24c7ae361f575f28ec6f94665a) )
2123   ROM_LOAD( "tms0980nll_mp6101b", 0x0000, 0x1000, CRC(8bde5bb4) SHA1(8c318fcce67acc24c7ae361f575f28ec6f94665a) )
22082124
22092125   ROM_REGION( 1246, "maincpu:ipla", 0 )
22102126   ROM_LOAD( "tms0980_default_ipla.pla", 0, 1246, CRC(42db9a38) SHA1(2d127d98028ec8ec6ea10c179c25e447b14ba4d0) )
r244651r244652
22322148
22332149ROM_START( bankshot )
22342150   ROM_REGION( 0x1000, "maincpu", 0 )
2235   ROM_LOAD( "mp7313", 0x0000, 0x1000, CRC(7a5016a9) SHA1(a8730dc8a282ffaa3d89e675f371d43eb39f39b4) )
2151   ROM_LOAD( "tms1400nll_mp7313", 0x0000, 0x1000, CRC(7a5016a9) SHA1(a8730dc8a282ffaa3d89e675f371d43eb39f39b4) )
22362152
22372153   ROM_REGION( 867, "maincpu:mpla", 0 )
22382154   ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) )
r244651r244652
22432159
22442160ROM_START( splitsec )
22452161   ROM_REGION( 0x1000, "maincpu", 0 )
2246   ROM_LOAD( "mp7314", 0x0000, 0x1000, CRC(e94b2098) SHA1(f0fc1f56a829252185592a2508740354c50bedf8) )
2162   ROM_LOAD( "tms1400nll_mp7314", 0x0000, 0x1000, CRC(e94b2098) SHA1(f0fc1f56a829252185592a2508740354c50bedf8) )
22472163
22482164   ROM_REGION( 867, "maincpu:mpla", 0 )
22492165   ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) )
r244651r244652
22642180
22652181ROM_START( unk3403 )
22662182   ROM_REGION( 0x0800, "maincpu", 0 )
2267   ROM_LOAD( "mp3403", 0x0000, 0x0800, CRC(9eabaa7d) SHA1(b1f54587ed7f2bbf3a5d49075c807296384c2b06) )
2183   ROM_LOAD( "tms1100nll_mp3403", 0x0000, 0x0800, CRC(9eabaa7d) SHA1(b1f54587ed7f2bbf3a5d49075c807296384c2b06) )
22682184
22692185   ROM_REGION( 867, "maincpu:mpla", 0 )
22702186   ROM_LOAD( "tms1100_default_mpla.pla", 0, 867, BAD_DUMP CRC(62445fc9) SHA1(d6297f2a4bc7a870b76cc498d19dbb0ce7d69fec) ) // not verified
trunk/src/mess/drivers/hh_ucom4.c
r244651r244652
55  NEC uCOM4 MCU handhelds
66
77
8
9  serial  device  etc
10------------------------------------------
11 @048     uPD552  1980, Tomy Tennis
12 *085     uPD650  1980, Roland TR-808
13  102     uPD553  1981, Bandai Block Out
14 *128     uPD650  1982, Roland TR-606
15  133     uPD650  1982, Roland TB-303
16 @160     uPD553  1982, Tomy Pac Man
17 @206     uPD553  1982, Epoch Dracula
18 @258     uPD553  1984, Tomy Alien Chase
19
20  (* denotes not yet emulated by MESS, @ denotes it's in this driver)
21
228***************************************************************************/
239
2410#include "emu.h"
2511#include "cpu/ucom4/ucom4.h"
2612#include "sound/speaker.h"
2713
28// test-layouts - use external artwork
29#include "alnchase.lh"
30#include "edracula.lh"
3114#include "tmpacman.lh"
32#include "tmtennis.lh"
3315
3416
3517class hh_ucom4_state : public driver_device
r244651r244652
4729
4830   // devices
4931   required_device<cpu_device> m_maincpu;
50   optional_ioport_array<3> m_inp_matrix; // max 3
32   optional_ioport_array<4> m_inp_matrix; // max 4
5133   optional_device<speaker_sound_device> m_speaker;
5234   
5335   // misc common
5436   UINT16 m_inp_mux;
5537
56   UINT8 read_inputs(int columns);
57
5838   virtual void machine_start();
39   virtual void machine_reset();
5940
6041   // display common
6142   int m_display_wait;
r244651r244652
7253
7354   TIMER_DEVICE_CALLBACK_MEMBER(display_decay_tick);
7455   void display_update();
75   void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety);
7656
7757   // game-specific handlers
78   DECLARE_WRITE8_MEMBER(edracula_grid_w);
79   DECLARE_WRITE8_MEMBER(edracula_plate_w);
80   DECLARE_WRITE8_MEMBER(edracula_port_i_w);
8158   
82   DECLARE_READ8_MEMBER(tmtennis_input_r);
83   DECLARE_WRITE8_MEMBER(tmtennis_grid_w);
84   DECLARE_WRITE8_MEMBER(tmtennis_plate_w);
85   DECLARE_WRITE8_MEMBER(tmtennis_port_e_w);
86   void tmtennis_set_clock();
87   DECLARE_INPUT_CHANGED_MEMBER(tmtennis_difficulty_switch);
88   DECLARE_MACHINE_RESET(tmtennis);
89   
90   DECLARE_READ8_MEMBER(alnchase_input_r);
91   DECLARE_WRITE8_MEMBER(alnchase_display_w);
92   DECLARE_WRITE8_MEMBER(alnchase_port_e_w);
9359};
9460
9561
r244651r244652
12187}
12288
12389
90void hh_ucom4_state::machine_reset()
91{
92}
12493
12594/***************************************************************************
12695
r244651r244652
12897
12998***************************************************************************/
13099
100// LED segments
101#if 0
102enum
103{
104   lA = 0x01,
105   lB = 0x02,
106   lC = 0x04,
107   lD = 0x08,
108   lE = 0x10,
109   lF = 0x20,
110   lG = 0x40,
111   lDP = 0x80
112};
113#endif
131114
132
133115// The device strobes the outputs very fast, it is unnoticeable to the user.
134116// To prevent flickering here, we need to simulate a decay.
135117
r244651r244652
180162   display_update();
181163}
182164
183void hh_ucom4_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
184{
185   m_display_maxx = maxx;
186   m_display_maxy = maxy;
187165
188   // update current state
189   for (int y = 0; y < maxy; y++)
190      m_display_state[y] = (sety >> y & 1) ? setx : 0;
191   
192   display_update();
193}
194166
195
196UINT8 hh_ucom4_state::read_inputs(int columns)
197{
198   UINT8 ret = 0;
199
200   // read selected input rows
201   for (int i = 0; i < columns; i++)
202      if (m_inp_mux >> i & 1)
203         ret |= m_inp_matrix[i]->read();
204
205   return ret;
206}
207
208
209167/***************************************************************************
210168
211169  Minidrivers (I/O, Inputs, Machine Config)
r244651r244652
214172
215173/***************************************************************************
216174
217  Epoch Dracula (manufactured in Japan)
218  * PCB label 96121
219  * NEC uCOM-43 MCU, labeled D553C 206
220  * cyan/red/green VFD display NEC FIP8BM20T (FIP=fluorescent indicator panel)
221
222  known releases:
223  - Japan: Dracula House, yellow case
224  - USA: Dracula, red case
225  - Other: Dracula, yellow case, published by Hales
226
227  NOTE!: MESS external artwork is recommended
228
229
230***************************************************************************/
231
232WRITE8_MEMBER(hh_ucom4_state::edracula_grid_w)
233{
234   // port C/D: vfd matrix grid
235   int shift = (offset - NEC_UCOM4_PORTC) * 4;
236   m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
237
238   display_matrix(18, 8, m_plate, m_grid);
239}
240
241WRITE8_MEMBER(hh_ucom4_state::edracula_plate_w)
242{
243   // port E/F/G/H/I01: vfd matrix plate
244   int shift = (offset - NEC_UCOM4_PORTE) * 4;
245   m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
246
247   display_matrix(18, 8, m_plate, m_grid);
248}
249
250WRITE8_MEMBER(hh_ucom4_state::edracula_port_i_w)
251{
252   edracula_plate_w(space, offset, data & 3);
253
254   // I2: speaker out
255   m_speaker->level_w(data >> 2 & 1);
256}
257
258
259static INPUT_PORTS_START( edracula )
260   PORT_START("IN.0")
261   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT )
262   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START )
263   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
264   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED )
265
266   PORT_START("IN.1")
267   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
268   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
269   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
270   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
271INPUT_PORTS_END
272
273
274static MACHINE_CONFIG_START( edracula, hh_ucom4_state )
275
276   /* basic machine hardware */
277   MCFG_CPU_ADD("maincpu", NEC_D553, XTAL_400kHz)
278   MCFG_UCOM4_READ_A_CB(IOPORT("IN.0"))
279   MCFG_UCOM4_READ_B_CB(IOPORT("IN.1"))
280   MCFG_UCOM4_WRITE_C_CB(WRITE8(hh_ucom4_state, edracula_grid_w))
281   MCFG_UCOM4_WRITE_D_CB(WRITE8(hh_ucom4_state, edracula_grid_w))
282   MCFG_UCOM4_WRITE_E_CB(WRITE8(hh_ucom4_state, edracula_plate_w))
283   MCFG_UCOM4_WRITE_F_CB(WRITE8(hh_ucom4_state, edracula_plate_w))
284   MCFG_UCOM4_WRITE_G_CB(WRITE8(hh_ucom4_state, edracula_plate_w))
285   MCFG_UCOM4_WRITE_H_CB(WRITE8(hh_ucom4_state, edracula_plate_w))
286   MCFG_UCOM4_WRITE_I_CB(WRITE8(hh_ucom4_state, edracula_port_i_w))
287
288   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_ucom4_state, display_decay_tick, attotime::from_msec(1))
289   MCFG_DEFAULT_LAYOUT(layout_edracula)
290
291   /* no video! */
292
293   /* sound hardware */
294   MCFG_SPEAKER_STANDARD_MONO("mono")
295   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
296   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
297MACHINE_CONFIG_END
298
299
300
301
302/***************************************************************************
303
304  Tomy(tronic) Tennis (manufactured in Japan)
305  * board labeled TOMY TN-04 TENNIS
306  * NEC uCOM-44 MCU, labeled D552C 048
307  * VFD display NEC FIP11AM15T
308
309  The initial release of this game was in 1979, known as Pro-Tennis,
310  it has a D553 instead of D552, with just a little over 50% ROM used.
311
312  This is an early VFD simple electronic tennis game. Player 1 is on the right
313  side, player 2 or CPU on the left. Each player has six possible positions
314  where to hit the ball. A backdrop behind the VFD shows a tennis court.
315
316  NOTE!: MESS external artwork is recommended
317
318***************************************************************************/
319
320
321READ8_MEMBER(hh_ucom4_state::tmtennis_input_r)
322{
323   // port A/B: buttons
324   return ~read_inputs(2) >> (offset*4);
325}
326
327WRITE8_MEMBER(hh_ucom4_state::tmtennis_port_e_w)
328{
329   // E0/E1: input mux
330   // E2: speaker out
331   // E3: N/C
332   m_inp_mux = data & 3;
333   m_speaker->level_w(data >> 2 & 1);
334}
335
336WRITE8_MEMBER(hh_ucom4_state::tmtennis_plate_w)
337{
338   // port C/D/F: vfd matrix plate
339   if (offset == NEC_UCOM4_PORTF) offset--;
340   int shift = (offset - NEC_UCOM4_PORTC) * 4;
341   m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
342
343   display_matrix(12, 12, m_plate, m_grid);
344}
345
346WRITE8_MEMBER(hh_ucom4_state::tmtennis_grid_w)
347{
348   // port G/H/I: vfd matrix grid
349   int shift = (offset - NEC_UCOM4_PORTG) * 4;
350   m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
351
352   display_matrix(12, 12, m_plate, m_grid);
353}
354
355
356
357/* Pro-Tennis physical button layout and labels is like this:
358
359    [SERVE] [1] [2] [3]       [3] [2] [1] [SERVE]
360            [4] [5] [6]       [6] [5] [4]
361
362    PRACTICE<--PRO1-->PRO2    1PLAYER<--OFF-->2PLAYER
363*/
364
365static INPUT_PORTS_START( tmtennis )
366   PORT_START("IN.0") // E0 port A/B
367   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("P1 Serve")
368   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_NAME("P2 Serve")
369   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 )
370   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 )
371   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON2 )
372   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON5 )
373   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON3 )
374   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON6 )
375
376   PORT_START("IN.1") // E1 port A/B
377   PORT_CONFNAME( 0x101, 0x100, DEF_STR( Difficulty ) ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_ucom4_state, tmtennis_difficulty_switch, NULL)
378   PORT_CONFSETTING(     0x001, "Practice" )
379   PORT_CONFSETTING(     0x100, "Pro 1" ) // -> tmtennis_difficulty_switch
380   PORT_CONFSETTING(     0x000, "Pro 2" )
381   PORT_CONFNAME( 0x02, 0x00, "Players" )
382   PORT_CONFSETTING(    0x00, "1" )
383   PORT_CONFSETTING(    0x02, "2" )
384   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2)
385   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(2)
386   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2)
387   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(2)
388   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(2)
389   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(2)
390INPUT_PORTS_END
391
392void hh_ucom4_state::tmtennis_set_clock()
393{
394   // MCU clock is from an LC circuit oscillating by default at ~360kHz,
395   // but on PRO1, the difficulty switch puts a capacitor across the LC circuit
396   // to slow it down to ~260kHz.
397   m_maincpu->set_unscaled_clock(m_inp_matrix[1]->read() & 0x100 ? 260000 : 360000);
398}
399
400INPUT_CHANGED_MEMBER(hh_ucom4_state::tmtennis_difficulty_switch)
401{
402   tmtennis_set_clock();
403}
404
405MACHINE_RESET_MEMBER(hh_ucom4_state, tmtennis)
406{
407   tmtennis_set_clock();
408}
409
410
411static MACHINE_CONFIG_START( tmtennis, hh_ucom4_state )
412
413   /* basic machine hardware */
414   MCFG_CPU_ADD("maincpu", NEC_D552, 360000) // see tmtennis_set_clock
415   MCFG_UCOM4_READ_A_CB(READ8(hh_ucom4_state, tmtennis_input_r))
416   MCFG_UCOM4_READ_B_CB(READ8(hh_ucom4_state, tmtennis_input_r))
417   MCFG_UCOM4_WRITE_C_CB(WRITE8(hh_ucom4_state, tmtennis_plate_w))
418   MCFG_UCOM4_WRITE_D_CB(WRITE8(hh_ucom4_state, tmtennis_plate_w))
419   MCFG_UCOM4_WRITE_E_CB(WRITE8(hh_ucom4_state, tmtennis_port_e_w))
420   MCFG_UCOM4_WRITE_F_CB(WRITE8(hh_ucom4_state, tmtennis_plate_w))
421   MCFG_UCOM4_WRITE_G_CB(WRITE8(hh_ucom4_state, tmtennis_grid_w))
422   MCFG_UCOM4_WRITE_H_CB(WRITE8(hh_ucom4_state, tmtennis_grid_w))
423   MCFG_UCOM4_WRITE_I_CB(WRITE8(hh_ucom4_state, tmtennis_grid_w))
424
425   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_ucom4_state, display_decay_tick, attotime::from_msec(1))
426   MCFG_DEFAULT_LAYOUT(layout_tmtennis)
427
428   MCFG_MACHINE_RESET_OVERRIDE(hh_ucom4_state, tmtennis)
429
430   /* no video! */
431
432   /* sound hardware */
433   MCFG_SPEAKER_STANDARD_MONO("mono")
434   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
435   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
436MACHINE_CONFIG_END
437
438/***************************************************************************
439
440  Tomy(tronic) Pac-Man (manufactured in Japan)
175  Tomytronic Pac-Man (manufactured in Japan)
441176  * boards are labeled TN-08 2E108E01
442177  * NEC uCOM-43 MCU, labeled D553C 160
443178  * cyan/red/green VFD display NEC FIP8AM18T
r244651r244652
449184  - UK: Puckman (Tomy), and also as Munchman, published by Grandstand
450185  - Australia: Pac Man-1, published by Futuretronics
451186
452  NOTE!: MESS external artwork is recommended
453
454187***************************************************************************/
455188
456189static INPUT_PORTS_START( tmpacman )
r244651r244652
474207
475208
476209
477/***************************************************************************
478210
479  Tomy Alien Chase (manufactured in Japan)
480  * boards are labeled TN-16 2E121B01
481  * NEC uCOM-43 MCU, labeled D553C 258
482  * red/green VFD display NEC FIP9AM24T with color overlay, 2-sided*
483211
484  *Player one views the VFD from the front (grid+filament side) while the
485  opposite player views it from the back side (through the conductive traces),
486  basically a mirror-image.
487212
488  This is a space-themed tabletop VFD electronic game. To start, simply
489  press [UP]. Hold a joystick direction to move around.
490213
491  NOTE!: MESS external artwork is recommended
492
493***************************************************************************/
494
495
496
497READ8_MEMBER(hh_ucom4_state::alnchase_input_r)
498{
499   // port A: buttons
500   return read_inputs(2);
501}
502
503WRITE8_MEMBER(hh_ucom4_state::alnchase_display_w)
504{
505   if (offset <= NEC_UCOM4_PORTE)
506   {
507      // C/D/E0: vfd matrix grid
508      int shift = (offset - NEC_UCOM4_PORTC) * 4;
509      m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
510
511      // C0(grid 0): input enable PL1
512      // D0(grid 4): input enable PL2
513      m_inp_mux = (m_grid & 1) | (m_grid >> 3 & 2);
514   }
515
516   if (offset >= NEC_UCOM4_PORTE)
517   {
518      // E23/F/G/H/I: vfd matrix plate
519      int shift = (offset - NEC_UCOM4_PORTE) * 4;
520      m_plate = ((m_plate << 2 & ~(0xf << shift)) | (data << shift)) >> 2;
521   }
522
523   display_matrix(17, 9, m_plate, m_grid);
524}
525
526WRITE8_MEMBER(hh_ucom4_state::alnchase_port_e_w)
527{
528   alnchase_display_w(space, offset, data);
529
530   // E1: speaker out
531   m_speaker->level_w(data >> 1 & 1);
532}
533
534/* physical button layout and labels is like this:
535
536    POWER SOUND LEVEL PLAYER
537     ON    ON    PRO   TWO        START
538      o     o     |     |
539      |     |     |     |       [joystick]
540      |     |     o     o
541     OFF   OFF   AMA   ONE     GAME 0,1,2,3
542
543    1 PLAYER SIDE
544
545    other player side only has a joystick
546*/
547
548static INPUT_PORTS_START( alnchase )
549   PORT_START("IN.0") // C0 port A
550   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
551   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
552   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
553   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
554
555   PORT_START("IN.1") // D0 port A
556   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) // on non-mirrored view, swap P2 left/right
557   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) // "
558   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
559   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
560
561   PORT_START("IN.2") // port B
562   PORT_CONFNAME( 0x01, 0x01, "Players" )
563   PORT_CONFSETTING(    0x01, "1" )
564   PORT_CONFSETTING(    0x00, "2" )
565   PORT_CONFNAME( 0x02, 0x00, DEF_STR( Difficulty ) )
566   PORT_CONFSETTING(    0x00, "Amateur" )
567   PORT_CONFSETTING(    0x02, "Professional" )
568   PORT_BIT( 0x0c, IP_ACTIVE_HIGH, IPT_UNUSED )
569INPUT_PORTS_END
570
571static MACHINE_CONFIG_START( alnchase, hh_ucom4_state )
572
573   /* basic machine hardware */
574   MCFG_CPU_ADD("maincpu", NEC_D553, XTAL_400kHz)
575   MCFG_UCOM4_READ_A_CB(READ8(hh_ucom4_state, alnchase_input_r))
576   MCFG_UCOM4_READ_B_CB(IOPORT("IN.2"))
577   MCFG_UCOM4_WRITE_C_CB(WRITE8(hh_ucom4_state, alnchase_display_w))
578   MCFG_UCOM4_WRITE_D_CB(WRITE8(hh_ucom4_state, alnchase_display_w))
579   MCFG_UCOM4_WRITE_E_CB(WRITE8(hh_ucom4_state, alnchase_port_e_w))
580   MCFG_UCOM4_WRITE_F_CB(WRITE8(hh_ucom4_state, alnchase_display_w))
581   MCFG_UCOM4_WRITE_G_CB(WRITE8(hh_ucom4_state, alnchase_display_w))
582   MCFG_UCOM4_WRITE_H_CB(WRITE8(hh_ucom4_state, alnchase_display_w))
583   MCFG_UCOM4_WRITE_I_CB(WRITE8(hh_ucom4_state, alnchase_display_w))
584
585   MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_ucom4_state, display_decay_tick, attotime::from_msec(1))
586   MCFG_DEFAULT_LAYOUT(layout_alnchase)
587
588   /* no video! */
589
590   /* sound hardware */
591   MCFG_SPEAKER_STANDARD_MONO("mono")
592   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
593   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
594MACHINE_CONFIG_END
595
596
597
598
599
600214/***************************************************************************
601215
602216  Game driver(s)
603217
604218***************************************************************************/
605219
606ROM_START( edracula )
607   ROM_REGION( 0x0800, "maincpu", 0 )
608   ROM_LOAD( "d553c-206", 0x0000, 0x0800, CRC(b524857b) SHA1(c1c89ed5dd4bb1e6e98462dc8fa5af2aa48d8ede) )
609ROM_END
610
611
612ROM_START( tmtennis )
613   ROM_REGION( 0x0400, "maincpu", 0 )
614   ROM_LOAD( "d552c-048", 0x0000, 0x0400, CRC(78702003) SHA1(4d427d4dbeed901770c682338867f58c7b54eee3) )
615ROM_END
616
617
618
619220ROM_START( tmpacman )
620221   ROM_REGION( 0x0800, "maincpu", 0 )
621222   ROM_LOAD( "d553c-160", 0x0000, 0x0800, CRC(b21a8af7) SHA1(e3122be1873ce76a4067386bf250802776f0c2f9) )
622223ROM_END
623224
624225
625ROM_START( alnchase )
626   ROM_REGION( 0x0800, "maincpu", 0 )
627   ROM_LOAD( "d553c-258", 0x0000, 0x0800, CRC(c5284ff5) SHA1(6a20aaacc9748f0e0335958f3cea482e36153704) )
628ROM_END
629
630
631
632CONS( 1982, edracula, 0, 0, edracula, edracula, driver_device, 0, "Epoch", "Dracula (Epoch)", GAME_SUPPORTS_SAVE | GAME_REQUIRES_ARTWORK )
633
634CONS( 1980, tmtennis, 0, 0, tmtennis, tmtennis, driver_device, 0, "Tomy", "Tennis (Tomy)", GAME_SUPPORTS_SAVE | GAME_REQUIRES_ARTWORK )
635CONS( 1982, tmpacman, 0, 0, tmpacman, tmpacman, driver_device, 0, "Tomy", "Pac Man (Tomy)", GAME_SUPPORTS_SAVE | GAME_REQUIRES_ARTWORK | GAME_NOT_WORKING )
636CONS( 1984, alnchase, 0, 0, alnchase, alnchase, driver_device, 0, "Tomy", "Alien Chase", GAME_SUPPORTS_SAVE | GAME_REQUIRES_ARTWORK )
226CONS( 1981, tmpacman, 0, 0, tmpacman, tmpacman, driver_device, 0, "Tomy", "Pac Man (Tomy)", GAME_SUPPORTS_SAVE | GAME_REQUIRES_ARTWORK | GAME_NOT_WORKING )
trunk/src/mess/drivers/mbee.c
r244651r244652
8888    3. At the Basic prompt, type in EDASM press enter. At the memory size
8989       prompt press enter. Now, make sure the keyboard works properly.
9090
91    How to use the config switch for PIO B7:
92    - Teleterm: Must use RTC. Anything else makes teleterm go crazy.
93    - 256TC, 128, 128p: Doesn't seem to matter, leave at the default.
94    - Standard: Has no effect, best left at "Tied High"
95    - Other rom-based models: "VS" to make the Telcom clock work, or "Tied high".
96    - 56k: not sure yet, leave as "Tied high" until more is known.
97
98    How to use programs that need functions keys on models that use the old
99    keyboard (for example, to run Simply Write on a 128k model).
100    Press Ctrl+Shift+number, eg for F1 press hold down Ctrl Shift, press 1.
101
10291***************************************************************************
10392
10493    TODO/not working:
r244651r244652
119108      crashes due to a bug in z80pio emulation.
120109
121110    - 256tc: Keyboard ROM U60 needs to be dumped.
122    - 128k, 64k: PALs need to be dumped for the bankswitching.
111    - 128k: GOLD PAL needs to be dumped for the bankswitching.
112    - 64k: RED PAL needs to be dumped for the bankswitching.
123113
124    - Teleterm: keyboard has problems. The schematic shows it using the old-style keyboard,
125                however it actually uses the new keyboard with interrupts.
114    - Teleterm: keyboard has multiple severe problems. Also, the schematic shows
115                it using the old-style keyboard, however this must be wrong since
116                the computer has function keys, which are only available on the
117                new keyboard.
126118
127119    - Mouse: a few programs support the use of a serial mouse which interfaced
128120             directly to the Z80PIO. However there's little info to be found.
r244651r244652
143135
144136static ADDRESS_MAP_START(mbee_mem, AS_PROGRAM, 8, mbee_state)
145137   ADDRESS_MAP_UNMAP_HIGH
146   AM_RANGE(0x0000, 0x3fff) AM_RAM
138   AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot")
139   AM_RANGE(0x1000, 0x3fff) AM_RAM
140   AM_RANGE(0x4000, 0x7fff) AM_WRITENOP    // Needed because quickload to here will crash MESS
147141   AM_RANGE(0x8000, 0xefff) AM_ROM
148   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(video_low_r, video_low_w)
149   AM_RANGE(0xf800, 0xffff) AM_READWRITE(video_high_r, video_high_w)
142   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(mbee_low_r, mbee_low_w)
143   AM_RANGE(0xf800, 0xffff) AM_READWRITE(mbee_high_r, mbee_high_w)
150144ADDRESS_MAP_END
151145
152146static ADDRESS_MAP_START(mbeeic_mem, AS_PROGRAM, 8, mbee_state)
153   AM_RANGE(0x0000, 0x7fff) AM_RAM
147   AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot")
148   AM_RANGE(0x1000, 0x7fff) AM_RAM
154149   AM_RANGE(0x8000, 0xbfff) AM_ROM
155150   AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("pak")
156151   AM_RANGE(0xe000, 0xefff) AM_ROM
157   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(video_low_r, video_low_w)
158   AM_RANGE(0xf800, 0xffff) AM_READWRITE(video_high_r, video_high_w)
152   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(mbee_low_r, mbee_low_w)
153   AM_RANGE(0xf800, 0xffff) AM_READWRITE(mbeeic_high_r, mbeeic_high_w)
159154ADDRESS_MAP_END
160155
161156static ADDRESS_MAP_START(mbeepc_mem, AS_PROGRAM, 8, mbee_state)
162   AM_RANGE(0x0000, 0x7fff) AM_RAM
157   AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot")
158   AM_RANGE(0x1000, 0x7fff) AM_RAM
163159   AM_RANGE(0x8000, 0xbfff) AM_ROM
164160   AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("pak")
165161   AM_RANGE(0xe000, 0xefff) AM_ROMBANK("telcom")
166   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(video_low_r, video_low_w)
167   AM_RANGE(0xf800, 0xffff) AM_READWRITE(video_high_r, video_high_w)
162   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(mbee_low_r, mbee_low_w)
163   AM_RANGE(0xf800, 0xffff) AM_READWRITE(mbeeic_high_r, mbeeic_high_w)
168164ADDRESS_MAP_END
169165
166static ADDRESS_MAP_START(mbeepc85_mem, AS_PROGRAM, 8, mbee_state)
167   AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot")
168   AM_RANGE(0x1000, 0x7fff) AM_RAM
169   AM_RANGE(0x8000, 0xbfff) AM_ROM
170   AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("pak")
171   AM_RANGE(0xe000, 0xefff) AM_ROMBANK("telcom")
172   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(mbee_low_r, mbee_low_w)
173   AM_RANGE(0xf800, 0xffff) AM_READWRITE(mbeeic_high_r, mbeeic_high_w)
174ADDRESS_MAP_END
175
170176static ADDRESS_MAP_START(mbeeppc_mem, AS_PROGRAM, 8, mbee_state)
171   AM_RANGE(0x0000, 0x7fff) AM_RAM
177   AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot")
178   AM_RANGE(0x1000, 0x7fff) AM_RAM
172179   AM_RANGE(0x8000, 0x9fff) AM_ROMBANK("basic")
173180   AM_RANGE(0xa000, 0xbfff) AM_ROM
174181   AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("pak")
175182   AM_RANGE(0xe000, 0xefff) AM_ROMBANK("telcom")
176   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(video_low_r, video_low_w)
177   AM_RANGE(0xf800, 0xffff) AM_READWRITE(video_high_r, video_high_w)
183   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(mbeeppc_low_r, mbeeppc_low_w)
184   AM_RANGE(0xf800, 0xffff) AM_READWRITE(mbeeppc_high_r, mbeeppc_high_w)
178185ADDRESS_MAP_END
179186
180187static ADDRESS_MAP_START(mbee56_mem, AS_PROGRAM, 8, mbee_state)
181   AM_RANGE(0x0000, 0xdfff) AM_RAM
188   AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot")
189   AM_RANGE(0x1000, 0xdfff) AM_RAM
182190   AM_RANGE(0xe000, 0xefff) AM_ROM
183   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(video_low_r, video_low_w)
184   AM_RANGE(0xf800, 0xffff) AM_READWRITE(video_high_r, video_high_w)
191   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(mbee_low_r, mbee_low_w)
192   AM_RANGE(0xf800, 0xffff) AM_READWRITE(mbeeic_high_r, mbeeic_high_w)
185193ADDRESS_MAP_END
186194
187195static ADDRESS_MAP_START(mbee256_mem, AS_PROGRAM, 8, mbee_state)
r244651r244652
204212ADDRESS_MAP_END
205213
206214static ADDRESS_MAP_START(mbeett_mem, AS_PROGRAM, 8, mbee_state)
207   AM_RANGE(0x0000, 0x7fff) AM_RAM
215   AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot")
216   AM_RANGE(0x1000, 0x7fff) AM_RAM
208217   AM_RANGE(0x8000, 0x9fff) AM_ROM
209218   AM_RANGE(0xa000, 0xbfff) AM_RAM
210219   AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("pak")
211220   AM_RANGE(0xe000, 0xefff) AM_ROMBANK("telcom")
212   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(video_low_r, video_low_w)
213   AM_RANGE(0xf800, 0xffff) AM_READWRITE(video_high_r, video_high_w)
221   AM_RANGE(0xf000, 0xf7ff) AM_READWRITE(mbeeppc_low_r, mbeeppc_low_w)
222   AM_RANGE(0xf800, 0xffff) AM_READWRITE(mbeeppc_high_r, mbeeppc_high_w)
214223ADDRESS_MAP_END
215224
216225static ADDRESS_MAP_START(mbee_io, AS_IO, 8, mbee_state)
217226   ADDRESS_MAP_GLOBAL_MASK(0xff)
218227   ADDRESS_MAP_UNMAP_HIGH
219228   AM_RANGE(0x00, 0x03) AM_MIRROR(0x10) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
220   AM_RANGE(0x0b, 0x0b) AM_MIRROR(0x10) AM_WRITE(port0b_w)
229   AM_RANGE(0x0b, 0x0b) AM_MIRROR(0x10) AM_READWRITE(mbee_0b_r, mbee_0b_w)
221230   AM_RANGE(0x0c, 0x0c) AM_MIRROR(0x10) AM_READWRITE(m6545_status_r, m6545_index_w)
222231   AM_RANGE(0x0d, 0x0d) AM_MIRROR(0x10) AM_READWRITE(m6545_data_r, m6545_data_w)
223232ADDRESS_MAP_END
r244651r244652
226235   ADDRESS_MAP_GLOBAL_MASK(0xff)
227236   ADDRESS_MAP_UNMAP_HIGH
228237   AM_RANGE(0x00, 0x03) AM_MIRROR(0x10) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
229   AM_RANGE(0x08, 0x08) AM_MIRROR(0x10) AM_READWRITE(port08_r, port08_w)
230   AM_RANGE(0x09, 0x09) AM_WRITENOP /* Listed as "Colour Wait Off" or "USART 2651" but doesn't appear in the schematics */
231   AM_RANGE(0x0a, 0x0a) AM_MIRROR(0x10) AM_WRITE(port0a_w)
232   AM_RANGE(0x0b, 0x0b) AM_MIRROR(0x10) AM_WRITE(port0b_w)
238   AM_RANGE(0x08, 0x08) AM_MIRROR(0x10) AM_READWRITE(mbeeic_08_r, mbeeic_08_w)
239   AM_RANGE(0x09, 0x09) AM_MIRROR(0x10) AM_NOP /* Listed as "Colour Wait Off" or "USART 2651" but doesn't appear in the schematics */
240   AM_RANGE(0x0a, 0x0a) AM_MIRROR(0x10) AM_READWRITE(mbeeic_0a_r, mbeeic_0a_w)
241   AM_RANGE(0x0b, 0x0b) AM_MIRROR(0x10) AM_READWRITE(mbee_0b_r, mbee_0b_w)
233242   AM_RANGE(0x0c, 0x0c) AM_MIRROR(0x10) AM_READWRITE(m6545_status_r, m6545_index_w)
234243   AM_RANGE(0x0d, 0x0d) AM_MIRROR(0x10) AM_READWRITE(m6545_data_r, m6545_data_w)
235244ADDRESS_MAP_END
r244651r244652
237246static ADDRESS_MAP_START(mbeepc_io, AS_IO, 8, mbee_state)
238247   ADDRESS_MAP_UNMAP_HIGH
239248   AM_RANGE(0x0000, 0x0003) AM_MIRROR(0xff10) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
240   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff10) AM_READWRITE(port08_r, port08_w)
241   AM_RANGE(0x0009, 0x0009) AM_MIRROR(0xff00) AM_WRITENOP
242   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff10) AM_WRITE(port0b_w)
249   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff10) AM_READWRITE(mbeeic_08_r, mbeeic_08_w)
250   AM_RANGE(0x000a, 0x000a) AM_MIRROR(0xfe10) AM_READWRITE(mbeepc_telcom_low_r, mbeeic_0a_w)
251   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff10) AM_READWRITE(mbee_0b_r, mbee_0b_w)
243252   AM_RANGE(0x000c, 0x000c) AM_MIRROR(0xff10) AM_READWRITE(m6545_status_r, m6545_index_w)
244253   AM_RANGE(0x000d, 0x000d) AM_MIRROR(0xff10) AM_READWRITE(m6545_data_r, m6545_data_w)
245   AM_RANGE(0x000a, 0x000a) AM_MIRROR(0xfe10) AM_READWRITE(telcom_low_r, port0a_w)
246   AM_RANGE(0x010a, 0x010a) AM_MIRROR(0xfe10) AM_READWRITE(telcom_high_r, port0a_w)
254   AM_RANGE(0x010a, 0x010a) AM_MIRROR(0xfe10) AM_READWRITE(mbeepc_telcom_high_r, mbeeic_0a_w)
247255ADDRESS_MAP_END
248256
249static ADDRESS_MAP_START(mbeeppc_io, AS_IO, 8, mbee_state)
257static ADDRESS_MAP_START(mbeepc85_io, AS_IO, 8, mbee_state)
250258   ADDRESS_MAP_UNMAP_HIGH
251259   AM_RANGE(0x0000, 0x0003) AM_MIRROR(0xff10) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
252   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff10) AM_READWRITE(port08_r, port08_w)
253   AM_RANGE(0x0009, 0x0009) AM_MIRROR(0xff00) AM_WRITENOP
254   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff10) AM_WRITE(port0b_w)
255   AM_RANGE(0x000c, 0x000c) AM_MIRROR(0xff00) AM_READWRITE(m6545_status_r, m6545_index_w)
260   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff10) AM_READWRITE(mbeeic_08_r, mbeeic_08_w)
261   AM_RANGE(0x000a, 0x000a) AM_MIRROR(0xfe10) AM_READWRITE(mbeepc_telcom_low_r, mbeeic_0a_w)
262   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff10) AM_READWRITE(mbee_0b_r, mbee_0b_w)
263   AM_RANGE(0x000c, 0x000c) AM_MIRROR(0xff10) AM_READWRITE(m6545_status_r, m6545_index_w)
256264   AM_RANGE(0x000d, 0x000d) AM_MIRROR(0xff10) AM_READWRITE(m6545_data_r, m6545_data_w)
257   AM_RANGE(0x001c, 0x001c) AM_MIRROR(0xff00) AM_READWRITE(port1c_r, port1c_w)
258   AM_RANGE(0x000a, 0x000a) AM_MIRROR(0xfe10) AM_READWRITE(telcom_low_r, port0a_w)
259   AM_RANGE(0x010a, 0x010a) AM_MIRROR(0xfe10) AM_READWRITE(telcom_high_r, port0a_w)
265   AM_RANGE(0x010a, 0x010a) AM_MIRROR(0xfe10) AM_READWRITE(mbeepc_telcom_high_r, mbeeic_0a_w)
260266ADDRESS_MAP_END
261267
262static ADDRESS_MAP_START(mbeett_io, AS_IO, 8, mbee_state)
268static ADDRESS_MAP_START(mbeeppc_io, AS_IO, 8, mbee_state)
263269   ADDRESS_MAP_UNMAP_HIGH
264   AM_RANGE(0x0000, 0x0003) AM_MIRROR(0xff00) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
265   AM_RANGE(0x0004, 0x0004) AM_MIRROR(0xff00) AM_WRITE(port04_w)
266   AM_RANGE(0x0006, 0x0006) AM_MIRROR(0xff00) AM_WRITE(port06_w)
267   AM_RANGE(0x0007, 0x0007) AM_MIRROR(0xff00) AM_READ(port07_r)
268   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff00) AM_READWRITE(port08_r, port08_w)
269   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff00) AM_WRITE(port0b_w)
270   AM_RANGE(0x0000, 0x0003) AM_MIRROR(0xff10) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
271   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff10) AM_READWRITE(mbeeic_08_r, mbeeic_08_w)
272   AM_RANGE(0x000a, 0x000a) AM_MIRROR(0xfe10) AM_READWRITE(mbeepc_telcom_low_r, mbeeic_0a_w)
273   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff10) AM_READWRITE(mbee_0b_r, mbee_0b_w)
270274   AM_RANGE(0x000c, 0x000c) AM_MIRROR(0xff00) AM_READWRITE(m6545_status_r, m6545_index_w)
271   AM_RANGE(0x000d, 0x000d) AM_MIRROR(0xff00) AM_READWRITE(m6545_data_r, m6545_data_w)
272   AM_RANGE(0x0018, 0x001b) AM_MIRROR(0xff00) AM_READ(port18_r)
273   AM_RANGE(0x001c, 0x001f) AM_MIRROR(0xff00) AM_READWRITE(port1c_r, port1c_w)
274   AM_RANGE(0x0009, 0x0009) AM_MIRROR(0xfe00) AM_READ(speed_low_r)
275   AM_RANGE(0x0109, 0x0109) AM_MIRROR(0xfe00) AM_READ(speed_high_r)
276   AM_RANGE(0x000a, 0x000a) AM_MIRROR(0xfe00) AM_READWRITE(telcom_low_r, port0a_w)
277   AM_RANGE(0x010a, 0x010a) AM_MIRROR(0xfe00) AM_READWRITE(telcom_high_r, port0a_w)
278   AM_RANGE(0x0068, 0x006f) AM_MIRROR(0xff00) AM_DEVREADWRITE("scc", scc8530_t, reg_r, reg_w)
275   AM_RANGE(0x000d, 0x000d) AM_MIRROR(0xff10) AM_READWRITE(m6545_data_r, m6545_data_w)
276   AM_RANGE(0x001c, 0x001c) AM_MIRROR(0xff00) AM_READWRITE(mbeeppc_1c_r, mbeeppc_1c_w)
277   AM_RANGE(0x010a, 0x010a) AM_MIRROR(0xfe10) AM_READWRITE(mbeepc_telcom_high_r, mbeeic_0a_w)
279278ADDRESS_MAP_END
280279
281280static ADDRESS_MAP_START(mbee56_io, AS_IO, 8, mbee_state)
282281   ADDRESS_MAP_GLOBAL_MASK(0xff)
283282   ADDRESS_MAP_UNMAP_HIGH
284   AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
285   AM_RANGE(0x08, 0x08) AM_READWRITE(port08_r, port08_w)
286   AM_RANGE(0x09, 0x09) AM_WRITENOP
287   AM_RANGE(0x0b, 0x0b) AM_WRITE(port0b_w)
288   AM_RANGE(0x0c, 0x0c) AM_READWRITE(m6545_status_r, m6545_index_w)
289   AM_RANGE(0x0d, 0x0d) AM_READWRITE(m6545_data_r, m6545_data_w)
283   AM_RANGE(0x00, 0x03) AM_MIRROR(0x10) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
284   AM_RANGE(0x08, 0x08) AM_MIRROR(0x10) AM_READWRITE(mbeeic_08_r, mbeeic_08_w)
285   AM_RANGE(0x0b, 0x0b) AM_MIRROR(0x10) AM_READWRITE(mbee_0b_r, mbee_0b_w)
286   AM_RANGE(0x0c, 0x0c) AM_MIRROR(0x10) AM_READWRITE(m6545_status_r, m6545_index_w)
287   AM_RANGE(0x0d, 0x0d) AM_MIRROR(0x10) AM_READWRITE(m6545_data_r, m6545_data_w)
290288   AM_RANGE(0x44, 0x47) AM_DEVREADWRITE("fdc", wd2793_t, read, write)
291289   AM_RANGE(0x48, 0x4f) AM_READWRITE(fdc_status_r, fdc_motor_w)
292290ADDRESS_MAP_END
r244651r244652
295293   ADDRESS_MAP_GLOBAL_MASK(0xff)
296294   ADDRESS_MAP_UNMAP_HIGH
297295   AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
298   AM_RANGE(0x04, 0x04) AM_WRITE(port04_w)
299   AM_RANGE(0x06, 0x06) AM_WRITE(port06_w)
300   AM_RANGE(0x07, 0x07) AM_READ(port07_r)
301   AM_RANGE(0x08, 0x08) AM_READWRITE(port08_r, port08_w)
302   AM_RANGE(0x09, 0x09) AM_WRITENOP
303   AM_RANGE(0x0b, 0x0b) AM_WRITE(port0b_w)
296   AM_RANGE(0x04, 0x04) AM_WRITE(mbee_04_w)
297   AM_RANGE(0x06, 0x06) AM_WRITE(mbee_06_w)
298   AM_RANGE(0x07, 0x07) AM_READ(mbee_07_r)
299   AM_RANGE(0x08, 0x08) AM_READWRITE(mbeeic_08_r, mbeeic_08_w)
300   AM_RANGE(0x0b, 0x0b) AM_READWRITE(mbee_0b_r, mbee_0b_w)
304301   AM_RANGE(0x0c, 0x0c) AM_READWRITE(m6545_status_r, m6545_index_w)
305302   AM_RANGE(0x0d, 0x0d) AM_READWRITE(m6545_data_r, m6545_data_w)
306   AM_RANGE(0x1c, 0x1f) AM_READWRITE(port1c_r, port1c_w)
303   AM_RANGE(0x1c, 0x1f) AM_READWRITE(mbeeppc_1c_r, mbee256_1c_w)
307304   AM_RANGE(0x44, 0x47) AM_DEVREADWRITE("fdc", wd2793_t, read, write)
308305   AM_RANGE(0x48, 0x4f) AM_READWRITE(fdc_status_r, fdc_motor_w)
309306   AM_RANGE(0x50, 0x57) AM_WRITE(mbee128_50_w)
r244651r244652
312309static ADDRESS_MAP_START(mbee256_io, AS_IO, 8, mbee_state)
313310   ADDRESS_MAP_UNMAP_HIGH
314311   AM_RANGE(0x0000, 0x0003) AM_MIRROR(0xff00) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
315   AM_RANGE(0x0004, 0x0004) AM_MIRROR(0xff00) AM_WRITE(port04_w)
316   AM_RANGE(0x0006, 0x0006) AM_MIRROR(0xff00) AM_WRITE(port06_w)
317   AM_RANGE(0x0007, 0x0007) AM_MIRROR(0xff00) AM_READ(port07_r)
318   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff00) AM_READWRITE(port08_r, port08_w)
319   AM_RANGE(0x0009, 0x0009) AM_MIRROR(0xfd00) AM_READ(speed_low_r)
320   AM_RANGE(0x0209, 0x0209) AM_MIRROR(0xfd00) AM_READ(speed_high_r)
321   AM_RANGE(0x0009, 0x0009) AM_MIRROR(0xff00) AM_WRITENOP
322   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff00) AM_WRITE(port0b_w)
312   AM_RANGE(0x0004, 0x0004) AM_MIRROR(0xff00) AM_WRITE(mbee_04_w)
313   AM_RANGE(0x0006, 0x0006) AM_MIRROR(0xff00) AM_WRITE(mbee_06_w)
314   AM_RANGE(0x0007, 0x0007) AM_MIRROR(0xff00) AM_READ(mbee_07_r)
315   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff00) AM_READWRITE(mbeeic_08_r, mbeeic_08_w)
316   AM_RANGE(0x0009, 0x0009) AM_MIRROR(0xfd00) AM_READ(mbee256_speed_low_r)
317   AM_RANGE(0x0209, 0x0209) AM_MIRROR(0xfd00) AM_READ(mbee256_speed_high_r)
318   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff00) AM_READWRITE(mbee_0b_r, mbee_0b_w)
323319   AM_RANGE(0x000c, 0x000c) AM_MIRROR(0xff00) AM_READWRITE(m6545_status_r, m6545_index_w)
324320   AM_RANGE(0x000d, 0x000d) AM_MIRROR(0xff00) AM_READWRITE(m6545_data_r, m6545_data_w)
325321   // AM_RANGE(0x0010, 0x0013) AM_MIRROR(0xff00) Optional SN76489AN audio chip
326   AM_RANGE(0x0018, 0x001b) AM_MIRROR(0xff00) AM_READ(port18_r)
327   AM_RANGE(0x001c, 0x001f) AM_MIRROR(0xff00) AM_READWRITE(port1c_r, port1c_w)
322   AM_RANGE(0x0018, 0x001b) AM_MIRROR(0xff00) AM_READ(mbee256_18_r)
323   AM_RANGE(0x001c, 0x001f) AM_MIRROR(0xff00) AM_READWRITE(mbeeppc_1c_r, mbee256_1c_w)
328324   AM_RANGE(0x0044, 0x0047) AM_MIRROR(0xff00) AM_DEVREADWRITE("fdc", wd2793_t, read, write)
329325   AM_RANGE(0x0048, 0x004f) AM_MIRROR(0xff00) AM_READWRITE(fdc_status_r, fdc_motor_w)
330326   AM_RANGE(0x0050, 0x0057) AM_MIRROR(0xff00) AM_WRITE(mbee256_50_w)
r244651r244652
333329   // AM_RANGE(0x0068, 0x006f) AM_MIRROR(0xff00) Reserved for 8530 SCC (unused)
334330ADDRESS_MAP_END
335331
332static ADDRESS_MAP_START(mbeett_io, AS_IO, 8, mbee_state)
333   ADDRESS_MAP_UNMAP_HIGH
334   AM_RANGE(0x0000, 0x0003) AM_MIRROR(0xff00) AM_DEVREADWRITE("z80pio", z80pio_device, read_alt, write_alt)
335   AM_RANGE(0x0004, 0x0004) AM_MIRROR(0xff00) AM_WRITE(mbee_04_w)
336   AM_RANGE(0x0006, 0x0006) AM_MIRROR(0xff00) AM_WRITE(mbee_06_w)
337   AM_RANGE(0x0007, 0x0007) AM_MIRROR(0xff00) AM_READ(mbee_07_r)
338   AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff00) AM_READWRITE(mbeeic_08_r, mbeeic_08_w)
339   AM_RANGE(0x000b, 0x000b) AM_MIRROR(0xff00) AM_READWRITE(mbee_0b_r, mbee_0b_w)
340   AM_RANGE(0x000c, 0x000c) AM_MIRROR(0xff00) AM_READWRITE(m6545_status_r, m6545_index_w)
341   AM_RANGE(0x000d, 0x000d) AM_MIRROR(0xff00) AM_READWRITE(m6545_data_r, m6545_data_w)
342   AM_RANGE(0x0018, 0x001b) AM_MIRROR(0xff00) AM_READ(mbee256_18_r)
343   AM_RANGE(0x001c, 0x001f) AM_MIRROR(0xff00) AM_READWRITE(mbeeppc_1c_r,mbee256_1c_w)
344   AM_RANGE(0x000a, 0x000a) AM_MIRROR(0xfe10) AM_READWRITE(mbeepc_telcom_low_r, mbeeic_0a_w)
345   AM_RANGE(0x010a, 0x010a) AM_MIRROR(0xfe10) AM_READWRITE(mbeepc_telcom_high_r, mbeeic_0a_w)
346   // AM_RANGE(0x0068, 0x006f) AM_MIRROR(0xff00) 8530 SCC
347ADDRESS_MAP_END
348
336349static INPUT_PORTS_START( mbee )
337350   PORT_START("X.0") /* IN0 KEY ROW 0 [000] */
338351   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("@") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('@') PORT_CHAR('`')
r244651r244652
406419
407420   PORT_START("X.7") /* IN7 KEY ROW 7 [380] */
408421   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Up)") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))
409   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
422   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Ctrl") PORT_CODE(KEYCODE_LCONTROL)
410423   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Down)") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN))
411424   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("(Left)") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT))
412425   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED )
r244651r244652
431444   PORT_CONFNAME( 0xc0, 0x80, "PIO B7")
432445   PORT_CONFSETTING(    0x00, "VS") // sync pulse to enable telcom clock
433446   PORT_CONFSETTING(    0x40, "RTC") // optional board usually not fitted
434   PORT_CONFSETTING(    0x80, "Tied high") // default resistor to vcc
435   PORT_CONFSETTING(    0xc0, "Reserved for net")
447   PORT_CONFSETTING(    0x80, "Not used") // default resistor to vcc
448   PORT_CONFSETTING(    0xc0, "Centronics") // busy line
436449INPUT_PORTS_END
437450
438451static INPUT_PORTS_START( mbee256 )
r244651r244652
563576   PORT_CONFSETTING(    0x00, DEF_STR(No))
564577   PORT_CONFSETTING(    0x01, DEF_STR(Yes))
565578   // Wire links on motherboard
566   PORT_CONFNAME( 0xc0, 0x40, "PIO B7")
579   PORT_CONFNAME( 0xc0, 0x80, "PIO B7") // default - do nothing
567580   PORT_CONFSETTING(    0x00, "VS") // sync pulse to enable telcom clock
568   PORT_CONFSETTING(    0x40, "RTC") // RTC IRQ must be used on teleterm
569   PORT_CONFSETTING(    0x80, "Tied high") // default resistor to vcc
570   PORT_CONFSETTING(    0xc0, "Reserved for net")
581   PORT_CONFSETTING(    0x40, "RTC") // optional board usually not fitted
582   PORT_CONFSETTING(    0x80, "Not used") // default resistor to vcc
583   PORT_CONFSETTING(    0xc0, "Centronics") // busy line
571584INPUT_PORTS_END
572585
573586static const z80_daisy_config mbee_daisy_chain[] =
r244651r244652
731744   MCFG_CPU_IO_MAP(mbeepc_io)
732745MACHINE_CONFIG_END
733746
734static MACHINE_CONFIG_DERIVED( mbeepc85b, mbeepc )
747static MACHINE_CONFIG_DERIVED( mbeepc85, mbeeic )
748   MCFG_CPU_MODIFY( "maincpu" )
749   MCFG_CPU_PROGRAM_MAP(mbeepc85_mem)
750   MCFG_CPU_IO_MAP(mbeepc85_io)
751MACHINE_CONFIG_END
752
753static MACHINE_CONFIG_DERIVED( mbeepc85b, mbeepc85 )
735754   MCFG_PALETTE_MODIFY("palette")
736755   MCFG_PALETTE_INIT_OWNER(mbee_state, mbeepc85b)
737756MACHINE_CONFIG_END
r244651r244652
745764   MCFG_PALETTE_MODIFY("palette")
746765   MCFG_PALETTE_ENTRIES(16)
747766   MCFG_PALETTE_INIT_OWNER(mbee_state, premium)
748   MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
749   MCFG_MC146818_IRQ_HANDLER(WRITELINE(mbee_state, rtc_irq_w))
750767MACHINE_CONFIG_END
751768
752769static MACHINE_CONFIG_DERIVED( mbee56, mbeeic )
r244651r244652
767784   MCFG_CPU_IO_MAP(mbee128_io)
768785   MCFG_MACHINE_RESET_OVERRIDE(mbee_state, mbee128)
769786   MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
770   MCFG_MC146818_IRQ_HANDLER(WRITELINE(mbee_state, rtc_irq_w))
771787MACHINE_CONFIG_END
772788
773789static MACHINE_CONFIG_DERIVED( mbee128p, mbeeppc )
r244651r244652
775791   MCFG_CPU_PROGRAM_MAP(mbee256_mem)
776792   MCFG_CPU_IO_MAP(mbee128_io)
777793   MCFG_MACHINE_RESET_OVERRIDE(mbee_state, mbee128)
794   MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
778795   MCFG_WD2793x_ADD("fdc", XTAL_4MHz / 4)
779796   MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(mbee_state, fdc_intrq_w))
780797   MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(mbee_state, fdc_drq_w))
r244651r244652
799816   MCFG_CPU_PROGRAM_MAP(mbeett_mem)
800817   MCFG_CPU_IO_MAP(mbeett_io)
801818   MCFG_MACHINE_RESET_OVERRIDE(mbee_state, mbeett)
802   MCFG_DEVICE_REMOVE("quickload")
803   MCFG_DEVICE_REMOVE("quickload2")
804   MCFG_DEVICE_ADD("scc", SCC8530, 4000000) // clock unknown
819   MCFG_MC146818_ADD( "rtc", XTAL_32_768kHz )
805820MACHINE_CONFIG_END
806821
807822/* Unused roms:
r244651r244652
11371152COMP( 1982, mbee,     0,        0,      mbee,     mbee,     mbee_state,  mbee,       "Applied Technology",  "Microbee 16 Standard" , 0 )
11381153COMP( 1982, mbeeic,   mbee,     0,      mbeeic,   mbee,     mbee_state,  mbeeic,     "Applied Technology",  "Microbee 32 IC" , 0 )
11391154COMP( 1982, mbeepc,   mbee,     0,      mbeepc,   mbee,     mbee_state,  mbeepc,     "Applied Technology",  "Microbee Personal Communicator" , 0 )
1140COMP( 1985, mbeepc85, mbee,     0,      mbeepc,  mbee,     mbee_state,  mbeepc85,   "Applied Technology",  "Microbee PC85" , 0 )
1155COMP( 1985, mbeepc85, mbee,     0,      mbeepc85, mbee,     mbee_state,  mbeepc85,   "Applied Technology",  "Microbee PC85" , 0 )
11411156COMP( 1985, mbeepc85b,mbee,     0,      mbeepc85b,mbee,     mbee_state,  mbeepc85,   "Applied Technology",  "Microbee PC85 (New version)" , 0 )
1142COMP( 1985, mbeepc85s,mbee,     0,      mbeepc,  mbee,     mbee_state,  mbeepc85,   "Applied Technology",  "Microbee PC85 (Swedish)" , 0 )
1157COMP( 1985, mbeepc85s,mbee,     0,      mbeepc85, mbee,     mbee_state,  mbeepc85,   "Applied Technology",  "Microbee PC85 (Swedish)" , 0 )
11431158COMP( 1986, mbeeppc,  mbee,     0,      mbeeppc,  mbee,     mbee_state,  mbeeppc,    "Applied Technology",  "Microbee Premium PC85" , 0 )
11441159COMP( 1986, mbeett,   mbee,     0,      mbeett,   mbee256,  mbee_state,  mbeett,     "Applied Technology",  "Microbee Teleterm" , GAME_NOT_WORKING )
11451160COMP( 1986, mbee56,   mbee,     0,      mbee56,   mbee,     mbee_state,  mbee56,     "Applied Technology",  "Microbee 56k" , GAME_NOT_WORKING )
trunk/src/mess/drivers/tmtennis.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:hap
3/***************************************************************************
4
5  Tomy Tennis (manufactured in Japan)
6  * board labeled TOMY TN-04 TENNIS
7  * NEC uCOM-44 MCU, labeled D552C 048
8  * VFD display NEC FIP11AM15T (FIP=fluorescent indicator panel)
9
10  The initial release of this game was in 1979, known as Pro-Tennis,
11  it is unknown if the hardware and/or ROM contents differ.
12
13  This is an early VFD simple electronic tennis game. Player 1 is on the right
14  side, player 2 or CPU on the left. Each player has six possible positions
15  where to hit the ball. A backdrop behind the VFD shows a tennis court.
16
17  NOTE!: MESS external artwork is required to be able to play
18
19
20  TODO:
21  - display should go off when sound is played, needs decay simulation?
22
23***************************************************************************/
24
25#include "emu.h"
26#include "cpu/ucom4/ucom4.h"
27#include "sound/speaker.h"
28
29#include "tmtennis.lh" // this is a test layout, external artwork is necessary
30
31
32class tmtennis_state : public driver_device
33{
34public:
35   tmtennis_state(const machine_config &mconfig, device_type type, const char *tag)
36      : driver_device(mconfig, type, tag),
37      m_maincpu(*this, "maincpu"),
38      m_button_matrix(*this, "IN"),
39      m_speaker(*this, "speaker")
40   { }
41
42   required_device<cpu_device> m_maincpu;
43   required_ioport_array<2> m_button_matrix;
44   required_device<speaker_sound_device> m_speaker;
45
46   UINT8 m_input_mux;
47   UINT16 m_plate;
48   UINT16 m_grid;
49
50   DECLARE_READ8_MEMBER(input_r);
51   DECLARE_WRITE8_MEMBER(port_e_w);
52   DECLARE_WRITE8_MEMBER(plate_w);
53   DECLARE_WRITE8_MEMBER(grid_w);
54
55   DECLARE_INPUT_CHANGED_MEMBER(difficulty_switch);
56   void update_clock();
57
58   UINT16 m_vfd_state[0x10];
59   void update_vfd();
60
61   virtual void machine_reset();
62   virtual void machine_start();
63};
64
65// master clock is from an LC circuit oscillating by default at 360kHz, but...
66#define MASTER_CLOCK (360000)
67
68void tmtennis_state::update_clock()
69{
70   // ...on PRO1, the difficulty switch puts a capacitor across the LC circuit
71   // to slow it down to approx. 260kHz (28%)
72   m_maincpu->set_clock_scale(m_button_matrix[1]->read() & 0x100 ? 0.72 : 1);
73}
74
75
76
77/***************************************************************************
78
79  Display
80
81***************************************************************************/
82
83void tmtennis_state::update_vfd()
84{
85   for (int i = 0; i < 12; i++)
86      if (m_grid & (1 << i) && m_vfd_state[i] != m_plate)
87      {
88         // on difference, send to output
89         for (int j = 0; j < 12; j++)
90            output_set_lamp_value(i*100 + j, m_plate >> j & 1);
91
92         m_vfd_state[i] = m_plate;
93      }
94}
95
96
97
98/***************************************************************************
99
100  I/O
101
102***************************************************************************/
103
104READ8_MEMBER(tmtennis_state::input_r)
105{
106   // port A/B: buttons
107   UINT8 inp = 0xff;
108
109   // read selected button rows
110   for (int i = 0; i < 2; i++)
111      if (m_input_mux >> i & 1)
112         inp &= m_button_matrix[i]->read();
113
114   return inp >> (offset*4);
115}
116
117WRITE8_MEMBER(tmtennis_state::port_e_w)
118{
119   // E0/E1: input mux
120   // E2: speaker out
121   // E3: N/C
122   m_input_mux = data & 3;
123   m_speaker->level_w(data >> 2 & 1);
124}
125
126WRITE8_MEMBER(tmtennis_state::plate_w)
127{
128   // port C/D/F: vfd matrix plate
129   if (offset == NEC_UCOM4_PORTF) offset--;
130   int shift = (offset - NEC_UCOM4_PORTC) * 4;
131   m_plate = (m_plate & ~(0xf << shift)) | (data << shift);
132
133   update_vfd();
134}
135
136WRITE8_MEMBER(tmtennis_state::grid_w)
137{
138   // port G/H/I: vfd matrix grid
139   int shift = (offset - NEC_UCOM4_PORTG) * 4;
140   m_grid = (m_grid & ~(0xf << shift)) | (data << shift);
141
142   update_vfd();
143}
144
145
146
147/***************************************************************************
148
149  Inputs
150
151***************************************************************************/
152
153INPUT_CHANGED_MEMBER(tmtennis_state::difficulty_switch)
154{
155   update_clock();
156}
157
158/* Pro-Tennis physical button layout and labels is like this:
159
160    [SERVE] [1] [2] [3]       [3] [2] [1] [SERVE]
161            [4] [5] [6]       [6] [5] [4]
162
163    PRACTICE<--PRO1-->PRO2    1PLAYER<--OFF-->2PLAYER
164*/
165
166static INPUT_PORTS_START( tmtennis )
167   PORT_START("IN.0") // E0 port A/B
168   PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("P1 Serve")
169   PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("P2 Serve")
170   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 )
171   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 )
172   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 )
173   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON5 )
174   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 )
175   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON6 )
176
177   PORT_START("IN.1") // E1 port A/B
178   PORT_CONFNAME( 0x101, 0x101, DEF_STR( Difficulty ) ) PORT_CHANGED_MEMBER(DEVICE_SELF, tmtennis_state, difficulty_switch, NULL)
179   PORT_CONFSETTING(     0x000, "Practice" )
180   PORT_CONFSETTING(     0x101, "Pro 1" ) // -> difficulty_switch
181   PORT_CONFSETTING(     0x001, "Pro 2" )
182   PORT_CONFNAME( 0x02, 0x02, "Players" )
183   PORT_CONFSETTING(    0x02, "1" )
184   PORT_CONFSETTING(    0x00, "2" )
185   PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
186   PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
187   PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
188   PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2)
189   PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
190   PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2)
191INPUT_PORTS_END
192
193
194
195/***************************************************************************
196
197  Machine Config
198
199***************************************************************************/
200
201void tmtennis_state::machine_reset()
202{
203   update_clock();
204}
205
206void tmtennis_state::machine_start()
207{
208   // zerofill
209   memset(m_vfd_state, 0, sizeof(m_vfd_state));
210   m_input_mux = 0;
211   m_plate = 0;
212   m_grid = 0;
213
214   // register for savestates
215   save_item(NAME(m_vfd_state));
216   save_item(NAME(m_input_mux));
217   save_item(NAME(m_plate));
218   save_item(NAME(m_grid));
219}
220
221
222static MACHINE_CONFIG_START( tmtennis, tmtennis_state )
223
224   /* basic machine hardware */
225   MCFG_CPU_ADD("maincpu", NEC_D552, MASTER_CLOCK)
226   MCFG_UCOM4_READ_A_CB(READ8(tmtennis_state, input_r))
227   MCFG_UCOM4_READ_B_CB(READ8(tmtennis_state, input_r))
228   MCFG_UCOM4_WRITE_C_CB(WRITE8(tmtennis_state, plate_w))
229   MCFG_UCOM4_WRITE_D_CB(WRITE8(tmtennis_state, plate_w))
230   MCFG_UCOM4_WRITE_E_CB(WRITE8(tmtennis_state, port_e_w))
231   MCFG_UCOM4_WRITE_F_CB(WRITE8(tmtennis_state, plate_w))
232   MCFG_UCOM4_WRITE_G_CB(WRITE8(tmtennis_state, grid_w))
233   MCFG_UCOM4_WRITE_H_CB(WRITE8(tmtennis_state, grid_w))
234   MCFG_UCOM4_WRITE_I_CB(WRITE8(tmtennis_state, grid_w))
235
236   MCFG_DEFAULT_LAYOUT(layout_tmtennis)
237
238   /* no video! */
239
240   /* sound hardware */
241   MCFG_SPEAKER_STANDARD_MONO("mono")
242   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
243   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
244MACHINE_CONFIG_END
245
246
247
248/***************************************************************************
249
250  Game driver(s)
251
252***************************************************************************/
253
254ROM_START( tmtennis )
255   ROM_REGION( 0x0400, "maincpu", 0 )
256   ROM_LOAD( "d552c-048", 0x0000, 0x0400, CRC(78702003) SHA1(4d427d4dbeed901770c682338867f58c7b54eee3) )
257ROM_END
258
259
260CONS( 1980, tmtennis, 0, 0, tmtennis, tmtennis, driver_device, 0, "Tomy", "Tennis (Tomy)", GAME_SUPPORTS_SAVE | GAME_REQUIRES_ARTWORK )
trunk/src/mess/drivers/wildfire.c
r244651r244652
99  to create the illusion of a moving ball, and even the flippers are leds.
1010  A drawing of a pinball table is added as overlay.
1111
12  NOTE!: MESS external artwork is recommended
12  NOTE!: MESS external artwork is required to be able to play
1313
1414
1515  TODO:
r244651r244652
2525#include "cpu/amis2000/amis2000.h"
2626#include "sound/speaker.h"
2727
28#include "wildfire.lh" // this is a test layout, use external artwork
28#include "wildfire.lh" // this is a test layout, external artwork is necessary
2929
3030// master clock is a single stage RC oscillator: R=?K, C=?pf,
3131// S2000 default frequency is 850kHz
trunk/src/mess/includes/mbee.h
r244651r244652
1010#include "emu.h"
1111#include "imagedev/snapquik.h"
1212#include "machine/z80pio.h"
13#include "machine/8530scc.h"
1413#include "imagedev/cassette.h"
1514#include "machine/buffer.h"
1615#include "bus/centronics/ctronics.h"
r244651r244652
2827public:
2928   enum
3029   {
31      TIMER_MBEE_NEWKB
30      TIMER_MBEE_NEWKB,
31      TIMER_MBEE_RTC_IRQ,
32      TIMER_MBEE_BOOT
3233   };
3334
3435   mbee_state(const machine_config &mconfig, device_type type, const char *tag)
r244651r244652
4647      , m_floppy0(*this, "fdc:0")
4748      , m_floppy1(*this, "fdc:1")
4849      , m_rtc(*this, "rtc")
50      , m_boot(*this, "boot")
4951      , m_pak(*this, "pak")
5052      , m_telcom(*this, "telcom")
5153      , m_basic(*this, "basic")
r244651r244652
5658      , m_screen(*this, "screen")
5759   { }
5860
59   DECLARE_WRITE8_MEMBER(port04_w);
60   DECLARE_WRITE8_MEMBER(port06_w);
61   DECLARE_READ8_MEMBER(port07_r);
62   DECLARE_READ8_MEMBER(port08_r);
63   DECLARE_WRITE8_MEMBER(port08_w);
64   DECLARE_WRITE8_MEMBER(port0a_w);
65   DECLARE_WRITE8_MEMBER(port0b_w);
66   DECLARE_READ8_MEMBER(port18_r);
67   DECLARE_READ8_MEMBER(port1c_r);
68   DECLARE_WRITE8_MEMBER(port1c_w);
61   DECLARE_WRITE8_MEMBER(mbee_04_w);
62   DECLARE_WRITE8_MEMBER(mbee_06_w);
63   DECLARE_READ8_MEMBER(mbee_07_r);
64   DECLARE_READ8_MEMBER(mbeeic_0a_r);
65   DECLARE_WRITE8_MEMBER(mbeeic_0a_w);
66   DECLARE_READ8_MEMBER(mbeepc_telcom_low_r);
67   DECLARE_READ8_MEMBER(mbeepc_telcom_high_r);
68   DECLARE_READ8_MEMBER(mbee256_speed_low_r);
69   DECLARE_READ8_MEMBER(mbee256_speed_high_r);
70   DECLARE_READ8_MEMBER(mbee256_18_r);
6971   DECLARE_WRITE8_MEMBER(mbee128_50_w);
7072   DECLARE_WRITE8_MEMBER(mbee256_50_w);
71   DECLARE_READ8_MEMBER(telcom_low_r);
72   DECLARE_READ8_MEMBER(telcom_high_r);
73   DECLARE_READ8_MEMBER(speed_low_r);
74   DECLARE_READ8_MEMBER(speed_high_r);
7573   DECLARE_READ8_MEMBER(m6545_status_r);
7674   DECLARE_WRITE8_MEMBER(m6545_index_w);
7775   DECLARE_READ8_MEMBER(m6545_data_r);
7876   DECLARE_WRITE8_MEMBER(m6545_data_w);
79   DECLARE_READ8_MEMBER(video_low_r);
80   DECLARE_READ8_MEMBER(video_high_r);
81   DECLARE_WRITE8_MEMBER(video_low_w);
82   DECLARE_WRITE8_MEMBER(video_high_w);
77   DECLARE_READ8_MEMBER(mbee_low_r);
78   DECLARE_READ8_MEMBER(mbee_high_r);
79   DECLARE_READ8_MEMBER(mbeeic_high_r);
80   DECLARE_WRITE8_MEMBER(mbeeic_high_w);
81   DECLARE_WRITE8_MEMBER(mbee_low_w);
82   DECLARE_WRITE8_MEMBER(mbee_high_w);
83   DECLARE_READ8_MEMBER(mbeeic_08_r);
84   DECLARE_WRITE8_MEMBER(mbeeic_08_w);
85   DECLARE_READ8_MEMBER(mbee_0b_r);
86   DECLARE_WRITE8_MEMBER(mbee_0b_w);
87   DECLARE_READ8_MEMBER(mbeeppc_1c_r);
88   DECLARE_WRITE8_MEMBER(mbeeppc_1c_w);
89   DECLARE_WRITE8_MEMBER(mbee256_1c_w);
90   DECLARE_READ8_MEMBER(mbeeppc_low_r);
91   DECLARE_READ8_MEMBER(mbeeppc_high_r);
92   DECLARE_WRITE8_MEMBER(mbeeppc_high_w);
93   DECLARE_WRITE8_MEMBER(mbeeppc_low_w);
8394   DECLARE_WRITE8_MEMBER(pio_port_b_w);
8495   DECLARE_READ8_MEMBER(pio_port_b_r);
8596   DECLARE_WRITE_LINE_MEMBER(pio_ardy);
r244651r244652
108119   DECLARE_MACHINE_RESET(mbeett);
109120   UINT32 screen_update_mbee(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
110121   TIMER_CALLBACK_MEMBER(timer_newkb);
122   TIMER_CALLBACK_MEMBER(timer_rtc_irq);
111123   TIMER_CALLBACK_MEMBER(timer_boot);
112124   DECLARE_QUICKLOAD_LOAD_MEMBER(mbee);
113125   DECLARE_QUICKLOAD_LOAD_MEMBER(mbee_z80bin);
114   WRITE_LINE_MEMBER(rtc_irq_w);
115126   WRITE_LINE_MEMBER(fdc_intrq_w);
116127   WRITE_LINE_MEMBER(fdc_drq_w);
128   UINT8 *m_p_videoram;
129   UINT8 *m_p_gfxram;
130   UINT8 *m_p_colorram;
131   UINT8 *m_p_attribram;
132   UINT8 m_framecnt;
133   UINT8 m_08;
134   UINT8 m_1c;
135   void mbee_video_kbd_scan(int param);
136   UINT8 m_sy6545_cursor[16];
137
117138   MC6845_UPDATE_ROW(mono_update_row);
118139   MC6845_UPDATE_ROW(colour_update_row);
119140   MC6845_ON_UPDATE_ADDR_CHANGED(crtc_update_addr);
120141
121142   required_device<palette_device> m_palette;
122143private:
123   UINT8 *m_p_videoram;
124   UINT8 *m_p_gfxram;
125   UINT8 *m_p_colorram;
126   UINT8 *m_p_attribram;
127144   bool m_is_premium;
128145   bool m_has_oldkb;
129146   size_t m_size;
r244651r244652
131148   bool m_b7_vs;
132149   bool m_b2;
133150   bool m_is_mbeett;
134   UINT8 m_framecnt;
135   UINT8 m_08;
136   UINT8 m_0a;
137   UINT8 m_0b;
138   UINT8 m_1c;
139   UINT8 m_sy6545_cursor[16];
140151   UINT8 m_mbee256_was_pressed[15];
141152   UINT8 m_mbee256_q[20];
142153   UINT8 m_mbee256_q_pos;
154   UINT8 m_0a;
155   UINT8 m_0b;
143156   UINT8 m_sy6545_status;
144157   UINT8 m_sy6545_reg[32];
145158   UINT8 m_sy6545_ind;
r244651r244652
147160   UINT8 m_bank_array[33];
148161   void setup_banks(UINT8 data, bool first_time, UINT8 b_mask);
149162   void sy6545_cursor_configure();
150   void oldkb_scan(UINT16 param);
151   void oldkb_matrix_r(UINT16 offs);
152   void machine_reset_common();
163   void keyboard_matrix_r(int offs);
164   void machine_reset_common_disk();
153165   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
154166   required_device<cpu_device> m_maincpu;
155167   required_device<z80pio_device> m_pio;
r244651r244652
163175   optional_device<floppy_connector> m_floppy0;
164176   optional_device<floppy_connector> m_floppy1;
165177   optional_device<mc146818_device> m_rtc;
178   optional_memory_bank m_boot;
166179   optional_memory_bank m_pak;
167180   optional_memory_bank m_telcom;
168181   optional_memory_bank m_basic;
trunk/src/mess/layout/ebball.lay
r244651r244652
1616
1717<!-- build screen -->
1818
19   <view name="Test Layout">
19   <view name="Internal Layout">
2020      <bounds left="0" right="64" top="0" bottom="64" />
2121      <bezel element="static_black">
2222         <bounds left="0" right="64" top="0" bottom="64" />
2323      </bezel>
2424
25      <bezel name="digit8" element="digit"><bounds x="0" y="0" width="10" height="15" /></bezel>
2625
27   <!-- 7*9 matrix -->
28
29      <bezel name="lamp0" element="led"><bounds x="0" y="20" width="1" height="1" /></bezel>
30      <bezel name="lamp1" element="led"><bounds x="2" y="20" width="1" height="1" /></bezel>
31      <bezel name="lamp2" element="led"><bounds x="4" y="20" width="1" height="1" /></bezel>
32      <bezel name="lamp3" element="led"><bounds x="6" y="20" width="1" height="1" /></bezel>
33      <bezel name="lamp4" element="led"><bounds x="8" y="20" width="1" height="1" /></bezel>
34      <bezel name="lamp5" element="led"><bounds x="10" y="20" width="1" height="1" /></bezel>
35      <bezel name="lamp6" element="led"><bounds x="12" y="20" width="1" height="1" /></bezel>
36
37      <bezel name="lamp10" element="led"><bounds x="0" y="22" width="1" height="1" /></bezel>
38      <bezel name="lamp11" element="led"><bounds x="2" y="22" width="1" height="1" /></bezel>
39      <bezel name="lamp12" element="led"><bounds x="4" y="22" width="1" height="1" /></bezel>
40      <bezel name="lamp13" element="led"><bounds x="6" y="22" width="1" height="1" /></bezel>
41      <bezel name="lamp14" element="led"><bounds x="8" y="22" width="1" height="1" /></bezel>
42      <bezel name="lamp15" element="led"><bounds x="10" y="22" width="1" height="1" /></bezel>
43      <bezel name="lamp16" element="led"><bounds x="12" y="22" width="1" height="1" /></bezel>
44
45      <bezel name="lamp20" element="led"><bounds x="0" y="24" width="1" height="1" /></bezel>
46      <bezel name="lamp21" element="led"><bounds x="2" y="24" width="1" height="1" /></bezel>
47      <bezel name="lamp22" element="led"><bounds x="4" y="24" width="1" height="1" /></bezel>
48      <bezel name="lamp23" element="led"><bounds x="6" y="24" width="1" height="1" /></bezel>
49      <bezel name="lamp24" element="led"><bounds x="8" y="24" width="1" height="1" /></bezel>
50      <bezel name="lamp25" element="led"><bounds x="10" y="24" width="1" height="1" /></bezel>
51      <bezel name="lamp26" element="led"><bounds x="12" y="24" width="1" height="1" /></bezel>
52
53      <bezel name="lamp30" element="led"><bounds x="0" y="26" width="1" height="1" /></bezel>
54      <bezel name="lamp31" element="led"><bounds x="2" y="26" width="1" height="1" /></bezel>
55      <bezel name="lamp32" element="led"><bounds x="4" y="26" width="1" height="1" /></bezel>
56      <bezel name="lamp33" element="led"><bounds x="6" y="26" width="1" height="1" /></bezel>
57      <bezel name="lamp34" element="led"><bounds x="8" y="26" width="1" height="1" /></bezel>
58      <bezel name="lamp35" element="led"><bounds x="10" y="26" width="1" height="1" /></bezel>
59      <bezel name="lamp36" element="led"><bounds x="12" y="26" width="1" height="1" /></bezel>
60
61      <bezel name="lamp40" element="led"><bounds x="0" y="28" width="1" height="1" /></bezel>
62      <bezel name="lamp41" element="led"><bounds x="2" y="28" width="1" height="1" /></bezel>
63      <bezel name="lamp42" element="led"><bounds x="4" y="28" width="1" height="1" /></bezel>
64      <bezel name="lamp43" element="led"><bounds x="6" y="28" width="1" height="1" /></bezel>
65      <bezel name="lamp44" element="led"><bounds x="8" y="28" width="1" height="1" /></bezel>
66      <bezel name="lamp45" element="led"><bounds x="10" y="28" width="1" height="1" /></bezel>
67      <bezel name="lamp46" element="led"><bounds x="12" y="28" width="1" height="1" /></bezel>
68
69      <bezel name="lamp50" element="led"><bounds x="0" y="30" width="1" height="1" /></bezel>
70      <bezel name="lamp51" element="led"><bounds x="2" y="30" width="1" height="1" /></bezel>
71      <bezel name="lamp52" element="led"><bounds x="4" y="30" width="1" height="1" /></bezel>
72      <bezel name="lamp53" element="led"><bounds x="6" y="30" width="1" height="1" /></bezel>
73      <bezel name="lamp54" element="led"><bounds x="8" y="30" width="1" height="1" /></bezel>
74      <bezel name="lamp55" element="led"><bounds x="10" y="30" width="1" height="1" /></bezel>
75      <bezel name="lamp56" element="led"><bounds x="12" y="30" width="1" height="1" /></bezel>
76
77      <bezel name="lamp60" element="led"><bounds x="0" y="32" width="1" height="1" /></bezel>
78      <bezel name="lamp61" element="led"><bounds x="2" y="32" width="1" height="1" /></bezel>
79      <bezel name="lamp62" element="led"><bounds x="4" y="32" width="1" height="1" /></bezel>
80      <bezel name="lamp63" element="led"><bounds x="6" y="32" width="1" height="1" /></bezel>
81      <bezel name="lamp64" element="led"><bounds x="8" y="32" width="1" height="1" /></bezel>
82      <bezel name="lamp65" element="led"><bounds x="10" y="32" width="1" height="1" /></bezel>
83      <bezel name="lamp66" element="led"><bounds x="12" y="32" width="1" height="1" /></bezel>
84
85      <bezel name="lamp70" element="led"><bounds x="0" y="34" width="1" height="1" /></bezel>
86      <bezel name="lamp71" element="led"><bounds x="2" y="34" width="1" height="1" /></bezel>
87      <bezel name="lamp72" element="led"><bounds x="4" y="34" width="1" height="1" /></bezel>
88      <bezel name="lamp73" element="led"><bounds x="6" y="34" width="1" height="1" /></bezel>
89      <bezel name="lamp74" element="led"><bounds x="8" y="34" width="1" height="1" /></bezel>
90      <bezel name="lamp75" element="led"><bounds x="10" y="34" width="1" height="1" /></bezel>
91      <bezel name="lamp76" element="led"><bounds x="12" y="34" width="1" height="1" /></bezel>
92
93      <bezel name="lamp80" element="led"><bounds x="0" y="36" width="1" height="1" /></bezel>
94      <bezel name="lamp81" element="led"><bounds x="2" y="36" width="1" height="1" /></bezel>
95      <bezel name="lamp82" element="led"><bounds x="4" y="36" width="1" height="1" /></bezel>
96      <bezel name="lamp83" element="led"><bounds x="6" y="36" width="1" height="1" /></bezel>
97      <bezel name="lamp84" element="led"><bounds x="8" y="36" width="1" height="1" /></bezel>
98      <bezel name="lamp85" element="led"><bounds x="10" y="36" width="1" height="1" /></bezel>
99      <bezel name="lamp86" element="led"><bounds x="12" y="36" width="1" height="1" /></bezel>
100
101      <bezel name="lamp90" element="led"><bounds x="0" y="38" width="1" height="1" /></bezel>
102      <bezel name="lamp91" element="led"><bounds x="2" y="38" width="1" height="1" /></bezel>
103      <bezel name="lamp92" element="led"><bounds x="4" y="38" width="1" height="1" /></bezel>
104      <bezel name="lamp93" element="led"><bounds x="6" y="38" width="1" height="1" /></bezel>
105      <bezel name="lamp94" element="led"><bounds x="8" y="38" width="1" height="1" /></bezel>
106      <bezel name="lamp95" element="led"><bounds x="10" y="38" width="1" height="1" /></bezel>
107      <bezel name="lamp96" element="led"><bounds x="12" y="38" width="1" height="1" /></bezel>
108
109
11026   </view>
11127</mamelayout>
trunk/src/mess/layout/edracula.lay
r244651r244652
1919         <bounds left="0" right="64" top="0" bottom="64" />
2020      </bezel>
2121
22   <!-- 18*8 matrix -->
22   <!-- 8*18 matrix -->
2323
2424      <bezel name="lamp700" element="led"><bounds x="0" y="0" width="1" height="1" /></bezel>
2525      <bezel name="lamp701" element="led"><bounds x="0" y="2" width="1" height="1" /></bezel>
trunk/src/mess/layout/tmpacman.lay
r244651r244652
1919         <bounds left="0" right="64" top="0" bottom="64" />
2020      </bezel>
2121
22   <!-- 19*8 matrix -->
22   <!-- 8*19 matrix -->
2323
2424      <bezel name="lamp0" element="led"><bounds x="0" y="0" width="1" height="1" /></bezel>
2525      <bezel name="lamp1" element="led"><bounds x="0" y="2" width="1" height="1" /></bezel>
trunk/src/mess/layout/wildfire.lay
r244651r244652
2626      <bezel name="digit1" element="digit"><bounds x="10" y="0" width="10" height="15" /></bezel>
2727      <bezel name="digit2" element="digit"><bounds x="20" y="0" width="10" height="15" /></bezel>
2828
29   <!-- 13*8 matrix (first 3 are the 7segs) -->
29   <!-- 8*13 matrix (first 3 are the 7segs) -->
3030
3131      <bezel name="lamp0" element="led"><bounds x="0" y="20" width="1" height="1" /></bezel>
3232      <bezel name="lamp1" element="led"><bounds x="2" y="20" width="1" height="1" /></bezel>
trunk/src/mess/machine/mbee.c
r244651r244652
2020   case TIMER_MBEE_NEWKB:
2121      timer_newkb(ptr, param);
2222      break;
23   case TIMER_MBEE_RTC_IRQ:
24      timer_rtc_irq(ptr, param);
25      break;
26   case TIMER_MBEE_BOOT:
27      timer_boot(ptr, param);
28      break;
2329   default:
2430      assert_always(FALSE, "Unknown id in mbee_state::device_timer");
2531   }
r244651r244652
4046WRITE8_MEMBER( mbee_state::pio_port_b_w )
4147{
4248/*  PIO port B - d5..d2 not emulated
43    d7 interrupt from network or rtc or vsync or not used (see config switch)
49    d7 network interrupt (microbee network for classrooms)
4450    d6 speaker
4551    d5 rs232 output (1=mark)
4652    d4 rs232 input (0=mark)
4753    d3 rs232 CTS (0=clear to send)
4854    d2 rs232 clock or DTR
49    d1 cass out and (on new keyboard) keyboard irq
55    d1 cass out and (on 256tc) keyboard irq
5056    d0 cass in */
5157
52   m_cassette->output(BIT(data, 1) ? -1.0 : +1.0);
58   m_cassette->output((data & 0x02) ? -1.0 : +1.0);
59
5360   m_speaker->level_w(BIT(data, 6));
5461};
5562
r244651r244652
5764{
5865   UINT8 data = 0;
5966
60   if (m_cassette->input() > 0.03)
61      data |= 1;
67   if (m_cassette->input() > 0.03) data |= 1;
6268
6369   data |= 8; // CTS held high via resistor. If low, the disk-based models think a mouse is plugged in.
6470
65   switch (m_io_config->read() & 0xc0)
71   if (m_is_mbeett)
6672   {
67      case 0x00:
68         data |= (UINT8)m_b7_vs << 7;
69         break;
70      case 0x40:
71         data |= (UINT8)m_b7_rtc << 7;
72         break;
73      case 0x80:
73      if (m_b2)
74         data |= 0x82;
75      else
7476         data |= 0x80;
75         break;
7677   }
77   data |= (UINT8)m_b2 << 1; // key pressed on new keyboard
78   else
79   {
80      switch (m_io_config->read() & 0xc0)
81      {
82         case 0x00:
83            data |= (UINT8)m_b7_vs << 7;
84            break;
85         case 0x40:
86            data |= (UINT8)m_b7_rtc << 7;
87            break;
88         case 0x80:
89            data |= 0x80;
90            break;
91         case 0xc0:
92            data |= 0x80; // centronics busy line - FIXME
93            break;
94      }
95      data |= (UINT8)m_b2 << 1; // key pressed on new keyboard
96   }
7897
7998   return data;
8099}
r244651r244652
175194
176195   // if anything queued, cause an interrupt
177196   if (m_mbee256_q_pos)
197   {
178198      m_b2 = 1; // set irq
199      //breaks keyboard m_pio->port_b_write(pio_port_b_r(generic_space(),0,0xff));
200   }
179201
180   if (m_b2)
181      m_pio->port_b_write(pio_port_b_r(generic_space(),0,0xff));
182
183   timer_set(attotime::from_hz(10), TIMER_MBEE_NEWKB);
202   timer_set(attotime::from_hz(25), TIMER_MBEE_NEWKB);
184203}
185204
186READ8_MEMBER( mbee_state::port18_r )
205READ8_MEMBER( mbee_state::mbee256_18_r )
187206{
188207   UINT8 i, data = m_mbee256_q[0]; // get oldest key
189208
r244651r244652
204223
205224************************************************************/
206225
207READ8_MEMBER( mbee_state::speed_low_r )
226READ8_MEMBER( mbee_state::mbee256_speed_low_r )
208227{
209228   m_maincpu->set_unscaled_clock(3375000);
210229   return 0xff;
211230}
212231
213READ8_MEMBER( mbee_state::speed_high_r )
232READ8_MEMBER( mbee_state::mbee256_speed_high_r )
214233{
215234   m_maincpu->set_unscaled_clock(6750000);
216235   return 0xff;
r244651r244652
224243
225244************************************************************/
226245
227WRITE8_MEMBER( mbee_state::port04_w )  // address
246WRITE8_MEMBER( mbee_state::mbee_04_w )  // address
228247{
229248   m_rtc->write(space, 0, data);
230249}
231250
232WRITE8_MEMBER( mbee_state::port06_w )  // write
251WRITE8_MEMBER( mbee_state::mbee_06_w )  // write
233252{
234253   m_rtc->write(space, 1, data);
235254}
236255
237READ8_MEMBER( mbee_state::port07_r )   // read
256READ8_MEMBER( mbee_state::mbee_07_r )   // read
238257{
239258   return m_rtc->read(space, 1);
240259}
241260
242// See it work: Run mbeett, choose RTC in the config switches, run the F3 test, press Esc.
243WRITE_LINE_MEMBER( mbee_state::rtc_irq_w )
261// This doesn't seem to do anything; the time works without it.
262TIMER_CALLBACK_MEMBER( mbee_state::timer_rtc_irq )
244263{
245   m_b7_rtc = (state) ? 0 : 1; // inverted by IC15 (pins 8,9,10)
264   if (!m_rtc)
265      return;
246266
267   UINT8 data = m_rtc->read(m_maincpu->space(AS_IO), 12);
268   m_b7_rtc = (data) ? 1 : 0;
269
247270   if ((m_io_config->read() & 0xc0) == 0x40) // RTC selected in config menu
248271      m_pio->port_b_write(pio_port_b_r(generic_space(),0,0xff));
272
273   timer_set(attotime::from_hz(10), TIMER_MBEE_RTC_IRQ);
249274}
250275
251276
r244651r244652
302327            if (!BIT(b_byte, 4))
303328            {
304329               // select video
305               mem.install_read_handler (b_vid, b_vid + 0x7ff, read8_delegate(FUNC(mbee_state::video_low_r), this));
306               mem.install_read_handler (b_vid + 0x800, b_vid + 0xfff, read8_delegate(FUNC(mbee_state::video_high_r), this));
330               if (m_is_premium)
331               {
332                  mem.install_read_handler (b_vid, b_vid + 0x7ff, read8_delegate(FUNC(mbee_state::mbeeppc_low_r), this));
333                  mem.install_read_handler (b_vid + 0x800, b_vid + 0xfff, read8_delegate(FUNC(mbee_state::mbeeppc_high_r), this));
334               }
335               else
336               {
337                  mem.install_read_handler (b_vid, b_vid + 0x7ff, read8_delegate(FUNC(mbee_state::mbee_low_r), this));
338                  mem.install_read_handler (b_vid + 0x800, b_vid + 0xfff, read8_delegate(FUNC(mbee_state::mbeeic_high_r), this));
339               }
307340            }
308341            else
309342            {
r244651r244652
334367            if (!BIT(b_byte, 4))
335368            {
336369               // select video
337               mem.install_write_handler (b_vid, b_vid + 0x7ff, write8_delegate(FUNC(mbee_state::video_low_w), this));
338               mem.install_write_handler (b_vid + 0x800, b_vid + 0xfff, write8_delegate(FUNC(mbee_state::video_high_w), this));
370               if (m_is_premium)
371               {
372                  mem.install_write_handler (b_vid, b_vid + 0x7ff, write8_delegate(FUNC(mbee_state::mbeeppc_low_w), this));
373                  mem.install_write_handler (b_vid + 0x800, b_vid + 0xfff, write8_delegate(FUNC(mbee_state::mbeeppc_high_w), this));
374               }
375               else
376               {
377                  mem.install_write_handler (b_vid, b_vid + 0x7ff, write8_delegate(FUNC(mbee_state::mbee_low_w), this));
378                  mem.install_write_handler (b_vid + 0x800, b_vid + 0xfff, write8_delegate(FUNC(mbee_state::mbeeic_high_w), this));
379               }
339380            }
340381            else
341382            {
r244651r244652
392433
393434************************************************************/
394435
395WRITE8_MEMBER( mbee_state::port0a_w )
436READ8_MEMBER( mbee_state::mbeeic_0a_r )
396437{
438   return m_0a;
439}
440
441WRITE8_MEMBER( mbee_state::mbeeic_0a_w )
442{
397443   m_0a = data;
398
399   if (m_pak)
400      m_pak->set_entry(data & 15);
444   m_pak->set_entry(data & 15);
401445}
402446
403READ8_MEMBER( mbee_state::telcom_low_r )
447READ8_MEMBER( mbee_state::mbeepc_telcom_low_r )
404448{
405449/* Read of port 0A - set Telcom rom to first half */
406   if (m_telcom)
407      m_telcom->set_entry(0);
408
450   m_telcom->set_entry(0);
409451   return m_0a;
410452}
411453
412READ8_MEMBER( mbee_state::telcom_high_r )
454READ8_MEMBER( mbee_state::mbeepc_telcom_high_r )
413455{
414456/* Read of port 10A - set Telcom rom to 2nd half */
415   if (m_telcom)
416      m_telcom->set_entry(1);
417
457   m_telcom->set_entry(1);
418458   return m_0a;
419459}
420460
r244651r244652
431471*/
432472
433473
434void mbee_state::machine_reset_common()
474/* after the first 4 bytes have been read from ROM, switch the ram back in */
475TIMER_CALLBACK_MEMBER( mbee_state::timer_boot )
435476{
477   m_boot->set_entry(0);
478}
479
480void mbee_state::machine_reset_common_disk()
481{
436482   m_fdc_rq = 0;
437   m_08 = 0;
438   m_0a = 0;
439   m_0b = 0;
440   m_1c = 0;
441
442   if (m_basic)
443      m_basic->set_entry(0);
444
445   if (m_telcom)
446      m_telcom->set_entry(0);
447483}
448484
449485MACHINE_RESET_MEMBER( mbee_state, mbee )
450486{
451   machine_reset_common();
452   m_maincpu->set_pc(0x8000);
487   m_boot->set_entry(1);
488   timer_set(attotime::from_usec(4), TIMER_MBEE_BOOT);
453489}
454490
455491MACHINE_RESET_MEMBER( mbee_state, mbee56 )
456492{
457   machine_reset_common();
458   m_maincpu->set_pc(0xE000);
493   machine_reset_common_disk();
494   m_boot->set_entry(1);
495   timer_set(attotime::from_usec(4), TIMER_MBEE_BOOT);
459496}
460497
461498MACHINE_RESET_MEMBER( mbee_state, mbee128 )
462499{
463   machine_reset_common();
500   machine_reset_common_disk();
464501   setup_banks(0, 1, 3); // set banks to default
465502   m_maincpu->set_pc(0x8000);
466503}
467504
468505MACHINE_RESET_MEMBER( mbee_state, mbee256 )
469506{
507   UINT8 i;
508   for (i = 0; i < 15; i++) m_mbee256_was_pressed[i] = 0;
470509   m_mbee256_q_pos = 0;
471   machine_reset_common();
510   machine_reset_common_disk();
472511   setup_banks(0, 1, 7); // set banks to default
473512   m_maincpu->set_pc(0x8000);
474513}
475514
476515MACHINE_RESET_MEMBER( mbee_state, mbeett )
477516{
517   UINT8 i;
518   for (i = 0; i < 15; i++) m_mbee256_was_pressed[i] = 0;
478519   m_mbee256_q_pos = 0;
479   machine_reset_common();
480   m_maincpu->set_pc(0x8000);
520   m_boot->set_entry(1);
521   timer_set(attotime::from_usec(4), TIMER_MBEE_BOOT);
481522}
482523
483524DRIVER_INIT_MEMBER( mbee_state, mbee )
484525{
526   UINT8 *RAM = memregion("maincpu")->base();
527   m_boot->configure_entries(0, 2, &RAM[0x0000], 0x8000);
485528   m_size = 0x4000;
486529   m_has_oldkb = 1;
487530   m_is_mbeett = 0;
r244651r244652
489532
490533DRIVER_INIT_MEMBER( mbee_state, mbeeic )
491534{
492   UINT8 *RAM = memregion("pakrom")->base();
535   UINT8 *RAM = memregion("maincpu")->base();
536   m_boot->configure_entries(0, 2, &RAM[0x0000], 0x8000);
537
538   RAM = memregion("pakrom")->base();
493539   m_pak->configure_entries(0, 16, &RAM[0x0000], 0x2000);
540
494541   m_pak->set_entry(0);
495
496542   m_size = 0x8000;
497543   m_has_oldkb = 1;
498544   m_is_mbeett = 0;
r244651r244652
500546
501547DRIVER_INIT_MEMBER( mbee_state, mbeepc )
502548{
503   UINT8 *RAM = memregion("telcomrom")->base();
549   UINT8 *RAM = memregion("maincpu")->base();
550   m_boot->configure_entries(0, 2, &RAM[0x0000], 0x8000);
551
552   RAM = memregion("telcomrom")->base();
504553   m_telcom->configure_entries(0, 2, &RAM[0x0000], 0x1000);
505554
506555   RAM = memregion("pakrom")->base();
507556   m_pak->configure_entries(0, 16, &RAM[0x0000], 0x2000);
557
508558   m_pak->set_entry(0);
509
559   m_telcom->set_entry(0);
510560   m_size = 0x8000;
511561   m_has_oldkb = 1;
512562   m_is_mbeett = 0;
r244651r244652
514564
515565DRIVER_INIT_MEMBER( mbee_state, mbeepc85 )
516566{
517   UINT8 *RAM = memregion("telcomrom")->base();
567   UINT8 *RAM = memregion("maincpu")->base();
568   m_boot->configure_entries(0, 2, &RAM[0x0000], 0x8000);
569
570   RAM = memregion("telcomrom")->base();
518571   m_telcom->configure_entries(0, 2, &RAM[0x0000], 0x1000);
519572
520573   RAM = memregion("pakrom")->base();
521574   m_pak->configure_entries(0, 16, &RAM[0x0000], 0x2000);
575
522576   m_pak->set_entry(5);
523
577   m_telcom->set_entry(0);
524578   m_size = 0x8000;
525579   m_has_oldkb = 1;
526580   m_is_mbeett = 0;
r244651r244652
528582
529583DRIVER_INIT_MEMBER( mbee_state, mbeeppc )
530584{
531   UINT8 *RAM = memregion("basicrom")->base();
585   UINT8 *RAM = memregion("maincpu")->base();
586   m_boot->configure_entry(0, &RAM[0x0000]);
587
588   RAM = memregion("basicrom")->base();
532589   m_basic->configure_entries(0, 2, &RAM[0x0000], 0x2000);
590   m_boot->configure_entry(1, &RAM[0x0000]);
533591
534592   RAM = memregion("telcomrom")->base();
535593   m_telcom->configure_entries(0, 2, &RAM[0x0000], 0x1000);
536594
537595   RAM = memregion("pakrom")->base();
538596   m_pak->configure_entries(0, 16, &RAM[0x0000], 0x2000);
597
539598   m_pak->set_entry(5);
540
599   m_telcom->set_entry(0);
600   m_basic->set_entry(0);
541601   m_size = 0x8000;
542602   m_has_oldkb = 1;
543603   m_is_mbeett = 0;
r244651r244652
545605
546606DRIVER_INIT_MEMBER( mbee_state, mbee56 )
547607{
608   UINT8 *RAM = memregion("maincpu")->base();
609   m_boot->configure_entries(0, 2, &RAM[0x0000], 0xe000);
548610   m_size = 0xe000;
549611   m_has_oldkb = 1;
550612   m_is_mbeett = 0;
r244651r244652
567629      membank(banktag)->configure_entries(64, 1, &ROM[0x4000], 0x1000); // dummy rom
568630   }
569631
632   timer_set(attotime::from_hz(1), TIMER_MBEE_RTC_IRQ);   /* timer for rtc */
633
570634   m_size = 0x8000;
571635   m_has_oldkb = 1;
572636   m_is_mbeett = 0;
r244651r244652
589653      membank(banktag)->configure_entries(64, 1, &ROM[0x4000], 0x1000); // dummy rom
590654   }
591655
592   timer_set(attotime::from_hz(1), TIMER_MBEE_NEWKB);   /* kick-start timer for kbd */
656   timer_set(attotime::from_hz(1), TIMER_MBEE_RTC_IRQ);   /* timer for rtc */
657   timer_set(attotime::from_hz(25), TIMER_MBEE_NEWKB);   /* timer for kbd */
593658
594659   m_size = 0x8000;
595660   m_has_oldkb = 0;
r244651r244652
598663
599664DRIVER_INIT_MEMBER( mbee_state, mbeett )
600665{
601   UINT8 *RAM = memregion("telcomrom")->base();
666   UINT8 *RAM = memregion("maincpu")->base();
667   m_boot->configure_entries(0, 2, &RAM[0x0000], 0x8000);
668
669   RAM = memregion("telcomrom")->base();
602670   m_telcom->configure_entries(0, 2, &RAM[0x0000], 0x1000);
603671
604672   RAM = memregion("pakrom")->base();
605673   m_pak->configure_entries(0, 16, &RAM[0x0000], 0x2000);
674
606675   m_pak->set_entry(5);
676   m_telcom->set_entry(0);
607677
608   timer_set(attotime::from_hz(1), TIMER_MBEE_NEWKB);   /* kick-start timer for kbd */
678   timer_set(attotime::from_hz(1), TIMER_MBEE_RTC_IRQ);   /* timer for rtc */
679   timer_set(attotime::from_hz(25), TIMER_MBEE_NEWKB);   /* timer for kbd */
609680
610681   m_size = 0x8000;
611682   m_has_oldkb = 0;
trunk/src/mess/mess.mak
r244651r244652
12261226   $(MESS_DRIVERS)/advision.o $(MESS_MACHINE)/advision.o $(MESS_VIDEO)/advision.o \
12271227
12281228$(MESSOBJ)/epoch.a:             \
1229   $(MESS_DRIVERS)/edracula.o  \
12291230   $(MESS_DRIVERS)/gamepock.o $(MESS_MACHINE)/gamepock.o \
12301231   $(MESS_DRIVERS)/scv.o $(MESS_AUDIO)/upd1771.o \
12311232
r244651r244652
17771778   $(MESS_DRIVERS)/tiki100.o   \
17781779
17791780$(MESSOBJ)/tomy.a:              \
1781   $(MESS_DRIVERS)/alnchase.o  \
1782   $(MESS_DRIVERS)/tmtennis.o  \
17801783   $(MESS_DRIVERS)/tutor.o     \
17811784
17821785$(MESSOBJ)/toshiba.a:           \
r244651r244652
20812084$(MESS_DRIVERS)/aim65.o:    $(MESS_LAYOUT)/aim65.lh
20822085$(MESS_DRIVERS)/aim65_40.o: $(MESS_LAYOUT)/aim65_40.lh
20832086$(MESS_DRIVERS)/alesis.o:   $(MESS_LAYOUT)/sr16.lh
2087$(MESS_DRIVERS)/alnchase.o: $(MESS_LAYOUT)/alnchase.lh
2088$(MESS_DRIVERS)/amaztron.o: $(MESS_LAYOUT)/amaztron.lh
20842089$(MESS_DRIVERS)/amico2k.o:  $(MESS_LAYOUT)/amico2k.lh
20852090$(MESS_DRIVERS)/amiga.o:    $(MESS_LAYOUT)/amiga.lh
20862091$(MESS_VIDEO)/apollo.o:     $(MESS_LAYOUT)/apollo.lh \
r244651r244652
20982103$(MESS_DRIVERS)/chessmst.o: $(MESS_LAYOUT)/chessmst.lh
20992104$(MESS_DRIVERS)/chesstrv.o: $(MESS_LAYOUT)/chesstrv.lh \
21002105                     $(MESS_LAYOUT)/borisdpl.lh
2106$(MESS_DRIVERS)/comp4.o:    $(MESS_LAYOUT)/comp4.lh
21012107$(MESS_DRIVERS)/cp1.o:      $(MESS_LAYOUT)/cp1.lh
21022108$(MESS_DRIVERS)/cvicny.o:   $(MESS_LAYOUT)/cvicny.lh
21032109$(MESS_DRIVERS)/coco3.o:    $(MESS_LAYOUT)/coco3.lh
r244651r244652
21072113$(MESS_DRIVERS)/dmv.o:      $(MESS_LAYOUT)/dmv.lh
21082114$(MESS_DRIVERS)/dolphunk.o: $(MESS_LAYOUT)/dolphunk.lh
21092115$(MESS_DRIVERS)/eacc.o:     $(MESS_LAYOUT)/eacc.lh
2116$(MESS_DRIVERS)/edracula.o: $(MESS_LAYOUT)/edracula.lh
21102117$(MESS_DRIVERS)/elekscmp.o: $(MESS_LAYOUT)/elekscmp.lh
21112118$(MESS_DRIVERS)/elf.o:      $(MESS_LAYOUT)/elf2.lh
21122119$(MESS_MACHINE)/esqvfd.o:   $(MESS_LAYOUT)/esq2by40.lh \
r244651r244652
21332140                            $(MESS_LAYOUT)/stopthie.lh \
21342141                            $(MESS_LAYOUT)/tandy12.lh \
21352142                            $(MESS_LAYOUT)/tc4.lh
2136$(MESS_DRIVERS)/hh_ucom4.o: $(MESS_LAYOUT)/alnchase.lh \
2137                            $(MESS_LAYOUT)/edracula.lh \
2138                            $(MESS_LAYOUT)/tmpacman.lh \
2139                            $(MESS_LAYOUT)/tmtennis.lh
2143$(MESS_DRIVERS)/hh_ucom4.o: $(MESS_LAYOUT)/tmpacman.lh
21402144$(MESS_DRIVERS)/ie15.o:     $(MESS_LAYOUT)/ie15.lh
21412145$(MESS_DRIVERS)/instruct.o: $(MESS_LAYOUT)/instruct.lh
21422146$(MESS_DRIVERS)/k1003.o:    $(MESS_LAYOUT)/k1003.lh
r244651r244652
21802184$(MESS_DRIVERS)/sdk85.o:    $(MESS_LAYOUT)/sdk85.lh
21812185$(MESS_DRIVERS)/sdk86.o:    $(MESS_LAYOUT)/sdk86.lh
21822186$(MESS_DRIVERS)/selz80.o:   $(MESS_LAYOUT)/selz80.lh
2187$(MESS_DRIVERS)/simon.o:    $(MESS_LAYOUT)/simon.lh
21832188$(MESS_DRIVERS)/sitcom.o:   $(MESS_LAYOUT)/sitcom.lh
21842189$(MESS_DRIVERS)/slc1.o:     $(MESS_LAYOUT)/slc1.lh
21852190$(MESS_DRIVERS)/sms.o:      $(MESS_LAYOUT)/sms1.lh
r244651r244652
22042209$(MESS_DRIVERS)/tk80.o:     $(MESS_LAYOUT)/tk80.lh
22052210$(MESS_DRIVERS)/tm990189.o: $(MESS_LAYOUT)/tm990189.lh \
22062211                     $(MESS_LAYOUT)/tm990189v.lh
2212$(MESS_DRIVERS)/tmtennis.o: $(MESS_LAYOUT)/tmtennis.lh
22072213$(MESS_DRIVERS)/unixpc.o:   $(MESS_LAYOUT)/unixpc.lh
22082214$(MESS_DRIVERS)/ut88.o:     $(MESS_LAYOUT)/ut88mini.lh
22092215$(MESS_DRIVERS)/vboy.o:     $(MESS_LAYOUT)/vboy.lh
trunk/src/mess/video/mbee.c
r244651r244652
6969************************************************************/
7070
7171
72READ8_MEMBER( mbee_state::video_low_r )
72READ8_MEMBER( mbee_state::mbee_low_r )
7373{
74   if (m_is_premium && ((m_1c & 0x9f) == 0x90))
75      return m_p_attribram[offset];
76   else
77   if BIT(m_0b, 0)
74   if (m_0b & 1)
7875      return m_p_gfxram[offset];
7976   else
8077      return m_p_videoram[offset];
8178}
8279
83WRITE8_MEMBER( mbee_state::video_low_w )
80WRITE8_MEMBER( mbee_state::mbee_low_w )
8481{
85   if BIT(m_1c, 4)
86   {
87      // non-premium attribute writes are discarded
88      if (m_is_premium && BIT(m_1c, 7))
89         m_p_attribram[offset] = data;
90   }
91   else
92      m_p_videoram[offset] = data;
82   m_p_videoram[offset] = data;
9383}
9484
95READ8_MEMBER( mbee_state::video_high_r )
85READ8_MEMBER( mbee_state::mbee_high_r )
9686{
97   if BIT(m_08, 6)
98      return m_p_colorram[offset];
99   else
100      return m_p_gfxram[(((m_1c & 15) + 1) << 11) | offset];
87   return m_p_gfxram[0x800 | offset];
10188}
10289
103WRITE8_MEMBER( mbee_state::video_high_w )
90WRITE8_MEMBER( mbee_state::mbee_high_w )
10491{
105   if (BIT(m_08, 6) && (~m_0b & 1))
106      m_p_colorram[offset] = data;
107   else
108      m_p_gfxram[(((m_1c & 15) + 1) << 11) | offset] = data;
92   m_p_gfxram[0x800 | offset] = data;
10993}
11094
111WRITE8_MEMBER( mbee_state::port0b_w )
95READ8_MEMBER( mbee_state::mbee_0b_r )
11296{
113   m_0b = data & 1;
97   return m_0b;
11498}
11599
116READ8_MEMBER( mbee_state::port08_r )
100WRITE8_MEMBER( mbee_state::mbee_0b_w )
117101{
102   m_0b = data;
103}
104
105READ8_MEMBER( mbee_state::mbeeic_08_r )
106{
118107   return m_08;
119108}
120109
121WRITE8_MEMBER( mbee_state::port08_w )
110WRITE8_MEMBER( mbee_state::mbeeic_08_w )
122111{
123112   m_08 = data;
124113}
125114
126READ8_MEMBER( mbee_state::port1c_r )
115READ8_MEMBER( mbee_state::mbeeic_high_r )
127116{
117   if (m_08 & 0x40)
118      return m_p_colorram[offset];
119   else
120      return m_p_gfxram[0x800 | offset];
121}
122
123WRITE8_MEMBER( mbee_state::mbeeic_high_w )
124{
125   if ((m_08 & 0x40) && (~m_0b & 1))
126      m_p_colorram[offset] = data;
127   else
128      m_p_gfxram[0x0800 | offset] = data;
129}
130
131READ8_MEMBER( mbee_state::mbeeppc_1c_r )
132{
128133   return m_1c;
129134}
130135
131WRITE8_MEMBER( mbee_state::port1c_w )
136WRITE8_MEMBER( mbee_state::mbeeppc_1c_w )
132137{
133138/*  d7 extended graphics (1=allow attributes and pcg banks)
134139    d5 bankswitch basic rom
135140    d4 select attribute ram
136141    d3..d0 select m_videoram bank */
137142
138   if (m_is_premium && BIT(data, 7))
139      m_1c = data;
143   m_1c = data;
144   membank("basic")->set_entry(BIT(data, 5));
145}
146
147WRITE8_MEMBER( mbee_state::mbee256_1c_w )
148{
149/*  d7 extended graphics (1=allow attributes and pcg banks)
150    d5 bankswitch basic rom
151    d4 select attribute ram
152    d3..d0 select m_videoram bank */
153
154   m_1c = data;
155}
156
157READ8_MEMBER( mbee_state::mbeeppc_low_r )
158{
159   if ((m_1c & 0x1f) == 0x10)
160      return m_p_attribram[offset];
140161   else
141      m_1c = data & 0x30;
162   if (m_0b & 1)
163      return m_p_gfxram[offset];
164   else
165      return m_p_videoram[offset];
166}
142167
143   if (m_basic)
144      m_basic->set_entry(BIT(data, 5));
168WRITE8_MEMBER( mbee_state::mbeeppc_low_w )
169{
170   if (m_1c & 16)
171      m_p_attribram[offset] = data;
172   else
173      m_p_videoram[offset] = data;
145174}
146175
176READ8_MEMBER( mbee_state::mbeeppc_high_r )
177{
178   if (m_08 & 0x40)
179      return m_p_colorram[offset];
180   else
181      return m_p_gfxram[(((m_1c & 15) + 1) << 11) | offset];
182}
147183
184WRITE8_MEMBER ( mbee_state::mbeeppc_high_w )
185{
186   if ((m_08 & 0x40) && (~m_0b & 1))
187      m_p_colorram[offset] = data;
188   else
189      m_p_gfxram[(((m_1c & 15) + 1) << 11) | offset] = data;
190}
191
192
148193/***********************************************************
149194
150195    CRTC-driven keyboard
r244651r244652
152197************************************************************/
153198
154199
155void mbee_state::oldkb_matrix_r(UINT16 offs)
200void mbee_state::keyboard_matrix_r(int offs)
156201{
157   if (m_has_oldkb)
202   UINT8 port = (offs >> 7) & 7;
203   UINT8 bit = (offs >> 4) & 7;
204   UINT8 data = m_io_oldkb[port]->read();
205   bool keydown  = ( data >> bit ) & 1;
206
207   // This adds premium-style cursor keys to the old keyboard
208   // They are used by the pc85 & ppc menu, and the 128k shell.
209   if (!keydown)
158210   {
159      UINT8 port = (offs >> 7) & 7;
160      UINT8 bit = (offs >> 4) & 7;
161      UINT8 data = m_io_oldkb[port]->read();
162      bool keydown  = ( data >> bit ) & 1;
211      UINT8 extra = m_io_extra->read();
163212
164      // This adds premium-style cursor keys to the old keyboard
165      // They are used by the pc85 & ppc menu, and the 128k shell.
166      if (!keydown)
167      {
168         UINT8 extra = m_io_extra->read();
213      if (extra && port == 7 && bit == 1) keydown = 1;   /* Control */
169214
170         if (extra && port == 7 && bit == 1) keydown = 1;   /* Control */
215      if (BIT(extra, 0) && ( port == 0 && bit == 5 )) keydown = 1; // cursor up = ^E
216      else
217      if (BIT(extra, 1) && ( port == 3 && bit == 0 )) keydown = 1; // cursor down = ^X
218      else
219      if (BIT(extra, 2) && ( port == 2 && bit == 3 )) keydown = 1; // cursor left = ^S
220      else
221      if (BIT(extra, 3) && ( port == 0 && bit == 4 )) keydown = 1; // cursor right = ^D
222#if 0
223      // this key doesn't appear on any keyboard afaik. It is a Wordbee function.
224      else
225      if (BIT(extra, 4) && ( port == 2 && bit == 6 )) keydown = 1;  // insert = ^V
226#endif
227   }
171228
172         if (BIT(extra, 0) && ( port == 0 && bit == 5 )) keydown = 1; // cursor up = ^E
173         else
174         if (BIT(extra, 1) && ( port == 3 && bit == 0 )) keydown = 1; // cursor down = ^X
175         else
176         if (BIT(extra, 2) && ( port == 2 && bit == 3 )) keydown = 1; // cursor left = ^S
177         else
178         if (BIT(extra, 3) && ( port == 0 && bit == 4 )) keydown = 1; // cursor right = ^D
179         else
180         if (BIT(extra, 4) && ( port == 2 && bit == 6 )) keydown = 1; // insert = ^V
181      }
182
183      if( keydown )
184      {
185         m_sy6545_reg[17] = offs;
186         m_sy6545_reg[16] = (offs >> 8) & 0x3f;
187         m_sy6545_status |= 0x40; //lpen_strobe
188      }
229   if( keydown )
230   {
231      m_sy6545_reg[17] = offs;
232      m_sy6545_reg[16] = (offs >> 8) & 0x3f;
233      m_sy6545_status |= 0x40; //lpen_strobe
189234   }
190235}
191236
192237
193void mbee_state::oldkb_scan( UINT16 param )
238void mbee_state::mbee_video_kbd_scan( int param )
194239{
195   if (m_0b) return; // IC5 (pins 11,12,13)
240   if (m_0b) return; // can't remember why this is here
196241   if (param & 15) return; // only scan once per row instead of 16 times
197   oldkb_matrix_r(param);
242   keyboard_matrix_r(param);
198243}
199244
200245
r244651r244652
232277      // This firstly pushes the contents of the transparent registers onto the MA lines,
233278      // then increments the address, then sets update strobe on.
234279      addr = (m_sy6545_reg[18] << 8) | m_sy6545_reg[19];
235      oldkb_matrix_r(addr);
280      keyboard_matrix_r(addr);
236281      m_sy6545_reg[19]++;
237282      if (!m_sy6545_reg[19]) m_sy6545_reg[18]++;
238283      m_sy6545_status |= 0x80; // update_strobe
r244651r244652
251296WRITE8_MEMBER ( mbee_state::m6545_data_w )
252297{
253298   static const UINT8 sy6545_mask[32]={0xff,0xff,0xff,0x0f,0x7f,0x1f,0x7f,0x7f,3,0x1f,0x7f,0x1f,0x3f,0xff,0x3f,0xff,0,0,0x3f,0xff};
254   UINT16 addr = 0;
299   int addr = 0;
255300
256301   switch( m_sy6545_ind )
257302   {
r244651r244652
264309      // This firstly pushes the contents of the transparent registers onto the MA lines,
265310      // then increments the address, then sets update strobe on.
266311      addr = (m_sy6545_reg[18] << 8) | m_sy6545_reg[19];
267      oldkb_matrix_r(addr);
312      keyboard_matrix_r(addr);
268313      m_sy6545_reg[19]++;
269314      if (!m_sy6545_reg[19]) m_sy6545_reg[18]++;
270315      m_sy6545_status |= 0x80; // update_strobe
r244651r244652
337382      mem = (ma + x) & 0x7ff;
338383      chr = m_p_videoram[mem];
339384
340      oldkb_scan(x+ma);
385      mbee_video_kbd_scan(x+ma);
341386
342387      /* process cursor */
343388      if (x == cursor_x)
r244651r244652
374419      chr = m_p_videoram[mem];
375420      col = m_p_colorram[mem];                     // read a byte of colour
376421
377      if BIT(m_1c, 7) // premium graphics enabled?
422      if (m_is_premium)
378423      {
379         attr = m_p_attribram[mem];
424         if (m_1c & 0x80)                     // are extended features enabled?
425         {
426            attr = m_p_attribram[mem];
380427
381         if BIT(chr, 7)
382            chr += ((attr & 15) << 7);          // bump chr to its particular pcg definition
428            if (chr & 0x80)
429               chr += ((attr & 15) << 7);          // bump chr to its particular pcg definition
383430
384         if BIT(attr, 6)
385            inv ^= 0xff;                    // inverse attribute
431            if (attr & 0x40)
432               inv ^= 0xff;                    // inverse attribute
386433
387         if (BIT(attr, 7) & BIT(m_framecnt, 4))            // flashing attribute
388            chr = 0x20;
434            if ((attr & 0x80) && (m_framecnt & 0x10))            // flashing attribute
435               chr = 0x20;
436         }
389437      }
390438      else
391439         col |= colourm;
392440
393      oldkb_scan(x+ma);
441      if (m_has_oldkb)
442         mbee_video_kbd_scan(x+ma);
394443
395444      /* process cursor */
396445      if (x == cursor_x)
trunk/src/osd/modules/render/blit13.h
r0r244652
1
2
3
4//============================================================
5//  INLINE
6//============================================================
7
8inline UINT32 premult32(const UINT32 pixel)
9{
10   const UINT16 a = (pixel >> 24) & 0xff;
11   const UINT16 r = (pixel >> 16) & 0xff;
12   const UINT16 g = (pixel >> 8) & 0xff;
13   const UINT16 b = (pixel >> 0) & 0xff;
14
15   return 0xFF000000 |
16      ((r * a) / 255) << 16 |
17      ((g * a) / 255) << 8 |
18      ((b * a) / 255);
19}
20
21inline UINT32 CLUL(const UINT32 x)
22{
23   return ((INT32) x < 0) ? 0 : ((x > 65535) ? 255 : x >> 8);
24}
25
26inline UINT32 ycc_to_rgb(const UINT8 y, const UINT8 cb, const UINT8 cr)
27{
28   const UINT32 common = 298 * y - 56992;
29   const UINT32 r = (common +            409 * cr);
30   const UINT32 g = (common - 100 * cb - 208 * cr + 91776);
31   const UINT32 b = (common + 516 * cb - 13696);
32
33   return 0xff000000 | (CLUL(r)<<16) | (CLUL(g)<<8) | (CLUL(b));
34}
35
36inline UINT32 pixel_ycc_to_rgb(const UINT16 *pixel)
37{
38   const UINT32 p = *(UINT32 *)((FPTR) pixel & ~3);
39   return ycc_to_rgb((*pixel >> 8) & 0xff, (p) & 0xff, (p>>16) & 0xff);
40}
41
42inline UINT32 pixel_ycc_to_rgb_pal(const UINT16 *pixel, const rgb_t *palette)
43{
44   const UINT32 p = *(UINT32 *)((FPTR) pixel & ~3);
45   return ycc_to_rgb(palette[(*pixel >> 8) & 0xff], (p) & 0xff, (p>>16) & 0xff);
46}
47
48//============================================================
49//  Pixel conversions
50//============================================================
51
52
53#define FUNC_DEF(source) op(const source &src, const rgb_t *palbase) const
54#define FUNCTOR(name, x...) \
55   template<typename _source, typename _dest> \
56   struct name { _dest FUNC_DEF(_source) { x } };
57
58FUNCTOR(op_argb32_argb32, return src; )
59FUNCTOR(op_rgb32_argb32,  return src | 0xff000000; )
60FUNCTOR(op_pal16_argb32,  return 0xff000000 |palbase[src]; )
61FUNCTOR(op_pal16_rgb32,   return palbase[src]; )
62FUNCTOR(op_rgb32pal_argb32,
63   return palbase[0x200 + (((src) >> 16) & 0xff) ] |
64      palbase[0x100 + (((src) >> 8) & 0xff) ] |
65      palbase[((src) & 0xff) ] | 0xff000000; )
66
67FUNCTOR(op_pal16a_argb32, return palbase[src]; )
68
69FUNCTOR(op_rgb15_argb32,
70      return 0xff000000 | ((src & 0x7c00) << 9) | ((src & 0x03e0) << 6)
71            | ((src & 0x001f) << 3) | ((((src & 0x7c00) << 9)
72            | ((src & 0x03e0) << 6) | ((src & 0x001f) << 3) >> 5) & 0x070707); )
73
74FUNCTOR(op_rgb15pal_argb32,
75      return 0xff000000 | palbase[0x40 + ((src >> 10) & 0x1f)] |
76      palbase[0x20 + ((src >> 5) & 0x1f)] | palbase[0x00 + ((src >> 0) & 0x1f)]; )
77
78FUNCTOR(op_argb32_rgb32, return premult32(src); )
79FUNCTOR(op_pal16a_rgb32, return premult32(palbase[src]); )
80FUNCTOR(op_pal16_argb1555,
81      return (palbase[src]&0xf80000) >> 9 |
82         (palbase[src]&0x00f800) >> 6 |
83         (palbase[src]&0x0000f8) >> 3 | 0x8000; )
84
85FUNCTOR(op_rgb15_argb1555, return src | 0x8000; )
86
87FUNCTOR(op_rgb15pal_argb1555,
88      return (palbase[src >> 10] & 0xf8) << 7 |
89         (palbase[(src >> 5) & 0x1f] & 0xf8) << 2 |
90         (palbase[src & 0x1f] & 0xf8) >> 3 | 0x8000; )
91
92FUNCTOR(op_yuv16_uyvy, return src; )
93FUNCTOR(op_yuv16pal_uyvy, return (palbase[(src >> 8) & 0xff] << 8) | (src & 0x00ff); )
94
95// FIXME: wrong ... see non_pal version
96FUNCTOR(op_yuv16pal_yvyu, return (palbase[(src >> 8) & 0xff] & 0xff) | ((src & 0xff) << 8); )
97FUNCTOR(op_yuv16_yvyu, return ((src & 0xff00ff00) >> 8 ) | (src << 24) | ((src >> 8) & 0x00ff00); )
98
99FUNCTOR(op_yuv16_yuy2, return ((src & 0xff00ff00) >> 8) | ((src & 0x00ff00ff) << 8); )
100
101FUNCTOR(op_yuv16pal_yuy2,
102      return  (palbase[(src>>8) & 0xff]) |
103            (palbase[(src>>24) & 0xff]<<16) |
104            ((src<<8)&0xff00ff00);)
105
106FUNCTOR(op_yuv16_argb32,
107      return (UINT64) ycc_to_rgb((src >>  8) & 0xff, src & 0xff , (src>>16) & 0xff)
108   | ((UINT64)ycc_to_rgb((src >> 24) & 0xff, src & 0xff , (src>>16) & 0xff) << 32); )
109
110FUNCTOR(op_yuv16pal_argb32,
111      return (UINT64)ycc_to_rgb(palbase[(src >>  8) & 0xff], src & 0xff , (src>>16) & 0xff)
112   | ((UINT64)ycc_to_rgb(palbase[(src >> 24) & 0xff], src & 0xff , (src>>16) & 0xff) << 32);)
113
114FUNCTOR(op_yuv16_argb32rot, return pixel_ycc_to_rgb(&src) ; )
115
116FUNCTOR(op_yuv16pal_argb32rot, return pixel_ycc_to_rgb_pal(&src, palbase); )
117
118//============================================================
119//  Copy and rotation
120//============================================================
121
122struct blit_base {
123   blit_base(int dest_bpp, bool is_rot, bool is_passthrough)
124   : m_dest_bpp(dest_bpp), m_is_rot(is_rot), m_is_passthrough(is_passthrough)
125   { }
126   virtual ~blit_base() { }
127
128   virtual void texop(const texture_info *texture, const render_texinfo *texsource) const = 0;
129   int m_dest_bpp;
130   bool m_is_rot;
131   bool m_is_passthrough;
132};
133
134template<typename _src_type, typename _dest_type, typename _op, int _len_div>
135struct blit_texcopy : public blit_base
136{
137   blit_texcopy() : blit_base(sizeof(_dest_type) / _len_div, false, false) { }
138   void texop(const texture_info *texture, const render_texinfo *texsource) const
139   {
140      ATTR_UNUSED const rgb_t *palbase = texsource->palette;
141      int x, y;
142      /* loop over Y */
143      for (y = 0; y < texsource->height; y++) {
144         _src_type *src = (_src_type *)texsource->base + y * texsource->rowpixels / (_len_div);
145         _dest_type *dst = (_dest_type *)((UINT8 *)texture->m_pixels + y * texture->m_pitch);
146         x = texsource->width / (_len_div);
147         while (x > 0) {
148            *dst++ = m_op.op(*src, palbase);
149            src++;
150            x--;
151         }
152      }
153   }
154private:
155   _op m_op;
156};
157
158#define TEXCOPYA(a, b, c, d) \
159      const struct blit_texcopy<b, c, op_ ## a <b, c>, d> texcopy_ ## a;
160
161template<typename _src_type, typename _dest_type, typename _op>
162struct blit_texrot : public blit_base
163{
164   blit_texrot() : blit_base(sizeof(_dest_type), true, false) { }
165   void texop(const texture_info *texture, const render_texinfo *texsource) const
166   {
167      ATTR_UNUSED const rgb_t *palbase = texsource->palette;
168      int x, y;
169      const quad_setup_data *setup = &texture->m_setup;
170      int dudx = setup->dudx;
171      int dvdx = setup->dvdx;
172      /* loop over Y */
173      for (y = 0; y < setup->rotheight; y++) {
174         INT32 curu = setup->startu + y * setup->dudy;
175         INT32 curv = setup->startv + y * setup->dvdy;
176         _dest_type *dst = (_dest_type *)((UINT8 *)texture->m_pixels + y * texture->m_pitch);
177         x = setup->rotwidth;
178         while (x>0) {
179            _src_type *src = (_src_type *) texsource->base + (curv >> 16) * texsource->rowpixels + (curu >> 16);
180            *dst++ = m_op.op(*src, palbase);
181            curu += dudx;
182            curv += dvdx;
183            x--;
184         }
185      }
186   }
187private:
188   _op m_op;
189};
190
191#define TEXROTA(a, b, c) \
192      const struct blit_texrot<b, c, op_ ## a <b, c> > texcopy_rot_ ## a;
193
194template<typename _src_type, typename _dest_type>
195struct blit_texpass : public blit_base
196{
197   blit_texpass() : blit_base(sizeof(_dest_type), false, true) { }
198   void texop(const texture_info *texture, const render_texinfo *texsource) const
199   {
200   }
201};
202
203#define TEXCOPYP(a, b, c) \
204      const struct blit_texpass<b, c> texcopy_ ## a;
205
206
207TEXCOPYA(rgb32_argb32,  UINT32, UINT32, 1)
208TEXCOPYP(rgb32_rgb32,   UINT32, UINT32)
209
210TEXCOPYA(rgb32pal_argb32,  UINT32, UINT32, 1)
211TEXCOPYA(pal16_argb32,  UINT16, UINT32, 1)
212TEXCOPYA(pal16a_argb32,  UINT16, UINT32, 1)
213TEXCOPYA(rgb15_argb32,  UINT16, UINT32, 1)
214TEXCOPYA(rgb15pal_argb32,  UINT16, UINT32, 1)
215
216TEXCOPYA(pal16_argb1555,  UINT16, UINT16, 1)
217TEXCOPYA(rgb15_argb1555,  UINT16, UINT16, 1)
218TEXCOPYA(rgb15pal_argb1555,  UINT16, UINT16, 1)
219
220TEXCOPYP(argb32_argb32,  UINT32, UINT32)
221TEXCOPYA(argb32_rgb32, UINT32, UINT32, 1)
222TEXCOPYA(pal16a_rgb32,  UINT16, UINT32, 1)
223
224TEXCOPYA(yuv16_argb32, UINT32, UINT64, 2)
225TEXCOPYA(yuv16pal_argb32, UINT32, UINT64, 2)
226
227TEXCOPYP(yuv16_uyvy, UINT16, UINT16)
228TEXCOPYP(rgb15_rgb555, UINT16, UINT16)
229
230TEXCOPYA(yuv16pal_uyvy, UINT16, UINT16, 1)
231
232TEXCOPYA(yuv16_yvyu, UINT32, UINT32, 2)
233TEXCOPYA(yuv16pal_yvyu, UINT16, UINT16, 1)
234
235TEXCOPYA(yuv16_yuy2, UINT32, UINT32, 2)
236TEXCOPYA(yuv16pal_yuy2, UINT32, UINT32, 2)
237
238
239
240TEXROTA(argb32_argb32, UINT32, UINT32)
241TEXROTA(rgb32_argb32,  UINT32, UINT32)
242TEXROTA(pal16_argb32,  UINT16, UINT32)
243TEXROTA(pal16_rgb32,  UINT16, UINT32)
244
245TEXROTA(rgb32pal_argb32,  UINT32, UINT32)
246TEXROTA(pal16a_argb32,  UINT16, UINT32)
247TEXROTA(rgb15_argb32,  UINT16, UINT32)
248TEXROTA(rgb15pal_argb32,  UINT16, UINT32)
249
250TEXROTA(pal16_argb1555,  UINT16, UINT16)
251TEXROTA(rgb15_argb1555,  UINT16, UINT16)
252TEXROTA(rgb15pal_argb1555,  UINT16, UINT16)
253
254TEXROTA(argb32_rgb32, UINT32, UINT32)
255TEXROTA(pal16a_rgb32,  UINT16, UINT32)
256
257TEXROTA(yuv16_argb32rot, UINT16, UINT32)
258TEXROTA(yuv16pal_argb32rot, UINT16, UINT32)
trunk/src/osd/modules/render/d3d/d3d9intf.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  d3d9intf.c - Direct3D 9 abstraction layer
6//
7//============================================================
8
9// standard windows headers
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12#include <d3d9.h>
13#include <d3dx9.h>
14#undef interface
15
16// MAME headers
17#include "emu.h"
18
19// MAMEOS headers
20#include "d3dintf.h"
21#include "winmain.h"
22
23
24
25//============================================================
26//  TYPE DEFINITIONS
27//============================================================
28
29typedef IDirect3D9 *(WINAPI *direct3dcreate9_ptr)(UINT SDKVersion);
30
31namespace d3d
32{
33//============================================================
34//  PROTOTYPES
35//============================================================
36
37static void set_interfaces(base *d3dptr);
38
39//============================================================
40//  INLINES
41//============================================================
42
43INLINE void convert_present_params(const present_parameters *params, D3DPRESENT_PARAMETERS *d3d9params)
44{
45   memset(d3d9params, 0, sizeof(*d3d9params));
46   d3d9params->BackBufferWidth = params->BackBufferWidth;
47   d3d9params->BackBufferHeight = params->BackBufferHeight;
48   d3d9params->BackBufferFormat = params->BackBufferFormat;
49   d3d9params->BackBufferCount = params->BackBufferCount;
50   d3d9params->MultiSampleType = params->MultiSampleType;
51   d3d9params->MultiSampleQuality = params->MultiSampleQuality;
52   d3d9params->SwapEffect = params->SwapEffect;
53   d3d9params->hDeviceWindow = params->hDeviceWindow;
54   d3d9params->Windowed = params->Windowed;
55   d3d9params->EnableAutoDepthStencil = params->EnableAutoDepthStencil;
56   d3d9params->AutoDepthStencilFormat = params->AutoDepthStencilFormat;
57   d3d9params->Flags = params->Flags;
58   d3d9params->FullScreen_RefreshRateInHz = params->FullScreen_RefreshRateInHz;
59   d3d9params->PresentationInterval = params->PresentationInterval;
60}
61
62
63
64//============================================================
65//  drawd3d9_init
66//============================================================
67
68base *drawd3d9_init(void)
69{
70   bool post_available = true;
71
72   // dynamically grab the create function from d3d9.dll
73   HINSTANCE dllhandle = LoadLibrary(TEXT("d3d9.dll"));
74   if (dllhandle == NULL)
75   {
76      osd_printf_verbose("Direct3D: Unable to access d3d9.dll\n");
77      return NULL;
78   }
79
80   // import the create function
81   direct3dcreate9_ptr direct3dcreate9 = (direct3dcreate9_ptr)GetProcAddress(dllhandle, "Direct3DCreate9");
82   if (direct3dcreate9 == NULL)
83   {
84      osd_printf_verbose("Direct3D: Unable to find Direct3DCreate9\n");
85      FreeLibrary(dllhandle);
86      dllhandle = NULL;
87      return NULL;
88   }
89
90   // create our core direct 3d object
91   IDirect3D9 *d3d9 = (*direct3dcreate9)(D3D_SDK_VERSION);
92   if (d3d9 == NULL)
93   {
94      osd_printf_verbose("Direct3D: Error attempting to initialize Direct3D9\n");
95      FreeLibrary(dllhandle);
96      dllhandle = NULL;
97      return NULL;
98   }
99
100   // dynamically grab the shader load function from d3dx9.dll
101   HINSTANCE fxhandle = NULL;
102   for (int idx = 99; idx >= 0; idx--) // a shameful moogle
103   {
104      wchar_t dllbuf[13];
105      wsprintf(dllbuf, TEXT("d3dx9_%d.dll"), idx);
106      fxhandle = LoadLibrary(dllbuf);
107      if (fxhandle != NULL)
108      {
109         break;
110      }
111   }
112   if (fxhandle == NULL)
113   {
114      osd_printf_verbose("Direct3D: Warning - Unable find any D3D9 DLLs; disabling post-effect rendering\n");
115      post_available = false;
116   }
117
118   // allocate an object to hold our data
119   base *d3dptr = global_alloc(base);
120   d3dptr->version = 9;
121   d3dptr->d3dobj = d3d9;
122   d3dptr->dllhandle = dllhandle;
123   d3dptr->post_fx_available = post_available;
124   d3dptr->libhandle = fxhandle;
125   set_interfaces(d3dptr);
126
127   osd_printf_verbose("Direct3D: Using Direct3D 9\n");
128   return d3dptr;
129}
130
131
132
133//============================================================
134//  Direct3D interfaces
135//============================================================
136
137static HRESULT check_device_format(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format)
138{
139   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
140   return IDirect3D9_CheckDeviceFormat(d3d9, adapter, devtype, adapterformat, usage, restype, format);
141}
142
143
144static HRESULT check_device_type(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed)
145{
146   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
147   return IDirect3D9_CheckDeviceType(d3d9, adapter, devtype, format, backformat, windowed);
148}
149
150static HRESULT create_device(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev)
151{
152   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
153   D3DPRESENT_PARAMETERS d3d9params;
154   convert_present_params(params, &d3d9params);
155   return IDirect3D9_CreateDevice(d3d9, adapter, devtype, focus, behavior, &d3d9params, (IDirect3DDevice9 **)dev);
156}
157
158static HRESULT enum_adapter_modes(base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode)
159{
160   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
161   return IDirect3D9_EnumAdapterModes(d3d9, adapter, format, index, mode);
162}
163
164
165static UINT get_adapter_count(base *d3dptr)
166{
167   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
168   return IDirect3D9_GetAdapterCount(d3d9);
169}
170
171
172static HRESULT get_adapter_display_mode(base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode)
173{
174   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
175   return IDirect3D9_GetAdapterDisplayMode(d3d9, adapter, mode);
176}
177
178
179static HRESULT get_adapter_identifier(base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier)
180{
181   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
182   D3DADAPTER_IDENTIFIER9 id;
183   HRESULT result = IDirect3D9_GetAdapterIdentifier(d3d9, adapter, flags, &id);
184   memcpy(identifier->Driver, id.Driver, sizeof(identifier->Driver));
185   memcpy(identifier->Description, id.Description, sizeof(identifier->Description));
186   identifier->DriverVersion = id.DriverVersion;
187   identifier->VendorId = id.VendorId;
188   identifier->DeviceId = id.DeviceId;
189   identifier->SubSysId = id.SubSysId;
190   identifier->Revision = id.Revision;
191   identifier->DeviceIdentifier = id.DeviceIdentifier;
192   identifier->WHQLLevel = id.WHQLLevel;
193   return result;
194}
195
196
197static UINT get_adapter_mode_count(base *d3dptr, UINT adapter, D3DFORMAT format)
198{
199   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
200   return IDirect3D9_GetAdapterModeCount(d3d9, adapter, format);
201}
202
203
204static HMONITOR get_adapter_monitor(base *d3dptr, UINT adapter)
205{
206   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
207   return IDirect3D9_GetAdapterMonitor(d3d9, adapter);
208}
209
210
211static HRESULT get_caps_dword(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value)
212{
213   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
214   D3DCAPS9 caps;
215   HRESULT result = IDirect3D9_GetDeviceCaps(d3d9, adapter, devtype, &caps);
216   switch (which)
217   {
218      case CAPS_PRESENTATION_INTERVALS:   *value = caps.PresentationIntervals;    break;
219      case CAPS_CAPS2:                    *value = caps.Caps2;                    break;
220      case CAPS_DEV_CAPS:                 *value = caps.DevCaps;                  break;
221      case CAPS_SRCBLEND_CAPS:            *value = caps.SrcBlendCaps;             break;
222      case CAPS_DSTBLEND_CAPS:            *value = caps.DestBlendCaps;            break;
223      case CAPS_TEXTURE_CAPS:             *value = caps.TextureCaps;              break;
224      case CAPS_TEXTURE_FILTER_CAPS:      *value = caps.TextureFilterCaps;        break;
225      case CAPS_TEXTURE_ADDRESS_CAPS:     *value = caps.TextureAddressCaps;       break;
226      case CAPS_TEXTURE_OP_CAPS:          *value = caps.TextureOpCaps;            break;
227      case CAPS_MAX_TEXTURE_ASPECT:       *value = caps.MaxTextureAspectRatio;    break;
228      case CAPS_MAX_TEXTURE_WIDTH:        *value = caps.MaxTextureWidth;          break;
229      case CAPS_MAX_TEXTURE_HEIGHT:       *value = caps.MaxTextureHeight;         break;
230      case CAPS_STRETCH_RECT_FILTER:      *value = caps.StretchRectFilterCaps;    break;
231      case CAPS_MAX_PS30_INSN_SLOTS:      *value = caps.MaxPixelShader30InstructionSlots; break;
232   }
233   return result;
234}
235
236
237static ULONG release(base *d3dptr)
238{
239   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
240   ULONG result = IDirect3D9_Release(d3d9);
241   FreeLibrary(d3dptr->dllhandle);
242   global_free(d3dptr);
243   return result;
244}
245
246
247static const interface d3d9_interface =
248{
249   check_device_format,
250   check_device_type,
251   create_device,
252   enum_adapter_modes,
253   get_adapter_count,
254   get_adapter_display_mode,
255   get_adapter_identifier,
256   get_adapter_mode_count,
257   get_adapter_monitor,
258   get_caps_dword,
259   release
260};
261
262
263
264//============================================================
265//  Direct3DDevice interfaces
266//============================================================
267
268static HRESULT device_begin_scene(device *dev)
269{
270   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
271   return IDirect3DDevice9_BeginScene(device);
272}
273
274static HRESULT device_clear(device *dev, DWORD count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
275{
276   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
277   return IDirect3DDevice9_Clear(device, count, rects, flags, color, z, stencil);
278}
279
280
281static HRESULT device_create_offscreen_plain_surface(device *dev, UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, surface **surface)
282{
283   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
284   return IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, pool, (IDirect3DSurface9 **)surface, NULL);
285}
286
287static HRESULT device_create_texture(device *dev, UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, texture **texture)
288{
289   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
290   return IDirect3DDevice9_CreateTexture(device, width, height, levels, usage, format, pool, (IDirect3DTexture9 **)texture, NULL);
291}
292
293
294static HRESULT device_create_vertex_buffer(device *dev, UINT length, DWORD usage, DWORD fvf, D3DPOOL pool, vertex_buffer **buf)
295{
296   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
297   return IDirect3DDevice9_CreateVertexBuffer(device, length, usage, fvf, pool, (IDirect3DVertexBuffer9 **)buf, NULL);
298}
299
300
301static HRESULT device_draw_primitive(device *dev, D3DPRIMITIVETYPE type, UINT start, UINT count)
302{
303   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
304   return IDirect3DDevice9_DrawPrimitive(device, type, start, count);
305}
306
307
308static HRESULT device_end_scene(device *dev)
309{
310   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
311   return IDirect3DDevice9_EndScene(device);
312}
313
314
315static HRESULT device_get_raster_status(device *dev, D3DRASTER_STATUS *status)
316{
317   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
318   return IDirect3DDevice9_GetRasterStatus(device, 0, status);
319}
320
321
322static HRESULT device_get_render_target(device *dev, DWORD index, surface **surface)
323{
324   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
325   return IDirect3DDevice9_GetRenderTarget(device, index, (IDirect3DSurface9 **)surface);
326}
327
328
329static HRESULT device_get_render_target_data(device *dev, surface *rendertarget, surface *destsurface)
330{
331   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
332   return IDirect3DDevice9_GetRenderTargetData(device, (IDirect3DSurface9 *)rendertarget, (IDirect3DSurface9 *)destsurface);
333}
334
335
336static HRESULT device_present(device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags)
337{
338   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
339   if (flags != 0)
340   {
341      IDirect3DSwapChain9 *chain;
342      HRESULT result = IDirect3DDevice9_GetSwapChain(device, 0, &chain);
343      if (result == D3D_OK)
344      {
345         result = IDirect3DSwapChain9_Present(chain, source, dest, override, dirty, flags);
346         IDirect3DSwapChain9_Release(chain);
347         return result;
348      }
349   }
350   return IDirect3DDevice9_Present(device, source, dest, override, dirty);
351}
352
353
354static ULONG device_release(device *dev)
355{
356   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
357   return IDirect3DDevice9_Release(device);
358}
359
360
361static HRESULT device_reset(device *dev, present_parameters *params)
362{
363   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
364   D3DPRESENT_PARAMETERS d3d9params;
365   convert_present_params(params, &d3d9params);
366   return IDirect3DDevice9_Reset(device, &d3d9params);
367}
368
369
370static void device_set_gamma_ramp(device *dev, DWORD flags, const D3DGAMMARAMP *ramp)
371{
372   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
373   IDirect3DDevice9_SetGammaRamp(device, 0, flags, ramp);
374}
375
376
377static HRESULT device_set_render_state(device *dev, D3DRENDERSTATETYPE state, DWORD value)
378{
379   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
380   return IDirect3DDevice9_SetRenderState(device, state, value);
381}
382
383
384static HRESULT device_set_render_target(device *dev, DWORD index, surface *surf)
385{
386   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
387   IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf;
388   return IDirect3DDevice9_SetRenderTarget(device, index, surface);
389}
390
391
392static HRESULT device_create_render_target(device *dev, UINT width, UINT height, D3DFORMAT format, surface **surface)
393{
394   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
395   return IDirect3DDevice9_CreateRenderTarget(device, width, height, format, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)surface, NULL);
396}
397
398
399static HRESULT device_set_stream_source(device *dev, UINT number, vertex_buffer *vbuf, UINT stride)
400{
401   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
402   IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf;
403   return IDirect3DDevice9_SetStreamSource(device, number, vertexbuf, 0, stride);
404}
405
406
407static HRESULT device_set_texture(device *dev, DWORD stage, texture *tex)
408{
409   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
410   IDirect3DBaseTexture9 *texture = (IDirect3DBaseTexture9 *)tex;
411   return IDirect3DDevice9_SetTexture(device, stage, texture);
412}
413
414
415static HRESULT device_set_texture_stage_state(device *dev, DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value)
416{
417   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
418
419   // some state which was here got pushed into sampler state in D3D9
420   switch ((DWORD)state)
421   {
422      case D3DTSS_ADDRESSU:
423         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_ADDRESSU, value);
424      case D3DTSS_ADDRESSV:
425         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_ADDRESSV, value);
426      case D3DTSS_BORDERCOLOR:
427         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_BORDERCOLOR, value);
428      case D3DTSS_MAGFILTER:
429         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAGFILTER, value);
430      case D3DTSS_MINFILTER:
431         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MINFILTER, value);
432      case D3DTSS_MIPFILTER:
433         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MIPFILTER, value);
434      case D3DTSS_MIPMAPLODBIAS:
435         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MIPMAPLODBIAS, value);
436      case D3DTSS_MAXMIPLEVEL:
437         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAXMIPLEVEL, value);
438      case D3DTSS_MAXANISOTROPY:
439         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAXANISOTROPY, value);
440      default:
441         return IDirect3DDevice9_SetTextureStageState(device, stage, state, value);
442   }
443}
444
445
446static HRESULT device_set_vertex_format(device *dev, D3DFORMAT format)
447{
448   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
449   return IDirect3DDevice9_SetFVF(device, format);
450}
451
452
453static HRESULT device_stretch_rect(device *dev, surface *source, const RECT *srcrect, surface *dest, const RECT *dstrect, D3DTEXTUREFILTERTYPE filter)
454{
455   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
456   IDirect3DSurface9 *ssurface = (IDirect3DSurface9 *)source;
457   IDirect3DSurface9 *dsurface = (IDirect3DSurface9 *)dest;
458   return IDirect3DDevice9_StretchRect(device, ssurface, srcrect, dsurface, dstrect, filter);
459}
460
461
462static HRESULT device_test_cooperative_level(device *dev)
463{
464   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
465   return IDirect3DDevice9_TestCooperativeLevel(device);
466}
467
468
469static const device_interface d3d9_device_interface =
470{
471   device_begin_scene,
472   device_clear,
473   device_create_offscreen_plain_surface,
474   device_create_texture,
475   device_create_vertex_buffer,
476   device_create_render_target,
477   device_draw_primitive,
478   device_end_scene,
479   device_get_raster_status,
480   device_get_render_target,
481   device_get_render_target_data,
482   device_present,
483   device_release,
484   device_reset,
485   device_set_gamma_ramp,
486   device_set_render_state,
487   device_set_render_target,
488   device_set_stream_source,
489   device_set_texture,
490   device_set_texture_stage_state,
491   device_set_vertex_format,
492   device_stretch_rect,
493   device_test_cooperative_level
494};
495
496
497
498//============================================================
499//  Direct3DSurface interfaces
500//============================================================
501
502static HRESULT surface_lock_rect(surface *surf, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags)
503{
504   IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf;
505   return IDirect3DSurface9_LockRect(surface, locked, rect, flags);
506}
507
508
509static ULONG surface_release(surface *surf)
510{
511   IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf;
512   return IDirect3DSurface9_Release(surface);
513}
514
515
516static HRESULT surface_unlock_rect(surface *surf)
517{
518   IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf;
519   return IDirect3DSurface9_UnlockRect(surface);
520}
521
522
523static const surface_interface d3d9_surface_interface =
524{
525   surface_lock_rect,
526   surface_release,
527   surface_unlock_rect
528};
529
530
531
532//============================================================
533//  Direct3DTexture interfaces
534//============================================================
535
536static HRESULT texture_get_surface_level(texture *tex, UINT level, surface **surface)
537{
538   IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex;
539   return IDirect3DTexture9_GetSurfaceLevel(texture, level, (IDirect3DSurface9 **)surface);
540}
541
542
543static HRESULT texture_lock_rect(texture *tex, UINT level, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags)
544{
545   IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex;
546   return IDirect3DTexture9_LockRect(texture, level, locked, rect, flags);
547}
548
549
550static ULONG texture_release(texture *tex)
551{
552   IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex;
553   return IDirect3DTexture9_Release(texture);
554}
555
556
557static HRESULT texture_unlock_rect(texture *tex, UINT level)
558{
559   IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex;
560   return IDirect3DTexture9_UnlockRect(texture, level);
561}
562
563
564static const texture_interface d3d9_texture_interface =
565{
566   texture_get_surface_level,
567   texture_lock_rect,
568   texture_release,
569   texture_unlock_rect
570};
571
572
573
574//============================================================
575//  Direct3DVertexBuffer interfaces
576//============================================================
577
578static HRESULT vertex_buffer_lock(vertex_buffer *vbuf, UINT offset, UINT size, VOID **data, DWORD flags)
579{
580   IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf;
581   return IDirect3DVertexBuffer9_Lock(vertexbuf, offset, size, data, flags);
582}
583
584
585static ULONG vertex_buffer_release(vertex_buffer *vbuf)
586{
587   IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf;
588   return IDirect3DVertexBuffer9_Release(vertexbuf);
589}
590
591
592static HRESULT vertex_buffer_unlock(vertex_buffer *vbuf)
593{
594   IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf;
595   return IDirect3DVertexBuffer9_Unlock(vertexbuf);
596}
597
598
599static const vertex_buffer_interface d3d9_vertex_buffer_interface =
600{
601   vertex_buffer_lock,
602   vertex_buffer_release,
603   vertex_buffer_unlock
604};
605
606
607//============================================================
608//  set_interfaces
609//============================================================
610
611static void set_interfaces(base *d3dptr)
612{
613   d3dptr->d3d = d3d9_interface;
614   d3dptr->device = d3d9_device_interface;
615   d3dptr->surface = d3d9_surface_interface;
616   d3dptr->texture = d3d9_texture_interface;
617   d3dptr->vertexbuf = d3d9_vertex_buffer_interface;
618}
619
620};
trunk/src/osd/modules/render/d3d/d3dcomm.h
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  d3dcomm.h - Common Win32 Direct3D structures
6//
7//============================================================
8
9#ifndef __WIN_D3DCOMM__
10#define __WIN_D3DCOMM__
11
12//============================================================
13//  FORWARD DECLARATIONS
14//============================================================
15
16namespace d3d
17{
18class texture_info;
19class renderer;
20
21//============================================================
22//  TYPE DEFINITIONS
23//============================================================
24
25class vec2f
26{
27public:
28   vec2f()
29   {
30      memset(&c, 0, sizeof(float) * 2);
31   }
32   vec2f(float x, float y)
33   {
34      c.x = x;
35      c.y = y;
36   }
37
38   vec2f operator+(const vec2f& a)
39   {
40      return vec2f(c.x + a.c.x, c.y + a.c.y);
41   }
42
43   vec2f operator-(const vec2f& a)
44   {
45      return vec2f(c.x - a.c.x, c.y - a.c.y);
46   }
47
48   struct
49   {
50      float x, y;
51   } c;
52};
53
54class texture_manager
55{
56public:
57   texture_manager() { }
58   texture_manager(renderer *d3d);
59   ~texture_manager();
60
61   void                    update_textures();
62
63   void                    create_resources();
64   void                    delete_resources();
65
66   texture_info *          find_texinfo(const render_texinfo *texture, UINT32 flags);
67   UINT32                  texture_compute_hash(const render_texinfo *texture, UINT32 flags);
68
69   texture_info *          get_texlist() { return m_texlist; }
70   void                    set_texlist(texture_info *texlist) { m_texlist = texlist; }
71   bool                    is_dynamic_supported() { return (bool)m_dynamic_supported; }
72   void                    set_dynamic_supported(bool dynamic_supported) { m_dynamic_supported = dynamic_supported; }
73   bool                    is_stretch_supported() { return (bool)m_stretch_supported; }
74   D3DFORMAT               get_yuv_format() { return m_yuv_format; }
75
76   DWORD                   get_texture_caps() { return m_texture_caps; }
77   DWORD                   get_max_texture_aspect() { return m_texture_max_aspect; }
78   DWORD                   get_max_texture_width() { return m_texture_max_width; }
79   DWORD                   get_max_texture_height() { return m_texture_max_height; }
80
81   texture_info *          get_default_texture() { return m_default_texture; }
82   texture_info *          get_vector_texture() { return m_vector_texture; }
83
84   renderer *              get_d3d() { return m_renderer; }
85
86private:
87   renderer *              m_renderer;
88
89   texture_info *          m_texlist;                  // list of active textures
90   int                     m_dynamic_supported;        // are dynamic textures supported?
91   int                     m_stretch_supported;        // is StretchRect with point filtering supported?
92   D3DFORMAT               m_yuv_format;               // format to use for YUV textures
93
94   DWORD                   m_texture_caps;             // textureCaps field
95   DWORD                   m_texture_max_aspect;       // texture maximum aspect ratio
96   DWORD                   m_texture_max_width;        // texture maximum width
97   DWORD                   m_texture_max_height;       // texture maximum height
98
99   bitmap_argb32           m_vector_bitmap;            // experimental: bitmap for vectors
100   texture_info *          m_vector_texture;           // experimental: texture for vectors
101
102   bitmap_rgb32            m_default_bitmap;           // experimental: default bitmap
103   texture_info *          m_default_texture;          // experimental: default texture
104};
105
106
107/* texture_info holds information about a texture */
108class texture_info
109{
110public:
111   texture_info(texture_manager *manager, const render_texinfo *texsource, int prescale, UINT32 flags);
112   ~texture_info();
113
114   render_texinfo &        get_texinfo() { return m_texinfo; }
115
116   int                     get_width() { return m_rawdims.c.x; }
117   int                     get_height() { return m_rawdims.c.y; }
118   int                     get_xscale() { return m_xprescale; }
119   int                     get_yscale() { return m_yprescale; }
120
121   UINT32                  get_flags() { return m_flags; }
122
123   void                    set_data(const render_texinfo *texsource, UINT32 flags);
124
125   texture_info *          get_next() { return m_next; }
126   texture_info *          get_prev() { return m_prev; }
127
128   UINT32                  get_hash() { return m_hash; }
129
130   void                    set_next(texture_info *next) { m_next = next; }
131   void                    set_prev(texture_info *prev) { m_prev = prev; }
132
133   bool                    paused() { return m_cur_frame == m_prev_frame; }
134   void                    advance_frame() { m_prev_frame = m_cur_frame; }
135   void                    increment_frame_count() { m_cur_frame++; }
136   void                    mask_frame_count(int mask) { m_cur_frame %= mask; }
137
138   int                     get_cur_frame() { return m_cur_frame; }
139   int                     get_prev_frame() { return m_prev_frame; }
140
141   texture *               get_tex() { return m_d3dtex; }
142   surface *               get_surface() { return m_d3dsurface; }
143   texture *               get_finaltex() { return m_d3dfinaltex; }
144
145   vec2f &                 get_uvstart() { return m_start; }
146   vec2f &                 get_uvstop() { return m_stop; }
147   vec2f &                 get_rawdims() { return m_rawdims; }
148
149private:
150   void prescale();
151   void compute_size(int texwidth, int texheight);
152
153   texture_manager *       m_texture_manager;          // texture manager pointer
154
155   renderer *              m_renderer;                 // renderer pointer
156
157   texture_info *          m_next;                     // next texture in the list
158   texture_info *          m_prev;                     // prev texture in the list
159
160   UINT32                  m_hash;                     // hash value for the texture
161   UINT32                  m_flags;                    // rendering flags
162   render_texinfo          m_texinfo;                  // copy of the texture info
163   vec2f                   m_start;                    // beggining UV coordinates
164   vec2f                   m_stop;                     // ending UV coordinates
165   vec2f                   m_rawdims;                  // raw dims of the texture
166   int                     m_type;                     // what type of texture are we?
167   int                     m_xborderpix, m_yborderpix; // number of border pixels on X/Y
168   int                     m_xprescale, m_yprescale;   // X/Y prescale factor
169   int                     m_cur_frame;                // what is our current frame?
170   int                     m_prev_frame;               // what was our last frame? (used to determine pause state)
171   texture *               m_d3dtex;                   // Direct3D texture pointer
172   surface *               m_d3dsurface;               // Direct3D offscreen plain surface pointer
173   texture *               m_d3dfinaltex;              // Direct3D final (post-scaled) texture
174};
175
176/* d3d::poly_info holds information about a single polygon/d3d primitive */
177class poly_info
178{
179public:
180   poly_info() { }
181
182   void init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
183         UINT32 flags, d3d::texture_info *texture, UINT32 modmode,
184         float prim_width, float prim_height);
185   void init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
186         UINT32 flags, d3d::texture_info *texture, UINT32 modmode,
187         float line_time, float line_length,
188         float prim_width, float prim_height);
189
190   D3DPRIMITIVETYPE        get_type() { return m_type; }
191   UINT32                  get_count() { return m_count; }
192   UINT32                  get_vertcount() { return m_numverts; }
193   UINT32                  get_flags() { return m_flags; }
194
195   d3d::texture_info *     get_texture() { return m_texture; }
196   DWORD                   get_modmode() { return m_modmode; }
197
198   float                   get_line_time() { return m_line_time; }
199   float                   get_line_length() { return m_line_length; }
200
201   float                   get_prim_width() { return m_prim_width; }
202   float                   get_prim_height() { return m_prim_height; }
203
204private:
205
206   D3DPRIMITIVETYPE        m_type;                       // type of primitive
207   UINT32                  m_count;                      // total number of primitives
208   UINT32                  m_numverts;                   // total number of vertices
209   UINT32                  m_flags;                      // rendering flags
210
211   texture_info *          m_texture;                    // pointer to texture info
212   DWORD                   m_modmode;                    // texture modulation mode
213
214   float                   m_line_time;                  // used by vectors
215   float                   m_line_length;                // used by vectors
216
217   float                   m_prim_width;                 // used by quads
218   float                   m_prim_height;                // used by quads
219};
220
221}; // d3d
222
223/* vertex describes a single vertex */
224struct vertex
225{
226   float                   x, y, z;                    // X,Y,Z coordinates
227   float                   rhw;                        // RHW when no HLSL, padding when HLSL
228   D3DCOLOR                color;                      // diffuse color
229   float                   u0, v0;                     // texture stage 0 coordinates
230   float                   u1, v1;                     // additional info for vector data
231};
232
233
234/* line_aa_step is used for drawing antialiased lines */
235struct line_aa_step
236{
237   float                   xoffs, yoffs;               // X/Y deltas
238   float                   weight;                     // weight contribution
239};
240
241
242#endif
trunk/src/osd/modules/render/d3d/d3dhlsl.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  d3dhlsl.c - Win32 Direct3D HLSL implementation
6//
7//============================================================
8
9// Useful info:
10//  Windows XP/2003 shipped with DirectX 8.1
11//  Windows 2000 shipped with DirectX 7a
12//  Windows 98SE shipped with DirectX 6.1a
13//  Windows 98 shipped with DirectX 5
14//  Windows NT shipped with DirectX 3.0a
15//  Windows 95 shipped with DirectX 2
16
17// standard windows headers
18#define WIN32_LEAN_AND_MEAN
19#include <windows.h>
20#include <tchar.h>
21#include <mmsystem.h>
22#include <d3d9.h>
23#include <d3dx9.h>
24#include <math.h>
25#undef interface
26
27// MAME headers
28#include "emu.h"
29#include "render.h"
30#include "ui/ui.h"
31#include "rendutil.h"
32#include "options.h"
33#include "emuopts.h"
34#include "aviio.h"
35#include "png.h"
36#include "screen.h"
37
38// MAMEOS headers
39#include "d3dintf.h"
40#include "winmain.h"
41#include "window.h"
42#include "config.h"
43#include "d3dcomm.h"
44#include "modules/render/drawd3d.h"
45#include "strconv.h"
46
47
48
49//============================================================
50//  GLOBALS
51//============================================================
52
53static slider_state *g_slider_list;
54static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *templ, const char *extension, int idx);
55
56namespace d3d
57{
58hlsl_options shaders::s_hlsl_presets[4] =
59{
60   {   // 25% Shadow mask, 50% Scanlines, 3% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
61      true,
62      0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
63      0.03f, 0.03f,
64      0.5f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
65      { 0.0f, 0.0f },
66      { 0.0f, 0.0f, 0.0f },
67      { 0.0f, 0.0f, 0.0f },
68      { 0.0f, 0.0f, 0.0f },
69      { 0.0f, 0.0f, 0.0f },
70      { 1.0f, 0.0f, 0.0f },
71      { 0.0f, 1.0f, 0.0f },
72      { 0.0f, 0.0f, 1.0f },
73      { 0.0f, 0.0f, 0.0f },
74      { 1.0f, 1.0f, 1.0f },
75      { 0.9f, 0.9f, 0.9f },
76      { 0.05f,0.05f,0.05f},
77      { 0.25f,0.25f,0.25f},
78      1.2f,
79      false, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0,
80      0.9f, 4.0f,
81      1.0f, 0.21f, 0.19f, 0.17f, 0.15f, 0.14f, 0.13f, 0.12f, 0.11f, 0.10f, 0.09f
82   },
83   {   // 25% Shadow mask, 0% Scanlines, 3% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
84      true,
85      0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
86      0.03f, 0.03f,
87      0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
88      { 0.0f, 0.0f },
89      { 0.0f, 0.0f, 0.0f },
90      { 0.0f, 0.0f, 0.0f },
91      { 0.0f, 0.0f, 0.0f },
92      { 0.0f, 0.0f, 0.0f },
93      { 1.0f, 0.0f, 0.0f },
94      { 0.0f, 1.0f, 0.0f },
95      { 0.0f, 0.0f, 1.0f },
96      { 0.0f, 0.0f, 0.0f },
97      { 1.0f, 1.0f, 1.0f },
98      { 0.9f, 0.9f, 0.9f },
99      { 0.05f,0.05f,0.05f},
100      { 0.25f,0.25f,0.25f},
101      1.2f,
102      false, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0,
103      0.9f, 4.0f,
104      1.0f, 0.21f, 0.19f, 0.17f, 0.15f, 0.14f, 0.13f, 0.12f, 0.11f, 0.10f, 0.09f
105   },
106   {   // 25% Shadow mask, 0% Scanlines, 0% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
107      true,
108      0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
109      0.0f, 0.0f,
110      0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
111      { 0.0f, 0.0f },
112      { 0.0f, 0.0f, 0.0f },
113      { 0.0f, 0.0f, 0.0f },
114      { 0.0f, 0.0f, 0.0f },
115      { 0.0f, 0.0f, 0.0f },
116      { 1.0f, 0.0f, 0.0f },
117      { 0.0f, 1.0f, 0.0f },
118      { 0.0f, 0.0f, 1.0f },
119      { 0.0f, 0.0f, 0.0f },
120      { 1.0f, 1.0f, 1.0f },
121      { 0.9f, 0.9f, 0.9f },
122      { 0.05f,0.05f,0.05f},
123      { 0.25f,0.25f,0.25f},
124      1.2f,
125      false, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0,
126      0.9f, 4.0f,
127      1.0f, 0.21f, 0.19f, 0.17f, 0.15f, 0.14f, 0.13f, 0.12f, 0.11f, 0.10f, 0.09f
128   },
129   {   // 25% Shadow mask, 100% Scanlines, 15% Pincushion, 3 defocus, 24-degree Tint Out, 1.5 Exponent, 5% Floor, 70% Phosphor Return, 80% Saturation, Bad Convergence
130      true,
131      0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
132      0.15f, 0.15f,
133      1.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.5f,
134      { 3.0f, 3.0f },
135      { 0.5f,-0.33f,0.7f },
136      { 0.0f,-1.0f, 0.5f },
137      { 0.0f, 0.2f, 0.3f },
138      { 0.0f, 0.2f, 0.0f },
139      { 0.8f, 0.2f, 0.0f },
140      { 0.0f, 0.8f, 0.2f},
141      { 0.2f, 0.0f, 0.8f},
142      { 0.0f, 0.0f, 0.0f },
143      { 1.0f, 1.0f, 1.0f },
144      { 1.5f, 1.5f, 1.5f },
145      { 0.05f,0.05f,0.05f},
146      { 0.7f, 0.7f, 0.7f},
147      0.8f,
148      false, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0,
149      0.9f, 4.0f,
150      1.0f, 0.21f, 0.19f, 0.17f, 0.15f, 0.14f, 0.13f, 0.12f, 0.11f, 0.10f, 0.09f
151   },
152};
153
154//============================================================
155//  PROTOTYPES
156//============================================================
157
158static void get_vector(const char *data, int count, float *out, int report_error);
159
160
161//============================================================
162//  TYPE DEFINITIONS
163//============================================================
164
165typedef HRESULT (WINAPI *direct3dx9_loadeffect_ptr)(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, const D3DXMACRO *pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT *ppEffect, LPD3DXBUFFER *ppCompilationErrors);
166static direct3dx9_loadeffect_ptr g_load_effect = NULL;
167
168//============================================================
169//  shader manager constructor
170//============================================================
171
172shaders::shaders()
173{
174   master_enable = false;
175   vector_enable = true;
176   prescale_size_x = 1;
177   prescale_size_y = 1;
178   prescale_force_x = 0;
179   prescale_force_y = 0;
180   preset = -1;
181   shadow_texture = NULL;
182   options = NULL;
183   paused = true;
184   lastidx = -1;
185   targethead = NULL;
186   cachehead = NULL;
187   initialized = false;
188}
189
190
191
192//============================================================
193//  shaders destructor
194//============================================================
195
196shaders::~shaders()
197{
198   global_free(options);
199   cache_target *currcache = cachehead;
200   while(cachehead != NULL)
201   {
202      cachehead = currcache->next;
203      global_free(currcache);
204      currcache = cachehead;
205   }
206
207   render_target *currtarget = targethead;
208   while(targethead != NULL)
209   {
210      targethead = currtarget->next;
211      global_free(currtarget);
212      currtarget = targethead;
213   }
214}
215
216
217
218//============================================================
219//  shaders::window_save
220//============================================================
221
222void shaders::window_save()
223{
224   if (!master_enable || !d3dintf->post_fx_available)
225      return;
226
227   HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &snap_copy_texture);
228   if (result != D3D_OK)
229   {
230      osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL snapshot (%08x), bailing\n", (UINT32)result);
231      return;
232   }
233   (*d3dintf->texture.get_surface_level)(snap_copy_texture, 0, &snap_copy_target);
234
235   result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &snap_texture);
236   if (result != D3D_OK)
237   {
238      osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL snapshot (%08x), bailing\n", (UINT32)result);
239      return;
240   }
241   (*d3dintf->texture.get_surface_level)(snap_texture, 0, &snap_target);
242
243   render_snap = true;
244   snap_rendered = false;
245}
246
247
248
249//============================================================
250//  shaders::window_record
251//============================================================
252
253void shaders::window_record()
254{
255   if (!master_enable || !d3dintf->post_fx_available)
256      return;
257
258   windows_options &options = downcast<windows_options &>(machine->options());
259   const char *filename = options.d3d_hlsl_write();
260
261   if (avi_output_file != NULL)
262      end_avi_recording();
263   else if (filename[0] != 0)
264      begin_avi_recording(filename);
265}
266
267
268//============================================================
269//  shaders::avi_update_snap
270//============================================================
271
272void shaders::avi_update_snap(surface *surface)
273{
274   if (!master_enable || !d3dintf->post_fx_available)
275      return;
276
277   D3DLOCKED_RECT rect;
278
279   // if we don't have a bitmap, or if it's not the right size, allocate a new one
280   if (!avi_snap.valid() || (int)snap_width != avi_snap.width() || (int)snap_height != avi_snap.height())
281   {
282      avi_snap.allocate((int)snap_width, (int)snap_height);
283   }
284
285   // copy the texture
286   HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->get_device(), surface, avi_copy_surface);
287   if (result != D3D_OK)
288   {
289      return;
290   }
291
292   // lock the texture
293   result = (*d3dintf->surface.lock_rect)(avi_copy_surface, &rect, NULL, D3DLOCK_DISCARD);
294   if (result != D3D_OK)
295   {
296      return;
297   }
298
299   // loop over Y
300   for (int srcy = 0; srcy < (int)snap_height; srcy++)
301   {
302      DWORD *src = (DWORD *)((BYTE *)rect.pBits + srcy * rect.Pitch);
303      UINT32 *dst = &avi_snap.pix32(srcy);
304
305      for(int x = 0; x < snap_width; x++)
306         *dst++ = *src++;
307   }
308
309   // unlock
310   result = (*d3dintf->surface.unlock_rect)(avi_copy_surface);
311   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
312}
313
314
315
316//============================================================
317//  hlsl_render_snapshot
318//============================================================
319
320void shaders::render_snapshot(surface *surface)
321{
322   if (!master_enable || !d3dintf->post_fx_available)
323      return;
324
325   D3DLOCKED_RECT rect;
326
327   render_snap = false;
328
329   // if we don't have a bitmap, or if it's not the right size, allocate a new one
330   if (!avi_snap.valid() || snap_width != (avi_snap.width() / 2) || snap_height != (avi_snap.height() / 2))
331   {
332      avi_snap.allocate(snap_width / 2, snap_height / 2);
333   }
334
335   // copy the texture
336   HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->get_device(), surface, snap_copy_target);
337   if (result != D3D_OK)
338   {
339      return;
340   }
341
342   // lock the texture
343   result = (*d3dintf->surface.lock_rect)(snap_copy_target, &rect, NULL, D3DLOCK_DISCARD);
344   if (result != D3D_OK)
345   {
346      return;
347   }
348
349   for(int cy = 0; cy < 2; cy++)
350   {
351      for(int cx = 0; cx < 2; cx++)
352      {
353         // loop over Y
354         for (int srcy = 0; srcy < snap_height / 2; srcy++)
355         {
356            int toty = (srcy + cy * (snap_height / 2));
357            int totx = cx * (snap_width / 2);
358            DWORD *src = (DWORD *)((BYTE *)rect.pBits + toty * rect.Pitch + totx * 4);
359            UINT32 *dst = &avi_snap.pix32(srcy);
360
361            for(int x = 0; x < snap_width / 2; x++)
362               *dst++ = *src++;
363         }
364
365         int idx = cy * 2 + cx;
366
367         emu_file file(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
368         file_error filerr = open_next(d3d, file, NULL, "png", idx);
369         if (filerr != FILERR_NONE)
370            return;
371
372         // add two text entries describing the image
373         astring text1(emulator_info::get_appname(), " ", build_version);
374         astring text2(machine->system().manufacturer, " ", machine->system().description);
375         png_info pnginfo = { 0 };
376         png_add_text(&pnginfo, "Software", text1);
377         png_add_text(&pnginfo, "System", text2);
378
379         // now do the actual work
380         png_error error = png_write_bitmap(file, &pnginfo, avi_snap, 1 << 24, NULL);
381         if (error != PNGERR_NONE)
382            osd_printf_error("Error generating PNG for HLSL snapshot: png_error = %d\n", error);
383
384         // free any data allocated
385         png_free(&pnginfo);
386      }
387   }
388
389   // unlock
390   result = (*d3dintf->surface.unlock_rect)(snap_copy_target);
391   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
392
393   if(snap_texture != NULL)
394   {
395      (*d3dintf->texture.release)(snap_texture);
396      snap_texture = NULL;
397   }
398
399   if(snap_target != NULL)
400   {
401      (*d3dintf->surface.release)(snap_target);
402      snap_target = NULL;
403   }
404
405   if(snap_copy_texture != NULL)
406   {
407      (*d3dintf->texture.release)(snap_copy_texture);
408      snap_copy_texture = NULL;
409   }
410
411   if(snap_copy_target != NULL)
412   {
413      (*d3dintf->surface.release)(snap_copy_target);
414      snap_copy_target = NULL;
415   }
416}
417
418
419//============================================================
420//  shaders::record_texture
421//============================================================
422
423void shaders::record_texture()
424{
425   if (!master_enable || !d3dintf->post_fx_available)
426      return;
427
428   surface *surface = avi_final_target;
429
430   // ignore if nothing to do
431   if (avi_output_file == NULL || surface == NULL)
432      return;
433
434   // get the current time
435   attotime curtime = machine->time();
436
437   avi_update_snap(surface);
438
439   // loop until we hit the right time
440   while (avi_next_frame_time <= curtime)
441   {
442      // handle an AVI recording
443      // write the next frame
444      avi_error avierr = avi_append_video_frame(avi_output_file, avi_snap);
445      if (avierr != AVIERR_NONE)
446      {
447         end_avi_recording();
448         return;
449      }
450
451      // advance time
452      avi_next_frame_time += avi_frame_period;
453      avi_frame++;
454   }
455}
456
457
458//============================================================
459//  shaders::end_hlsl_avi_recording
460//============================================================
461
462void shaders::end_avi_recording()
463{
464   if (!master_enable || !d3dintf->post_fx_available)
465      return;
466
467   if (avi_output_file != NULL)
468      avi_close(avi_output_file);
469
470   avi_output_file = NULL;
471   avi_frame = 0;
472}
473
474
475//============================================================
476//  shaders::toggle
477//============================================================
478
479void shaders::toggle()
480{
481   if (master_enable)
482   {
483      if (initialized)
484      {
485         delete_resources(false);
486      }
487      master_enable = !master_enable;
488   }
489   else
490   {
491      if (!initialized)
492      {
493         master_enable = !master_enable;
494         bool failed = create_resources(false);
495         if (failed)
496         {
497            master_enable = false;
498         }
499      }
500      else
501      {
502         master_enable = !master_enable;
503      }
504   }
505}
506
507//============================================================
508//  shaders::begin_avi_recording
509//============================================================
510
511void shaders::begin_avi_recording(const char *name)
512{
513   if (!master_enable || !d3dintf->post_fx_available)
514      return;
515
516   // stop any existing recording
517   end_avi_recording();
518
519   // reset the state
520   avi_frame = 0;
521   avi_next_frame_time = machine->time();
522
523   // build up information about this new movie
524   avi_movie_info info;
525   info.video_format = 0;
526   info.video_timescale = 1000 * ((machine->first_screen() != NULL) ? ATTOSECONDS_TO_HZ(machine->first_screen()->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE);
527   info.video_sampletime = 1000;
528   info.video_numsamples = 0;
529   info.video_width = snap_width;
530   info.video_height = snap_height;
531   info.video_depth = 24;
532
533   info.audio_format = 0;
534   info.audio_timescale = machine->sample_rate();
535   info.audio_sampletime = 1;
536   info.audio_numsamples = 0;
537   info.audio_channels = 2;
538   info.audio_samplebits = 16;
539   info.audio_samplerate = machine->sample_rate();
540
541   // create a new temporary movie file
542   file_error filerr;
543   astring fullpath;
544   {
545      emu_file tempfile(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
546      if (name != NULL)
547      {
548         filerr = tempfile.open(name);
549      }
550      else
551      {
552         filerr = open_next(d3d, tempfile, NULL, "avi", 0);
553      }
554
555      // compute the frame time
556      {
557         avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
558      }
559
560      // if we succeeded, make a copy of the name and create the real file over top
561      if (filerr == FILERR_NONE)
562      {
563         fullpath = tempfile.fullpath();
564      }
565   }
566
567   if (filerr == FILERR_NONE)
568   {
569      // create the file and free the string
570      avi_error avierr = avi_create(fullpath, &info, &avi_output_file);
571      if (avierr != AVIERR_NONE)
572      {
573         osd_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
574      }
575   }
576}
577
578
579//============================================================
580//  remove_cache_target - remove an active cache target when
581//  refcount hits zero
582//============================================================
583
584void shaders::remove_cache_target(cache_target *cache)
585{
586   if (cache != NULL)
587   {
588      if (cache == cachehead)
589      {
590         cachehead = cachehead->next;
591      }
592
593      if (cache->prev != NULL)
594      {
595         cache->prev->next = cache->next;
596      }
597
598      if (cache->next != NULL)
599      {
600         cache->next->prev = cache->prev;
601      }
602
603      global_free(cache);
604   }
605}
606
607
608//============================================================
609//  remove_render_target - remove an active target
610//============================================================
611
612void shaders::remove_render_target(texture_info *texture)
613{
614   remove_render_target(find_render_target(texture));
615}
616
617void shaders::remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index)
618{
619   render_target *target = find_render_target(width, height, screen_index, page_index);
620   if (target != NULL)
621   {
622      remove_render_target(target);
623   }
624}
625
626void shaders::remove_render_target(render_target *rt)
627{
628   if (rt != NULL)
629   {
630      if (rt == targethead)
631      {
632         targethead = targethead->next;
633      }
634
635      if (rt->prev != NULL)
636      {
637         rt->prev->next = rt->next;
638      }
639
640      if (rt->next != NULL)
641      {
642         rt->next->prev = rt->prev;
643      }
644
645      cache_target *cache = find_cache_target(rt->screen_index, rt->width, rt->height);
646      if (cache != NULL)
647      {
648         remove_cache_target(cache);
649      }
650
651      int screen_index = rt->screen_index;
652      int other_page = 1 - rt->page_index;
653      int width = rt->width;
654      int height = rt->height;
655
656      global_free(rt);
657
658      // Remove other double-buffered page (if it exists)
659      remove_render_target(width, height, screen_index, other_page);
660   }
661}
662
663
664//============================================================
665//  shaders::set_texture
666//============================================================
667
668void shaders::set_texture(texture_info *texture)
669{
670   if (!master_enable || !d3dintf->post_fx_available)
671      return;
672
673   if(texture != NULL)
674   {
675      paused = texture->paused();
676      texture->advance_frame();
677   }
678
679   texture_info *default_texture = d3d->get_default_texture();
680   default_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
681   if (options->yiq_enable)
682      yiq_encode_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
683   else
684      color_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
685}
686
687
688//============================================================
689//  shaders::init
690//============================================================
691
692void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *renderer)
693{
694   if (!d3dintf->post_fx_available)
695      return;
696
697   g_load_effect = (direct3dx9_loadeffect_ptr)GetProcAddress(d3dintf->libhandle, "D3DXCreateEffectFromFileW");
698   if (g_load_effect == NULL)
699   {
700      printf("Direct3D: Unable to find D3DXCreateEffectFromFileW\n");
701      d3dintf->post_fx_available = false;
702      return;
703   }
704
705   this->d3dintf = d3dintf;
706   this->machine = machine;
707   this->d3d = renderer;
708
709   master_enable = downcast<windows_options &>(machine->options()).d3d_hlsl_enable();
710   prescale_size_x = 1;
711   prescale_size_y = 1;
712   preset = downcast<windows_options &>(machine->options()).d3d_hlsl_preset();
713   if (preset < -1 || preset > 3)
714   {
715      preset = -1;
716   }
717
718   snap_width = downcast<windows_options &>(machine->options()).d3d_snap_width();
719   snap_height = downcast<windows_options &>(machine->options()).d3d_snap_height();
720   prescale_force_x = 0;
721   prescale_force_y = 0;
722
723   windows_options &winoptions = downcast<windows_options &>(machine->options());
724
725   options = (hlsl_options*)global_alloc_clear(hlsl_options);
726
727   options->params_dirty = true;
728   strcpy(options->shadow_mask_texture, downcast<windows_options &>(machine->options()).screen_shadow_mask_texture()); // unsafe
729
730   prescale_force_x = winoptions.d3d_hlsl_prescale_x();
731   prescale_force_y = winoptions.d3d_hlsl_prescale_y();
732   if(preset == -1)
733   {
734      options->shadow_mask_alpha = winoptions.screen_shadow_mask_alpha();
735      options->shadow_mask_count_x = winoptions.screen_shadow_mask_count_x();
736      options->shadow_mask_count_y = winoptions.screen_shadow_mask_count_y();
737      options->shadow_mask_u_size = winoptions.screen_shadow_mask_u_size();
738      options->shadow_mask_v_size = winoptions.screen_shadow_mask_v_size();
739      options->curvature = winoptions.screen_curvature();
740      options->pincushion = winoptions.screen_pincushion();
741      options->scanline_alpha = winoptions.screen_scanline_amount();
742      options->scanline_scale = winoptions.screen_scanline_scale();
743      options->scanline_height = winoptions.screen_scanline_height();
744      options->scanline_bright_scale = winoptions.screen_scanline_bright_scale();
745      options->scanline_bright_offset = winoptions.screen_scanline_bright_offset();
746      options->scanline_offset = winoptions.screen_scanline_offset();
747      get_vector(winoptions.screen_defocus(), 2, options->defocus, TRUE);
748      get_vector(winoptions.screen_converge_x(), 3, options->converge_x, TRUE);
749      get_vector(winoptions.screen_converge_y(), 3, options->converge_y, TRUE);
750      get_vector(winoptions.screen_radial_converge_x(), 3, options->radial_converge_x, TRUE);
751      get_vector(winoptions.screen_radial_converge_y(), 3, options->radial_converge_y, TRUE);
752      get_vector(winoptions.screen_red_ratio(), 3, options->red_ratio, TRUE);
753      get_vector(winoptions.screen_grn_ratio(), 3, options->grn_ratio, TRUE);
754      get_vector(winoptions.screen_blu_ratio(), 3, options->blu_ratio, TRUE);
755      get_vector(winoptions.screen_offset(), 3, options->offset, TRUE);
756      get_vector(winoptions.screen_scale(), 3, options->scale, TRUE);
757      get_vector(winoptions.screen_power(), 3, options->power, TRUE);
758      get_vector(winoptions.screen_floor(), 3, options->floor, TRUE);
759      get_vector(winoptions.screen_phosphor(), 3, options->phosphor, TRUE);
760      options->saturation = winoptions.screen_saturation();
761   }
762   else
763   {
764      options = &s_hlsl_presets[preset];
765   }
766
767   options->yiq_enable = winoptions.screen_yiq_enable();
768   options->yiq_cc = winoptions.screen_yiq_cc();
769   options->yiq_a = winoptions.screen_yiq_a();
770   options->yiq_b = winoptions.screen_yiq_b();
771   options->yiq_o = winoptions.screen_yiq_o();
772   options->yiq_p = winoptions.screen_yiq_p();
773   options->yiq_n = winoptions.screen_yiq_n();
774   options->yiq_y = winoptions.screen_yiq_y();
775   options->yiq_i = winoptions.screen_yiq_i();
776   options->yiq_q = winoptions.screen_yiq_q();
777   options->yiq_scan_time = winoptions.screen_yiq_scan_time();
778   options->yiq_phase_count = winoptions.screen_yiq_phase_count();
779   options->vector_length_scale = winoptions.screen_vector_length_scale();
780   options->vector_length_ratio = winoptions.screen_vector_length_ratio();
781   options->vector_bloom_scale = winoptions.screen_vector_bloom_scale();
782   options->raster_bloom_scale = winoptions.screen_raster_bloom_scale();
783   options->bloom_level0_weight = winoptions.screen_bloom_lvl0_weight();
784   options->bloom_level1_weight = winoptions.screen_bloom_lvl1_weight();
785   options->bloom_level2_weight = winoptions.screen_bloom_lvl2_weight();
786   options->bloom_level3_weight = winoptions.screen_bloom_lvl3_weight();
787   options->bloom_level4_weight = winoptions.screen_bloom_lvl4_weight();
788   options->bloom_level5_weight = winoptions.screen_bloom_lvl5_weight();
789   options->bloom_level6_weight = winoptions.screen_bloom_lvl6_weight();
790   options->bloom_level7_weight = winoptions.screen_bloom_lvl7_weight();
791   options->bloom_level8_weight = winoptions.screen_bloom_lvl8_weight();
792   options->bloom_level9_weight = winoptions.screen_bloom_lvl9_weight();
793   options->bloom_level10_weight = winoptions.screen_bloom_lvl10_weight();
794
795   options->params_dirty = true;
796
797   g_slider_list = init_slider_list();
798}
799
800
801
802//============================================================
803//  shaders::init_fsfx_quad
804//============================================================
805
806void shaders::init_fsfx_quad(void *vertbuf)
807{
808   // Called at the start of each frame by the D3D code in order to reserve two triangles
809   // that are guaranteed to be at a fixed position so as to simply use D3DPT_TRIANGLELIST, 0, 2
810   // instead of having to do bookkeeping about a specific screen quad
811   if (!master_enable || !d3dintf->post_fx_available)
812      return;
813
814   // get a pointer to the vertex buffer
815   fsfx_vertices = (vertex *)vertbuf;
816   if (fsfx_vertices == NULL)
817      return;
818
819   // fill in the vertexes clockwise
820   fsfx_vertices[0].x = 0.0f;
821   fsfx_vertices[0].y = 0.0f;
822   fsfx_vertices[1].x = d3d->get_width();
823   fsfx_vertices[1].y = 0.0f;
824   fsfx_vertices[2].x = 0.0f;
825   fsfx_vertices[2].y = d3d->get_height();
826   fsfx_vertices[3].x = d3d->get_width();
827   fsfx_vertices[3].y = 0.0f;
828   fsfx_vertices[4].x = 0.0f;
829   fsfx_vertices[4].y = d3d->get_height();
830   fsfx_vertices[5].x = d3d->get_width();
831   fsfx_vertices[5].y = d3d->get_height();
832
833   fsfx_vertices[0].u0 = 0.0f;
834   fsfx_vertices[0].v0 = 0.0f;
835
836   fsfx_vertices[1].u0 = 1.0f;
837   fsfx_vertices[1].v0 = 0.0f;
838
839   fsfx_vertices[2].u0 = 0.0f;
840   fsfx_vertices[2].v0 = 1.0f;
841
842   fsfx_vertices[3].u0 = 1.0f;
843   fsfx_vertices[3].v0 = 0.0f;
844
845   fsfx_vertices[4].u0 = 0.0f;
846   fsfx_vertices[4].v0 = 1.0f;
847
848   fsfx_vertices[5].u0 = 1.0f;
849   fsfx_vertices[5].v0 = 1.0f;
850
851   fsfx_vertices[0].u1 = 0.0f;
852   fsfx_vertices[0].v1 = 0.0f;
853   fsfx_vertices[1].u1 = 0.0f;
854   fsfx_vertices[1].v1 = 0.0f;
855   fsfx_vertices[2].u1 = 0.0f;
856   fsfx_vertices[2].v1 = 0.0f;
857   fsfx_vertices[3].u1 = 0.0f;
858   fsfx_vertices[3].v1 = 0.0f;
859   fsfx_vertices[4].u1 = 0.0f;
860   fsfx_vertices[4].v1 = 0.0f;
861   fsfx_vertices[5].u1 = 0.0f;
862   fsfx_vertices[5].v1 = 0.0f;
863
864   // set the color, Z parameters to standard values
865   for (int i = 0; i < 6; i++)
866   {
867      fsfx_vertices[i].z = 0.0f;
868      fsfx_vertices[i].rhw = 1.0f;
869      fsfx_vertices[i].color = D3DCOLOR_ARGB(255, 255, 255, 255);
870   }
871}
872
873
874
875//============================================================
876//  shaders::create_resources
877//============================================================
878
879int shaders::create_resources(bool reset)
880{
881   if (!master_enable || !d3dintf->post_fx_available)
882      return 0;
883
884   HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
885   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
886
887   result = (*d3dintf->device.create_texture)(d3d->get_device(), 4, 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &black_texture);
888   if (result != D3D_OK)
889   {
890      osd_printf_verbose("Direct3D: Unable to init video-memory target for black texture (%08x)\n", (UINT32)result);
891      return 1;
892   }
893   (*d3dintf->texture.get_surface_level)(black_texture, 0, &black_surface);
894   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, black_surface);
895   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
896   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
897   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
898   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
899   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
900
901   result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)snap_width, (int)snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &avi_copy_texture);
902   if (result != D3D_OK)
903   {
904      osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
905      return 1;
906   }
907   (*d3dintf->texture.get_surface_level)(avi_copy_texture, 0, &avi_copy_surface);
908
909   result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)snap_width, (int)snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &avi_final_texture);
910   if (result != D3D_OK)
911   {
912      osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
913      return 1;
914   }
915   (*d3dintf->texture.get_surface_level)(avi_final_texture, 0, &avi_final_target);
916
917   emu_file file(machine->options().art_path(), OPEN_FLAG_READ);
918   render_load_png(shadow_bitmap, file, NULL, options->shadow_mask_texture);
919
920   // experimental: if we have a shadow bitmap, create a texture for it
921   if (shadow_bitmap.valid())
922   {
923      render_texinfo texture;
924
925      // fake in the basic data so it looks like it came from render.c
926      texture.base = shadow_bitmap.raw_pixptr(0);
927      texture.rowpixels = shadow_bitmap.rowpixels();
928      texture.width = shadow_bitmap.width();
929      texture.height = shadow_bitmap.height();
930      texture.palette = NULL;
931      texture.seqid = 0;
932
933      // FIXME: should shadow bitmap really use prescale?
934      // now create it
935      shadow_texture = new texture_info(d3d->get_texture_manager(), &texture, video_config.prescale, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
936   }
937
938   const char *fx_dir = downcast<windows_options &>(machine->options()).screen_post_fx_dir();
939
940   default_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir);
941   post_effect = new effect(this, d3d->get_device(), "post.fx", fx_dir);
942   prescale_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir);
943   phosphor_effect = new effect(this, d3d->get_device(), "phosphor.fx", fx_dir);
944   focus_effect = new effect(this, d3d->get_device(), "focus.fx", fx_dir);
945   deconverge_effect = new effect(this, d3d->get_device(), "deconverge.fx", fx_dir);
946   color_effect = new effect(this, d3d->get_device(), "color.fx", fx_dir);
947   yiq_encode_effect = new effect(this, d3d->get_device(), "yiq_encode.fx", fx_dir);
948   yiq_decode_effect = new effect(this, d3d->get_device(), "yiq_decode.fx", fx_dir);
949   bloom_effect = new effect(this, d3d->get_device(), "bloom.fx", fx_dir);
950   downsample_effect = new effect(this, d3d->get_device(), "downsample.fx", fx_dir);
951   vector_effect = new effect(this, d3d->get_device(), "vector.fx", fx_dir);
952
953   if (!default_effect->is_valid()) return 1;
954   if (!post_effect->is_valid()) return 1;
955   if (!prescale_effect->is_valid()) return 1;
956   if (!phosphor_effect->is_valid()) return 1;
957   if (!focus_effect->is_valid()) return 1;
958   if (!deconverge_effect->is_valid()) return 1;
959   if (!color_effect->is_valid()) return 1;
960   if (!yiq_encode_effect->is_valid()) return 1;
961   if (!yiq_decode_effect->is_valid()) return 1;
962   if (!bloom_effect->is_valid()) return 1;
963   if (!downsample_effect->is_valid()) return 1;
964   if (!vector_effect->is_valid()) return 1;
965
966   yiq_encode_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
967   yiq_encode_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
968   yiq_encode_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
969   yiq_encode_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
970   yiq_encode_effect->add_uniform("AValue", uniform::UT_FLOAT, uniform::CU_NTSC_A);
971   yiq_encode_effect->add_uniform("BValue", uniform::UT_FLOAT, uniform::CU_NTSC_B);
972   yiq_encode_effect->add_uniform("PValue", uniform::UT_FLOAT, uniform::CU_NTSC_P);
973   yiq_encode_effect->add_uniform("NotchHalfWidth", uniform::UT_FLOAT, uniform::CU_NTSC_NOTCH);
974   yiq_encode_effect->add_uniform("YFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_YFREQ);
975   yiq_encode_effect->add_uniform("IFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_IFREQ);
976   yiq_encode_effect->add_uniform("QFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_QFREQ);
977   yiq_encode_effect->add_uniform("ScanTime", uniform::UT_FLOAT, uniform::CU_NTSC_HTIME);
978
979   yiq_decode_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
980   yiq_decode_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
981   yiq_decode_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
982   yiq_decode_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
983   yiq_decode_effect->add_uniform("AValue", uniform::UT_FLOAT, uniform::CU_NTSC_A);
984   yiq_decode_effect->add_uniform("BValue", uniform::UT_FLOAT, uniform::CU_NTSC_B);
985   yiq_decode_effect->add_uniform("OValue", uniform::UT_FLOAT, uniform::CU_NTSC_O);
986   yiq_decode_effect->add_uniform("PValue", uniform::UT_FLOAT, uniform::CU_NTSC_P);
987   yiq_decode_effect->add_uniform("NotchHalfWidth", uniform::UT_FLOAT, uniform::CU_NTSC_NOTCH);
988   yiq_decode_effect->add_uniform("YFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_YFREQ);
989   yiq_decode_effect->add_uniform("IFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_IFREQ);
990   yiq_decode_effect->add_uniform("QFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_QFREQ);
991   yiq_decode_effect->add_uniform("ScanTime", uniform::UT_FLOAT, uniform::CU_NTSC_HTIME);
992
993   color_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
994   color_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
995
996   color_effect->add_uniform("YIQEnable", uniform::UT_FLOAT, uniform::CU_NTSC_ENABLE);
997   color_effect->add_uniform("RedRatios", uniform::UT_VEC3, uniform::CU_COLOR_RED_RATIOS);
998   color_effect->add_uniform("GrnRatios", uniform::UT_VEC3, uniform::CU_COLOR_GRN_RATIOS);
999   color_effect->add_uniform("BluRatios", uniform::UT_VEC3, uniform::CU_COLOR_BLU_RATIOS);
1000   color_effect->add_uniform("Offset", uniform::UT_VEC3, uniform::CU_COLOR_OFFSET);
1001   color_effect->add_uniform("Scale", uniform::UT_VEC3, uniform::CU_COLOR_SCALE);
1002   color_effect->add_uniform("Saturation", uniform::UT_FLOAT, uniform::CU_COLOR_SATURATION);
1003
1004   prescale_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1005   prescale_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
1006
1007   deconverge_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1008   deconverge_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
1009   deconverge_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
1010   deconverge_effect->add_uniform("ConvergeX", uniform::UT_VEC3, uniform::CU_CONVERGE_LINEAR_X);
1011   deconverge_effect->add_uniform("ConvergeY", uniform::UT_VEC3, uniform::CU_CONVERGE_LINEAR_Y);
1012   deconverge_effect->add_uniform("RadialConvergeX", uniform::UT_VEC3, uniform::CU_CONVERGE_RADIAL_X);
1013   deconverge_effect->add_uniform("RadialConvergeY", uniform::UT_VEC3, uniform::CU_CONVERGE_RADIAL_Y);
1014
1015   focus_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1016   focus_effect->add_uniform("Defocus", uniform::UT_VEC2, uniform::CU_FOCUS_SIZE);
1017
1018   phosphor_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1019   phosphor_effect->add_uniform("Phosphor", uniform::UT_VEC3, uniform::CU_PHOSPHOR_LIFE);
1020   phosphor_effect->add_uniform("Passthrough", uniform::UT_FLOAT, uniform::CU_PHOSPHOR_IGNORE);
1021
1022   post_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
1023   post_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
1024   post_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1025
1026   post_effect->add_uniform("PincushionAmount", uniform::UT_FLOAT, uniform::CU_POST_PINCUSHION);
1027   post_effect->add_uniform("CurvatureAmount", uniform::UT_FLOAT, uniform::CU_POST_CURVATURE);
1028
1029   post_effect->add_uniform("ShadowAlpha", uniform::UT_FLOAT, uniform::CU_POST_SHADOW_ALPHA);
1030   post_effect->add_uniform("ShadowCount", uniform::UT_VEC2, uniform::CU_POST_SHADOW_COUNT);
1031   post_effect->add_uniform("ShadowUV", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV);
1032   post_effect->add_uniform("ShadowDims", uniform::UT_VEC2, uniform::CU_POST_SHADOW_DIMS);
1033
1034   post_effect->add_uniform("ScanlineAlpha", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_ALPHA);
1035   post_effect->add_uniform("ScanlineScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_SCALE);
1036   post_effect->add_uniform("ScanlineHeight", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_HEIGHT);
1037   post_effect->add_uniform("ScanlineBrightScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_SCALE);
1038   post_effect->add_uniform("ScanlineBrightOffset", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_OFFSET);
1039   post_effect->add_uniform("Power", uniform::UT_VEC3, uniform::CU_POST_POWER);
1040   post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR);
1041
1042   initialized = true;
1043
1044   return 0;
1045}
1046
1047
1048//============================================================
1049//  shaders::begin_draw
1050//============================================================
1051
1052void shaders::begin_draw()
1053{
1054   if (!master_enable || !d3dintf->post_fx_available)
1055      return;
1056
1057   curr_effect = default_effect;
1058
1059   default_effect->set_technique("TestTechnique");
1060   post_effect->set_technique("ScanMaskTechnique");
1061   phosphor_effect->set_technique("TestTechnique");
1062   focus_effect->set_technique("TestTechnique");
1063   deconverge_effect->set_technique("DeconvergeTechnique");
1064   color_effect->set_technique("ColorTechnique");
1065   yiq_encode_effect->set_technique("EncodeTechnique");
1066   yiq_decode_effect->set_technique("DecodeTechnique");
1067
1068   HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
1069   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
1070}
1071
1072
1073//============================================================
1074//  shaders::begin_frame
1075//============================================================
1076
1077void shaders::begin_frame()
1078{
1079   record_texture();
1080}
1081
1082
1083//============================================================
1084//  shaders::blit
1085//============================================================
1086
1087void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type,
1088                  UINT32 prim_index, UINT32 prim_count, int dstw, int dsth)
1089{
1090   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
1091   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1092
1093   curr_effect = default_effect;
1094
1095   curr_effect->set_texture("Diffuse", src);
1096
1097   float dst_dims[2] = { (float)dstw, (float)dsth };
1098   curr_effect->set_vector("ScreenDims", 2, dst_dims);
1099   curr_effect->set_float("PostPass", 1.0f);
1100   curr_effect->set_float("PincushionAmount", options->pincushion);
1101   curr_effect->set_float("Brighten", 0.0f);
1102
1103   unsigned int num_passes = 0;
1104   curr_effect->begin(&num_passes, 0);
1105
1106   for (UINT pass = 0; pass < num_passes; pass++)
1107   {
1108      curr_effect->begin_pass(pass);
1109      // add the primitives
1110      HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count);
1111      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1112      curr_effect->end_pass();
1113   }
1114
1115   curr_effect->end();
1116
1117   if (new_dst)
1118   {
1119      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, new_dst);
1120      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1121   }
1122}
1123
1124
1125
1126//============================================================
1127//  shaders::blit
1128//============================================================
1129
1130void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type,
1131                  UINT32 prim_index, UINT32 prim_count)
1132{
1133   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
1134   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1135   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
1136   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1137
1138   curr_effect = default_effect;
1139
1140   curr_effect->set_texture("Diffuse", src);
1141
1142   vec2f screendims = d3d->get_dims();
1143   curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
1144   curr_effect->set_float("PostPass", 1.0f);
1145   curr_effect->set_float("PincushionAmount", options->pincushion);
1146   curr_effect->set_float("Brighten", 1.0f);
1147
1148   unsigned int num_passes = 0;
1149   curr_effect->begin(&num_passes, 0);
1150
1151   for (UINT pass = 0; pass < num_passes; pass++)
1152   {
1153      curr_effect->begin_pass(pass);
1154      // add the primitives
1155      HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count);
1156      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1157      curr_effect->end_pass();
1158   }
1159
1160   curr_effect->end();
1161
1162   curr_effect->set_float("Brighten", 0.0f);
1163
1164   if (new_dst)
1165   {
1166      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, new_dst);
1167      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1168   }
1169}
1170
1171//============================================================
1172//  shaders::end_frame
1173//============================================================
1174
1175void shaders::end_frame()
1176{
1177   if (!master_enable || !d3dintf->post_fx_available)
1178      return;
1179
1180   if(render_snap && snap_rendered)
1181   {
1182      render_snapshot(snap_target);
1183   }
1184
1185   if (!lines_pending)
1186      return;
1187
1188   lines_pending = false;
1189
1190   /*render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
1191   if (rt == NULL)
1192   {
1193       return;
1194   }
1195
1196   blit(backbuffer, rt->render_texture[1], NULL, vecbuf_type, vecbuf_index, vecbuf_count);
1197
1198   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]);
1199   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1200   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1201   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1202   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
1203   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);*/
1204}
1205
1206
1207//============================================================
1208//  shaders::init_effect_info
1209//============================================================
1210
1211void shaders::init_effect_info(poly_info *poly)
1212{
1213   if (!master_enable || !d3dintf->post_fx_available)
1214      return;
1215
1216   texture_info *texture = poly->get_texture();
1217
1218   if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && texture != NULL)
1219   {
1220      // Plug in all of the shader settings we're going to need
1221      // This is extremely slow, but we're not rendering models here,
1222      // just post-processing.
1223      curr_effect = post_effect;
1224
1225      curr_effect->set_float("ScanlineOffset", (texture->get_cur_frame() == 0) ? 0.0f : options->scanline_offset);
1226   }
1227   else
1228   {
1229      curr_effect = default_effect;
1230
1231      curr_effect->set_float("FixedAlpha", 1.0f);
1232   }
1233}
1234
1235
1236//============================================================
1237//  shaders::find_render_target
1238//============================================================
1239
1240render_target* shaders::find_render_target(texture_info *info)
1241{
1242   render_target *curr = targethead;
1243   UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata;
1244   UINT32 screen_index = screen_index_data >> 1;
1245   UINT32 page_index = screen_index_data & 1;
1246
1247   while (curr != NULL && (curr->screen_index != screen_index || curr->page_index != page_index ||
1248      curr->width != info->get_texinfo().width || curr->height != info->get_texinfo().height))
1249   {
1250      curr = curr->next;
1251   }
1252
1253   return curr;
1254}
1255
1256
1257//============================================================
1258//  shaders::find_render_target
1259//============================================================
1260
1261render_target* shaders::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index)
1262{
1263   render_target *curr = targethead;
1264
1265   while (curr != NULL && (curr->width != width || curr->height != height || curr->screen_index != screen_index || curr->page_index != page_index))
1266   {
1267      curr = curr->next;
1268   }
1269
1270   return curr;
1271}
1272
1273
1274//============================================================
1275//  shaders::find_cache_target
1276//============================================================
1277
1278cache_target* shaders::find_cache_target(UINT32 screen_index, int width, int height)
1279{
1280   cache_target *curr = cachehead;
1281
1282   while (curr != NULL && (curr->screen_index != screen_index || curr->width != width || curr->height != height))
1283   {
1284      curr = curr->next;
1285   }
1286
1287   return curr;
1288}
1289
1290void shaders::ntsc_pass(render_target *rt, vec2f &sourcedims, vec2f &delta)
1291{
1292   UINT num_passes = 0;
1293
1294   if(options->yiq_enable)
1295   {
1296      // Convert our signal into YIQ
1297      curr_effect = yiq_encode_effect;
1298      curr_effect->update_uniforms();
1299
1300      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[4]);
1301
1302      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1303      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1304      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1305
1306      curr_effect->begin(&num_passes, 0);
1307
1308      for (UINT pass = 0; pass < num_passes; pass++)
1309      {
1310         curr_effect->begin_pass(pass);
1311         // add the primitives
1312         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1313         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1314         curr_effect->end_pass();
1315      }
1316
1317      curr_effect->end();
1318
1319      // Convert our signal from YIQ
1320      curr_effect = yiq_decode_effect;
1321
1322      curr_effect->set_texture("Composite", rt->render_texture[4]);
1323      curr_effect->set_texture("Diffuse", curr_texture->get_finaltex());
1324      curr_effect->update_uniforms();
1325
1326      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[3]);
1327
1328      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1329      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1330      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1331
1332      curr_effect->begin(&num_passes, 0);
1333
1334      for (UINT pass = 0; pass < num_passes; pass++)
1335      {
1336         curr_effect->begin_pass(pass);
1337         // add the primitives
1338         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1339         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1340         curr_effect->end_pass();
1341      }
1342
1343      curr_effect->end();
1344
1345      curr_effect = color_effect;
1346
1347      curr_effect->set_texture("Diffuse", rt->render_texture[3]);
1348   }
1349}
1350
1351void shaders::color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims)
1352{
1353   UINT num_passes = 0;
1354
1355   curr_effect = color_effect;
1356   curr_effect->update_uniforms();
1357
1358   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->smalltarget);
1359
1360   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1361   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1362   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1363
1364   curr_effect->begin(&num_passes, 0);
1365
1366   for (UINT pass = 0; pass < num_passes; pass++)
1367   {
1368      curr_effect->begin_pass(pass);
1369      // add the primitives
1370      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1371      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1372      curr_effect->end_pass();
1373   }
1374
1375   curr_effect->end();
1376}
1377
1378void shaders::prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims)
1379{
1380   UINT num_passes = 0;
1381
1382   curr_effect = prescale_effect;
1383   curr_effect->update_uniforms();
1384   curr_effect->set_texture("Diffuse", rt->smalltexture);
1385
1386   curr_effect->begin(&num_passes, 0);
1387
1388   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->prescaletarget);
1389   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1390   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1391   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1392
1393   for (UINT pass = 0; pass < num_passes; pass++)
1394   {
1395      curr_effect->begin_pass(pass);
1396      // add the primitives
1397      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1398      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1399      curr_effect->end_pass();
1400   }
1401
1402   curr_effect->end();
1403}
1404
1405void shaders::deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims)
1406{
1407   UINT num_passes = 0;
1408
1409   curr_effect = deconverge_effect;
1410   curr_effect->update_uniforms();
1411   curr_effect->set_texture("Diffuse", rt->prescaletexture);
1412
1413   curr_effect->begin(&num_passes, 0);
1414
1415   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[2]);
1416   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1417   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1418   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1419
1420   for (UINT pass = 0; pass < num_passes; pass++)
1421   {
1422      curr_effect->begin_pass(pass);
1423      // add the primitives
1424      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1425      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1426      curr_effect->end_pass();
1427   }
1428
1429   curr_effect->end();
1430}
1431
1432void shaders::defocus_pass(render_target *rt, vec2f &texsize)
1433{
1434   UINT num_passes = 0;
1435
1436   // Defocus pass 1
1437   curr_effect = focus_effect;
1438   curr_effect->update_uniforms();
1439   curr_effect->set_texture("Diffuse", rt->render_texture[2]);
1440
1441   curr_effect->begin(&num_passes, 0);
1442
1443   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]);
1444   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1445   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1446   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1447
1448   for (UINT pass = 0; pass < num_passes; pass++)
1449   {
1450      curr_effect->begin_pass(pass);
1451      // add the primitives
1452      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1453      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1454      curr_effect->end_pass();
1455   }
1456
1457   curr_effect->end();
1458
1459   // Defocus pass 2
1460
1461   curr_effect->set_texture("Diffuse", rt->render_texture[0]);
1462
1463   curr_effect->begin(&num_passes, 0);
1464
1465   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]);
1466   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 7\n", (int)result);
1467
1468   for (UINT pass = 0; pass < num_passes; pass++)
1469   {
1470      curr_effect->begin_pass(pass);
1471      // add the primitives
1472      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1473      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1474      curr_effect->end_pass();
1475   }
1476
1477   curr_effect->end();
1478}
1479
1480void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable)
1481{
1482   UINT num_passes = 0;
1483
1484   curr_effect = phosphor_effect;
1485   phosphor_passthrough = false;
1486   curr_effect->update_uniforms();
1487
1488   float rtsize[2] = { rt->target_width, rt->target_height };
1489   curr_effect->set_vector("TargetDims", 2, rtsize);
1490
1491   curr_effect->set_texture("Diffuse", focus_enable ? rt->render_texture[1] : rt->render_texture[2]);
1492   curr_effect->set_texture("LastPass", ct->last_texture);
1493
1494   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]);
1495   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result);
1496   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1497   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1498
1499   curr_effect->begin(&num_passes, 0);
1500
1501   for (UINT pass = 0; pass < num_passes; pass++)
1502   {
1503      curr_effect->begin_pass(pass);
1504      // add the primitives
1505      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1506      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1507      curr_effect->end_pass();
1508   }
1509
1510   curr_effect->end();
1511
1512   // Pass along our phosphor'd screen
1513   phosphor_passthrough = true;
1514   curr_effect->update_uniforms();
1515   curr_effect->set_texture("Diffuse", rt->render_texture[0]);
1516   curr_effect->set_texture("LastPass", rt->render_texture[0]);
1517
1518   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, ct->last_target); // Avoid changing targets due to page flipping
1519   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result);
1520   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1521   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1522
1523   curr_effect->begin(&num_passes, 0);
1524
1525   for (UINT pass = 0; pass < num_passes; pass++)
1526   {
1527      curr_effect->begin_pass(pass);
1528      // add the primitives
1529      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1530      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1531      curr_effect->end_pass();
1532   }
1533
1534   curr_effect->end();
1535}
1536
1537void shaders::avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum)
1538{
1539   UINT num_passes = 0;
1540
1541   curr_effect = post_effect;
1542   curr_effect->update_uniforms();
1543   curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex());
1544
1545   // Scanlines and shadow mask, at high res for AVI logging
1546   if(avi_output_file != NULL)
1547   {
1548      curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
1549
1550      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, avi_final_target);
1551      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1552
1553      curr_effect->begin(&num_passes, 0);
1554
1555      for (UINT pass = 0; pass < num_passes; pass++)
1556      {
1557         curr_effect->begin_pass(pass);
1558         // add the primitives
1559         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1560         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1561         curr_effect->end_pass();
1562      }
1563
1564      curr_effect->end();
1565   }
1566
1567   if(render_snap)
1568   {
1569      curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
1570
1571      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, snap_target);
1572      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1573
1574      curr_effect->begin(&num_passes, 0);
1575
1576      for (UINT pass = 0; pass < num_passes; pass++)
1577      {
1578         curr_effect->begin_pass(pass);
1579         // add the primitives
1580         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1581         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1582         curr_effect->end_pass();
1583      }
1584
1585      curr_effect->end();
1586
1587      snap_rendered = true;
1588   }
1589}
1590
1591void shaders::screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum)
1592{
1593   UINT num_passes = 0;
1594
1595   curr_effect = post_effect;
1596   curr_effect->update_uniforms();
1597   curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex());
1598
1599   curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
1600
1601   d3d->set_wrap(D3DTADDRESS_MIRROR);
1602
1603   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[2]);
1604
1605   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
1606   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1607
1608   curr_effect->begin(&num_passes, 0);
1609
1610   for (UINT pass = 0; pass < num_passes; pass++)
1611   {
1612      curr_effect->begin_pass(pass);
1613      // add the primitives
1614      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1615      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1616      curr_effect->end_pass();
1617   }
1618
1619   curr_effect->end();
1620
1621   d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(poly->get_texture()->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
1622}
1623
1624void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum)
1625{
1626   UINT num_passes = 0;
1627
1628   curr_effect = downsample_effect;
1629
1630   curr_effect->set_texture("Diffuse", rt->render_texture[2]);
1631   curr_effect->set_float("BloomRescale", options->raster_bloom_scale);
1632
1633   float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
1634   int bloom_index = 0;
1635   float bloom_width = rt->target_width;
1636   float bloom_height = rt->target_height;
1637   vec2f screendims = d3d->get_dims();
1638   curr_effect->set_vector("ScreenSize", 2, &screendims.c.x);
1639   float bloom_dims[11][2];
1640   for(; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
1641   {
1642      bloom_dims[bloom_index][0] = bloom_width;
1643      bloom_dims[bloom_index][1] = bloom_height;
1644      curr_effect->set_vector("TargetSize", 2, bloom_dims[bloom_index]);
1645
1646      curr_effect->begin(&num_passes, 0);
1647
1648      curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->render_texture[2] : rt->bloom_texture[bloom_index - 1]);
1649
1650      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->bloom_target[bloom_index]);
1651      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1652      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1653      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1654
1655      for (UINT pass = 0; pass < num_passes; pass++)
1656      {
1657         curr_effect->begin_pass(pass);
1658         // add the primitives
1659         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1660         //result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1661         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1662         curr_effect->end_pass();
1663      }
1664
1665      curr_effect->end();
1666
1667      bloom_index++;
1668      bloom_width *= 0.5f;
1669      bloom_height *= 0.5f;
1670   }
1671
1672   curr_effect = bloom_effect;
1673
1674   float target_size[2] = { d3d->get_width(), d3d->get_height() };
1675   curr_effect->set_vector("TargetSize", 2, target_size);
1676   float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight, options->bloom_level2_weight, options->bloom_level3_weight };
1677   float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight, options->bloom_level6_weight, options->bloom_level7_weight };
1678   float weight89A[3]  = { options->bloom_level8_weight, options->bloom_level9_weight, options->bloom_level10_weight };
1679   curr_effect->set_vector("Level0123Weight", 4, weight0123);
1680   curr_effect->set_vector("Level4567Weight", 4, weight4567);
1681   curr_effect->set_vector("Level89AWeight", 3, weight89A);
1682   curr_effect->set_vector("Level01Size", 4, bloom_dims[0]);
1683   curr_effect->set_vector("Level23Size", 4, bloom_dims[2]);
1684   curr_effect->set_vector("Level45Size", 4, bloom_dims[4]);
1685   curr_effect->set_vector("Level67Size", 4, bloom_dims[6]);
1686   curr_effect->set_vector("Level89Size", 4, bloom_dims[8]);
1687   curr_effect->set_vector("LevelASize", 2, bloom_dims[10]);
1688
1689   curr_effect->set_texture("DiffuseA", rt->render_texture[2]);
1690
1691   char name[9] = "Diffuse*";
1692   for(int index = 1; index < bloom_index; index++)
1693   {
1694      name[7] = 'A' + index;
1695      curr_effect->set_texture(name, rt->bloom_texture[index - 1]);
1696   }
1697   for(int index = bloom_index; index < 11; index++)
1698   {
1699      name[7] = 'A' + index;
1700      curr_effect->set_texture(name, black_texture);
1701   }
1702
1703   curr_effect->begin(&num_passes, 0);
1704
1705   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
1706   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1707
1708   for (UINT pass = 0; pass < num_passes; pass++)
1709   {
1710      curr_effect->begin_pass(pass);
1711      // add the primitives
1712      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1713      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1714      curr_effect->end_pass();
1715   }
1716
1717   curr_effect->end();
1718}
1719
1720//============================================================
1721//  shaders::render_quad
1722//============================================================
1723
1724void shaders::render_quad(poly_info *poly, int vertnum)
1725{
1726   if (!master_enable || !d3dintf->post_fx_available)
1727      return;
1728
1729   UINT num_passes = 0;
1730   curr_texture = poly->get_texture();
1731
1732   if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && curr_texture != NULL)
1733   {
1734      render_target *rt = find_render_target(curr_texture);
1735      if (rt == NULL)
1736      {
1737         return;
1738      }
1739      cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_texinfo().width, curr_texture->get_texinfo().height);
1740
1741      vec2f& sourcedims = curr_texture->get_rawdims();
1742      vec2f delta = curr_texture->get_uvstop() - curr_texture->get_uvstart();
1743      vec2f texsize(rt->width, rt->height);
1744      float defocus_x = options->defocus[0];
1745      float defocus_y = options->defocus[1];
1746      bool focus_enable = defocus_x != 0.0f || defocus_y != 0.0f;
1747
1748      ntsc_pass(rt, sourcedims, delta);
1749      color_convolution_pass(rt, texsize, sourcedims);
1750      prescale_pass(rt, texsize, sourcedims);
1751      deconverge_pass(rt, texsize, delta, sourcedims);
1752      if (focus_enable)
1753      {
1754         defocus_pass(rt, texsize);
1755      }
1756      phosphor_pass(rt, ct, texsize, focus_enable);
1757      avi_post_pass(rt, texsize, delta, sourcedims, poly, vertnum);
1758      screen_post_pass(rt, texsize, delta, sourcedims, poly, vertnum);
1759      raster_bloom_pass(rt, texsize, delta, poly, vertnum);
1760
1761      curr_texture->increment_frame_count();
1762      curr_texture->mask_frame_count(options->yiq_phase_count);
1763
1764      options->params_dirty = false;
1765
1766   }
1767   else if(PRIMFLAG_GET_VECTOR(poly->get_flags()) && vector_enable)
1768   {
1769      render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
1770      if (rt == NULL)
1771      {
1772         return;
1773      }
1774
1775      lines_pending = true;
1776
1777      curr_effect = vector_effect;
1778
1779      if(options->params_dirty)
1780      {
1781         vec2f screendims = d3d->get_dims();
1782         curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
1783      }
1784
1785      float time_params[2] = { 0.0f, 0.0f };
1786      float length_params[3] = { poly->get_line_length(), options->vector_length_scale, options->vector_length_ratio };
1787      curr_effect->set_vector("TimeParams", 2, time_params);
1788      curr_effect->set_vector("LengthParams", 3, length_params);
1789
1790      curr_effect->begin(&num_passes, 0);
1791
1792      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]);
1793      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1794
1795      for (UINT pass = 0; pass < num_passes; pass++)
1796      {
1797         curr_effect->begin_pass(pass);
1798         // add the primitives
1799         HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1800         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1801         curr_effect->end_pass();
1802      }
1803
1804      curr_effect->end();
1805      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
1806      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1807
1808      curr_effect = default_effect;
1809
1810      curr_effect->set_float("FixedAlpha", 1.0f);
1811   }
1812   else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable)
1813   {
1814      render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
1815
1816      /* Bloom */
1817      curr_effect = downsample_effect;
1818
1819      curr_effect->set_texture("Diffuse", rt->render_texture[0]);
1820      curr_effect->set_float("BloomRescale", options->vector_bloom_scale);
1821
1822      float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
1823      int bloom_index = 0;
1824      float bloom_width = rt->target_width;
1825      float bloom_height = rt->target_height;
1826      float screen_size[2] = { d3d->get_width(), d3d->get_height() };
1827      curr_effect->set_vector("ScreenSize", 2, screen_size);
1828      float bloom_dims[11][2];
1829      for(; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
1830      {
1831         bloom_dims[bloom_index][0] = bloom_width;
1832         bloom_dims[bloom_index][1] = bloom_height;
1833         curr_effect->set_vector("TargetSize", 2, bloom_dims[bloom_index]);
1834
1835         curr_effect->begin(&num_passes, 0);
1836
1837         curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->render_texture[0] : rt->bloom_texture[bloom_index - 1]);
1838
1839         HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->bloom_target[bloom_index]);
1840         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1841         result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1842         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1843
1844         for (UINT pass = 0; pass < num_passes; pass++)
1845         {
1846            curr_effect->begin_pass(pass);
1847            // add the primitives
1848            result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1849            if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1850            curr_effect->end_pass();
1851         }
1852
1853         curr_effect->end();
1854
1855         bloom_index++;
1856         bloom_width *= 0.5f;
1857         bloom_height *= 0.5f;
1858      }
1859
1860      // Bloom composite pass
1861      curr_effect = bloom_effect;
1862
1863      float target_size[2] = { d3d->get_width(), d3d->get_height() };
1864      curr_effect->set_vector("TargetSize", 2, target_size);
1865      float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight,
1866                        options->bloom_level2_weight, options->bloom_level3_weight };
1867      float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight,
1868                        options->bloom_level6_weight, options->bloom_level7_weight };
1869      float weight89A[3] = { options->bloom_level8_weight, options->bloom_level9_weight,
1870                        options->bloom_level10_weight };
1871      curr_effect->set_vector("Level0123Weight", 4, weight0123);
1872      curr_effect->set_vector("Level4567Weight", 4, weight4567);
1873      curr_effect->set_vector("Level89AWeight", 3, weight89A);
1874      curr_effect->set_vector("Level01Size", 4, bloom_dims[0]);
1875      curr_effect->set_vector("Level23Size", 4, bloom_dims[2]);
1876      curr_effect->set_vector("Level45Size", 4, bloom_dims[4]);
1877      curr_effect->set_vector("Level67Size", 4, bloom_dims[6]);
1878      curr_effect->set_vector("Level89Size", 4, bloom_dims[8]);
1879      curr_effect->set_vector("LevelASize", 2, bloom_dims[10]);
1880
1881      curr_effect->set_texture("DiffuseA", rt->render_texture[0]);
1882
1883      char name[9] = "Diffuse*";
1884      for(int index = 1; index < bloom_index; index++)
1885      {
1886         name[7] = 'A' + index;
1887         curr_effect->set_texture(name, rt->bloom_texture[index - 1]);
1888      }
1889      for(int index = bloom_index; index < 11; index++)
1890      {
1891         name[7] = 'A' + index;
1892         curr_effect->set_texture(name, black_texture);
1893      }
1894
1895      curr_effect->begin(&num_passes, 0);
1896
1897      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]);
1898      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1899      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1900      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1901
1902      for (UINT pass = 0; pass < num_passes; pass++)
1903      {
1904         curr_effect->begin_pass(pass);
1905         // add the primitives
1906         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1907         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1908         curr_effect->end_pass();
1909      }
1910
1911      curr_effect->end();
1912
1913      /* Phosphor */
1914      curr_effect = phosphor_effect;
1915
1916      if(options->params_dirty)
1917      {
1918         vec2f screendims = d3d->get_dims();
1919         curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
1920         curr_effect->set_vector("Phosphor", 3, options->phosphor);
1921      }
1922      float target_dims[2] = { d3d->get_width(), d3d->get_height() };
1923      curr_effect->set_vector("TargetDims", 2, target_dims);
1924      curr_effect->set_float("Passthrough", 0.0f);
1925
1926      curr_effect->set_texture("Diffuse", rt->render_texture[1]);
1927      curr_effect->set_texture("LastPass", rt->render_texture[2]);
1928
1929      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[3]);
1930      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result);
1931      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1932      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1933
1934      curr_effect->begin(&num_passes, 0);
1935
1936      for (UINT pass = 0; pass < num_passes; pass++)
1937      {
1938         curr_effect->begin_pass(pass);
1939         // add the primitives
1940         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1941         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1942         curr_effect->end_pass();
1943      }
1944
1945      curr_effect->end();
1946
1947      blit(rt->target[2], rt->render_texture[3], NULL, poly->get_type(), vertnum, poly->get_count());
1948      blit(backbuffer, rt->render_texture[3], backbuffer, poly->get_type(), vertnum, poly->get_count());
1949
1950      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]);
1951      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1952      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1953      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1954      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
1955      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1956
1957      lines_pending = false;
1958   }
1959   else
1960   {
1961      curr_effect = default_effect;
1962
1963      vec2f screendims = d3d->get_dims();
1964      curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
1965      curr_effect->set_float("PostPass", 0.0f);
1966
1967      curr_effect->begin(&num_passes, 0);
1968
1969      for (UINT pass = 0; pass < num_passes; pass++)
1970      {
1971         curr_effect->begin_pass(pass);
1972         // add the primitives
1973         HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1974         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1975         curr_effect->end_pass();
1976      }
1977
1978      curr_effect->end();
1979   }
1980
1981   curr_texture = NULL;
1982}
1983
1984
1985
1986//============================================================
1987//  shaders::end_draw
1988//============================================================
1989
1990void shaders::end_draw()
1991{
1992   if (!master_enable || !d3dintf->post_fx_available)
1993      return;
1994
1995   (*d3dintf->surface.release)(backbuffer);
1996}
1997
1998
1999//============================================================
2000//  shaders::register_prescaled_texture
2001//============================================================
2002
2003bool shaders::register_prescaled_texture(texture_info *texture)
2004{
2005   return register_texture(texture);
2006}
2007
2008
2009//============================================================
2010//  shaders::add_cache_target - register a cache target
2011//============================================================
2012bool shaders::add_cache_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index)
2013{
2014   cache_target* target = (cache_target*)global_alloc_clear(cache_target);
2015
2016   if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale))
2017   {
2018      global_free(target);
2019      return false;
2020   }
2021
2022   if (info != NULL)
2023   {
2024      target->width = info->get_texinfo().width;
2025      target->height = info->get_texinfo().height;
2026   }
2027   else
2028   {
2029      target->width = d3d->get_width();
2030      target->height = d3d->get_height();
2031   }
2032
2033   target->next = cachehead;
2034   target->prev = NULL;
2035
2036   target->screen_index = screen_index;
2037
2038   if (cachehead != NULL)
2039   {
2040      cachehead->prev = target;
2041   }
2042   cachehead = target;
2043
2044   return true;
2045}
2046
2047render_target* shaders::get_vector_target()
2048{
2049   if (!vector_enable)
2050   {
2051      return NULL;
2052   }
2053
2054   return find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
2055}
2056
2057void shaders::create_vector_target(render_primitive *prim)
2058{
2059   if (!add_render_target(d3d, NULL, d3d->get_width(), d3d->get_height(), 1, 1))
2060   {
2061      vector_enable = false;
2062   }
2063}
2064
2065//============================================================
2066//  shaders::add_render_target - register a render target
2067//============================================================
2068
2069bool shaders::add_render_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale)
2070{
2071   UINT32 screen_index = 0;
2072   UINT32 page_index = 0;
2073   if (info != NULL)
2074   {
2075      render_target *existing_target = find_render_target(info);
2076      if (existing_target != NULL)
2077      {
2078         remove_render_target(existing_target);
2079      }
2080
2081      UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata;
2082      screen_index = screen_index_data >> 1;
2083      page_index = screen_index_data & 1;
2084   }
2085   else
2086   {
2087      render_target *existing_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
2088      if (existing_target != NULL)
2089      {
2090         remove_render_target(existing_target);
2091      }
2092   }
2093
2094   render_target* target = (render_target*)global_alloc_clear(render_target);
2095
2096   if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale))
2097   {
2098      global_free(target);
2099      return false;
2100   }
2101
2102   if (info != NULL)
2103   {
2104      target->width = info->get_texinfo().width;
2105      target->height = info->get_texinfo().height;
2106   }
2107   else
2108   {
2109      target->width = d3d->get_width();
2110      target->height = d3d->get_height();
2111   }
2112
2113   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->target[0]);
2114   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
2115   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
2116   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
2117   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
2118   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
2119
2120   target->screen_index = screen_index;
2121   target->page_index = page_index;
2122
2123   cache_target* cache = find_cache_target(target->screen_index, target->width, target->height);
2124   if (cache == NULL)
2125   {
2126      if (!add_cache_target(d3d, info, width, height, xprescale, yprescale, target->screen_index))
2127      {
2128         global_free(target);
2129         return false;
2130      }
2131   }
2132
2133   target->next = targethead;
2134   target->prev = NULL;
2135
2136   if (targethead != NULL)
2137   {
2138      targethead->prev = target;
2139   }
2140   targethead = target;
2141
2142   return true;
2143}
2144
2145//============================================================
2146//  shaders::enumerate_screens
2147//============================================================
2148void shaders::enumerate_screens()
2149{
2150   screen_device_iterator iter(machine->root_device());
2151   num_screens = iter.count();
2152}
2153
2154
2155//============================================================
2156//  shaders::register_texture(texture::info)
2157//============================================================
2158
2159bool shaders::register_texture(texture_info *texture)
2160{
2161   int width = texture->get_width();
2162   int height = texture->get_height();
2163   int xscale = texture->get_xscale();
2164   int yscale = texture->get_yscale();
2165
2166   if (!master_enable || !d3dintf->post_fx_available)
2167   {
2168      return false;
2169   }
2170
2171   enumerate_screens();
2172
2173   int hlsl_prescale_x = prescale_force_x;
2174   int hlsl_prescale_y = prescale_force_y;
2175
2176   // Find the nearest prescale factor that is over our screen size
2177   if (hlsl_prescale_x == 0)
2178   {
2179      hlsl_prescale_x = 1;
2180      while (width * xscale * hlsl_prescale_x <= d3d->get_width())
2181      {
2182         hlsl_prescale_x++;
2183      }
2184      hlsl_prescale_x--;
2185   }
2186
2187   if (hlsl_prescale_y == 0)
2188   {
2189      hlsl_prescale_y = 1;
2190      while (height * yscale * hlsl_prescale_y <= d3d->get_height())
2191      {
2192         hlsl_prescale_y++;
2193      }
2194      hlsl_prescale_y--;
2195   }
2196
2197   hlsl_prescale_x = ((hlsl_prescale_x == 0) ? 1 : hlsl_prescale_x);
2198   hlsl_prescale_y = ((hlsl_prescale_y == 0) ? 1 : hlsl_prescale_y);
2199
2200   if (!add_render_target(d3d, texture, width, height, xscale * hlsl_prescale_x, yscale * hlsl_prescale_y))
2201      return false;
2202
2203   options->params_dirty = true;
2204
2205   return true;
2206}
2207
2208//============================================================
2209//  shaders::delete_resources
2210//============================================================
2211
2212void shaders::delete_resources(bool reset)
2213{
2214   if (!master_enable || !d3dintf->post_fx_available)
2215      return;
2216
2217   initialized = false;
2218
2219   cache_target *currcache = cachehead;
2220   while(cachehead != NULL)
2221   {
2222      cachehead = currcache->next;
2223      global_free(currcache);
2224      currcache = cachehead;
2225   }
2226
2227   render_target *currtarget = targethead;
2228   while(targethead != NULL)
2229   {
2230      targethead = currtarget->next;
2231      global_free(currtarget);
2232      currtarget = targethead;
2233   }
2234
2235   if (downsample_effect != NULL)
2236   {
2237      delete downsample_effect;
2238      downsample_effect = NULL;
2239   }
2240   if (bloom_effect != NULL)
2241   {
2242      delete bloom_effect;
2243      bloom_effect = NULL;
2244   }
2245   if (vector_effect != NULL)
2246   {
2247      delete vector_effect;
2248      vector_effect = NULL;
2249   }
2250   if (default_effect != NULL)
2251   {
2252      delete default_effect;
2253      default_effect = NULL;
2254   }
2255   if (post_effect != NULL)
2256   {
2257      delete post_effect;
2258      post_effect = NULL;
2259   }
2260   if (prescale_effect != NULL)
2261   {
2262      delete prescale_effect;
2263      prescale_effect = NULL;
2264   }
2265   if (phosphor_effect != NULL)
2266   {
2267      delete phosphor_effect;
2268      phosphor_effect = NULL;
2269   }
2270   if (focus_effect != NULL)
2271   {
2272      delete focus_effect;
2273      focus_effect = NULL;
2274   }
2275   if (deconverge_effect != NULL)
2276   {
2277      delete deconverge_effect;
2278      deconverge_effect = NULL;
2279   }
2280   if (color_effect != NULL)
2281   {
2282      delete color_effect;
2283      color_effect = NULL;
2284   }
2285   if (yiq_encode_effect != NULL)
2286   {
2287      delete yiq_encode_effect;
2288      yiq_encode_effect = NULL;
2289   }
2290   if (yiq_decode_effect != NULL)
2291   {
2292      delete yiq_decode_effect;
2293      yiq_decode_effect = NULL;
2294   }
2295
2296   if (backbuffer != NULL)
2297   {
2298      (*d3dintf->surface.release)(backbuffer);
2299      backbuffer = NULL;
2300   }
2301
2302   if (black_surface != NULL)
2303   {
2304      (*d3dintf->surface.release)(black_surface);
2305      black_surface = NULL;
2306   }
2307   if (black_texture != NULL)
2308   {
2309      (*d3dintf->texture.release)(black_texture);
2310      black_texture = NULL;
2311   }
2312
2313   if (avi_copy_texture != NULL)
2314   {
2315      (*d3dintf->texture.release)(avi_copy_texture);
2316      avi_copy_texture = NULL;
2317   }
2318
2319   if (avi_copy_surface != NULL)
2320   {
2321      (*d3dintf->surface.release)(avi_copy_surface);
2322      avi_copy_surface = NULL;
2323   }
2324
2325   if (avi_final_texture != NULL)
2326   {
2327      (*d3dintf->texture.release)(avi_final_texture);
2328      avi_final_texture = NULL;
2329   }
2330
2331   if (avi_final_target != NULL)
2332   {
2333      (*d3dintf->surface.release)(avi_final_target);
2334      avi_final_target = NULL;
2335   }
2336
2337   shadow_bitmap.reset();
2338}
2339
2340
2341//============================================================
2342//  get_vector
2343//============================================================
2344
2345static void get_vector(const char *data, int count, float *out, int report_error)
2346{
2347   if (count > 3)
2348   {
2349      if (sscanf(data, "%f,%f,%f,%f", &out[0], &out[1], &out[2], &out[3]) < 4 && report_error)
2350         osd_printf_error("Illegal quad vector value = %s\n", data);
2351   }
2352   else if(count > 2)
2353   {
2354      if (sscanf(data, "%f,%f,%f", &out[0], &out[1], &out[2]) < 3 && report_error)
2355         osd_printf_error("Illegal triple vector value = %s\n", data);
2356   }
2357   else if(count > 1)
2358   {
2359      if (sscanf(data, "%f,%f", &out[0], &out[1]) < 2 && report_error)
2360         osd_printf_error("Illegal double vector value = %s\n", data);
2361   }
2362   else if(count > 0)
2363   {
2364      if (sscanf(data, "%f", &out[0]) < 1 && report_error)
2365         osd_printf_error("Illegal single vector value = %s\n", data);
2366   }
2367}
2368
2369
2370/*-------------------------------------------------
2371    slider_alloc - allocate a new slider entry
2372    currently duplicated from ui.c, this could
2373    be done in a more ideal way.
2374-------------------------------------------------*/
2375
2376static slider_state *slider_alloc(running_machine &machine, const char *title, INT32 minval, INT32 defval, INT32 maxval, INT32 incval, slider_update update, void *arg)
2377{
2378   int size = sizeof(slider_state) + strlen(title);
2379   slider_state *state = (slider_state *)auto_alloc_array_clear(machine, UINT8, size);
2380
2381   state->minval = minval;
2382   state->defval = defval;
2383   state->maxval = maxval;
2384   state->incval = incval;
2385   state->update = update;
2386   state->arg = arg;
2387   strcpy(state->description, title);
2388
2389   return state;
2390}
2391
2392
2393//============================================================
2394//  assorted global slider accessors
2395//============================================================
2396
2397static INT32 slider_set(float *option, float scale, const char *fmt, astring *string, INT32 newval)
2398{
2399   if (option != NULL && newval != SLIDER_NOCHANGE) *option = (float)newval * scale;
2400   if (string != NULL) string->printf(fmt, *option);
2401   return floor(*option / scale + 0.5f);
2402}
2403
2404static INT32 slider_shadow_mask_alpha(running_machine &machine, void *arg, astring *string, INT32 newval)
2405{
2406   return slider_set(&(((hlsl_options*)arg)->shadow_mask_alpha), 0.01f, "%2.2f", string, newval);
2407}
2408
2409static INT32 slider_shadow_mask_x_count(running_machine &machine, void *arg, astring *string, INT32 newval)
2410{
2411   hlsl_options *options = (hlsl_options*)arg;
2412   if (newval != SLIDER_NOCHANGE) options->shadow_mask_count_x = newval;
2413   if (string != NULL) string->printf("%d", options->shadow_mask_count_x);
2414   options->params_dirty = true;
2415   return options->shadow_mask_count_x;
2416}
2417
2418static INT32 slider_shadow_mask_y_count(running_machine &machine, void *arg, astring *string, INT32 newval)
2419{
2420   hlsl_options *options = (hlsl_options*)arg;
2421   if (newval != SLIDER_NOCHANGE) options->shadow_mask_count_y = newval;
2422   if (string != NULL) string->printf("%d", options->shadow_mask_count_y);
2423   options->params_dirty = true;
2424   return options->shadow_mask_count_y;
2425}
2426
2427static INT32 slider_shadow_mask_usize(running_machine &machine, void *arg, astring *string, INT32 newval)
2428{
2429   ((hlsl_options*)arg)->params_dirty = true;
2430   return slider_set(&(((hlsl_options*)arg)->shadow_mask_u_size), 1.0f / 32.0f, "%2.5f", string, newval);
2431}
2432
2433static INT32 slider_shadow_mask_vsize(running_machine &machine, void *arg, astring *string, INT32 newval)
2434{
2435   ((hlsl_options*)arg)->params_dirty = true;
2436   return slider_set(&(((hlsl_options*)arg)->shadow_mask_v_size), 1.0f / 32.0f, "%2.5f", string, newval);
2437}
2438
2439static INT32 slider_curvature(running_machine &machine, void *arg, astring *string, INT32 newval)
2440{
2441   ((hlsl_options*)arg)->params_dirty = true;
2442   return slider_set(&(((hlsl_options*)arg)->curvature), 0.01f, "%2.2f", string, newval);
2443}
2444
2445static INT32 slider_pincushion(running_machine &machine, void *arg, astring *string, INT32 newval)
2446{
2447   ((hlsl_options*)arg)->params_dirty = true;
2448   return slider_set(&(((hlsl_options*)arg)->pincushion), 0.01f, "%2.2f", string, newval);
2449}
2450
2451static INT32 slider_scanline_alpha(running_machine &machine, void *arg, astring *string, INT32 newval)
2452{
2453   ((hlsl_options*)arg)->params_dirty = true;
2454   return slider_set(&(((hlsl_options*)arg)->scanline_alpha), 0.01f, "%2.2f", string, newval);
2455}
2456
2457static INT32 slider_scanline_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2458{
2459   ((hlsl_options*)arg)->params_dirty = true;
2460   return slider_set(&(((hlsl_options*)arg)->scanline_scale), 0.05f, "%2.2f", string, newval);
2461}
2462
2463static INT32 slider_scanline_height(running_machine &machine, void *arg, astring *string, INT32 newval)
2464{
2465   ((hlsl_options*)arg)->params_dirty = true;
2466   return slider_set(&(((hlsl_options*)arg)->scanline_height), 0.05f, "%2.2f", string, newval);
2467}
2468
2469static INT32 slider_scanline_bright_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2470{
2471   ((hlsl_options*)arg)->params_dirty = true;
2472   return slider_set(&(((hlsl_options*)arg)->scanline_bright_scale), 0.05f, "%2.2f", string, newval);
2473}
2474
2475static INT32 slider_scanline_bright_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2476{
2477   ((hlsl_options*)arg)->params_dirty = true;
2478   return slider_set(&(((hlsl_options*)arg)->scanline_bright_offset), 0.05f, "%2.2f", string, newval);
2479}
2480
2481static INT32 slider_scanline_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2482{
2483   ((hlsl_options*)arg)->params_dirty = true;
2484   return slider_set(&(((hlsl_options*)arg)->scanline_offset), 0.05f, "%2.2f", string, newval);
2485}
2486
2487static INT32 slider_defocus_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2488{
2489   ((hlsl_options*)arg)->params_dirty = true;
2490   return slider_set(&(((hlsl_options*)arg)->defocus[0]), 0.5f, "%2.1f", string, newval);
2491}
2492
2493static INT32 slider_defocus_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2494{
2495   ((hlsl_options*)arg)->params_dirty = true;
2496   return slider_set(&(((hlsl_options*)arg)->defocus[1]), 0.5f, "%2.1f", string, newval);
2497}
2498
2499static INT32 slider_red_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2500{
2501   ((hlsl_options*)arg)->params_dirty = true;
2502   return slider_set(&(((hlsl_options*)arg)->converge_x[0]), 0.1f, "%3.1f", string, newval);
2503}
2504
2505static INT32 slider_red_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2506{
2507   ((hlsl_options*)arg)->params_dirty = true;
2508   return slider_set(&(((hlsl_options*)arg)->converge_y[0]), 0.1f, "%3.1f", string, newval);
2509}
2510
2511static INT32 slider_green_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2512{
2513   ((hlsl_options*)arg)->params_dirty = true;
2514   return slider_set(&(((hlsl_options*)arg)->converge_x[1]), 0.1f, "%3.1f", string, newval);
2515}
2516
2517static INT32 slider_green_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2518{
2519   ((hlsl_options*)arg)->params_dirty = true;
2520   return slider_set(&(((hlsl_options*)arg)->converge_y[1]), 0.1f, "%3.1f", string, newval);
2521}
2522
2523static INT32 slider_blue_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2524{
2525   ((hlsl_options*)arg)->params_dirty = true;
2526   return slider_set(&(((hlsl_options*)arg)->converge_x[2]), 0.1f, "%3.1f", string, newval);
2527}
2528
2529static INT32 slider_blue_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2530{
2531   ((hlsl_options*)arg)->params_dirty = true;
2532   return slider_set(&(((hlsl_options*)arg)->converge_y[2]), 0.1f, "%3.1f", string, newval);
2533}
2534
2535static INT32 slider_red_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2536{
2537   ((hlsl_options*)arg)->params_dirty = true;
2538   return slider_set(&(((hlsl_options*)arg)->radial_converge_x[0]), 0.1f, "%3.1f", string, newval);
2539}
2540
2541static INT32 slider_red_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2542{
2543   ((hlsl_options*)arg)->params_dirty = true;
2544   return slider_set(&(((hlsl_options*)arg)->radial_converge_y[0]), 0.1f, "%3.1f", string, newval);
2545}
2546
2547static INT32 slider_green_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2548{
2549   ((hlsl_options*)arg)->params_dirty = true;
2550   return slider_set(&(((hlsl_options*)arg)->radial_converge_x[1]), 0.1f, "%3.1f", string, newval);
2551}
2552
2553static INT32 slider_green_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2554{
2555   ((hlsl_options*)arg)->params_dirty = true;
2556   return slider_set(&(((hlsl_options*)arg)->radial_converge_y[1]), 0.1f, "%3.1f", string, newval);
2557}
2558
2559static INT32 slider_blue_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2560{
2561   ((hlsl_options*)arg)->params_dirty = true;
2562   return slider_set(&(((hlsl_options*)arg)->radial_converge_x[2]), 0.1f, "%3.1f", string, newval);
2563}
2564
2565static INT32 slider_blue_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2566{
2567   ((hlsl_options*)arg)->params_dirty = true;
2568   return slider_set(&(((hlsl_options*)arg)->radial_converge_y[2]), 0.1f, "%3.1f", string, newval);
2569}
2570
2571static INT32 slider_red_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
2572{
2573   ((hlsl_options*)arg)->params_dirty = true;
2574   return slider_set(&(((hlsl_options*)arg)->red_ratio[0]), 0.005f, "%2.3f", string, newval);
2575}
2576
2577static INT32 slider_red_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
2578{
2579   ((hlsl_options*)arg)->params_dirty = true;
2580   return slider_set(&(((hlsl_options*)arg)->red_ratio[1]), 0.005f, "%2.3f", string, newval);
2581}
2582
2583static INT32 slider_red_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
2584{
2585   ((hlsl_options*)arg)->params_dirty = true;
2586   return slider_set(&(((hlsl_options*)arg)->red_ratio[2]), 0.005f, "%2.3f", string, newval);
2587}
2588
2589static INT32 slider_green_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
2590{
2591   ((hlsl_options*)arg)->params_dirty = true;
2592   return slider_set(&(((hlsl_options*)arg)->grn_ratio[0]), 0.005f, "%2.3f", string, newval);
2593}
2594
2595static INT32 slider_green_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
2596{
2597   ((hlsl_options*)arg)->params_dirty = true;
2598   return slider_set(&(((hlsl_options*)arg)->grn_ratio[1]), 0.005f, "%2.3f", string, newval);
2599}
2600
2601static INT32 slider_green_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
2602{
2603   ((hlsl_options*)arg)->params_dirty = true;
2604   return slider_set(&(((hlsl_options*)arg)->grn_ratio[2]), 0.005f, "%2.3f", string, newval);
2605}
2606
2607static INT32 slider_blue_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
2608{
2609   ((hlsl_options*)arg)->params_dirty = true;
2610   return slider_set(&(((hlsl_options*)arg)->blu_ratio[0]), 0.005f, "%2.3f", string, newval);
2611}
2612
2613static INT32 slider_blue_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
2614{
2615   ((hlsl_options*)arg)->params_dirty = true;
2616   return slider_set(&(((hlsl_options*)arg)->blu_ratio[1]), 0.005f, "%2.3f", string, newval);
2617}
2618
2619static INT32 slider_blue_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
2620{
2621   ((hlsl_options*)arg)->params_dirty = true;
2622   return slider_set(&(((hlsl_options*)arg)->blu_ratio[2]), 0.005f, "%2.3f", string, newval);
2623}
2624
2625static INT32 slider_red_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2626{
2627   ((hlsl_options*)arg)->params_dirty = true;
2628   return slider_set(&(((hlsl_options*)arg)->offset[0]), 0.01f, "%2.2f", string, newval);
2629}
2630
2631static INT32 slider_green_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2632{
2633   ((hlsl_options*)arg)->params_dirty = true;
2634   return slider_set(&(((hlsl_options*)arg)->offset[1]), 0.01f, "%2.2f", string, newval);
2635}
2636
2637static INT32 slider_blue_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2638{
2639   ((hlsl_options*)arg)->params_dirty = true;
2640   return slider_set(&(((hlsl_options*)arg)->offset[2]), 0.01f, "%2.2f", string, newval);
2641}
2642
2643static INT32 slider_red_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2644{
2645   ((hlsl_options*)arg)->params_dirty = true;
2646   return slider_set(&(((hlsl_options*)arg)->scale[0]), 0.01f, "%2.2f", string, newval);
2647}
2648
2649static INT32 slider_green_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2650{
2651   ((hlsl_options*)arg)->params_dirty = true;
2652   return slider_set(&(((hlsl_options*)arg)->scale[1]), 0.01f, "%2.2f", string, newval);
2653}
2654
2655static INT32 slider_blue_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2656{
2657   ((hlsl_options*)arg)->params_dirty = true;
2658   return slider_set(&(((hlsl_options*)arg)->scale[2]), 0.01f, "%2.2f", string, newval);
2659}
2660
2661static INT32 slider_red_power(running_machine &machine, void *arg, astring *string, INT32 newval)
2662{
2663   ((hlsl_options*)arg)->params_dirty = true;
2664   return slider_set(&(((hlsl_options*)arg)->power[0]), 0.05f, "%2.2f", string, newval);
2665}
2666
2667static INT32 slider_green_power(running_machine &machine, void *arg, astring *string, INT32 newval)
2668{
2669   ((hlsl_options*)arg)->params_dirty = true;
2670   return slider_set(&(((hlsl_options*)arg)->power[1]), 0.05f, "%2.2f", string, newval);
2671}
2672
2673static INT32 slider_blue_power(running_machine &machine, void *arg, astring *string, INT32 newval)
2674{
2675   ((hlsl_options*)arg)->params_dirty = true;
2676   return slider_set(&(((hlsl_options*)arg)->power[2]), 0.05f, "%2.2f", string, newval);
2677}
2678
2679static INT32 slider_red_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
2680{
2681   ((hlsl_options*)arg)->params_dirty = true;
2682   return slider_set(&(((hlsl_options*)arg)->floor[0]), 0.01f, "%2.2f", string, newval);
2683}
2684
2685static INT32 slider_green_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
2686{
2687   ((hlsl_options*)arg)->params_dirty = true;
2688   return slider_set(&(((hlsl_options*)arg)->floor[1]), 0.01f, "%2.2f", string, newval);
2689}
2690
2691static INT32 slider_blue_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
2692{
2693   ((hlsl_options*)arg)->params_dirty = true;
2694   return slider_set(&(((hlsl_options*)arg)->floor[2]), 0.01f, "%2.2f", string, newval);
2695}
2696
2697static INT32 slider_red_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
2698{
2699   ((hlsl_options*)arg)->params_dirty = true;
2700   return slider_set(&(((hlsl_options*)arg)->phosphor[0]), 0.01f, "%2.2f", string, newval);
2701}
2702
2703static INT32 slider_green_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
2704{
2705   ((hlsl_options*)arg)->params_dirty = true;
2706   return slider_set(&(((hlsl_options*)arg)->phosphor[1]), 0.01f, "%2.2f", string, newval);
2707}
2708
2709static INT32 slider_blue_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
2710{
2711   ((hlsl_options*)arg)->params_dirty = true;
2712   return slider_set(&(((hlsl_options*)arg)->phosphor[2]), 0.01f, "%2.2f", string, newval);
2713}
2714
2715static INT32 slider_saturation(running_machine &machine, void *arg, astring *string, INT32 newval)
2716{
2717   ((hlsl_options*)arg)->params_dirty = true;
2718   return slider_set(&(((hlsl_options*)arg)->saturation), 0.01f, "%2.2f", string, newval);
2719}
2720
2721static INT32 slider_vector_attenuation(running_machine &machine, void *arg, astring *string, INT32 newval)
2722{
2723   ((hlsl_options*)arg)->params_dirty = true;
2724   return slider_set(&(((hlsl_options*)arg)->vector_length_scale), 0.01f, "%1.2f", string, newval);
2725}
2726
2727static INT32 slider_vector_length_max(running_machine &machine, void *arg, astring *string, INT32 newval)
2728{
2729   ((hlsl_options*)arg)->params_dirty = true;
2730   return slider_set(&(((hlsl_options*)arg)->vector_length_ratio), 1.0f, "%4f", string, newval);
2731}
2732
2733static INT32 slider_vector_bloom_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2734{
2735   ((hlsl_options*)arg)->params_dirty = true;
2736   return slider_set(&(((hlsl_options*)arg)->vector_bloom_scale), 0.001f, "%1.3f", string, newval);
2737}
2738
2739static INT32 slider_raster_bloom_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2740{
2741   ((hlsl_options*)arg)->params_dirty = true;
2742   return slider_set(&(((hlsl_options*)arg)->raster_bloom_scale), 0.001f, "%1.3f", string, newval);
2743}
2744
2745static INT32 slider_bloom_lvl0_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2746{
2747   ((hlsl_options*)arg)->params_dirty = true;
2748   return slider_set(&(((hlsl_options*)arg)->bloom_level0_weight), 0.01f, "%1.2f", string, newval);
2749}
2750
2751static INT32 slider_bloom_lvl1_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2752{
2753   ((hlsl_options*)arg)->params_dirty = true;
2754   return slider_set(&(((hlsl_options*)arg)->bloom_level1_weight), 0.01f, "%1.2f", string, newval);
2755}
2756
2757static INT32 slider_bloom_lvl2_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2758{
2759   ((hlsl_options*)arg)->params_dirty = true;
2760   return slider_set(&(((hlsl_options*)arg)->bloom_level2_weight), 0.01f, "%1.2f", string, newval);
2761}
2762
2763static INT32 slider_bloom_lvl3_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2764{
2765   ((hlsl_options*)arg)->params_dirty = true;
2766   return slider_set(&(((hlsl_options*)arg)->bloom_level3_weight), 0.01f, "%1.2f", string, newval);
2767}
2768
2769static INT32 slider_bloom_lvl4_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2770{
2771   ((hlsl_options*)arg)->params_dirty = true;
2772   return slider_set(&(((hlsl_options*)arg)->bloom_level4_weight), 0.01f, "%1.2f", string, newval);
2773}
2774
2775static INT32 slider_bloom_lvl5_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2776{
2777   ((hlsl_options*)arg)->params_dirty = true;
2778   return slider_set(&(((hlsl_options*)arg)->bloom_level5_weight), 0.01f, "%1.2f", string, newval);
2779}
2780
2781static INT32 slider_bloom_lvl6_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2782{
2783   ((hlsl_options*)arg)->params_dirty = true;
2784   return slider_set(&(((hlsl_options*)arg)->bloom_level6_weight), 0.01f, "%1.2f", string, newval);
2785}
2786
2787static INT32 slider_bloom_lvl7_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2788{
2789   ((hlsl_options*)arg)->params_dirty = true;
2790   return slider_set(&(((hlsl_options*)arg)->bloom_level7_weight), 0.01f, "%1.2f", string, newval);
2791}
2792
2793static INT32 slider_bloom_lvl8_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2794{
2795   ((hlsl_options*)arg)->params_dirty = true;
2796   return slider_set(&(((hlsl_options*)arg)->bloom_level8_weight), 0.01f, "%1.2f", string, newval);
2797}
2798
2799static INT32 slider_bloom_lvl9_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2800{
2801   ((hlsl_options*)arg)->params_dirty = true;
2802   return slider_set(&(((hlsl_options*)arg)->bloom_level9_weight), 0.01f, "%1.2f", string, newval);
2803}
2804
2805static INT32 slider_bloom_lvl10_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2806{
2807   ((hlsl_options*)arg)->params_dirty = true;
2808   return slider_set(&(((hlsl_options*)arg)->bloom_level10_weight), 0.01f, "%1.2f", string, newval);
2809}
2810
2811//============================================================
2812//  init_slider_list
2813//============================================================
2814
2815shaders::slider_desc shaders::s_sliders[] =
2816{
2817   { "Shadow Mask Darkness",                0,     0,   100, 1, slider_shadow_mask_alpha },
2818   { "Shadow Mask X Count",                 1,   320,  1024, 1, slider_shadow_mask_x_count },
2819   { "Shadow Mask Y Count",                 1,   240,  1024, 1, slider_shadow_mask_y_count },
2820   { "Shadow Mask Pixel Count X",           1,     6,    64, 1, slider_shadow_mask_usize },
2821   { "Shadow Mask Pixel Count Y",           1,     7,    64, 1, slider_shadow_mask_vsize },
2822   { "Shadow Mask Pixel Count Y",           1,     7,    64, 1, slider_shadow_mask_vsize },
2823   { "Shadow Mask Pixel Count Y",           1,     7,    64, 1, slider_shadow_mask_vsize },
2824   { "Shadow Mask Pixel Count Y",           1,     7,    64, 1, slider_shadow_mask_vsize },
2825   { "Screen Curvature",                    0,     3,   100, 1, slider_curvature },
2826   { "Image Pincushion",                    0,     3,   100, 1, slider_pincushion },
2827   { "Scanline Darkness",                   0,   100,   100, 1, slider_scanline_alpha },
2828   { "Scanline Screen Height",              1,    20,    80, 1, slider_scanline_scale },
2829   { "Scanline Indiv. Height",              1,    20,    80, 1, slider_scanline_height },
2830   { "Scanline Brightness",                 0,    20,    40, 1, slider_scanline_bright_scale },
2831   { "Scanline Brightness Overdrive",       0,     0,    20, 1, slider_scanline_bright_offset },
2832   { "Scanline Jitter",                     0,     0,    40, 1, slider_scanline_offset },
2833   { "Defocus X",                           0,     0,    64, 1, slider_defocus_x },
2834   { "Defocus Y",                           0,     0,    64, 1, slider_defocus_y },
2835   { "Red Position Offset X",           -1500,     3,  1500, 1, slider_red_converge_x },
2836   { "Red Position Offset Y",           -1500,     0,  1500, 1, slider_red_converge_y },
2837   { "Green Position Offset X",         -1500,     0,  1500, 1, slider_green_converge_x },
2838   { "Green Position Offset Y",         -1500,     3,  1500, 1, slider_green_converge_y },
2839   { "Blue Position Offset X",          -1500,     3,  1500, 1, slider_blue_converge_x },
2840   { "Blue Position Offset Y",          -1500,     3,  1500, 1, slider_blue_converge_y },
2841   { "Red Convergence X",               -1500,     0,  1500, 1, slider_red_radial_converge_x },
2842   { "Red Convergence Y",               -1500,     0,  1500, 1, slider_red_radial_converge_y },
2843   { "Green Convergence X",             -1500,     0,  1500, 1, slider_green_radial_converge_x },
2844   { "Green Convergence Y",             -1500,     0,  1500, 1, slider_green_radial_converge_y },
2845   { "Blue Convergence X",              -1500,     0,  1500, 1, slider_blue_radial_converge_x },
2846   { "Blue Convergence Y",              -1500,     0,  1500, 1, slider_blue_radial_converge_y },
2847   { "Red Output from Red Input",        -400,     0,   400, 5, slider_red_from_r },
2848   { "Red Output from Green Input",      -400,     0,   400, 5, slider_red_from_g },
2849   { "Red Output from Blue Input",       -400,     0,   400, 5, slider_red_from_b },
2850   { "Green Output from Red Input",      -400,     0,   400, 5, slider_green_from_r },
2851   { "Green Output from Green Input",    -400,     0,   400, 5, slider_green_from_g },
2852   { "Green Output from Blue Input",     -400,     0,   400, 5, slider_green_from_b },
2853   { "Blue Output from Red Input",       -400,     0,   400, 5, slider_blue_from_r },
2854   { "Blue Output from Green Input",     -400,     0,   400, 5, slider_blue_from_g },
2855   { "Blue Output from Blue Input",      -400,     0,   400, 5, slider_blue_from_b },
2856   { "Saturation",                          0,   140,   400, 1, slider_saturation },
2857   { "Red DC Offset",                    -100,     0,   100, 1, slider_red_offset },
2858   { "Green DC Offset",                  -100,     0,   100, 1, slider_green_offset },
2859   { "Blue DC Offset",                   -100,     0,   100, 1, slider_blue_offset },
2860   { "Red Scale",                        -200,    95,   200, 1, slider_red_scale },
2861   { "Green Scale",                      -200,    95,   200, 1, slider_green_scale },
2862   { "Blue Scale",                       -200,    95,   200, 1, slider_blue_scale },
2863   { "Red Gamma",                         -80,    16,    80, 1, slider_red_power },
2864   { "Green Gamma",                       -80,    16,    80, 1, slider_green_power },
2865   { "Blue Gamma",                        -80,    16,    80, 1, slider_blue_power },
2866   { "Red Floor",                           0,     5,   100, 1, slider_red_floor },
2867   { "Green Floor",                         0,     5,   100, 1, slider_green_floor },
2868   { "Blue Floor",                          0,     5,   100, 1, slider_blue_floor },
2869   { "Red Phosphor Life",                   0,    40,   100, 1, slider_red_phosphor_life },
2870   { "Green Phosphor Life",                 0,    40,   100, 1, slider_green_phosphor_life },
2871   { "Blue Phosphor Life",                  0,    40,   100, 1, slider_blue_phosphor_life },
2872   { "Vector Length Attenuation",           0,    80,   100, 1, slider_vector_attenuation },
2873   { "Vector Attenuation Length Limit",     1,   500,  1000, 1, slider_vector_length_max },
2874   { "Vector Bloom Scale",                  0,   300,  1000, 5, slider_vector_bloom_scale },
2875   { "Raster Bloom Scale",                  0,   225,  1000, 5, slider_raster_bloom_scale },
2876   { "Bloom Level 0 Scale",                 0,   100,   100, 1, slider_bloom_lvl0_scale },
2877   { "Bloom Level 1 Scale",                 0,    21,   100, 1, slider_bloom_lvl1_scale },
2878   { "Bloom Level 2 Scale",                 0,    19,   100, 1, slider_bloom_lvl2_scale },
2879   { "Bloom Level 3 Scale",                 0,    17,   100, 1, slider_bloom_lvl3_scale },
2880   { "Bloom Level 4 Scale",                 0,    15,   100, 1, slider_bloom_lvl4_scale },
2881   { "Bloom Level 5 Scale",                 0,    14,   100, 1, slider_bloom_lvl5_scale },
2882   { "Bloom Level 6 Scale",                 0,    13,   100, 1, slider_bloom_lvl6_scale },
2883   { "Bloom Level 7 Scale",                 0,    12,   100, 1, slider_bloom_lvl7_scale },
2884   { "Bloom Level 8 Scale",                 0,    11,   100, 1, slider_bloom_lvl8_scale },
2885   { "Bloom Level 9 Scale",                 0,    10,   100, 1, slider_bloom_lvl9_scale },
2886   { "Bloom Level 10 Scale",                0,     9,   100, 1, slider_bloom_lvl10_scale },
2887   { NULL, 0, 0, 0, 0, NULL },
2888};
2889
2890slider_state *shaders::init_slider_list()
2891{
2892   if (!master_enable || !d3dintf->post_fx_available)
2893   {
2894      g_slider_list = NULL;
2895      return NULL;
2896   }
2897
2898   slider_state *listhead = NULL;
2899   slider_state **tailptr = &listhead;
2900
2901   for (int index = 0; s_sliders[index].name != NULL; index++)
2902   {
2903      slider_desc *slider = &s_sliders[index];
2904      *tailptr = slider_alloc(*machine, slider->name, slider->minval, slider->defval, slider->maxval, slider->step, slider->adjustor, (void*)options);
2905      tailptr = &(*tailptr)->next;
2906   }
2907
2908   return listhead;
2909}
2910
2911//============================================================
2912//  uniform functions
2913//============================================================
2914
2915uniform::uniform(effect *shader, const char *name, uniform_type type, int id)
2916{
2917   m_shader = shader;
2918   m_type = type;
2919   m_next = NULL;
2920   m_handle = m_shader->get_parameter(NULL, name);
2921   m_ival = 0;
2922   memset(m_vec, 0, sizeof(float) * 4);
2923   m_mval = NULL;
2924   m_texture = NULL;
2925   m_id = id;
2926
2927   switch (type)
2928   {
2929   case UT_INT:
2930   case UT_FLOAT:
2931   case UT_MATRIX:
2932   case UT_SAMPLER:
2933      m_count = 1;
2934      break;
2935   case UT_VEC2:
2936      m_count = 2;
2937      break;
2938   case UT_VEC3:
2939      m_count = 3;
2940      break;
2941   case UT_VEC4:
2942      m_count = 4;
2943      break;
2944   default:
2945      m_count = 1;
2946      break;
2947   }
2948}
2949
2950void uniform::set_next(uniform *next)
2951{
2952   m_next = next;
2953}
2954
2955void uniform::update()
2956{
2957   if (m_id >= CU_COUNT)
2958   {
2959      return;
2960   }
2961
2962   shaders *shadersys = m_shader->m_shaders;
2963   hlsl_options *options = shadersys->options;
2964   renderer *d3d = shadersys->d3d;
2965
2966
2967   switch(m_id)
2968   {
2969      case CU_SCREEN_DIMS:
2970      {
2971         vec2f screendims = d3d->get_dims();
2972         m_shader->set_vector("ScreenDims", 2, &screendims.c.x);
2973         break;
2974      }
2975      case CU_SOURCE_DIMS:
2976      {
2977         vec2f& sourcedims = shadersys->curr_texture->get_rawdims();
2978         m_shader->set_vector("SourceDims", 2, &sourcedims.c.x);
2979         break;
2980      }
2981      case CU_SOURCE_RECT:
2982      {
2983         vec2f delta = shadersys->curr_texture->get_uvstop() - shadersys->curr_texture->get_uvstart();
2984         m_shader->set_vector("SourceRect", 2, &delta.c.x);
2985         break;
2986      }
2987
2988      case CU_NTSC_CCFREQ:
2989         m_shader->set_float("CCValue", options->yiq_cc);
2990         break;
2991      case CU_NTSC_A:
2992         m_shader->set_float("AValue", options->yiq_a);
2993         break;
2994      case CU_NTSC_B:
2995         m_shader->set_float("BValue", options->yiq_b);
2996         break;
2997      case CU_NTSC_O:
2998         m_shader->set_float("OValue", options->yiq_o);
2999         break;
3000      case CU_NTSC_P:
3001         m_shader->set_float("PValue", options->yiq_p);
3002         break;
3003      case CU_NTSC_NOTCH:
3004         m_shader->set_float("NotchHalfWidth", options->yiq_n);
3005         break;
3006      case CU_NTSC_YFREQ:
3007         m_shader->set_float("YFreqResponse", options->yiq_y);
3008         break;
3009      case CU_NTSC_IFREQ:
3010         m_shader->set_float("IFreqResponse", options->yiq_i);
3011         break;
3012      case CU_NTSC_QFREQ:
3013         m_shader->set_float("QFreqResponse", options->yiq_q);
3014         break;
3015      case CU_NTSC_HTIME:
3016         m_shader->set_float("ScanTime", options->yiq_scan_time);
3017         break;
3018      case CU_NTSC_ENABLE:
3019         m_shader->set_float("YIQEnable", options->yiq_enable ? 1.0f : 0.0f);
3020         break;
3021
3022      case CU_COLOR_RED_RATIOS:
3023         m_shader->set_vector("RedRatios", 3, options->red_ratio);
3024         break;
3025      case CU_COLOR_GRN_RATIOS:
3026         m_shader->set_vector("GrnRatios", 3, options->grn_ratio);
3027         break;
3028      case CU_COLOR_BLU_RATIOS:
3029         m_shader->set_vector("BluRatios", 3, options->blu_ratio);
3030         break;
3031      case CU_COLOR_OFFSET:
3032         m_shader->set_vector("Offset", 3, options->offset);
3033         break;
3034      case CU_COLOR_SCALE:
3035         m_shader->set_vector("Scale", 3, options->scale);
3036         break;
3037      case CU_COLOR_SATURATION:
3038         m_shader->set_float("Saturation", options->saturation);
3039         break;
3040
3041      case CU_CONVERGE_LINEAR_X:
3042         m_shader->set_vector("ConvergeX", 3, options->converge_x);
3043         break;
3044      case CU_CONVERGE_LINEAR_Y:
3045         m_shader->set_vector("ConvergeY", 3, options->converge_y);
3046         break;
3047      case CU_CONVERGE_RADIAL_X:
3048         m_shader->set_vector("RadialConvergeX", 3, options->radial_converge_x);
3049         break;
3050      case CU_CONVERGE_RADIAL_Y:
3051         m_shader->set_vector("RadialConvergeY", 3, options->radial_converge_y);
3052         break;
3053
3054      case CU_FOCUS_SIZE:
3055         m_shader->set_vector("Defocus", 2, &options->defocus[0]);
3056         break;
3057
3058      case CU_PHOSPHOR_LIFE:
3059         m_shader->set_vector("Phosphor", 3, options->phosphor);
3060         break;
3061      case CU_PHOSPHOR_IGNORE:
3062         m_shader->set_float("Passthrough", shadersys->phosphor_passthrough ? 1.0f : 0.0f);
3063         break;
3064
3065      case CU_POST_PINCUSHION:
3066         m_shader->set_float("PincushionAmount", options->pincushion);
3067         break;
3068      case CU_POST_CURVATURE:
3069         m_shader->set_float("CurvatureAmount", options->curvature);
3070         break;
3071      case CU_POST_SHADOW_ALPHA:
3072         m_shader->set_float("ShadowAlpha", shadersys->shadow_texture == NULL ? 0.0f : options->shadow_mask_alpha);
3073         break;
3074      case CU_POST_SHADOW_COUNT:
3075      {
3076         float shadowcount[2] = { options->shadow_mask_count_x, options->shadow_mask_count_y };
3077         m_shader->set_vector("ShadowCount", 2, shadowcount);
3078         break;
3079      }
3080      case CU_POST_SHADOW_UV:
3081      {
3082         float shadowuv[2] = { options->shadow_mask_u_size, options->shadow_mask_v_size };
3083         m_shader->set_vector("ShadowUV", 2, shadowuv);
3084         break;
3085      }
3086      case CU_POST_SHADOW_DIMS:
3087      {
3088         vec2f shadow_dims;
3089
3090         if (shadersys->shadow_texture)
3091         {
3092            shadow_dims = shadersys->shadow_texture->get_rawdims();
3093         }
3094         else
3095         {
3096            shadow_dims.c.x = 1.0f;
3097            shadow_dims.c.y = 1.0f;
3098         }
3099
3100         m_shader->set_vector("ShadowDims", 2, &shadow_dims.c.x);
3101         break;
3102      }
3103      case CU_POST_SCANLINE_ALPHA:
3104         m_shader->set_float("ScanlineAlpha", options->scanline_alpha);
3105         break;
3106      case CU_POST_SCANLINE_SCALE:
3107         m_shader->set_float("ScanlineScale", options->scanline_scale);
3108         break;
3109      case CU_POST_SCANLINE_HEIGHT:
3110         m_shader->set_float("ScanlineHeight", options->scanline_height);
3111         break;
3112      case CU_POST_SCANLINE_BRIGHT_SCALE:
3113         m_shader->set_float("ScanlineBrightScale", options->scanline_bright_scale);
3114         break;
3115      case CU_POST_SCANLINE_BRIGHT_OFFSET:
3116         m_shader->set_float("ScanlineBrightOffset", options->scanline_bright_offset);
3117         break;
3118      case CU_POST_POWER:
3119         m_shader->set_vector("Power", 3, options->power);
3120         break;
3121      case CU_POST_FLOOR:
3122         m_shader->set_vector("Floor", 3, options->floor);
3123         break;
3124
3125      case CU_BLOOM_RESCALE:
3126         m_shader->set_float("BloomRescale", options->raster_bloom_scale);
3127         break;
3128      case CU_BLOOM_LVL0123_WEIGHTS:
3129      {
3130         float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight, options->bloom_level2_weight, options->bloom_level3_weight };
3131         m_shader->set_vector("Level0123Weight", 4, weight0123);
3132         break;
3133      }
3134      case CU_BLOOM_LVL4567_WEIGHTS:
3135      {
3136         float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight, options->bloom_level6_weight, options->bloom_level7_weight };
3137         m_shader->set_vector("Level4567Weight", 4, weight4567);
3138         break;
3139      }
3140      case CU_BLOOM_LVL89A_WEIGHTS:
3141      {
3142         float weight89A[3]  = { options->bloom_level8_weight, options->bloom_level9_weight, options->bloom_level10_weight };
3143         m_shader->set_vector("Level89AWeight", 3, weight89A);
3144         break;
3145      }
3146   }
3147}
3148
3149void uniform::set(float x, float y, float z, float w)
3150{
3151   m_vec[0] = x;
3152   m_vec[1] = y;
3153   m_vec[2] = z;
3154   m_vec[3] = w;
3155}
3156
3157void uniform::set(float x, float y, float z)
3158{
3159   m_vec[0] = x;
3160   m_vec[1] = y;
3161   m_vec[2] = z;
3162}
3163
3164void uniform::set(float x, float y)
3165{
3166   m_vec[0] = x;
3167   m_vec[1] = y;
3168}
3169
3170void uniform::set(float x)
3171{
3172   m_vec[0] = x;
3173}
3174
3175void uniform::set(int x)
3176{
3177   m_ival = x;
3178}
3179
3180void uniform::set(matrix *mat)
3181{
3182   m_mval = mat;
3183}
3184
3185void uniform::set(texture *tex)
3186{
3187   m_texture = tex;
3188}
3189
3190void uniform::upload()
3191{
3192   switch(m_type)
3193   {
3194      case UT_INT:
3195         m_shader->set_int(m_handle, m_ival);
3196         break;
3197      case UT_FLOAT:
3198         m_shader->set_float(m_handle, m_vec[0]);
3199         break;
3200      case UT_VEC2:
3201      case UT_VEC3:
3202      case UT_VEC4:
3203         m_shader->set_vector(m_handle, m_count, m_vec);
3204         break;
3205      case UT_MATRIX:
3206         m_shader->set_matrix(m_handle, m_mval);
3207         break;
3208      case UT_SAMPLER:
3209         m_shader->set_texture(m_handle, m_texture);
3210         break;
3211   }
3212}
3213
3214//============================================================
3215//  effect functions
3216//============================================================
3217
3218effect::effect(shaders *shadersys, device *dev, const char *name, const char *path)
3219{
3220   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
3221   LPD3DXBUFFER buffer_errors = NULL;
3222
3223   m_shaders = shadersys;
3224   m_uniform_head = NULL;
3225   m_uniform_tail = NULL;
3226   m_effect = NULL;
3227   m_valid = false;
3228
3229   char name_cstr[1024];
3230   sprintf(name_cstr, "%s\\%s", path, name);
3231   TCHAR *effect_name = tstring_from_utf8(name_cstr);
3232
3233   HRESULT hr = (*g_load_effect)(device, effect_name, NULL, NULL, 0, NULL, &m_effect, &buffer_errors);
3234   if(FAILED(hr))
3235   {
3236      if(buffer_errors != NULL)
3237      {
3238         LPVOID compile_errors = buffer_errors->GetBufferPointer();
3239         printf("Unable to compile shader: %s\n", (const char*)compile_errors); fflush(stdout);
3240      }
3241      else
3242      {
3243         printf("Shader %s is missing, corrupt or cannot be compiled.\n", (const char*)name); fflush(stdout);
3244      }
3245   }
3246   else
3247   {
3248      m_valid = true;
3249   }
3250
3251   osd_free(effect_name);
3252}
3253
3254effect::~effect()
3255{
3256   m_effect->Release();
3257   m_effect = NULL;
3258   uniform *curr = m_uniform_head;
3259   while (curr != NULL)
3260   {
3261      uniform *next = curr->get_next();
3262      delete curr;
3263      curr = next;
3264   }
3265   m_uniform_head = NULL;
3266   m_uniform_tail = NULL;
3267}
3268
3269void effect::add_uniform(const char *name, uniform::uniform_type type, int id)
3270{
3271   uniform *newuniform = new uniform(this, name, type, id);
3272   if (newuniform == NULL)
3273   {
3274      return;
3275   }
3276
3277   if (m_uniform_head == NULL)
3278   {
3279      m_uniform_head = newuniform;
3280   }
3281   if (m_uniform_tail != NULL)
3282   {
3283      m_uniform_tail->set_next(newuniform);
3284   }
3285   m_uniform_tail = newuniform;
3286}
3287
3288void effect::update_uniforms()
3289{
3290   uniform *curr = m_uniform_head;
3291   while(curr != NULL)
3292   {
3293      curr->update();
3294      curr = curr->get_next();
3295   }
3296}
3297
3298void effect::begin(UINT *passes, DWORD flags)
3299{
3300   m_effect->Begin(passes, flags);
3301}
3302
3303void effect::end()
3304{
3305   m_effect->End();
3306}
3307
3308void effect::begin_pass(UINT pass)
3309{
3310   m_effect->BeginPass(pass);
3311}
3312
3313void effect::end_pass()
3314{
3315   m_effect->EndPass();
3316}
3317
3318void effect::set_technique(const char *name)
3319{
3320   m_effect->SetTechnique(name);
3321}
3322
3323void effect::set_vector(D3DXHANDLE param, int count, float *vector)
3324{
3325   static D3DXVECTOR4 out_vector;
3326   if (count > 0)
3327      out_vector.x = vector[0];
3328   if (count > 1)
3329      out_vector.y = vector[1];
3330   if (count > 2)
3331      out_vector.z = vector[2];
3332   if (count > 3)
3333      out_vector.w = vector[3];
3334   m_effect->SetVector(param, &out_vector);
3335}
3336
3337void effect::set_float(D3DXHANDLE param, float value)
3338{
3339   m_effect->SetFloat(param, value);
3340}
3341
3342void effect::set_int(D3DXHANDLE param, int value)
3343{
3344   m_effect->SetInt(param, value);
3345}
3346
3347void effect::set_matrix(D3DXHANDLE param, matrix *matrix)
3348{
3349   m_effect->SetMatrix(param, (D3DXMATRIX*)matrix);
3350}
3351
3352void effect::set_texture(D3DXHANDLE param, texture *tex)
3353{
3354   m_effect->SetTexture(param, (IDirect3DTexture9*)tex);
3355}
3356
3357D3DXHANDLE effect::get_parameter(D3DXHANDLE param, const char *name)
3358{
3359   return m_effect->GetParameterByName(param, name);
3360}
3361
3362ULONG effect::release()
3363{
3364   return m_effect->Release();
3365}
3366
3367};
3368
3369//============================================================
3370//  get_slider_list
3371//============================================================
3372
3373void *windows_osd_interface::get_slider_list()
3374{
3375   return (void*)g_slider_list;
3376}
3377
3378
3379
3380// NOTE: The function below is taken directly from src/emu/video.c and should likely be moved into a global helper function.
3381//-------------------------------------------------
3382//  open_next - open the next non-existing file of
3383//  type filetype according to our numbering
3384//  scheme
3385//-------------------------------------------------
3386
3387static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *templ, const char *extension, int idx)
3388{
3389   UINT32 origflags = file.openflags();
3390
3391   // handle defaults
3392   const char *snapname = templ ? templ : d3d->window().machine().options().snap_name();
3393
3394   if (snapname == NULL || snapname[0] == 0)
3395      snapname = "%g/%i";
3396   astring snapstr(snapname);
3397
3398   // strip any extension in the provided name
3399   int index = snapstr.rchr(0, '.');
3400   if (index != -1)
3401      snapstr.substr(0, index);
3402
3403   // handle %d in the template (for image devices)
3404   astring snapdev("%d_");
3405   int pos = snapstr.find(0, snapdev);
3406
3407   if (pos != -1)
3408   {
3409      // if more %d are found, revert to default and ignore them all
3410      if (snapstr.find(pos + 3, snapdev) != -1)
3411         snapstr.cpy("%g/%i");
3412      // else if there is a single %d, try to create the correct snapname
3413      else
3414      {
3415         int name_found = 0;
3416
3417         // find length of the device name
3418         int end1 = snapstr.find(pos + 3, "/");
3419         int end2 = snapstr.find(pos + 3, "%");
3420         int end = -1;
3421
3422         if ((end1 != -1) && (end2 != -1))
3423            end = MIN(end1, end2);
3424         else if (end1 != -1)
3425            end = end1;
3426         else if (end2 != -1)
3427            end = end2;
3428         else
3429            end = snapstr.len();
3430
3431         if (end - pos < 3)
3432            fatalerror("Something very wrong is going on!!!\n");
3433
3434         // copy the device name to an astring
3435         astring snapdevname;
3436         snapdevname.cpysubstr(snapstr, pos + 3, end - pos - 3);
3437
3438         // verify that there is such a device for this system
3439         image_interface_iterator iter(d3d->window().machine().root_device());
3440         for (device_image_interface *image = iter.first(); image != NULL; iter.next())
3441         {
3442            // get the device name
3443            astring tempdevname(image->brief_instance_name());
3444
3445            if (snapdevname.cmp(tempdevname) == 0)
3446            {
3447               // verify that such a device has an image mounted
3448               if (image->basename() != NULL)
3449               {
3450                  astring filename(image->basename());
3451
3452                  // strip extension
3453                  filename.substr(0, filename.rchr(0, '.'));
3454
3455                  // setup snapname and remove the %d_
3456                  snapstr.replace(0, snapdevname, filename);
3457                  snapstr.del(pos, 3);
3458
3459                  name_found = 1;
3460               }
3461            }
3462         }
3463
3464         // or fallback to default
3465         if (name_found == 0)
3466            snapstr.cpy("%g/%i");
3467      }
3468   }
3469
3470   // add our own index
3471   // add our own extension
3472   snapstr.cat(".").cat(extension);
3473
3474   // substitute path and gamename up front
3475   snapstr.replace(0, "/", PATH_SEPARATOR);
3476   snapstr.replace(0, "%g", d3d->window().machine().basename());
3477
3478   // determine if the template has an index; if not, we always use the same name
3479   astring fname;
3480   if (snapstr.find(0, "%i") == -1)
3481      fname.cpy(snapstr);
3482
3483   // otherwise, we scan for the next available filename
3484   else
3485   {
3486      // try until we succeed
3487      astring seqtext;
3488      file.set_openflags(OPEN_FLAG_READ);
3489      for (int seq = 0; ; seq++)
3490      {
3491         // build up the filename
3492         fname.cpy(snapstr).replace(0, "%i", seqtext.format("%04d_%d", seq, idx).cstr());
3493
3494         // try to open the file; stop when we fail
3495         file_error filerr = file.open(fname);
3496         if (filerr != FILERR_NONE)
3497            break;
3498      }
3499   }
3500
3501   // create the final file
3502   file.set_openflags(origflags);
3503   return file.open(fname);
3504}
trunk/src/osd/modules/render/d3d/d3dhlsl.h
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawd3d.c - Win32 Direct3D HLSL-specific header
6//
7//============================================================
8
9#ifndef __WIN_D3DHLSL__
10#define __WIN_D3DHLSL__
11
12#include "aviio.h"
13
14//============================================================
15//  CONSTANTS
16//============================================================
17
18
19//============================================================
20//  TYPE DEFINITIONS
21//============================================================
22
23namespace d3d
24{
25class effect;
26class shaders;
27
28class uniform
29{
30public:
31   typedef enum
32   {
33      UT_VEC4,
34      UT_VEC3,
35      UT_VEC2,
36      UT_FLOAT,
37      UT_INT,
38      UT_MATRIX,
39      UT_SAMPLER,
40   } uniform_type;
41
42   enum
43   {
44      CU_SCREEN_DIMS = 0,
45      CU_SOURCE_DIMS,
46      CU_SOURCE_RECT,
47
48      CU_NTSC_CCFREQ,
49      CU_NTSC_A,
50      CU_NTSC_B,
51      CU_NTSC_O,
52      CU_NTSC_P,
53      CU_NTSC_NOTCH,
54      CU_NTSC_YFREQ,
55      CU_NTSC_IFREQ,
56      CU_NTSC_QFREQ,
57      CU_NTSC_HTIME,
58      CU_NTSC_ENABLE,
59
60      CU_COLOR_RED_RATIOS,
61      CU_COLOR_GRN_RATIOS,
62      CU_COLOR_BLU_RATIOS,
63      CU_COLOR_OFFSET,
64      CU_COLOR_SCALE,
65      CU_COLOR_SATURATION,
66
67      CU_CONVERGE_LINEAR_X,
68      CU_CONVERGE_LINEAR_Y,
69      CU_CONVERGE_RADIAL_X,
70      CU_CONVERGE_RADIAL_Y,
71
72      CU_FOCUS_SIZE,
73
74      CU_PHOSPHOR_LIFE,
75      CU_PHOSPHOR_IGNORE,
76
77      CU_POST_PINCUSHION,
78      CU_POST_CURVATURE,
79      CU_POST_SHADOW_ALPHA,
80      CU_POST_SHADOW_COUNT,
81      CU_POST_SHADOW_UV,
82      CU_POST_SHADOW_DIMS,
83      CU_POST_SCANLINE_ALPHA,
84      CU_POST_SCANLINE_SCALE,
85      CU_POST_SCANLINE_HEIGHT,
86      CU_POST_SCANLINE_BRIGHT_SCALE,
87      CU_POST_SCANLINE_BRIGHT_OFFSET,
88      CU_POST_POWER,
89      CU_POST_FLOOR,
90
91      CU_BLOOM_RESCALE,
92      CU_BLOOM_LVL0123_WEIGHTS,
93      CU_BLOOM_LVL4567_WEIGHTS,
94      CU_BLOOM_LVL89A_WEIGHTS,
95
96      CU_COUNT,
97   };
98
99   uniform(effect *shader, const char *name, uniform_type type, int id);
100
101   void        set_next(uniform *next);
102   uniform *   get_next() { return m_next; }
103
104   void        set(float x, float y, float z, float w);
105   void        set(float x, float y, float z);
106   void        set(float x, float y);
107   void        set(float x);
108   void        set(int x);
109   void        set(matrix *mat);
110   void        set(texture *tex);
111
112   void        upload();
113   void        update();
114
115protected:
116   uniform     *m_next;
117
118   float       m_vec[4];
119   int         m_ival;
120   matrix      *m_mval;
121   texture     *m_texture;
122   int         m_count;
123   uniform_type    m_type;
124   int         m_id;
125
126   effect      *m_shader;
127   D3DXHANDLE  m_handle;
128};
129
130class effect
131{
132   friend class uniform;
133
134public:
135   effect(shaders *shadersys, device *dev, const char *name, const char *path);
136   ~effect();
137
138   void        begin(UINT *passes, DWORD flags);
139   void        begin_pass(UINT pass);
140
141   void        end();
142   void        end_pass();
143
144   void        set_technique(const char *name);
145
146   void        set_vector(D3DXHANDLE param, int count, float *vector);
147   void        set_float(D3DXHANDLE param, float value);
148   void        set_int(D3DXHANDLE param, int value);
149   void        set_matrix(D3DXHANDLE param, matrix *matrix);
150   void        set_texture(D3DXHANDLE param, texture *tex);
151
152   void        add_uniform(const char *name, uniform::uniform_type type, int id);
153   void        update_uniforms();
154
155   D3DXHANDLE  get_parameter(D3DXHANDLE param, const char *name);
156
157   ULONG       release();
158
159   shaders*    get_shaders() { return m_shaders; }
160
161   bool        is_valid() { return m_valid; }
162
163private:
164   uniform     *m_uniform_head;
165   uniform     *m_uniform_tail;
166   ID3DXEffect *m_effect;
167   shaders     *m_shaders;
168
169   bool        m_valid;
170};
171
172class render_target;
173class cache_target;
174class renderer;
175
176/* hlsl_options is the information about runtime-mutable Direct3D HLSL options */
177/* in the future this will be moved into an OSD/emu shared buffer */
178struct hlsl_options
179{
180   bool                    params_dirty;
181   float                   shadow_mask_alpha;
182   char                    shadow_mask_texture[1024];
183   int                     shadow_mask_count_x;
184   int                     shadow_mask_count_y;
185   float                   shadow_mask_u_size;
186   float                   shadow_mask_v_size;
187   float                   curvature;
188   float                   pincushion;
189   float                   scanline_alpha;
190   float                   scanline_scale;
191   float                   scanline_height;
192   float                   scanline_bright_scale;
193   float                   scanline_bright_offset;
194   float                   scanline_offset;
195   float                   defocus[2];
196   float                   converge_x[3];
197   float                   converge_y[3];
198   float                   radial_converge_x[3];
199   float                   radial_converge_y[3];
200   float                   red_ratio[3];
201   float                   grn_ratio[3];
202   float                   blu_ratio[3];
203   float                   offset[3];
204   float                   scale[3];
205   float                   power[3];
206   float                   floor[3];
207   float                   phosphor[3];
208   float                   saturation;
209
210   // NTSC
211   bool                    yiq_enable;
212   float                   yiq_cc;
213   float                   yiq_a;
214   float                   yiq_b;
215   float                   yiq_o;
216   float                   yiq_p;
217   float                   yiq_n;
218   float                   yiq_y;
219   float                   yiq_i;
220   float                   yiq_q;
221   float                   yiq_scan_time;
222   int                     yiq_phase_count;
223
224   // Vectors
225   float                   vector_length_scale;
226   float                   vector_length_ratio;
227
228   // Bloom
229   float                   vector_bloom_scale;
230   float                   raster_bloom_scale;
231   float                   bloom_level0_weight;
232   float                   bloom_level1_weight;
233   float                   bloom_level2_weight;
234   float                   bloom_level3_weight;
235   float                   bloom_level4_weight;
236   float                   bloom_level5_weight;
237   float                   bloom_level6_weight;
238   float                   bloom_level7_weight;
239   float                   bloom_level8_weight;
240   float                   bloom_level9_weight;
241   float                   bloom_level10_weight;
242};
243
244class shaders
245{
246   friend class effect;
247   friend class uniform;
248
249public:
250   // construction/destruction
251   shaders();
252   ~shaders();
253
254   void init(base *d3dintf, running_machine *machine, d3d::renderer *renderer);
255
256   bool enabled() { return master_enable; }
257   void toggle();
258
259   bool vector_enabled() { return master_enable && vector_enable; }
260   render_target* get_vector_target();
261   void create_vector_target(render_primitive *prim);
262
263   void begin_frame();
264   void end_frame();
265
266   void begin_draw();
267   void end_draw();
268
269   void init_effect_info(poly_info *poly);
270   void render_quad(poly_info *poly, int vertnum);
271
272   bool register_texture(texture_info *texture);
273   bool register_prescaled_texture(texture_info *texture);
274   bool add_render_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale);
275   bool add_cache_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index);
276
277   void window_save();
278   void window_record();
279   bool recording() { return avi_output_file != NULL; }
280
281   void avi_update_snap(surface *surface);
282   void render_snapshot(surface *surface);
283   void record_texture();
284   void init_fsfx_quad(void *vertbuf);
285
286   void                    set_texture(texture_info *texture);
287   render_target *         find_render_target(texture_info *info);
288   void                    remove_render_target(texture_info *texture);
289   void                    remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
290   void                    remove_render_target(render_target *rt);
291
292   int create_resources(bool reset);
293   void delete_resources(bool reset);
294
295   // slider-related functions
296   slider_state *init_slider_list();
297
298   struct slider_desc
299   {
300      const char *        name;
301      int                 minval;
302      int                 defval;
303      int                 maxval;
304      int                 step;
305      INT32 (*adjustor)(running_machine &, void *, astring *, INT32);
306   };
307
308private:
309   void                    blit(surface *dst, texture *src, surface *new_dst,
310                           D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count,
311                           int dstw, int dsth);
312   void                    blit(surface *dst, texture *src, surface *new_dst,
313                           D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
314   void                    enumerate_screens();
315
316   void                    end_avi_recording();
317   void                    begin_avi_recording(const char *name);
318
319   bool                    register_texture(texture_info *texture, int width, int height, int xscale, int yscale);
320
321   render_target*          find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
322   cache_target *          find_cache_target(UINT32 screen_index, int width, int height);
323   void                    remove_cache_target(cache_target *cache);
324
325   // Shader passes
326   void                    ntsc_pass(render_target *rt, vec2f &texsize, vec2f &delta);
327   void                    color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims);
328   void                    prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims);
329   void                    deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims);
330   void                    defocus_pass(render_target *rt, vec2f &texsize);
331   void                    phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable);
332   void                    screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum);
333   void                    avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum);
334   void                    raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum);
335
336   base *                  d3dintf;                    // D3D interface
337
338   running_machine *       machine;
339   d3d::renderer *         d3d;                        // D3D renderer
340
341   bool                    master_enable;              // overall enable flag
342   bool                    vector_enable;              // vector post-processing enable flag
343   bool                    paused;                     // whether or not rendering is currently paused
344   int                     num_screens;                // number of emulated physical screens
345   int                     curr_screen;                // current screen for render target operations
346   int                     curr_frame;                 // current frame (0/1) of a screen for render target operations
347   int                     lastidx;                    // index of the last-encountered target
348   bool                    write_ini;                  // enable external ini saving
349   bool                    read_ini;                   // enable external ini loading
350   int                     prescale_force_x;           // prescale force x
351   int                     prescale_force_y;           // prescale force y
352   int                     prescale_size_x;            // prescale size x
353   int                     prescale_size_y;            // prescale size y
354   int                     preset;                     // preset, if relevant
355   bitmap_argb32           shadow_bitmap;              // shadow mask bitmap for post-processing shader
356   texture_info *          shadow_texture;             // shadow mask texture for post-processing shader
357   hlsl_options *          options;                    // current uniform state
358   D3DPRIMITIVETYPE        vecbuf_type;
359   UINT32                  vecbuf_index;
360   UINT32                  vecbuf_count;
361
362   avi_file *              avi_output_file;            // AVI file
363   bitmap_rgb32            avi_snap;                   // AVI snapshot
364   int                     avi_frame;                  // AVI frame
365   attotime                avi_frame_period;           // AVI frame period
366   attotime                avi_next_frame_time;        // AVI next frame time
367   surface *               avi_copy_surface;           // AVI destination surface in system memory
368   texture *               avi_copy_texture;           // AVI destination texture in system memory
369   surface *               avi_final_target;           // AVI upscaled surface
370   texture *               avi_final_texture;          // AVI upscaled texture
371
372   surface *               black_surface;              // black dummy surface
373   texture *               black_texture;              // black dummy texture
374
375   bool                    render_snap;                // whether or not to take HLSL post-render snapshot
376   bool                    snap_rendered;              // whether we just rendered our HLSL post-render shot or not
377   surface *               snap_copy_target;           // snapshot destination surface in system memory
378   texture *               snap_copy_texture;          // snapshot destination surface in system memory
379   surface *               snap_target;                // snapshot upscaled surface
380   texture *               snap_texture;               // snapshot upscaled texture
381   int                     snap_width;                 // snapshot width
382   int                     snap_height;                // snapshot height
383   bool                    lines_pending;              // whether or not we have lines to flush on the next quad
384
385   bool                    initialized;                // whether or not we're initialize
386
387   // HLSL effects
388   surface *               backbuffer;                 // pointer to our device's backbuffer
389   effect *                curr_effect;                // pointer to the currently active effect object
390   effect *                default_effect;             // pointer to the primary-effect object
391   effect *                prescale_effect;            // pointer to the prescale-effect object
392   effect *                post_effect;                // pointer to the post-effect object
393   effect *                focus_effect;               // pointer to the focus-effect object
394   effect *                phosphor_effect;            // pointer to the phosphor-effect object
395   effect *                deconverge_effect;          // pointer to the deconvergence-effect object
396   effect *                color_effect;               // pointer to the color-effect object
397   effect *                yiq_encode_effect;          // pointer to the YIQ encoder effect object
398   effect *                yiq_decode_effect;          // pointer to the YIQ decoder effect object
399   effect *                bloom_effect;               // pointer to the bloom composite effect
400   effect *                downsample_effect;          // pointer to the bloom downsample effect
401   effect *                vector_effect;              // pointer to the vector-effect object
402   vertex *                fsfx_vertices;              // pointer to our full-screen-quad object
403
404   texture_info *          curr_texture;
405   bool                    phosphor_passthrough;
406
407public:
408   render_target *         targethead;
409   cache_target *          cachehead;
410
411   static slider_desc      s_sliders[];
412   static hlsl_options     s_hlsl_presets[4];
413};
414
415};
416
417#endif
trunk/src/osd/modules/render/d3d/d3dintf.h
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  d3dintf.h - Direct3D 8/9 interface abstractions
6//
7//============================================================
8
9#ifndef __WIN_D3DINTF__
10#define __WIN_D3DINTF__
11
12
13//============================================================
14//  CONSTANTS
15//============================================================
16
17#ifndef D3DCAPS2_DYNAMICTEXTURES
18#define D3DCAPS2_DYNAMICTEXTURES 0x20000000L
19#endif
20
21#ifndef D3DPRESENT_DONOTWAIT
22#define D3DPRESENT_DONOTWAIT 0x00000001L
23#endif
24
25
26#define D3DTSS_ADDRESSU       13
27#define D3DTSS_ADDRESSV       14
28#define D3DTSS_BORDERCOLOR    15
29#define D3DTSS_MAGFILTER      16
30#define D3DTSS_MINFILTER      17
31#define D3DTSS_MIPFILTER      18
32#define D3DTSS_MIPMAPLODBIAS  19
33#define D3DTSS_MAXMIPLEVEL    20
34#define D3DTSS_MAXANISOTROPY  21
35
36namespace d3d
37{
38//============================================================
39//  TYPE DEFINITIONS
40//============================================================
41
42struct base;
43struct device;
44struct surface;
45struct texture;
46struct vertex_buffer;
47class effect;
48typedef D3DXVECTOR4 vector;
49typedef D3DMATRIX matrix;
50
51//============================================================
52//  Abstracted presentation parameters
53//============================================================
54
55struct present_parameters
56{
57   UINT BackBufferWidth;
58   UINT BackBufferHeight;
59   D3DFORMAT BackBufferFormat;
60   UINT BackBufferCount;
61   D3DMULTISAMPLE_TYPE MultiSampleType;
62   DWORD MultiSampleQuality;
63   D3DSWAPEFFECT SwapEffect;
64   HWND hDeviceWindow;
65   BOOL Windowed;
66   BOOL EnableAutoDepthStencil;
67   D3DFORMAT AutoDepthStencilFormat;
68   DWORD Flags;
69   UINT FullScreen_RefreshRateInHz;
70   UINT PresentationInterval;
71};
72
73
74//============================================================
75//  Abstracted device identifier
76//============================================================
77
78struct adapter_identifier
79{
80   char            Driver[512];
81   char            Description[512];
82   LARGE_INTEGER   DriverVersion;
83   DWORD           VendorId;
84   DWORD           DeviceId;
85   DWORD           SubSysId;
86   DWORD           Revision;
87   GUID            DeviceIdentifier;
88   DWORD           WHQLLevel;
89};
90
91
92//============================================================
93//  Caps enumeration
94//============================================================
95
96enum caps_index
97{
98   CAPS_PRESENTATION_INTERVALS,
99   CAPS_CAPS2,
100   CAPS_DEV_CAPS,
101   CAPS_SRCBLEND_CAPS,
102   CAPS_DSTBLEND_CAPS,
103   CAPS_TEXTURE_CAPS,
104   CAPS_TEXTURE_FILTER_CAPS,
105   CAPS_TEXTURE_ADDRESS_CAPS,
106   CAPS_TEXTURE_OP_CAPS,
107   CAPS_MAX_TEXTURE_ASPECT,
108   CAPS_MAX_TEXTURE_WIDTH,
109   CAPS_MAX_TEXTURE_HEIGHT,
110   CAPS_STRETCH_RECT_FILTER,
111   CAPS_MAX_PS30_INSN_SLOTS
112};
113
114
115//============================================================
116//  Direct3D interfaces
117//============================================================
118
119struct interface
120{
121   HRESULT  (*check_device_format)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format);
122   HRESULT  (*check_device_type)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed);
123   HRESULT  (*create_device)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev);
124   HRESULT  (*enum_adapter_modes)(base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode);
125   UINT     (*get_adapter_count)(base *d3dptr);
126   HRESULT  (*get_adapter_display_mode)(base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode);
127   HRESULT  (*get_adapter_identifier)(base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier);
128   UINT     (*get_adapter_mode_count)(base *d3dptr, UINT adapter, D3DFORMAT format);
129   HMONITOR (*get_adapter_monitor)(base *d3dptr, UINT adapter);
130   HRESULT  (*get_caps_dword)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value);
131   ULONG    (*release)(base *d3dptr);
132};
133
134
135//============================================================
136//  Direct3DDevice interfaces
137//============================================================
138
139struct device_interface
140{
141   HRESULT (*begin_scene)(device *dev);
142   HRESULT (*clear)(device *dev, DWORD count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil);
143   HRESULT (*create_offscreen_plain_surface)(device *dev, UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, surface **surface);
144   HRESULT (*create_texture)(device *dev, UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, texture **texture);
145   HRESULT (*create_vertex_buffer)(device *dev, UINT length, DWORD usage, DWORD fvf, D3DPOOL pool, vertex_buffer **buf);
146   HRESULT (*create_render_target)(device *dev, UINT width, UINT height, D3DFORMAT format, surface **surface);
147   HRESULT (*draw_primitive)(device *dev, D3DPRIMITIVETYPE type, UINT start, UINT count);
148   HRESULT (*end_scene)(device *dev);
149   HRESULT (*get_raster_status)(device *dev, D3DRASTER_STATUS *status);
150   HRESULT (*get_render_target)(device *dev, DWORD index, surface **surface);
151   HRESULT (*get_render_target_data)(device *dev, surface *rendertarget, surface *destsurface);
152   HRESULT (*present)(device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags);
153   ULONG   (*release)(device *dev);
154   HRESULT (*reset)(device *dev, present_parameters *params);
155   void    (*set_gamma_ramp)(device *dev, DWORD flags, const D3DGAMMARAMP *ramp);
156   HRESULT (*set_render_state)(device *dev, D3DRENDERSTATETYPE state, DWORD value);
157   HRESULT (*set_render_target)(device *dev, DWORD index, surface *surf);
158   HRESULT (*set_stream_source)(device *dev, UINT number, vertex_buffer *vbuf, UINT stride);
159   HRESULT (*set_texture)(device *dev, DWORD stage, texture *tex);
160   HRESULT (*set_texture_stage_state)(device *dev, DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value);
161   HRESULT (*set_vertex_format)(device *dev, D3DFORMAT format);
162   HRESULT (*stretch_rect)(device *dev, surface *source, const RECT *srcrect, surface *dest, const RECT *dstrect, D3DTEXTUREFILTERTYPE filter);
163   HRESULT (*test_cooperative_level)(device *dev);
164};
165
166
167//============================================================
168//  Direct3DSurface interfaces
169//============================================================
170
171struct surface_interface
172{
173   HRESULT (*lock_rect)(surface *surf, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags);
174   ULONG   (*release)(surface *tex);
175   HRESULT (*unlock_rect)(surface *surf);
176};
177
178
179//============================================================
180//  Direct3DTexture interfaces
181//============================================================
182
183struct texture_interface
184{
185   HRESULT (*get_surface_level)(texture *tex, UINT level, surface **surface);
186   HRESULT (*lock_rect)(texture *tex, UINT level, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags);
187   ULONG   (*release)(texture *tex);
188   HRESULT (*unlock_rect)(texture *tex, UINT level);
189};
190
191
192//============================================================
193//  Direct3DVertexBuffer interfaces
194//============================================================
195
196struct vertex_buffer_interface
197{
198   HRESULT (*lock)(vertex_buffer *vbuf, UINT offset, UINT size, VOID **data, DWORD flags);
199   ULONG   (*release)(vertex_buffer *vbuf);
200   HRESULT (*unlock)(vertex_buffer *vbuf);
201};
202
203
204//============================================================
205//  Core D3D object
206//============================================================
207
208struct base
209{
210   // internal objects
211   int                         version;
212   void *                      d3dobj;
213   HINSTANCE                   dllhandle;
214   bool                        post_fx_available;
215   HINSTANCE                   libhandle;
216
217   // interface pointers
218   interface               d3d;
219   device_interface        device;
220   surface_interface       surface;
221   texture_interface       texture;
222   vertex_buffer_interface vertexbuf;
223};
224
225
226//============================================================
227//  PROTOTYPES
228//============================================================
229
230base *drawd3d9_init(void);
231
232};
233
234#endif
trunk/src/osd/modules/render/draw13.c
r0r244652
1//============================================================
2//
3//  draw13.c - SDL 2.0 drawing implementation
4//
5//  Copyright (c) 1996-2014, Nicola Salmoria and the MAME Team.
6//  Visit http://mamedev.org for licensing and usage restrictions.
7//
8//  SDLMAME by Olivier Galibert and R. Belmont
9//
10//============================================================
11
12// standard C headers
13#include <math.h>
14#include <stdio.h>
15
16// MAME headers
17#include "emu.h"
18#include "options.h"
19
20// standard SDL headers
21#include "sdlinc.h"
22
23// OSD headers
24#include "osdsdl.h"
25#include "window.h"
26
27
28//============================================================
29//  DEBUGGING
30//============================================================
31
32//============================================================
33//  CONSTANTS
34//============================================================
35
36#define STAT_PIXEL_THRESHOLD (150*150)
37
38enum
39{
40   TEXTURE_TYPE_NONE,
41   TEXTURE_TYPE_PLAIN,
42   TEXTURE_TYPE_SURFACE
43};
44
45
46//============================================================
47//  Inline functions
48//============================================================
49
50static inline bool is_opaque(const float &a)
51{
52   return (a >= 1.0f);
53}
54
55static inline bool is_transparent(const float &a)
56{
57   return (a <  0.0001f);
58}
59
60//============================================================
61//  TYPES
62//============================================================
63
64
65struct quad_setup_data
66{
67   quad_setup_data()
68   : dudx(0), dvdx(0), dudy(0), dvdy(0), startu(0), startv(0),
69      rotwidth(0), rotheight(0)
70   {}
71   void compute(const render_primitive &prim, const int prescale);
72
73   INT32           dudx, dvdx, dudy, dvdy;
74   INT32           startu, startv;
75   INT32           rotwidth, rotheight;
76};
77
78//============================================================
79//  Textures
80//============================================================
81
82class sdl_info13;
83struct copy_info_t;
84
85/* texture_info holds information about a texture */
86class texture_info
87{
88   friend class simple_list<texture_info>;
89public:
90   texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const UINT32 flags);
91   ~texture_info();
92
93   void set_data(const render_texinfo &texsource, const UINT32 flags);
94   void render_quad(const render_primitive *prim, const int x, const int y);
95   bool matches(const render_primitive &prim, const quad_setup_data &setup);
96
97   copy_info_t *compute_size_type();
98
99   void                *m_pixels;            // pixels for the texture
100   int                 m_pitch;
101
102   copy_info_t         *m_copyinfo;
103   quad_setup_data     m_setup;
104
105   osd_ticks_t         m_last_access;
106
107   int raw_width() const { return m_texinfo.width; }
108   int raw_height() const { return m_texinfo.height; }
109
110   texture_info *next() { return m_next; }
111   const render_texinfo &texinfo() const { return m_texinfo; }
112   render_texinfo &texinfo() { return m_texinfo; }
113
114   const HashT hash() const { return m_hash; }
115   const UINT32 flags() const { return m_flags; }
116   // FIXME:
117   const bool is_pixels_owned() const;
118
119private:
120   Uint32              m_sdl_access;
121   SDL_Renderer *      m_sdl_renderer;
122   render_texinfo      m_texinfo;            // copy of the texture info
123   HashT               m_hash;               // hash value for the texture (must be >= pointer size)
124   UINT32              m_flags;              // rendering flags
125
126   SDL_Texture *       m_texture_id;
127   bool                m_is_rotated;
128
129   int                 m_format;             // texture format
130   SDL_BlendMode       m_sdl_blendmode;
131
132   texture_info *      m_next;               // next texture in the list
133};
134
135//============================================================
136//  TEXCOPY FUNCS
137//============================================================
138
139#include "blit13.h"
140
141/* sdl_info is the information about SDL for the current screen */
142class sdl_info13 : public osd_renderer
143{
144public:
145   sdl_info13(osd_window *w)
146   : osd_renderer(w, FLAG_NONE), m_blittimer(0), m_sdl_renderer(NULL),
147      m_last_hofs(0), m_last_vofs(0),
148      m_width(0), m_height(0),
149      m_blit_dim(0,0),
150      m_last_blit_time(0), m_last_blit_pixels(0)
151   {}
152
153   /* virtual */ int create();
154   /* virtual */ int draw(const int update);
155   /* virtual */ int xy_to_render_target(const int x, const int y, int *xt, int *yt);
156   /* virtual */ void destroy();
157   /* virtual */ render_primitive_list *get_primitives()
158   {
159      osd_dim nd = window().blit_surface_size();
160      if (nd != m_blit_dim)
161      {
162         m_blit_dim = nd;
163         notify_changed();
164      }
165      window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
166      return &window().target()->get_primitives();
167   }
168
169private:
170   void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y);
171
172   texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
173   texture_info *texture_update(const render_primitive &prim);
174
175   void destroy_all_textures();
176
177   INT32           m_blittimer;
178
179#if (SDLMAME_SDL2)
180   //SDL_GLContext   m_gl_context_id;
181#else
182   // SDL surface
183   SDL_Surface         *m_sdlsurf;
184#endif
185
186   SDL_Renderer *  m_sdl_renderer;
187   simple_list<texture_info>  m_texlist;                // list of active textures
188
189   float           m_last_hofs;
190   float           m_last_vofs;
191
192   int             m_width;
193   int             m_height;
194
195   osd_dim         m_blit_dim;
196
197   // Stats
198   INT64           m_last_blit_time;
199   INT64           m_last_blit_pixels;
200};
201
202struct copy_info_t {
203   int                 src_fmt;
204   Uint32              dst_fmt;
205   const blit_base     *blitter;
206   Uint32              bm_mask;
207   const char          *srcname;
208   const char          *dstname;
209   /* Statistics */
210   UINT64              pixel_count;
211   INT64               time;
212   int                 samples;
213   int                 perf;
214   /* list */
215   copy_info_t           *next;
216};
217
218
219//============================================================
220//  PROTOTYPES
221//============================================================
222
223// core functions
224
225static void drawsdl2_exit(void);
226
227//============================================================
228//  STATIC VARIABLES
229//============================================================
230
231#define SDL_TEXFORMAT_LAST SDL_TEXFORMAT_PALETTE16A
232#define BM_ALL (-1)
233//( SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD)
234
235#define ENTRY(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, 0}
236#define ENTRY_BM(a,b,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0}
237#define ENTRY_LR(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1}
238
239static copy_info_t blit_info_default[] =
240{
241   /* no rotation */
242   ENTRY(ARGB32,           ARGB8888,   argb32_argb32),
243   ENTRY_LR(ARGB32,        RGB888,     argb32_rgb32),
244   /* Entry primarily for directfb */
245   ENTRY_BM(ARGB32,        RGB888,     argb32_rgb32, SDL_BLENDMODE_ADD),
246   ENTRY_BM(ARGB32,        RGB888,     argb32_rgb32, SDL_BLENDMODE_MOD),
247   ENTRY_BM(ARGB32,        RGB888,     argb32_rgb32, SDL_BLENDMODE_NONE),
248
249   ENTRY(RGB32,            ARGB8888,   rgb32_argb32),
250   ENTRY(RGB32,            RGB888,     rgb32_rgb32),
251
252   ENTRY(RGB32_PALETTED,   ARGB8888,   rgb32pal_argb32),
253   ENTRY(RGB32_PALETTED,   RGB888,     rgb32pal_argb32),
254
255   ENTRY(YUY16,            UYVY,       yuv16_uyvy),
256   ENTRY(YUY16,            YUY2,       yuv16_yuy2),
257   ENTRY(YUY16,            YVYU,       yuv16_yvyu),
258   ENTRY(YUY16,            ARGB8888,   yuv16_argb32),
259   ENTRY(YUY16,            RGB888,     yuv16_argb32),
260
261   ENTRY(YUY16_PALETTED,   UYVY,       yuv16pal_uyvy),
262   ENTRY(YUY16_PALETTED,   YUY2,       yuv16pal_yuy2),
263   ENTRY(YUY16_PALETTED,   YVYU,       yuv16pal_yvyu),
264   ENTRY(YUY16_PALETTED,   ARGB8888,   yuv16pal_argb32),
265   ENTRY(YUY16_PALETTED,   RGB888,     yuv16pal_argb32),
266
267   ENTRY(PALETTE16,        ARGB8888,   pal16_argb32),
268   ENTRY(PALETTE16,        RGB888,     pal16_argb32),
269
270   ENTRY(RGB15,            RGB555,     rgb15_rgb555),
271   ENTRY(RGB15,            ARGB1555,   rgb15_argb1555),
272   ENTRY(RGB15,            ARGB8888,   rgb15_argb32),
273   ENTRY(RGB15,            RGB888,     rgb15_argb32),
274
275   ENTRY(RGB15_PALETTED,   ARGB8888,   rgb15pal_argb32),
276   ENTRY(RGB15_PALETTED,   RGB888,     rgb15pal_argb32),
277
278   ENTRY(PALETTE16A,       ARGB8888,   pal16a_argb32),
279   ENTRY(PALETTE16A,       RGB888,     pal16a_rgb32),
280
281   /* rotation */
282   ENTRY(ARGB32,           ARGB8888,   rot_argb32_argb32),
283   ENTRY_LR(ARGB32,        RGB888,     rot_argb32_rgb32),
284   /* Entry primarily for directfb */
285   ENTRY_BM(ARGB32,        RGB888,     rot_argb32_rgb32, SDL_BLENDMODE_ADD),
286   ENTRY_BM(ARGB32,        RGB888,     rot_argb32_rgb32, SDL_BLENDMODE_MOD),
287   ENTRY_BM(ARGB32,        RGB888,     rot_argb32_rgb32, SDL_BLENDMODE_NONE),
288
289   ENTRY(RGB32,            ARGB8888,   rot_rgb32_argb32),
290   ENTRY(RGB32,            RGB888,     rot_argb32_argb32),
291
292   ENTRY(RGB32_PALETTED,   ARGB8888,   rot_rgb32pal_argb32),
293   ENTRY(RGB32_PALETTED,   RGB888,     rot_rgb32pal_argb32),
294
295   ENTRY(YUY16,            ARGB8888,   rot_yuv16_argb32rot),
296   ENTRY(YUY16,            RGB888,     rot_yuv16_argb32rot),
297
298   ENTRY(YUY16_PALETTED,   ARGB8888,   rot_yuv16pal_argb32rot),
299   ENTRY(YUY16_PALETTED,   RGB888,     rot_yuv16pal_argb32rot),
300
301   ENTRY(PALETTE16,        ARGB8888,   rot_pal16_argb32),
302   ENTRY(PALETTE16,        RGB888,     rot_pal16_argb32),
303
304   ENTRY(RGB15,            RGB555,     rot_rgb15_argb1555),
305   ENTRY(RGB15,            ARGB1555,   rot_rgb15_argb1555),
306   ENTRY(RGB15,            ARGB8888,   rot_rgb15_argb32),
307   ENTRY(RGB15,            RGB888,     rot_rgb15_argb32),
308
309   ENTRY(RGB15_PALETTED,   ARGB8888,   rot_rgb15pal_argb32),
310   ENTRY(RGB15_PALETTED,   RGB888,     rot_rgb15pal_argb32),
311
312   ENTRY(PALETTE16A,       ARGB8888,   rot_pal16a_argb32),
313   ENTRY(PALETTE16A,       RGB888,     rot_pal16a_rgb32),
314
315{ -1 },
316};
317
318static copy_info_t *blit_info[SDL_TEXFORMAT_LAST+1];
319
320static struct
321{
322   Uint32  format;
323   int     status;
324} fmt_support[30] = { { 0, 0 } };
325
326
327//============================================================
328//  INLINES
329//============================================================
330
331
332INLINE float round_nearest(float f)
333{
334   return floor(f + 0.5f);
335}
336
337INLINE HashT texture_compute_hash(const render_texinfo &texture, const UINT32 flags)
338{
339   return (HashT)texture.base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK));
340}
341
342INLINE SDL_BlendMode map_blendmode(const int blendmode)
343{
344   switch (blendmode)
345   {
346      case BLENDMODE_NONE:
347         return SDL_BLENDMODE_NONE;
348      case BLENDMODE_ALPHA:
349         return SDL_BLENDMODE_BLEND;
350      case BLENDMODE_RGB_MULTIPLY:
351         return SDL_BLENDMODE_MOD;
352      case BLENDMODE_ADD:
353         return SDL_BLENDMODE_ADD;
354      default:
355         osd_printf_warning("Unknown Blendmode %d", blendmode);
356   }
357   return SDL_BLENDMODE_NONE;
358}
359
360INLINE void set_coloralphamode(SDL_Texture  *texture_id, const render_color *color)
361{
362   UINT32 sr = (UINT32)(255.0f * color->r);
363   UINT32 sg = (UINT32)(255.0f * color->g);
364   UINT32 sb = (UINT32)(255.0f * color->b);
365   UINT32 sa = (UINT32)(255.0f * color->a);
366
367
368   if (color->r >= 1.0f && color->g >= 1.0f && color->b >= 1.0f && is_opaque(color->a))
369   {
370      SDL_SetTextureColorMod(texture_id, 0xFF, 0xFF, 0xFF);
371      SDL_SetTextureAlphaMod(texture_id, 0xFF);
372   }
373   /* coloring-only case */
374   else if (is_opaque(color->a))
375   {
376      SDL_SetTextureColorMod(texture_id, sr, sg, sb);
377      SDL_SetTextureAlphaMod(texture_id, 0xFF);
378   }
379   /* alpha and/or coloring case */
380   else if (!is_transparent(color->a))
381   {
382      SDL_SetTextureColorMod(texture_id, sr, sg, sb);
383      SDL_SetTextureAlphaMod(texture_id, sa);
384   }
385   else
386   {
387      SDL_SetTextureColorMod(texture_id, 0xFF, 0xFF, 0xFF);
388      SDL_SetTextureAlphaMod(texture_id, 0x00);
389   }
390}
391
392void texture_info::render_quad(const render_primitive *prim, const int x, const int y)
393{
394   SDL_Rect target_rect;
395
396   target_rect.x = x;
397   target_rect.y = y;
398   target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0);
399   target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0);
400
401   SDL_SetTextureBlendMode(m_texture_id, m_sdl_blendmode);
402   set_coloralphamode(m_texture_id, &prim->color);
403   SDL_RenderCopy(m_sdl_renderer,  m_texture_id, NULL, &target_rect);
404}
405
406void sdl_info13::render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y)
407{
408   SDL_Rect target_rect;
409
410   target_rect.x = x;
411   target_rect.y = y;
412   target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0);
413   target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0);
414
415   if (texture)
416   {
417      copy_info_t *copyinfo = texture->m_copyinfo;
418      copyinfo->time -= osd_ticks();
419      texture->render_quad(prim, x, y);
420      copyinfo->time += osd_ticks();
421
422      copyinfo->pixel_count += MAX(STAT_PIXEL_THRESHOLD , (texture->raw_width() * texture->raw_height()));
423      if (m_last_blit_pixels)
424      {
425         copyinfo->time += (m_last_blit_time * (INT64) (texture->raw_width() * texture->raw_height())) / (INT64) m_last_blit_pixels;
426      }
427      copyinfo->samples++;
428      copyinfo->perf = ( texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->m_copyinfo->time;
429   }
430   else
431   {
432      UINT32 sr = (UINT32)(255.0f * prim->color.r);
433      UINT32 sg = (UINT32)(255.0f * prim->color.g);
434      UINT32 sb = (UINT32)(255.0f * prim->color.b);
435      UINT32 sa = (UINT32)(255.0f * prim->color.a);
436
437      SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)));
438      SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa);
439      SDL_RenderFillRect(m_sdl_renderer, &target_rect);
440   }
441}
442
443static int RendererSupportsFormat(SDL_Renderer *renderer, Uint32 format, Uint32 access, const char *sformat)
444{
445   int i;
446   SDL_Texture *texid;
447   for (i=0; fmt_support[i].format != 0; i++)
448   {
449      if (format == fmt_support[i].format)
450      {
451         return fmt_support[i].status;
452      }
453   }
454   /* not tested yet */
455   fmt_support[i].format = format;
456   fmt_support[i + 1].format = 0;
457   texid = SDL_CreateTexture(renderer, format, access, 16, 16);
458   if (texid)
459   {
460      fmt_support[i].status = 1;
461      SDL_DestroyTexture(texid);
462      return 1;
463   }
464   osd_printf_verbose("Pixelformat <%s> error %s \n", sformat, SDL_GetError());
465   osd_printf_verbose("Pixelformat <%s> not supported\n", sformat);
466   fmt_support[i].status = 0;
467   return 0;
468}
469
470//============================================================
471//  drawsdl_init
472//============================================================
473
474static void add_list(copy_info_t **head, copy_info_t *element, Uint32 bm)
475{
476   copy_info_t *newci = global_alloc(copy_info_t);
477   *newci = *element;
478
479   newci->bm_mask = bm;
480   newci->next = *head;
481   *head = newci;
482}
483
484static void expand_copy_info(copy_info_t *list)
485{
486   copy_info_t   *bi;
487
488   for (bi = list; bi->src_fmt != -1; bi++)
489   {
490      if (bi->bm_mask == BM_ALL)
491      {
492         add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_NONE);
493         add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_ADD);
494         add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_MOD);
495         add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_BLEND);
496      }
497      else
498         add_list(&blit_info[bi->src_fmt], bi, bi->bm_mask);
499   }
500}
501
502static osd_renderer *drawsdl2_create(osd_window *window)
503{
504   return global_alloc(sdl_info13(window));
505}
506
507// FIXME: machine only used to access options.
508int drawsdl2_init(running_machine &machine, osd_draw_callbacks *callbacks)
509{
510   const char *stemp;
511
512   // fill in the callbacks
513   callbacks->exit = drawsdl2_exit;
514   callbacks->create = drawsdl2_create;
515
516   osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n");
517
518   expand_copy_info(blit_info_default);
519
520#if USE_OPENGL
521   // Load the GL library now - else MT will fail
522   stemp = downcast<sdl_options &>(machine.options()).gl_lib();
523#else
524   stemp = NULL;
525#endif
526   if (stemp != NULL && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
527      stemp = NULL;
528
529   // No fatalerror here since not all video drivers support GL !
530   if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==NULL
531      osd_printf_warning("Warning: Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
532   else
533      osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
534
535   return 0;
536}
537
538
539//============================================================
540//  drawsdl_exit
541//============================================================
542
543static void drawsdl2_exit(void)
544{
545   int i;
546   copy_info_t *bi, *freeme;
547   for (i = 0; i <= SDL_TEXFORMAT_LAST; i++)
548      for (bi = blit_info[i]; bi != NULL; )
549      {
550         if (bi->pixel_count)
551            osd_printf_verbose("%s -> %s %s blendmode 0x%02x, %d samples: %d KPixel/sec\n", bi->srcname, bi->dstname,
552                  bi->blitter->m_is_rot ? "rot" : "norot", bi->bm_mask, bi->samples,
553                  (int) bi->perf);
554         freeme = bi;
555         bi = bi->next;
556         global_free(freeme);
557      }
558}
559
560//============================================================
561//  sdl_info::create
562// a
563// a
564// a
565// a
566// a
567// a
568// a
569// a
570// a
571// a
572// a
573// a
574// a
575// a
576// a
577// a
578// a
579// a
580// a
581// a
582// a
583// a
584// a
585// a
586// a
587// a
588//============================================================
589
590int sdl_info13::create()
591{
592#if (SDLMAME_SDL2)
593   // create renderer
594
595   /* Enable bilinear filtering in case it is supported.
596    * This applies to all texture operations. However, artwort is pre-scaled
597    * and thus shouldn't be affected.
598    */
599   if (video_config.filter)
600   {
601      SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
602   }
603   else
604   {
605      SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
606   }
607
608   if (video_config.waitvsync)
609      m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
610   else
611      m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_ACCELERATED);
612
613   if (!m_sdl_renderer)
614   {
615      fatalerror("Error on creating renderer: %s\n", SDL_GetError());
616   }
617
618   //SDL_SelectRenderer(window().sdl_window);
619
620   m_blittimer = 3;
621
622   SDL_RenderPresent(m_sdl_renderer);
623   osd_printf_verbose("Leave sdl_info13::create\n");
624
625#else
626
627#endif
628   return 0;
629}
630
631
632//============================================================
633//  sdl_info::destroy
634//============================================================
635
636void sdl_info13::destroy()
637{
638   destroy_all_textures();
639}
640
641
642//============================================================
643//  drawsdl_xy_to_render_target
644//============================================================
645
646int sdl_info13::xy_to_render_target(int x, int y, int *xt, int *yt)
647{
648   *xt = x - m_last_hofs;
649   *yt = y - m_last_vofs;
650   if (*xt<0 || *xt >= m_blit_dim.width())
651      return 0;
652   if (*yt<0 || *yt >= m_blit_dim.height())
653      return 0;
654   return 1;
655}
656
657//============================================================
658//  drawsdl_destroy_all_textures
659//============================================================
660
661void sdl_info13::destroy_all_textures()
662{
663   if(window().m_primlist)
664   {
665      window().m_primlist->acquire_lock();
666      m_texlist.reset();
667      window().m_primlist->release_lock();
668   }
669   else
670      m_texlist.reset();
671}
672
673//============================================================
674//  sdl_info::draw
675//============================================================
676
677int sdl_info13::draw(int update)
678{
679   render_primitive *prim;
680   texture_info *texture=NULL;
681   float vofs, hofs;
682   int blit_pixels = 0;
683
684   if (video_config.novideo)
685   {
686      return 0;
687   }
688
689   osd_dim wdim = window().get_size();
690
691   if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
692   {
693      destroy_all_textures();
694      m_width = wdim.width();
695      m_height = wdim.height();
696      SDL_RenderSetViewport(m_sdl_renderer, NULL);
697      m_blittimer = 3;
698      clear_flags(FI_CHANGED);
699   }
700
701   //SDL_SelectRenderer(window().sdl_window);
702
703   if (m_blittimer > 0)
704   {
705      /* SDL Underlays need alpha = 0 ! */
706      SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_NONE);
707      //SDL_SetRenderDrawColor(0,0,0,255);
708      SDL_SetRenderDrawColor(m_sdl_renderer, 0,0,0,0);
709      SDL_RenderFillRect(m_sdl_renderer, NULL);
710      m_blittimer--;
711   }
712
713   // compute centering parameters
714   vofs = hofs = 0.0f;
715
716   if (video_config.centerv || video_config.centerh)
717   {
718      int ch, cw;
719
720      ch = wdim.height();
721      cw = wdim.width();
722
723      if (video_config.centerv)
724      {
725         vofs = (ch - m_blit_dim.height()) / 2.0f;
726      }
727      if (video_config.centerh)
728      {
729         hofs = (cw - m_blit_dim.width()) / 2.0f;
730      }
731   }
732
733   m_last_hofs = hofs;
734   m_last_vofs = vofs;
735
736   window().m_primlist->acquire_lock();
737
738   // now draw
739   for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
740   {
741      Uint8 sr, sg, sb, sa;
742
743      switch (prim->type)
744      {
745         case render_primitive::LINE:
746            sr = (int)(255.0f * prim->color.r);
747            sg = (int)(255.0f * prim->color.g);
748            sb = (int)(255.0f * prim->color.b);
749            sa = (int)(255.0f * prim->color.a);
750
751            SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)));
752            SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa);
753            SDL_RenderDrawLine(m_sdl_renderer, prim->bounds.x0 + hofs, prim->bounds.y0 + vofs,
754                  prim->bounds.x1 + hofs, prim->bounds.y1 + vofs);
755            break;
756         case render_primitive::QUAD:
757            texture = texture_update(*prim);
758            if (texture)
759               blit_pixels += (texture->raw_height() * texture->raw_width());
760            render_quad(texture, prim,
761                  round_nearest(hofs + prim->bounds.x0),
762                  round_nearest(vofs + prim->bounds.y0));
763            break;
764         default:
765            throw emu_fatalerror("Unexpected render_primitive type\n");
766      }
767   }
768
769   window().m_primlist->release_lock();
770
771   m_last_blit_pixels = blit_pixels;
772   m_last_blit_time = -osd_ticks();
773   SDL_RenderPresent(m_sdl_renderer);
774   m_last_blit_time += osd_ticks();
775
776   return 0;
777}
778
779
780//============================================================
781//  texture handling
782//============================================================
783
784//============================================================
785//  texture_compute_size and type
786//============================================================
787
788copy_info_t *texture_info::compute_size_type()
789{
790   copy_info_t *bi;
791   copy_info_t *result = NULL;
792   int maxperf = 0;
793
794   for (bi = blit_info[m_format]; bi != NULL; bi = bi->next)
795   {
796      if ((m_is_rotated == bi->blitter->m_is_rot)
797            && (m_sdl_blendmode == bi->bm_mask))
798      {
799         if (RendererSupportsFormat(m_sdl_renderer, bi->dst_fmt, m_sdl_access, bi->dstname))
800         {
801            int perf = bi->perf;
802            if (perf == 0)
803               return bi;
804            else if (perf > (maxperf * 102) / 100)
805            {
806               result = bi;
807               maxperf = perf;
808            }
809         }
810      }
811   }
812   if (result)
813      return result;
814   /* try last resort handlers */
815   for (bi = blit_info[m_format]; bi != NULL; bi = bi->next)
816   {
817      if ((m_is_rotated == bi->blitter->m_is_rot)
818         && (m_sdl_blendmode == bi->bm_mask))
819         if (RendererSupportsFormat(m_sdl_renderer, bi->dst_fmt, m_sdl_access, bi->dstname))
820            return bi;
821   }
822   //FIXME: crash implement a -do nothing handler */
823   return NULL;
824}
825
826// FIXME:
827const bool texture_info::is_pixels_owned() const
828{ // do we own / allocated it ?
829   return ((m_sdl_access == SDL_TEXTUREACCESS_STATIC)
830         && (m_copyinfo->blitter->m_is_passthrough));
831}
832
833//============================================================
834//  texture_info::matches
835//============================================================
836
837bool texture_info::matches(const render_primitive &prim, const quad_setup_data &setup)
838{
839   return  texinfo().base == prim.texture.base &&
840         texinfo().width == prim.texture.width &&
841         texinfo().height == prim.texture.height &&
842         texinfo().rowpixels == prim.texture.rowpixels &&
843         m_setup.dudx == setup.dudx &&
844         m_setup.dvdx == setup.dvdx &&
845         m_setup.dudy == setup.dudy &&
846         m_setup.dvdy == setup.dvdy &&
847         ((flags() ^ prim.flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0;
848}
849
850//============================================================
851//  texture_create
852//============================================================
853
854texture_info::texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, UINT32 flags)
855{
856   // fill in the core data
857   m_sdl_renderer = renderer;
858   m_hash = texture_compute_hash(texsource, flags);
859   m_flags = flags;
860   m_texinfo = texsource;
861   m_texinfo.seqid = -1; // force set data
862   m_is_rotated = false;
863   m_setup = setup;
864   m_sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags));
865   m_pitch = 0;
866
867   switch (PRIMFLAG_GET_TEXFORMAT(flags))
868   {
869      case TEXFORMAT_ARGB32:
870         m_format = SDL_TEXFORMAT_ARGB32;
871         break;
872      case TEXFORMAT_RGB32:
873         m_format = texsource.palette ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32;
874         break;
875      case TEXFORMAT_PALETTE16:
876         m_format = SDL_TEXFORMAT_PALETTE16;
877         break;
878      case TEXFORMAT_PALETTEA16:
879         m_format = SDL_TEXFORMAT_PALETTE16A;
880         break;
881      case TEXFORMAT_YUY16:
882         m_format = texsource.palette ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16;
883         break;
884
885      default:
886         osd_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags));
887   }
888
889   if (setup.rotwidth != m_texinfo.width || setup.rotheight != m_texinfo.height
890         || setup.dudx < 0 || setup.dvdy < 0)
891      m_is_rotated = true;
892   else
893      m_is_rotated = false;
894
895   //m_sdl_access = SDL_TEXTUREACCESS_STATIC;
896   m_sdl_access = SDL_TEXTUREACCESS_STREAMING;
897
898   // Watch out for 0x0 textures ...
899   if (!m_setup.rotwidth || !m_setup.rotheight)
900      osd_printf_warning("Trying to create texture with zero dim\n");
901
902   // set copy_info
903
904   m_copyinfo = compute_size_type();
905
906   m_texture_id = SDL_CreateTexture(m_sdl_renderer, m_copyinfo->dst_fmt, m_sdl_access,
907         m_setup.rotwidth, m_setup.rotheight);
908
909   if (!m_texture_id)
910      osd_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", m_setup.rotwidth, m_setup.rotheight,
911            m_copyinfo->dstname, SDL_GetError());
912
913   if (m_sdl_access == SDL_TEXTUREACCESS_STATIC)
914   {
915      if (m_copyinfo->blitter->m_is_passthrough)
916         m_pixels = NULL;
917      else
918         m_pixels = malloc(m_setup.rotwidth * m_setup.rotheight * m_copyinfo->blitter->m_dest_bpp);
919   }
920   m_last_access = osd_ticks();
921
922}
923
924texture_info::~texture_info()
925{
926   if ( is_pixels_owned() && (m_pixels != NULL) )
927      free(m_pixels);
928   SDL_DestroyTexture(m_texture_id);
929}
930
931//============================================================
932//  texture_set_data
933//============================================================
934
935void texture_info::set_data(const render_texinfo &texsource, const UINT32 flags)
936{
937   m_copyinfo->time -= osd_ticks();
938   if (m_sdl_access == SDL_TEXTUREACCESS_STATIC)
939   {
940      if ( m_copyinfo->blitter->m_is_passthrough )
941      {
942         m_pixels = texsource.base;
943         m_pitch = m_texinfo.rowpixels * m_copyinfo->blitter->m_dest_bpp;
944      }
945      else
946      {
947         m_pitch = m_setup.rotwidth * m_copyinfo->blitter->m_dest_bpp;
948         m_copyinfo->blitter->texop(this, &texsource);
949      }
950      SDL_UpdateTexture(m_texture_id, NULL, m_pixels, m_pitch);
951   }
952   else
953   {
954      SDL_LockTexture(m_texture_id, NULL, (void **) &m_pixels, &m_pitch);
955      if ( m_copyinfo->blitter->m_is_passthrough )
956      {
957         UINT8 *src = (UINT8 *) texsource.base;
958         UINT8 *dst = (UINT8 *) m_pixels;
959         int spitch = texsource.rowpixels * m_copyinfo->blitter->m_dest_bpp;
960         int num = texsource.width * m_copyinfo->blitter->m_dest_bpp;
961         int h = texsource.height;
962         while (h--) {
963            memcpy(dst, src, num);
964            src += spitch;
965            dst += m_pitch;
966         }
967      }
968      else
969         m_copyinfo->blitter->texop(this, &texsource);
970      SDL_UnlockTexture(m_texture_id);
971   }
972   m_copyinfo->time += osd_ticks();
973}
974
975//============================================================
976//  compute rotation setup
977//============================================================
978
979void quad_setup_data::compute(const render_primitive &prim, const int prescale)
980{
981   const render_quad_texuv *texcoords = &prim.texcoords;
982   int texwidth = prim.texture.width;
983   int texheight = prim.texture.height;
984   float fdudx, fdvdx, fdudy, fdvdy;
985   float width, height;
986   float fscale;
987   /* determine U/V deltas */
988   if ((PRIMFLAG_GET_SCREENTEX(prim.flags)))
989      fscale = (float) prescale;
990   else
991      fscale = 1.0f;
992
993   fdudx = (texcoords->tr.u - texcoords->tl.u) / fscale; // a a11
994   fdvdx = (texcoords->tr.v - texcoords->tl.v) / fscale; // c a21
995   fdudy = (texcoords->bl.u - texcoords->tl.u) / fscale; // b a12
996   fdvdy = (texcoords->bl.v - texcoords->tl.v) / fscale; // d a22
997
998#if 0
999   printf("tl.u %f tl.v %f\n", texcoords->tl.u, texcoords->tl.v);
1000   printf("tr.u %f tr.v %f\n", texcoords->tr.u, texcoords->tr.v);
1001   printf("bl.u %f bl.v %f\n", texcoords->bl.u, texcoords->bl.v);
1002   printf("br.u %f br.v %f\n", texcoords->br.u, texcoords->br.v);
1003   /* compute start and delta U,V coordinates now */
1004#endif
1005
1006   dudx = round_nearest(65536.0f * fdudx);
1007   dvdx = round_nearest(65536.0f * fdvdx);
1008   dudy = round_nearest(65536.0f * fdudy);
1009   dvdy = round_nearest(65536.0f * fdvdy);
1010   startu = round_nearest(65536.0f * (float) texwidth * texcoords->tl.u);
1011   startv = round_nearest(65536.0f * (float) texheight * texcoords->tl.v);
1012
1013   /* clamp to integers */
1014
1015   width = fabs((fdudx * (float) (texwidth) + fdvdx * (float) (texheight)) * fscale * fscale);
1016   height = fabs((fdudy * (float)(texwidth) + fdvdy * (float) (texheight)) * fscale * fscale);
1017
1018   rotwidth = width;
1019   rotheight = height;
1020
1021   startu += (dudx + dudy) / 2;
1022   startv += (dvdx + dvdy) / 2;
1023
1024}
1025
1026//============================================================
1027//  texture_find
1028//============================================================
1029
1030texture_info *sdl_info13::texture_find(const render_primitive &prim, const quad_setup_data &setup)
1031{
1032   HashT texhash = texture_compute_hash(prim.texture, prim.flags);
1033   texture_info *texture;
1034   osd_ticks_t now = osd_ticks();
1035
1036   // find a match
1037   for (texture = m_texlist.first(); texture != NULL; )
1038      if (texture->hash() == texhash &&
1039         texture->matches(prim, setup))
1040      {
1041         /* would we choose another blitter based on performance ? */
1042         if ((texture->m_copyinfo->samples & 0x7f) == 0x7f)
1043         {
1044            if (texture->m_copyinfo != texture->compute_size_type())
1045               return NULL;
1046         }
1047         texture->m_last_access = now;
1048         return texture;
1049      }
1050      else
1051      {
1052         /* free resources not needed any longer? */
1053         texture_info *expire = texture;
1054         texture = texture->next();
1055         if (now - expire->m_last_access > osd_ticks_per_second())
1056            m_texlist.remove(*expire);
1057      }
1058
1059   // nothing found
1060   return NULL;
1061}
1062
1063//============================================================
1064//  texture_update
1065//============================================================
1066
1067texture_info * sdl_info13::texture_update(const render_primitive &prim)
1068{
1069   quad_setup_data setup;
1070   texture_info *texture;
1071
1072   setup.compute(prim, window().prescale());
1073
1074   texture = texture_find(prim, setup);
1075
1076   // if we didn't find one, create a new texture
1077   if (texture == NULL && prim.texture.base != NULL)
1078   {
1079      texture = global_alloc(texture_info(m_sdl_renderer, prim.texture, setup, prim.flags));
1080      /* add us to the texture list */
1081      m_texlist.prepend(*texture);
1082
1083   }
1084
1085   if (texture != NULL)
1086   {
1087      if (prim.texture.base != NULL && texture->texinfo().seqid != prim.texture.seqid)
1088      {
1089         texture->texinfo().seqid = prim.texture.seqid;
1090         // if we found it, but with a different seqid, copy the data
1091         texture->set_data(prim.texture, prim.flags);
1092      }
1093
1094   }
1095   return texture;
1096}
trunk/src/osd/modules/render/drawbgfx.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Miodrag Milanovic
3//============================================================
4//
5//  drawbgfx.c - BGFX drawer
6//
7//============================================================
8
9#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
10// standard windows headers
11#define __STDC_LIMIT_MACROS
12#define __STDC_FORMAT_MACROS
13#define __STDC_CONSTANT_MACROS
14#define WIN32_LEAN_AND_MEAN
15#include <windows.h>
16#else
17#include "sdlinc.h"
18#endif
19
20// MAMEOS headers
21#include "emu.h"
22#include "window.h"
23
24#include <bgfxplatform.h>
25#include <bgfx.h>
26
27//============================================================
28//  DEBUGGING
29//============================================================
30
31//============================================================
32//  CONSTANTS
33//============================================================
34
35//============================================================
36//  MACROS
37//============================================================
38
39//============================================================
40//  INLINES
41//============================================================
42
43
44//============================================================
45//  TYPES
46//============================================================
47
48
49/* sdl_info is the information about SDL for the current screen */
50class renderer_bgfx : public osd_renderer
51{
52public:
53   renderer_bgfx(osd_window *w)
54   : osd_renderer(w, FLAG_NONE), m_blittimer(0),
55      m_blit_dim(0, 0),
56      m_last_hofs(0), m_last_vofs(0),
57      m_last_blit_time(0), m_last_blit_pixels(0)
58   {}
59
60   /* virtual */ int create();
61   /* virtual */ int draw(const int update);
62#ifdef OSD_SDL
63   /* virtual */ int xy_to_render_target(const int x, const int y, int *xt, int *yt);
64#else
65   /* virtual */ void save() { }
66   /* virtual */ void record() { }
67   /* virtual */ void toggle_fsfx() { }
68#endif
69   /* virtual */ void destroy();
70   /* virtual */ render_primitive_list *get_primitives()
71   {
72#ifdef OSD_WINDOWS
73      RECT client;
74      GetClientRect(window().m_hwnd, &client);
75      window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
76      return &window().target()->get_primitives();
77#else
78      osd_dim nd = window().blit_surface_size();
79      if (nd != m_blit_dim)
80      {
81         m_blit_dim = nd;
82         notify_changed();
83      }
84      window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
85      return &window().target()->get_primitives();
86#endif
87   }
88
89   // void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y);
90
91   //texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
92   //texture_info *texture_update(const render_primitive &prim);
93
94   INT32           m_blittimer;
95
96   //simple_list<texture_info>  m_texlist;                // list of active textures
97
98   osd_dim         m_blit_dim;
99   float           m_last_hofs;
100   float           m_last_vofs;
101
102   // Stats
103   INT64           m_last_blit_time;
104   INT64           m_last_blit_pixels;
105
106   // Original display_mode
107};
108
109
110//============================================================
111//  PROTOTYPES
112//============================================================
113
114// core functions
115static void drawbgfx_exit(void);
116
117//============================================================
118//  drawnone_create
119//============================================================
120
121static osd_renderer *drawbgfx_create(osd_window *window)
122{
123   return global_alloc(renderer_bgfx(window));
124}
125
126//============================================================
127//  drawbgfx_init
128//============================================================
129
130int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks)
131{
132   // fill in the callbacks
133   //memset(callbacks, 0, sizeof(*callbacks));
134   callbacks->exit = drawbgfx_exit;
135   callbacks->create = drawbgfx_create;
136
137   return 0;
138}
139
140//============================================================
141//  drawbgfx_exit
142//============================================================
143
144static void drawbgfx_exit(void)
145{
146}
147
148//============================================================
149//  renderer_bgfx::create
150//============================================================
151
152int renderer_bgfx::create()
153{
154   // create renderer
155
156#ifdef OSD_WINDOWS
157   RECT client;
158   GetClientRect(window().m_hwnd, &client);
159
160   bgfx::winSetHwnd(window().m_hwnd);
161   bgfx::init();
162   bgfx::reset(rect_width(&client), rect_height(&client), BGFX_RESET_VSYNC);
163#else
164   osd_dim d = window().get_size();
165   m_blittimer = 3;
166
167   bgfx::sdlSetWindow(window().sdl_window());
168   bgfx::init();
169   bgfx::reset(d.width(), d.height(), BGFX_RESET_VSYNC);
170#endif
171
172   // Enable debug text.
173   bgfx::setDebug(BGFX_DEBUG_STATS);// BGFX_DEBUG_TEXT);
174
175   osd_printf_verbose("Leave drawsdl2_window_create\n");
176   return 0;
177}
178
179//============================================================
180//  drawbgfx_window_destroy
181//============================================================
182
183void renderer_bgfx::destroy()
184{
185   // free the memory in the window
186
187   // destroy_all_textures();
188
189   // Shutdown bgfx.
190   bgfx::shutdown();
191}
192
193
194//============================================================
195//  drawsdl_xy_to_render_target
196//============================================================
197
198#ifdef OSD_SDL
199int renderer_bgfx::xy_to_render_target(int x, int y, int *xt, int *yt)
200{
201   *xt = x - m_last_hofs;
202   *yt = y - m_last_vofs;
203   if (*xt<0 || *xt >= m_blit_dim.width())
204      return 0;
205   if (*yt<0 || *yt >= m_blit_dim.height())
206      return 0;
207   return 1;
208}
209#endif
210
211//============================================================
212//  drawbgfx_window_draw
213//============================================================
214
215int renderer_bgfx::draw(int update)
216{
217   //if (has_flags(FI_CHANGED) || (window().width() != m_last_width) || (window().height() != m_last_height))
218      // do something
219   //clear_flags(FI_CHANGED);
220
221   bgfx::setViewClear(0
222      , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
223      , 0x000000ff
224      , 1.0f
225      , 0
226      );
227   // Set view 0 default viewport.
228#ifdef OSD_WINDOWS
229   RECT client;
230   GetClientRect(window().m_hwnd, &client);
231   bgfx::setViewRect(0, 0, 0, rect_width(&client), rect_height(&client));
232#else
233   bgfx::setViewRect(0, 0, 0, m_blit_dim.width(), m_blit_dim.height());
234#endif
235   // This dummy draw call is here to make sure that view 0 is cleared
236   // if no other draw calls are submitted to view 0.
237   bgfx::submit(0);
238
239   window().m_primlist->acquire_lock();
240
241   // now draw
242   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
243   {
244      switch (prim->type)
245      {
246         /**
247          * Try to stay in one Begin/End block as long as possible,
248          * since entering and leaving one is most expensive..
249          */
250         case render_primitive::LINE:
251            // check if it's really a point
252/*
253                if (((prim->bounds.x1 - prim->bounds.x0) == 0) && ((prim->bounds.y1 - prim->bounds.y0) == 0))
254                {
255                    curPrimitive=GL_POINTS;
256                } else {
257                    curPrimitive=GL_LINES;
258                }
259
260                if(pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
261                {
262                    glEnd();
263                    pendingPrimitive=GL_NO_PRIMITIVE;
264                }
265
266                if ( pendingPrimitive==GL_NO_PRIMITIVE )
267                {
268                            set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags));
269                }
270
271                glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
272
273                if(pendingPrimitive!=curPrimitive)
274                {
275                    glBegin(curPrimitive);
276                    pendingPrimitive=curPrimitive;
277                }
278
279                // check if it's really a point
280                if (curPrimitive==GL_POINTS)
281                {
282                    glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
283                }
284                else
285                {
286                    glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
287                    glVertex2f(prim->bounds.x1+hofs, prim->bounds.y1+vofs);
288                }*/
289            break;
290
291         case render_primitive::QUAD:
292/*
293                if(pendingPrimitive!=GL_NO_PRIMITIVE)
294                {
295                    glEnd();
296                    pendingPrimitive=GL_NO_PRIMITIVE;
297                }
298
299                glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
300
301                set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags));
302
303                texture = texture_update(window, prim, 0);
304
305
306                sdl->texVerticex[0]=prim->bounds.x0 + hofs;
307                sdl->texVerticex[1]=prim->bounds.y0 + vofs;
308                sdl->texVerticex[2]=prim->bounds.x1 + hofs;
309                sdl->texVerticex[3]=prim->bounds.y0 + vofs;
310                sdl->texVerticex[4]=prim->bounds.x1 + hofs;
311                sdl->texVerticex[5]=prim->bounds.y1 + vofs;
312                sdl->texVerticex[6]=prim->bounds.x0 + hofs;
313                sdl->texVerticex[7]=prim->bounds.y1 + vofs;
314
315                glDrawArrays(GL_QUADS, 0, 4);
316*/
317            break;
318
319         default:
320            throw emu_fatalerror("Unexpected render_primitive type");
321      }
322   }
323
324   window().m_primlist->release_lock();
325   // Advance to next frame. Rendering thread will be kicked to
326   // process submitted rendering primitives.
327   bgfx::frame();
328
329   return 0;
330}
trunk/src/osd/modules/render/drawd3d.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawd3d.c - Win32 Direct3D implementation
6//
7//============================================================
8
9// Useful info:
10//  Windows XP/2003 shipped with DirectX 8.1
11//  Windows 2000 shipped with DirectX 7a
12//  Windows 98SE shipped with DirectX 6.1a
13//  Windows 98 shipped with DirectX 5
14//  Windows NT shipped with DirectX 3.0a
15//  Windows 95 shipped with DirectX 2
16
17// standard windows headers
18#define WIN32_LEAN_AND_MEAN
19#include <windows.h>
20#include <tchar.h>
21#include <mmsystem.h>
22#include <d3d9.h>
23#include <d3dx9.h>
24#include <math.h>
25#undef interface
26
27// MAME headers
28#include "emu.h"
29#include "render.h"
30#include "ui/ui.h"
31#include "rendutil.h"
32#include "options.h"
33#include "emuopts.h"
34#include "aviio.h"
35#include "png.h"
36
37// MAMEOS headers
38#include "modules/render/d3d/d3dintf.h"
39#include "winmain.h"
40#include "window.h"
41#include "config.h"
42#include "strconv.h"
43#include "modules/render/d3d/d3dcomm.h"
44#include "drawd3d.h"
45
46
47
48//============================================================
49//  DEBUGGING
50//============================================================
51
52extern void mtlog_add(const char *event);
53
54
55
56//============================================================
57//  CONSTANTS
58//============================================================
59
60#define ENABLE_BORDER_PIX   (1)
61
62enum
63{
64   TEXTURE_TYPE_PLAIN,
65   TEXTURE_TYPE_DYNAMIC,
66   TEXTURE_TYPE_SURFACE
67};
68
69
70
71//============================================================
72//  MACROS
73//============================================================
74
75#define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0)
76
77
78
79//============================================================
80//  GLOBALS
81//============================================================
82
83static const line_aa_step line_aa_1step[] =
84{
85   {  0.00f,  0.00f,  1.00f  },
86   { 0 }
87};
88
89static const line_aa_step line_aa_4step[] =
90{
91   { -0.25f,  0.00f,  0.25f  },
92   {  0.25f,  0.00f,  0.25f  },
93   {  0.00f, -0.25f,  0.25f  },
94   {  0.00f,  0.25f,  0.25f  },
95   { 0 }
96};
97
98//============================================================
99//  INLINES
100//============================================================
101
102INLINE BOOL GetClientRectExceptMenu(HWND hWnd, PRECT pRect, BOOL fullscreen)
103{
104   static HMENU last_menu;
105   static RECT last_rect;
106   static RECT cached_rect;
107   HMENU menu = GetMenu(hWnd);
108   BOOL result = GetClientRect(hWnd, pRect);
109
110   if (!fullscreen || !menu)
111      return result;
112
113   // to avoid flicker use cache if we can use
114   if (last_menu != menu || memcmp(&last_rect, pRect, sizeof *pRect) != 0)
115   {
116      last_menu = menu;
117      last_rect = *pRect;
118
119      SetMenu(hWnd, NULL);
120      result = GetClientRect(hWnd, &cached_rect);
121      SetMenu(hWnd, menu);
122   }
123
124   *pRect = cached_rect;
125   return result;
126}
127
128
129INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr)
130{
131   /* original equations:
132
133       C = Y - 16
134       D = Cb - 128
135       E = Cr - 128
136
137       R = clip(( 298 * C           + 409 * E + 128) >> 8)
138       G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
139       B = clip(( 298 * C + 516 * D           + 128) >> 8)
140
141       R = clip(( 298 * (Y - 16)                    + 409 * (Cr - 128) + 128) >> 8)
142       G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8)
143       B = clip(( 298 * (Y - 16) + 516 * (Cb - 128)                    + 128) >> 8)
144
145       R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
146       G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
147       B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
148
149       R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
150       G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
151       B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
152   */
153   int r, g, b, common;
154
155   common = 298 * y - 298 * 16;
156   r = (common +                        409 * cr - 409 * 128 + 128) >> 8;
157   g = (common - 100 * cb + 100 * 128 - 208 * cr + 208 * 128 + 128) >> 8;
158   b = (common + 516 * cb - 516 * 128                        + 128) >> 8;
159
160   if (r < 0) r = 0;
161   else if (r > 255) r = 255;
162   if (g < 0) g = 0;
163   else if (g > 255) g = 255;
164   if (b < 0) b = 0;
165   else if (b > 255) b = 255;
166
167   return rgb_t(0xff, r, g, b);
168}
169
170//============================================================
171//  drawd3d_init
172//============================================================
173
174static d3d::base *               d3dintf; // FIX ME
175
176//============================================================
177//  PROTOTYPES
178//============================================================
179
180// core functions
181static void drawd3d_exit(void);
182
183//============================================================
184//  drawd3d_window_init
185//============================================================
186
187int d3d::renderer::create()
188{
189   if (!initialize())
190   {
191      destroy();
192      osd_printf_error("Unable to initialize Direct3D.\n");
193      return 1;
194   }
195
196   return 0;
197}
198
199//============================================================
200//  drawd3d_exit
201//============================================================
202
203static void drawd3d_exit(void)
204{
205   if (d3dintf != NULL)
206      (*d3dintf->d3d.release)(d3dintf);
207}
208
209void d3d::renderer::toggle_fsfx()
210{
211   set_restarting(true);
212}
213
214void d3d::renderer::record()
215{
216   get_shaders()->window_record();
217}
218
219void d3d::renderer::save()
220{
221   get_shaders()->window_save();
222}
223
224
225
226//============================================================
227//  drawd3d_window_destroy
228//============================================================
229
230void d3d::renderer::destroy()
231{
232   if (get_shaders() != NULL && get_shaders()->recording())
233      get_shaders()->window_record();
234
235}
236
237
238
239//============================================================
240//  drawd3d_window_get_primitives
241//============================================================
242
243render_primitive_list *d3d::renderer::get_primitives()
244{
245   RECT client;
246
247   GetClientRectExceptMenu(window().m_hwnd, &client, window().fullscreen());
248   if (rect_width(&client) > 0 && rect_height(&client) > 0)
249   {
250      window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
251      window().target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh());
252   }
253   return &window().target()->get_primitives();
254}
255
256//============================================================
257//  drawnone_create
258//============================================================
259
260static osd_renderer *drawd3d_create(osd_window *window)
261{
262   return global_alloc(d3d::renderer(window));
263}
264
265int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks)
266{
267   d3dintf = NULL;
268
269   // Use Direct3D9
270   d3dintf = d3d::drawd3d9_init();
271
272   // if we failed, note the error
273   if (d3dintf == NULL)
274   {
275      osd_printf_error("Unable to initialize Direct3D.\n");
276      return 1;
277   }
278
279   // fill in the callbacks
280   memset(callbacks, 0, sizeof(*callbacks));
281   callbacks->exit = drawd3d_exit;
282   callbacks->create = drawd3d_create;
283   return 0;
284}
285
286//============================================================
287//  drawd3d_window_draw
288//============================================================
289
290int d3d::renderer::draw(const int update)
291{
292   int check = pre_window_draw_check();
293   if (check >= 0)
294      return check;
295
296   begin_frame();
297   process_primitives();
298   end_frame();
299
300   return 0;
301}
302
303namespace d3d
304{
305void renderer::set_texture(texture_info *texture)
306{
307   if (texture != m_last_texture)
308   {
309      m_last_texture = texture;
310      m_last_texture_flags = (texture == NULL ? 0 : texture->get_flags());
311      HRESULT result = (*d3dintf->device.set_texture)(m_device, 0, (texture == NULL) ? get_default_texture()->get_finaltex() : texture->get_finaltex());
312      m_shaders->set_texture(texture);
313      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result);
314   }
315}
316
317
318void renderer::set_filter(int filter)
319{
320   if (filter != m_last_filter)
321   {
322      m_last_filter = filter;
323      HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
324      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
325      result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
326      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
327      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
328      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
329      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
330      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
331   }
332}
333
334
335void renderer::set_wrap(D3DTEXTUREADDRESS wrap)
336{
337   if (wrap != m_last_wrap)
338   {
339      m_last_wrap = wrap;
340      HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, wrap);
341      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
342      result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, wrap);
343      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
344      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, wrap);
345      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
346      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, wrap);
347      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
348   }
349}
350
351
352void renderer::set_modmode(DWORD modmode)
353{
354   if (modmode != m_last_modmode)
355   {
356      m_last_modmode = modmode;
357      HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_COLOROP, modmode);
358      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
359      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_COLOROP, modmode);
360      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
361   }
362}
363
364
365void renderer::set_blendmode(int blendmode)
366{
367   int blendenable;
368   int blendop;
369   int blendsrc;
370   int blenddst;
371
372   // choose the parameters
373   switch (blendmode)
374   {
375      default:
376      case BLENDMODE_NONE:            blendenable = FALSE;    blendop = D3DBLENDOP_ADD;   blendsrc = D3DBLEND_SRCALPHA;   blenddst = D3DBLEND_INVSRCALPHA;    break;
377      case BLENDMODE_ALPHA:           blendenable = TRUE;     blendop = D3DBLENDOP_ADD;   blendsrc = D3DBLEND_SRCALPHA;   blenddst = D3DBLEND_INVSRCALPHA;    break;
378      case BLENDMODE_RGB_MULTIPLY:    blendenable = TRUE;     blendop = D3DBLENDOP_ADD;   blendsrc = D3DBLEND_DESTCOLOR;  blenddst = D3DBLEND_ZERO;           break;
379      case BLENDMODE_ADD:             blendenable = TRUE;     blendop = D3DBLENDOP_ADD;   blendsrc = D3DBLEND_SRCALPHA;   blenddst = D3DBLEND_ONE;            break;
380   }
381
382   // adjust the bits that changed
383   if (blendenable != m_last_blendenable)
384   {
385      m_last_blendenable = blendenable;
386      HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHABLENDENABLE, blendenable);
387      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
388   }
389
390   if (blendop != m_last_blendop)
391   {
392      m_last_blendop = blendop;
393      HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_BLENDOP, blendop);
394      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
395   }
396
397   if (blendsrc != m_last_blendsrc)
398   {
399      m_last_blendsrc = blendsrc;
400      HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SRCBLEND, blendsrc);
401      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
402   }
403
404   if (blenddst != m_last_blenddst)
405   {
406      m_last_blenddst = blenddst;
407      HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_DESTBLEND, blenddst);
408      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
409   }
410}
411
412
413void renderer::reset_render_states()
414{
415   // this ensures subsequent calls to the above setters will force-update the data
416   m_last_texture = (texture_info *)~0;
417   m_last_filter = -1;
418   m_last_blendenable = -1;
419   m_last_blendop = -1;
420   m_last_blendsrc = -1;
421   m_last_blenddst = -1;
422   m_last_wrap = (D3DTEXTUREADDRESS)-1;
423}
424
425
426
427texture_manager::texture_manager(renderer *d3d)
428{
429   m_renderer = d3d;
430
431   m_texlist = NULL;
432   m_vector_texture = NULL;
433   m_default_texture = NULL;
434
435   // check for dynamic texture support
436   DWORD tempcaps;
437   HRESULT result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_CAPS2, &tempcaps);
438   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
439   m_dynamic_supported = ((tempcaps & D3DCAPS2_DYNAMICTEXTURES) != 0);
440   if (m_dynamic_supported) osd_printf_verbose("Direct3D: Using dynamic textures\n");
441
442   // check for stretchrect support
443   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_STRETCH_RECT_FILTER, &tempcaps);
444   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
445   m_stretch_supported = ((tempcaps & D3DPTFILTERCAPS_MAGFPOINT) != 0);
446   if (m_stretch_supported && video_config.prescale > 1) osd_printf_verbose("Direct3D: Using StretchRect for prescaling\n");
447
448   // get texture caps
449   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_TEXTURE_CAPS, &m_texture_caps);
450   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
451   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_ASPECT, &m_texture_max_aspect);
452   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
453   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_WIDTH, &m_texture_max_width);
454   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
455   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_HEIGHT, &m_texture_max_height);
456   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
457
458   // pick a YUV texture format
459   m_yuv_format = D3DFMT_UYVY;
460   result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
461   if (result != D3D_OK)
462   {
463      m_yuv_format = D3DFMT_YUY2;
464      result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
465      if (result != D3D_OK)
466         m_yuv_format = D3DFMT_A8R8G8B8;
467   }
468   osd_printf_verbose("Direct3D: YUV format = %s\n", (m_yuv_format == D3DFMT_YUY2) ? "YUY2" : (m_yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB");
469
470   // set the max texture size
471   d3d->window().target()->set_max_texture_size(m_texture_max_width, m_texture_max_height);
472   osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height);
473}
474
475texture_manager::~texture_manager()
476{
477}
478
479void texture_manager::create_resources()
480{
481   // experimental: load a PNG to use for vector rendering; it is treated
482   // as a brightness map
483   emu_file file(m_renderer->window().machine().options().art_path(), OPEN_FLAG_READ);
484   render_load_png(m_vector_bitmap, file, NULL, "vector.png");
485   if (m_vector_bitmap.valid())
486   {
487      m_vector_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
488      render_load_png(m_vector_bitmap, file, NULL, "vector.png", true);
489   }
490
491   m_default_bitmap.allocate(8, 8);
492   m_default_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
493
494   if (m_default_bitmap.valid())
495   {
496      render_texinfo texture;
497
498      // fake in the basic data so it looks like it came from render.c
499      texture.base = m_default_bitmap.raw_pixptr(0);
500      texture.rowpixels = m_default_bitmap.rowpixels();
501      texture.width = m_default_bitmap.width();
502      texture.height = m_default_bitmap.height();
503      texture.palette = NULL;
504      texture.seqid = 0;
505
506      // now create it
507      m_default_texture = global_alloc(texture_info(this, &texture, m_renderer->window().prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32)));
508   }
509
510   // experimental: if we have a vector bitmap, create a texture for it
511   if (m_vector_bitmap.valid())
512   {
513      render_texinfo texture;
514
515      // fake in the basic data so it looks like it came from render.c
516      texture.base = &m_vector_bitmap.pix32(0);
517      texture.rowpixels = m_vector_bitmap.rowpixels();
518      texture.width = m_vector_bitmap.width();
519      texture.height = m_vector_bitmap.height();
520      texture.palette = NULL;
521      texture.seqid = 0;
522
523      // now create it
524      m_vector_texture = global_alloc(texture_info(this, &texture, m_renderer->window().prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32)));
525   }
526}
527
528void texture_manager::delete_resources()
529{
530   // is part of m_texlist and will be free'd there
531   //global_free(m_default_texture);
532   m_default_texture = NULL;
533
534   //global_free(m_vector_texture);
535   m_vector_texture = NULL;
536
537   // free all textures
538   while (m_texlist != NULL)
539   {
540      texture_info *tex = m_texlist;
541      m_texlist = tex->get_next();
542      global_free(tex);
543   }
544}
545
546UINT32 texture_manager::texture_compute_hash(const render_texinfo *texture, UINT32 flags)
547{
548   return (FPTR)texture->base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK));
549}
550
551texture_info *texture_manager::find_texinfo(const render_texinfo *texinfo, UINT32 flags)
552{
553   UINT32 hash = texture_compute_hash(texinfo, flags);
554   texture_info *texture;
555
556   // find a match
557   for (texture = m_renderer->get_texture_manager()->get_texlist(); texture != NULL; texture = texture->get_next())
558   {
559      UINT32 test_screen = (UINT32)texture->get_texinfo().osddata >> 1;
560      UINT32 test_page = (UINT32)texture->get_texinfo().osddata & 1;
561      UINT32 prim_screen = (UINT32)texinfo->osddata >> 1;
562      UINT32 prim_page = (UINT32)texinfo->osddata & 1;
563      if (test_screen != prim_screen || test_page != prim_page)
564      {
565         continue;
566      }
567
568      if (texture->get_hash() == hash &&
569         texture->get_texinfo().base == texinfo->base &&
570         texture->get_texinfo().width == texinfo->width &&
571         texture->get_texinfo().height == texinfo->height &&
572         ((texture->get_flags() ^ flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0)
573      {
574         // Reject a texture if it belongs to an out-of-date render target, so as to cause the HLSL system to re-cache
575         if (m_renderer->get_shaders()->enabled() && texinfo->width != 0 && texinfo->height != 0 && (flags & PRIMFLAG_SCREENTEX_MASK) != 0)
576         {
577            if (m_renderer->get_shaders()->find_render_target(texture) != NULL)
578            {
579               return texture;
580            }
581         }
582         else
583         {
584            return texture;
585         }
586      }
587   }
588
589   // Nothing found, check if we need to unregister something with HLSL
590   if (m_renderer->get_shaders()->enabled())
591   {
592      if (texinfo->width == 0 || texinfo->height == 0)
593      {
594         return NULL;
595      }
596
597      UINT32 prim_screen = texinfo->osddata >> 1;
598      UINT32 prim_page = texinfo->osddata & 1;
599
600      for (texture = m_renderer->get_texture_manager()->get_texlist(); texture != NULL; texture = texture->get_next())
601      {
602         UINT32 test_screen = texture->get_texinfo().osddata >> 1;
603         UINT32 test_page = texture->get_texinfo().osddata & 1;
604         if (test_screen != prim_screen || test_page != prim_page)
605         {
606            continue;
607         }
608
609         // Clear out our old texture reference
610         if (texture->get_hash() == hash &&
611            texture->get_texinfo().base == texinfo->base &&
612            ((texture->get_flags() ^ flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0 &&
613            (texture->get_texinfo().width != texinfo->width ||
614               texture->get_texinfo().height != texinfo->height))
615         {
616            m_renderer->get_shaders()->remove_render_target(texture);
617         }
618      }
619   }
620
621   return NULL;
622}
623
624renderer::renderer(osd_window *window)
625   : osd_renderer(window, FLAG_NONE)
626{
627   m_device = NULL;
628   m_restarting = false;
629   m_shaders = NULL;
630   m_numverts = 0;
631   m_numpolys = 0;
632   m_vertexbuf = NULL;
633   m_lockedbuf = NULL;
634   m_vectorbatch = NULL;
635   m_last_texture = NULL;
636   m_hlsl_buf = NULL;
637   m_texture_manager = NULL;
638}
639
640int renderer::initialize()
641{
642   // configure the adapter for the mode we want
643   if (config_adapter_mode())
644      return false;
645
646   // create the device immediately for the full screen case (defer for window mode)
647   if (window().fullscreen() && device_create(window().m_focus_hwnd))
648      return false;
649
650   return true;
651}
652
653int renderer::pre_window_draw_check()
654{
655   // if we're in the middle of resizing, leave things alone
656   if (window().m_resize_state == RESIZE_STATE_RESIZING)
657      return 0;
658
659   // if we're restarting the renderer, leave things alone
660   if (m_restarting)
661   {
662      m_shaders->toggle();
663
664      // free all existing resources and re-create
665      device_delete_resources();
666      device_create_resources();
667
668      m_restarting = false;
669   }
670
671   // if we have a device, check the cooperative level
672   if (m_device != NULL)
673   {
674      if (device_test_cooperative())
675      {
676         return 1;
677      }
678   }
679
680   // in window mode, we need to track the window size
681   if (!window().fullscreen() || m_device == NULL)
682   {
683      // if the size changes, skip this update since the render target will be out of date
684      if (update_window_size())
685         return 0;
686
687      // if we have no device, after updating the size, return an error so GDI can try
688      if (m_device == NULL)
689         return 1;
690   }
691
692   return -1;
693}
694
695void texture_manager::update_textures()
696{
697   for (render_primitive *prim = m_renderer->window().m_primlist->first(); prim != NULL; prim = prim->next())
698   {
699      if (prim->texture.base != NULL)
700      {
701         texture_info *texture = find_texinfo(&prim->texture, prim->flags);
702         if (texture == NULL)
703         {
704            // if there isn't one, create a new texture
705            global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags));
706         }
707         else
708         {
709            // if there is one, but with a different seqid, copy the data
710            if (texture->get_texinfo().seqid != prim->texture.seqid)
711            {
712               texture->set_data(&prim->texture, prim->flags);
713               texture->get_texinfo().seqid = prim->texture.seqid;
714            }
715         }
716      }
717      else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim->flags))
718      {
719         if (!m_renderer->get_shaders()->get_vector_target())
720         {
721            m_renderer->get_shaders()->create_vector_target(prim);
722         }
723      }
724   }
725}
726
727void renderer::begin_frame()
728{
729   HRESULT result = (*d3dintf->device.clear)(m_device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
730   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
731
732   m_shaders->begin_frame();
733
734   window().m_primlist->acquire_lock();
735
736   // first update any textures
737   m_texture_manager->update_textures();
738
739   // begin the scene
740mtlog_add("drawd3d_window_draw: begin_scene");
741   result = (*d3dintf->device.begin_scene)(m_device);
742   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
743
744   m_lockedbuf = NULL;
745
746   if(m_shaders->enabled())
747   {
748      m_hlsl_buf = (void*)mesh_alloc(6);
749      m_shaders->init_fsfx_quad(m_hlsl_buf);
750   }
751
752   m_line_count = 0;
753
754   // loop over primitives
755   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
756      if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags))
757         m_line_count++;
758}
759
760void renderer::process_primitives()
761{
762   // Rotating index for vector time offsets
763   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
764   {
765      switch (prim->type)
766      {
767         case render_primitive::LINE:
768            if (PRIMFLAG_GET_VECTOR(prim->flags))
769            {
770               if (m_line_count > 0)
771                  batch_vectors();
772               else
773                  continue;
774            }
775            else
776            {
777               draw_line(prim);
778            }
779            break;
780
781         case render_primitive::QUAD:
782            draw_quad(prim);
783            break;
784
785         default:
786            throw emu_fatalerror("Unexpected render_primitive type");
787      }
788   }
789}
790
791void renderer::end_frame()
792{
793   window().m_primlist->release_lock();
794
795   // flush any pending polygons
796   primitive_flush_pending();
797
798   m_shaders->end_frame();
799
800   // finish the scene
801   HRESULT result = (*d3dintf->device.end_scene)(m_device);
802   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result);
803
804   // present the current buffers
805   result = (*d3dintf->device.present)(m_device, NULL, NULL, NULL, NULL, 0);
806   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device present call\n", (int)result);
807}
808
809//============================================================
810//  device_create
811//============================================================
812
813int renderer::device_create(HWND device_hwnd)
814{
815   // if a device exists, free it
816   if (m_device != NULL)
817      device_delete();
818
819   // verify the caps
820   int verify = device_verify_caps();
821   if (verify == 2)
822   {
823      osd_printf_error("Error: Device does not meet minimum requirements for Direct3D rendering\n");
824      return 1;
825   }
826   if (verify == 1)
827      osd_printf_warning("Warning: Device may not perform well for Direct3D rendering\n");
828
829   // verify texture formats
830   HRESULT result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
831   if (result != D3D_OK)
832   {
833      osd_printf_error("Error: A8R8G8B8 format textures not supported\n");
834      return 1;
835   }
836
837   m_texture_manager = global_alloc(texture_manager(this));
838
839try_again:
840   // try for XRGB first
841   m_screen_format = D3DFMT_X8R8G8B8;
842   result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, m_screen_format);
843   if (result != D3D_OK)
844   {
845      // if not, try for ARGB
846      m_screen_format = D3DFMT_A8R8G8B8;
847      result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, m_screen_format);
848      if (result != D3D_OK && m_texture_manager->is_dynamic_supported())
849      {
850         m_texture_manager->set_dynamic_supported(FALSE);
851         goto try_again;
852      }
853      if (result != D3D_OK)
854      {
855         osd_printf_error("Error: unable to configure a screen texture format\n");
856         return 1;
857      }
858   }
859
860   // initialize the D3D presentation parameters
861   memset(&m_presentation, 0, sizeof(m_presentation));
862   m_presentation.BackBufferWidth               = m_width;
863   m_presentation.BackBufferHeight              = m_height;
864   m_presentation.BackBufferFormat              = m_pixformat;
865   m_presentation.BackBufferCount               = video_config.triplebuf ? 2 : 1;
866   m_presentation.MultiSampleType               = D3DMULTISAMPLE_NONE;
867   m_presentation.SwapEffect                    = D3DSWAPEFFECT_DISCARD;
868   m_presentation.hDeviceWindow                 = window().m_hwnd;
869   m_presentation.Windowed                      = !window().fullscreen() || window().win_has_menu();
870   m_presentation.EnableAutoDepthStencil        = FALSE;
871   m_presentation.AutoDepthStencilFormat        = D3DFMT_D16;
872   m_presentation.Flags                         = 0;
873   m_presentation.FullScreen_RefreshRateInHz    = m_refresh;
874   m_presentation.PresentationInterval          = ((video_config.triplebuf && window().fullscreen()) ||
875                                       video_config.waitvsync || video_config.syncrefresh) ?
876                                       D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
877
878   // create the D3D device
879   result = (*d3dintf->d3d.create_device)(d3dintf, m_adapter, D3DDEVTYPE_HAL, device_hwnd,
880               D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &m_presentation, &m_device);
881   if (result != D3D_OK)
882   {
883      // if we got a "DEVICELOST" error, it may be transitory; count it and only fail if
884      // we exceed a threshold
885      if (result == D3DERR_DEVICELOST)
886      {
887         m_create_error_count++;
888         if (m_create_error_count < 10)
889         {
890            return 0;
891         }
892      }
893
894      //  fatal error if we just can't do it
895      osd_printf_error("Unable to create the Direct3D device (%08X)\n", (UINT32)result);
896      return 1;
897   }
898   m_create_error_count = 0;
899   osd_printf_verbose("Direct3D: Device created at %dx%d\n", m_width, m_height);
900
901   // set the gamma if we need to
902   if (window().fullscreen())
903   {
904      // only set the gamma if it's not 1.0f
905      windows_options &options = downcast<windows_options &>(window().machine().options());
906      float brightness = options.full_screen_brightness();
907      float contrast = options.full_screen_contrast();
908      float gamma = options.full_screen_gamma();
909      if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f)
910      {
911         // warn if we can't do it
912         if (!m_gamma_supported)
913         {
914            osd_printf_warning("Direct3D: Warning - device does not support full screen gamma correction.\n");
915         }
916         else
917         {
918            // create a standard ramp and set it
919            D3DGAMMARAMP ramp;
920            for (int i = 0; i < 256; i++)
921            {
922               ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, gamma) << 8;
923            }
924            (*d3dintf->device.set_gamma_ramp)(m_device, 0, &ramp);
925         }
926      }
927   }
928
929   int ret = m_shaders->create_resources(false);
930   if (ret != 0)
931      return ret;
932
933   return device_create_resources();
934}
935
936
937
938//============================================================
939//  device_create_resources
940//============================================================
941
942int renderer::device_create_resources()
943{
944   // allocate a vertex buffer to use
945   HRESULT result = (*d3dintf->device.create_vertex_buffer)(m_device,
946            sizeof(vertex) * VERTEX_BUFFER_SIZE,
947            D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
948            VERTEX_BASE_FORMAT | ((m_shaders->enabled() && d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW),
949            D3DPOOL_DEFAULT, &m_vertexbuf);
950   if (result != D3D_OK)
951   {
952      osd_printf_error("Error creating vertex buffer (%08X)\n", (UINT32)result);
953      return 1;
954   }
955
956   // set the vertex format
957   result = (*d3dintf->device.set_vertex_format)(m_device, (D3DFORMAT)(VERTEX_BASE_FORMAT | ((m_shaders->enabled() &&
958      d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW)));
959   if (result != D3D_OK)
960   {
961      osd_printf_error("Error setting vertex format (%08X)\n", (UINT32)result);
962      return 1;
963   }
964
965   // set the fixed render state
966   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZENABLE, D3DZB_FALSE);
967   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_FILLMODE, D3DFILL_SOLID);
968   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SHADEMODE, D3DSHADE_FLAT);
969   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZWRITEENABLE, FALSE);
970   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHATESTENABLE, TRUE);
971   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_LASTPIXEL, TRUE);
972   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_CULLMODE, D3DCULL_NONE);
973   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZFUNC, D3DCMP_LESS);
974   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHAREF, 0);
975   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHAFUNC, D3DCMP_GREATER);
976   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_DITHERENABLE, FALSE);
977   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_FOGENABLE, FALSE);
978   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SPECULARENABLE, FALSE);
979   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_STENCILENABLE, FALSE);
980   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_WRAP0, FALSE);
981   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_CLIPPING, TRUE);
982   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_LIGHTING, FALSE);
983   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_COLORVERTEX, TRUE);
984
985   result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
986   result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
987   result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
988   result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
989
990   // reset the local states to force updates
991   reset_render_states();
992
993   // clear the buffer
994   result = (*d3dintf->device.clear)(m_device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
995   result = (*d3dintf->device.present)(m_device, NULL, NULL, NULL, NULL, 0);
996
997   m_texture_manager->create_resources();
998
999   return 0;
1000}
1001
1002
1003
1004//============================================================
1005//  device_delete
1006//============================================================
1007
1008renderer::~renderer()
1009{
1010   device_delete();
1011}
1012
1013void renderer::device_delete()
1014{
1015   if (m_shaders != NULL)
1016   {
1017      // free our effects
1018      m_shaders->delete_resources(false);
1019
1020      // delete the HLSL interface
1021      global_free(m_shaders);
1022   }
1023
1024   // free our base resources
1025   device_delete_resources();
1026
1027   if (m_texture_manager != NULL)
1028   {
1029      global_free(m_texture_manager);
1030   }
1031   m_texture_manager = NULL;
1032
1033   // free the device itself
1034   if (m_device != NULL)
1035   {
1036      (*d3dintf->device.reset)(m_device, &m_presentation);
1037      (*d3dintf->device.release)(m_device);
1038   }
1039   m_device = NULL;
1040}
1041
1042//============================================================
1043//  device_delete_resources
1044//============================================================
1045
1046void renderer::device_delete_resources()
1047{
1048   if (m_texture_manager != NULL)
1049      m_texture_manager->delete_resources();
1050   // free the vertex buffer
1051   if (m_vertexbuf != NULL)
1052      (*d3dintf->vertexbuf.release)(m_vertexbuf);
1053   m_vertexbuf = NULL;
1054}
1055
1056
1057
1058//============================================================
1059//  device_verify_caps
1060//============================================================
1061
1062int renderer::device_verify_caps()
1063{
1064   int retval = 0;
1065
1066   m_shaders = global_alloc_clear(shaders);
1067   // FIXME: Dynamic cast
1068   m_shaders->init(d3dintf, &window().machine(), this);
1069
1070   DWORD tempcaps;
1071   HRESULT result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_MAX_PS30_INSN_SLOTS, &tempcaps);
1072   if (result != D3D_OK) osd_printf_verbose("Direct3D Error %08X during get_caps_dword call\n", (int)result);
1073   if (tempcaps < 512)
1074   {
1075      osd_printf_verbose("Direct3D: Warning - Device does not support Pixel Shader 3.0, falling back to non-PS rendering\n");
1076      d3dintf->post_fx_available = false;
1077   }
1078
1079   // verify presentation capabilities
1080   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_PRESENTATION_INTERVALS, &tempcaps);
1081   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
1082   if (!(tempcaps & D3DPRESENT_INTERVAL_IMMEDIATE))
1083   {
1084      osd_printf_verbose("Direct3D: Error - Device does not support immediate presentations\n");
1085      retval = 2;
1086   }
1087   if (!(tempcaps & D3DPRESENT_INTERVAL_ONE))
1088   {
1089      osd_printf_verbose("Direct3D: Error - Device does not support per-refresh presentations\n");
1090      retval = 2;
1091   }
1092
1093   // verify device capabilities
1094   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_DEV_CAPS, &tempcaps);
1095   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
1096   if (!(tempcaps & D3DDEVCAPS_CANRENDERAFTERFLIP))
1097   {
1098      osd_printf_verbose("Direct3D: Warning - Device does not support queued rendering after a page flip\n");
1099      retval = 1;
1100   }
1101   if (!(tempcaps & D3DDEVCAPS_HWRASTERIZATION))
1102   {
1103      osd_printf_verbose("Direct3D: Warning - Device does not support hardware rasterization\n");
1104      retval = 1;
1105   }
1106
1107   // verify texture operation capabilities
1108   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_TEXTURE_OP_CAPS, &tempcaps);
1109   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
1110   if (!(tempcaps & D3DTEXOPCAPS_MODULATE))
1111   {
1112      osd_printf_verbose("Direct3D: Warning - Device does not support texture modulation\n");
1113      retval = 1;
1114   }
1115
1116   // set a simpler flag to indicate mod2x and mod4x texture modes
1117   m_mod2x_supported = ((tempcaps & D3DTEXOPCAPS_MODULATE2X) != 0);
1118   m_mod4x_supported = ((tempcaps & D3DTEXOPCAPS_MODULATE4X) != 0);
1119
1120   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_CAPS2, &tempcaps);
1121   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
1122   m_gamma_supported = ((tempcaps & D3DCAPS2_FULLSCREENGAMMA) != 0);
1123
1124   return retval;
1125}
1126
1127
1128
1129//============================================================
1130//  device_test_cooperative
1131//============================================================
1132
1133int renderer::device_test_cooperative()
1134{
1135   // check our current status; if we lost the device, punt to GDI
1136   HRESULT result = (*d3dintf->device.test_cooperative_level)(m_device);
1137   if (result == D3DERR_DEVICELOST)
1138      return 1;
1139
1140   // if we're able to reset ourselves, try it
1141   if (result == D3DERR_DEVICENOTRESET)
1142   {
1143      osd_printf_verbose("Direct3D: resetting device\n");
1144
1145      // free all existing resources and call reset on the device
1146      //device_delete();
1147      device_delete_resources();
1148      m_shaders->delete_resources(true);
1149      result = (*d3dintf->device.reset)(m_device, &m_presentation);
1150
1151      // if it didn't work, punt to GDI
1152      if (result != D3D_OK)
1153      {
1154         osd_printf_error("Unable to reset, result %08x\n", (UINT32)result);
1155         return 1;
1156      }
1157
1158      // try to create the resources again; if that didn't work, delete the whole thing
1159      if (device_create_resources())
1160      {
1161         osd_printf_verbose("Direct3D: failed to recreate resources for device; failing permanently\n");
1162         device_delete();
1163         return 1;
1164      }
1165
1166      if (m_shaders->create_resources(true))
1167      {
1168         osd_printf_verbose("Direct3D: failed to recreate HLSL resources for device; failing permanently\n");
1169         device_delete();
1170         return 1;
1171      }
1172   }
1173   return 0;
1174}
1175
1176
1177
1178//============================================================
1179//  config_adapter_mode
1180//============================================================
1181
1182int renderer::config_adapter_mode()
1183{
1184   adapter_identifier identifier;
1185
1186   // choose the monitor number
1187   m_adapter = get_adapter_for_monitor();
1188
1189   // get the identifier
1190   HRESULT result = (*d3dintf->d3d.get_adapter_identifier)(d3dintf, m_adapter, 0, &identifier);
1191   if (result != D3D_OK)
1192   {
1193      osd_printf_error("Error getting identifier for adapter #%d\n", m_adapter);
1194      return 1;
1195   }
1196   osd_printf_verbose("Direct3D: Configuring adapter #%d = %s\n", m_adapter, identifier.Description);
1197
1198   // get the current display mode
1199   result = (*d3dintf->d3d.get_adapter_display_mode)(d3dintf, m_adapter, &m_origmode);
1200   if (result != D3D_OK)
1201   {
1202      osd_printf_error("Error getting mode for adapter #%d\n", m_adapter);
1203      return 1;
1204   }
1205
1206   // choose a resolution: window mode case
1207   if (!window().fullscreen() || !video_config.switchres || window().win_has_menu())
1208   {
1209      RECT client;
1210
1211      // bounds are from the window client rect
1212      GetClientRectExceptMenu(window().m_hwnd, &client, window().fullscreen());
1213      m_width = client.right - client.left;
1214      m_height = client.bottom - client.top;
1215
1216      // pix format is from the current mode
1217      m_pixformat = m_origmode.Format;
1218      m_refresh = 0;
1219
1220      // make sure it's a pixel format we can get behind
1221      if (m_pixformat != D3DFMT_X1R5G5B5 && m_pixformat != D3DFMT_R5G6B5 && m_pixformat != D3DFMT_X8R8G8B8)
1222      {
1223         osd_printf_error("Device %s currently in an unsupported mode\n", window().monitor()->devicename());
1224         return 1;
1225      }
1226   }
1227
1228   // choose a resolution: full screen mode case
1229   else
1230   {
1231      // default to the current mode exactly
1232      m_width = m_origmode.Width;
1233      m_height = m_origmode.Height;
1234      m_pixformat = m_origmode.Format;
1235      m_refresh = m_origmode.RefreshRate;
1236
1237      // if we're allowed to switch resolutions, override with something better
1238      if (video_config.switchres)
1239         pick_best_mode();
1240   }
1241
1242   // see if we can handle the device type
1243   result = (*d3dintf->d3d.check_device_type)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !window().fullscreen());
1244   if (result != D3D_OK)
1245   {
1246      osd_printf_error("Proposed video mode not supported on device %s\n", window().monitor()->devicename());
1247      return 1;
1248   }
1249   return 0;
1250}
1251
1252
1253
1254//============================================================
1255//  get_adapter_for_monitor
1256//============================================================
1257
1258int renderer::get_adapter_for_monitor()
1259{
1260   int maxadapter = (*d3dintf->d3d.get_adapter_count)(d3dintf);
1261
1262   // iterate over adapters until we error or find a match
1263   for (int adapternum = 0; adapternum < maxadapter; adapternum++)
1264   {
1265      // get the monitor for this adapter
1266      HMONITOR curmonitor = (*d3dintf->d3d.get_adapter_monitor)(d3dintf, adapternum);
1267
1268      // if we match the proposed monitor, this is it
1269      if (curmonitor == window().monitor()->handle())
1270      {
1271         return adapternum;
1272      }
1273   }
1274
1275   // default to the default
1276   return D3DADAPTER_DEFAULT;
1277}
1278
1279
1280
1281//============================================================
1282//  pick_best_mode
1283//============================================================
1284
1285void renderer::pick_best_mode()
1286{
1287   double target_refresh = 60.0;
1288   INT32 minwidth, minheight;
1289   float best_score = 0.0f;
1290
1291   // determine the refresh rate of the primary screen
1292   const screen_device *primary_screen = window().machine().config().first_screen();
1293   if (primary_screen != NULL)
1294   {
1295      target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
1296   }
1297
1298   // determine the minimum width/height for the selected target
1299   // note: technically we should not be calling this from an alternate window
1300   // thread; however, it is only done during init time, and the init code on
1301   // the main thread is waiting for us to finish, so it is safe to do so here
1302   window().target()->compute_minimum_size(minwidth, minheight);
1303
1304   // use those as the target for now
1305   INT32 target_width = minwidth;
1306   INT32 target_height = minheight;
1307
1308   // determine the maximum number of modes
1309   int maxmodes = (*d3dintf->d3d.get_adapter_mode_count)(d3dintf, m_adapter, D3DFMT_X8R8G8B8);
1310
1311   // enumerate all the video modes and find the best match
1312   osd_printf_verbose("Direct3D: Selecting video mode...\n");
1313   for (int modenum = 0; modenum < maxmodes; modenum++)
1314   {
1315      // check this mode
1316      D3DDISPLAYMODE mode;
1317      HRESULT result = (*d3dintf->d3d.enum_adapter_modes)(d3dintf, m_adapter, D3DFMT_X8R8G8B8, modenum, &mode);
1318      if (result != D3D_OK)
1319         break;
1320
1321      // skip non-32 bit modes
1322      if (mode.Format != D3DFMT_X8R8G8B8)
1323         continue;
1324
1325      // compute initial score based on difference between target and current
1326      float size_score = 1.0f / (1.0f + fabs((float)(mode.Width - target_width)) + fabs((float)(mode.Height - target_height)));
1327
1328      // if the mode is too small, give a big penalty
1329      if (mode.Width < minwidth || mode.Height < minheight)
1330         size_score *= 0.01f;
1331
1332      // if mode is smaller than we'd like, it only scores up to 0.1
1333      if (mode.Width < target_width || mode.Height < target_height)
1334         size_score *= 0.1f;
1335
1336      // if we're looking for a particular mode, that's a winner
1337      if (mode.Width == window().m_win_config.width && mode.Height == window().m_win_config.height)
1338         size_score = 2.0f;
1339
1340      // compute refresh score
1341      float refresh_score = 1.0f / (1.0f + fabs((double)mode.RefreshRate - target_refresh));
1342
1343      // if refresh is smaller than we'd like, it only scores up to 0.1
1344      if ((double)mode.RefreshRate < target_refresh)
1345         refresh_score *= 0.1f;
1346
1347      // if we're looking for a particular refresh, make sure it matches
1348      if (mode.RefreshRate == window().m_win_config.refresh)
1349         refresh_score = 2.0f;
1350
1351      // weight size and refresh equally
1352      float final_score = size_score + refresh_score;
1353
1354      // best so far?
1355      osd_printf_verbose("  %4dx%4d@%3dHz -> %f\n", mode.Width, mode.Height, mode.RefreshRate, final_score * 1000.0f);
1356      if (final_score > best_score)
1357      {
1358         best_score = final_score;
1359         m_width = mode.Width;
1360         m_height = mode.Height;
1361         m_pixformat = mode.Format;
1362         m_refresh = mode.RefreshRate;
1363      }
1364   }
1365   osd_printf_verbose("Direct3D: Mode selected = %4dx%4d@%3dHz\n", m_width, m_height, m_refresh);
1366}
1367
1368
1369
1370//============================================================
1371//  update_window_size
1372//============================================================
1373
1374int renderer::update_window_size()
1375{
1376   // get the current window bounds
1377   RECT client;
1378   GetClientRectExceptMenu(window().m_hwnd, &client, window().fullscreen());
1379
1380   // if we have a device and matching width/height, nothing to do
1381   if (m_device != NULL && rect_width(&client) == m_width && rect_height(&client) == m_height)
1382   {
1383      // clear out any pending resizing if the area didn't change
1384      if (window().m_resize_state == RESIZE_STATE_PENDING)
1385         window().m_resize_state = RESIZE_STATE_NORMAL;
1386      return FALSE;
1387   }
1388
1389   // if we're in the middle of resizing, leave it alone as well
1390   if (window().m_resize_state == RESIZE_STATE_RESIZING)
1391      return FALSE;
1392
1393   // set the new bounds and create the device again
1394   m_width = rect_width(&client);
1395   m_height = rect_height(&client);
1396   if (device_create(window().m_focus_hwnd))
1397      return FALSE;
1398
1399   // reset the resize state to normal, and indicate we made a change
1400   window().m_resize_state = RESIZE_STATE_NORMAL;
1401   return TRUE;
1402}
1403
1404//============================================================
1405//  batch_vectors
1406//============================================================
1407
1408void renderer::batch_vectors()
1409{
1410   windows_options &options = downcast<windows_options &>(window().machine().options());
1411
1412   int vector_size = (options.antialias() ? 24 : 6);
1413   m_vectorbatch = mesh_alloc(m_line_count * vector_size);
1414   m_batchindex = 0;
1415
1416   static int start_index = 0;
1417   int line_index = 0;
1418   float period = options.screen_vector_time_period();
1419   UINT32 cached_flags = 0;
1420   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
1421   {
1422      switch (prim->type)
1423      {
1424         case render_primitive::LINE:
1425            if (PRIMFLAG_GET_VECTOR(prim->flags))
1426            {
1427               if (period == 0.0f || m_line_count == 0)
1428               {
1429                  batch_vector(prim, 1.0f);
1430               }
1431               else
1432               {
1433                  batch_vector(prim, (float)(start_index + line_index) / ((float)m_line_count * period));
1434                  line_index++;
1435               }
1436               cached_flags = prim->flags;
1437            }
1438            break;
1439
1440         default:
1441            // Skip
1442            break;
1443      }
1444   }
1445
1446   // now add a polygon entry
1447   m_poly[m_numpolys].init(D3DPT_TRIANGLELIST, m_line_count * (options.antialias() ? 8 : 2), vector_size * m_line_count, cached_flags,
1448      m_texture_manager->get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f);
1449   m_numpolys++;
1450
1451   start_index += (int)((float)line_index * period);
1452   if (m_line_count > 0)
1453   {
1454      start_index %= m_line_count;
1455   }
1456
1457   m_line_count = 0;
1458}
1459
1460void renderer::batch_vector(const render_primitive *prim, float line_time)
1461{
1462   // compute the effective width based on the direction of the line
1463   float effwidth = prim->width;
1464   if (effwidth < 0.5f)
1465   {
1466      effwidth = 0.5f;
1467   }
1468
1469   // determine the bounds of a quad to draw this line
1470   render_bounds b0, b1;
1471   render_line_to_quad(&prim->bounds, effwidth, &b0, &b1);
1472
1473   // iterate over AA steps
1474   for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step;
1475      step->weight != 0; step++)
1476   {
1477      // get a pointer to the vertex buffer
1478      if (m_vectorbatch == NULL)
1479         return;
1480
1481      m_vectorbatch[m_batchindex + 0].x = b0.x0 + step->xoffs;
1482      m_vectorbatch[m_batchindex + 0].y = b0.y0 + step->yoffs;
1483      m_vectorbatch[m_batchindex + 1].x = b0.x1 + step->xoffs;
1484      m_vectorbatch[m_batchindex + 1].y = b0.y1 + step->yoffs;
1485      m_vectorbatch[m_batchindex + 2].x = b1.x0 + step->xoffs;
1486      m_vectorbatch[m_batchindex + 2].y = b1.y0 + step->yoffs;
1487
1488      m_vectorbatch[m_batchindex + 3].x = b0.x1 + step->xoffs;
1489      m_vectorbatch[m_batchindex + 3].y = b0.y1 + step->yoffs;
1490      m_vectorbatch[m_batchindex + 4].x = b1.x0 + step->xoffs;
1491      m_vectorbatch[m_batchindex + 4].y = b1.y0 + step->yoffs;
1492      m_vectorbatch[m_batchindex + 5].x = b1.x1 + step->xoffs;
1493      m_vectorbatch[m_batchindex + 5].y = b1.y1 + step->yoffs;
1494
1495      float dx = b1.x1 - b0.x1;
1496      float dy = b1.y1 - b0.y1;
1497      float line_length = sqrtf(dx * dx + dy * dy);
1498
1499      // determine the color of the line
1500      INT32 r = (INT32)(prim->color.r * step->weight * 255.0f);
1501      INT32 g = (INT32)(prim->color.g * step->weight * 255.0f);
1502      INT32 b = (INT32)(prim->color.b * step->weight * 255.0f);
1503      INT32 a = (INT32)(prim->color.a * 255.0f);
1504      if (r > 255 || g > 255 || b > 255)
1505      {
1506         if (r > 2*255 || g > 2*255 || b > 2*255)
1507         {
1508            r >>= 2; g >>= 2; b >>= 2;
1509         }
1510         else
1511         {
1512            r >>= 1; g >>= 1; b >>= 1;
1513         }
1514      }
1515      if (r > 255) r = 255;
1516      if (g > 255) g = 255;
1517      if (b > 255) b = 255;
1518      if (a > 255) a = 255;
1519      DWORD color = D3DCOLOR_ARGB(a, r, g, b);
1520
1521      vec2f& start = (get_vector_texture() ? get_vector_texture()->get_uvstart() : get_default_texture()->get_uvstart());
1522      vec2f& stop = (get_vector_texture() ? get_vector_texture()->get_uvstop() : get_default_texture()->get_uvstop());
1523
1524      m_vectorbatch[m_batchindex + 0].u0 = start.c.x;
1525      m_vectorbatch[m_batchindex + 0].v0 = start.c.y;
1526      m_vectorbatch[m_batchindex + 1].u0 = start.c.x;
1527      m_vectorbatch[m_batchindex + 1].v0 = stop.c.y;
1528      m_vectorbatch[m_batchindex + 2].u0 = stop.c.x;
1529      m_vectorbatch[m_batchindex + 2].v0 = start.c.y;
1530
1531      m_vectorbatch[m_batchindex + 3].u0 = start.c.x;
1532      m_vectorbatch[m_batchindex + 3].v0 = stop.c.y;
1533      m_vectorbatch[m_batchindex + 4].u0 = stop.c.x;
1534      m_vectorbatch[m_batchindex + 4].v0 = start.c.y;
1535      m_vectorbatch[m_batchindex + 5].u0 = stop.c.x;
1536      m_vectorbatch[m_batchindex + 5].v0 = stop.c.y;
1537
1538      m_vectorbatch[m_batchindex + 0].u1 = line_length;
1539      m_vectorbatch[m_batchindex + 1].u1 = line_length;
1540      m_vectorbatch[m_batchindex + 2].u1 = line_length;
1541      m_vectorbatch[m_batchindex + 3].u1 = line_length;
1542      m_vectorbatch[m_batchindex + 4].u1 = line_length;
1543      m_vectorbatch[m_batchindex + 5].u1 = line_length;
1544
1545      // set the color, Z parameters to standard values
1546      for (int i = 0; i < 6; i++)
1547      {
1548         m_vectorbatch[m_batchindex + i].z = 0.0f;
1549         m_vectorbatch[m_batchindex + i].rhw = 1.0f;
1550         m_vectorbatch[m_batchindex + i].color = color;
1551      }
1552
1553      m_batchindex += 6;
1554   }
1555}
1556
1557//============================================================
1558//  draw_line
1559//============================================================
1560
1561void renderer::draw_line(const render_primitive *prim)
1562{
1563   // compute the effective width based on the direction of the line
1564   float effwidth = prim->width;
1565   if (effwidth < 0.5f)
1566   {
1567      effwidth = 0.5f;
1568   }
1569
1570   // determine the bounds of a quad to draw this line
1571   render_bounds b0, b1;
1572   render_line_to_quad(&prim->bounds, effwidth, &b0, &b1);
1573
1574   // iterate over AA steps
1575   for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step;
1576      step->weight != 0; step++)
1577   {
1578      // get a pointer to the vertex buffer
1579      vertex *vertex = mesh_alloc(4);
1580      if (vertex == NULL)
1581         return;
1582
1583      // rotate the unit vector by 135 degrees and add to point 0
1584      vertex[0].x = b0.x0 + step->xoffs;
1585      vertex[0].y = b0.y0 + step->yoffs;
1586
1587      // rotate the unit vector by -135 degrees and add to point 0
1588      vertex[1].x = b0.x1 + step->xoffs;
1589      vertex[1].y = b0.y1 + step->yoffs;
1590
1591      // rotate the unit vector by 45 degrees and add to point 1
1592      vertex[2].x = b1.x0 + step->xoffs;
1593      vertex[2].y = b1.y0 + step->yoffs;
1594
1595      // rotate the unit vector by -45 degrees and add to point 1
1596      vertex[3].x = b1.x1 + step->xoffs;
1597      vertex[3].y = b1.y1 + step->yoffs;
1598
1599      // determine the color of the line
1600      INT32 r = (INT32)(prim->color.r * step->weight * 255.0f);
1601      INT32 g = (INT32)(prim->color.g * step->weight * 255.0f);
1602      INT32 b = (INT32)(prim->color.b * step->weight * 255.0f);
1603      INT32 a = (INT32)(prim->color.a * 255.0f);
1604      if (r > 255) r = 255;
1605      if (g > 255) g = 255;
1606      if (b > 255) b = 255;
1607      if (a > 255) a = 255;
1608      DWORD color = D3DCOLOR_ARGB(a, r, g, b);
1609
1610      vec2f& start = (get_vector_texture() ? get_vector_texture()->get_uvstart() : get_default_texture()->get_uvstart());
1611      vec2f& stop = (get_vector_texture() ? get_vector_texture()->get_uvstop() : get_default_texture()->get_uvstop());
1612
1613      vertex[0].u0 = start.c.x;
1614      vertex[0].v0 = start.c.y;
1615
1616      vertex[2].u0 = stop.c.x;
1617      vertex[2].v0 = start.c.y;
1618
1619      vertex[1].u0 = start.c.x;
1620      vertex[1].v0 = stop.c.y;
1621
1622      vertex[3].u0 = stop.c.x;
1623      vertex[3].v0 = stop.c.y;
1624
1625      // set the color, Z parameters to standard values
1626      for (int i = 0; i < 4; i++)
1627      {
1628         vertex[i].z = 0.0f;
1629         vertex[i].rhw = 1.0f;
1630         vertex[i].color = color;
1631      }
1632
1633      // now add a polygon entry
1634      m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim->flags, get_vector_texture(),
1635                        D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f);
1636      m_numpolys++;
1637   }
1638}
1639
1640
1641
1642//============================================================
1643//  draw_quad
1644//============================================================
1645
1646void renderer::draw_quad(const render_primitive *prim)
1647{
1648   texture_info *texture = m_texture_manager->find_texinfo(&prim->texture, prim->flags);
1649
1650   if (texture == NULL)
1651   {
1652      texture = get_default_texture();
1653   }
1654
1655   // get a pointer to the vertex buffer
1656   vertex *vertex = mesh_alloc(4);
1657   if (vertex == NULL)
1658      return;
1659
1660   // fill in the vertexes clockwise
1661   vertex[0].x = prim->bounds.x0 - 0.5f;
1662   vertex[0].y = prim->bounds.y0 - 0.5f;
1663   vertex[1].x = prim->bounds.x1 - 0.5f;
1664   vertex[1].y = prim->bounds.y0 - 0.5f;
1665   vertex[2].x = prim->bounds.x0 - 0.5f;
1666   vertex[2].y = prim->bounds.y1 - 0.5f;
1667   vertex[3].x = prim->bounds.x1 - 0.5f;
1668   vertex[3].y = prim->bounds.y1 - 0.5f;
1669   float width = prim->bounds.x1 - prim->bounds.x0;
1670   float height = prim->bounds.y1 - prim->bounds.y0;
1671
1672   // set the texture coordinates
1673   if(texture != NULL)
1674   {
1675      vec2f& start = texture->get_uvstart();
1676      vec2f& stop = texture->get_uvstop();
1677      vec2f delta = stop - start;
1678      vertex[0].u0 = start.c.x + delta.c.x * prim->texcoords.tl.u;
1679      vertex[0].v0 = start.c.y + delta.c.y * prim->texcoords.tl.v;
1680      vertex[1].u0 = start.c.x + delta.c.x * prim->texcoords.tr.u;
1681      vertex[1].v0 = start.c.y + delta.c.y * prim->texcoords.tr.v;
1682      vertex[2].u0 = start.c.x + delta.c.x * prim->texcoords.bl.u;
1683      vertex[2].v0 = start.c.y + delta.c.y * prim->texcoords.bl.v;
1684      vertex[3].u0 = start.c.x + delta.c.x * prim->texcoords.br.u;
1685      vertex[3].v0 = start.c.y + delta.c.y * prim->texcoords.br.v;
1686   }
1687
1688   // determine the color, allowing for over modulation
1689   INT32 r = (INT32)(prim->color.r * 255.0f);
1690   INT32 g = (INT32)(prim->color.g * 255.0f);
1691   INT32 b = (INT32)(prim->color.b * 255.0f);
1692   INT32 a = (INT32)(prim->color.a * 255.0f);
1693   DWORD modmode = D3DTOP_MODULATE;
1694   if (texture != NULL)
1695   {
1696      if (m_mod2x_supported && (r > 255 || g > 255 || b > 255))
1697      {
1698         if (m_mod4x_supported && (r > 2*255 || g > 2*255 || b > 2*255))
1699         {
1700            r >>= 2; g >>= 2; b >>= 2;
1701            modmode = D3DTOP_MODULATE4X;
1702         }
1703         else
1704         {
1705            r >>= 1; g >>= 1; b >>= 1;
1706            modmode = D3DTOP_MODULATE2X;
1707         }
1708      }
1709   }
1710   if (r > 255) r = 255;
1711   if (g > 255) g = 255;
1712   if (b > 255) b = 255;
1713   if (a > 255) a = 255;
1714   DWORD color = D3DCOLOR_ARGB(a, r, g, b);
1715
1716   // set the color, Z parameters to standard values
1717   for (int i = 0; i < 4; i++)
1718   {
1719      vertex[i].z = 0.0f;
1720      vertex[i].rhw = 1.0f;
1721      vertex[i].color = color;
1722   }
1723
1724   // now add a polygon entry
1725   m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim->flags, texture, modmode, width, height);
1726   m_numpolys++;
1727}
1728
1729void poly_info::init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
1730                     UINT32 flags, texture_info *texture, UINT32 modmode,
1731                     float line_time, float line_length,
1732                     float prim_width, float prim_height)
1733{
1734   init(type, count, numverts, flags, texture, modmode, prim_width, prim_height);
1735   m_line_time = line_time;
1736   m_line_length = line_length;
1737}
1738
1739void poly_info::init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
1740                     UINT32 flags, texture_info *texture, UINT32 modmode,
1741                     float prim_width, float prim_height)
1742{
1743   m_type = type;
1744   m_count = count;
1745   m_numverts = numverts;
1746   m_flags = flags;
1747   m_texture = texture;
1748   m_modmode = modmode;
1749   m_prim_width = prim_width;
1750   m_prim_height = prim_height;
1751}
1752
1753//============================================================
1754//  primitive_alloc
1755//============================================================
1756
1757vertex *renderer::mesh_alloc(int numverts)
1758{
1759   HRESULT result;
1760
1761   // if we're going to overflow, flush
1762   if (m_lockedbuf != NULL && m_numverts + numverts >= VERTEX_BUFFER_SIZE)
1763   {
1764      primitive_flush_pending();
1765
1766      if(m_shaders->enabled())
1767      {
1768         m_hlsl_buf = (void*)mesh_alloc(6);
1769         m_shaders->init_fsfx_quad(m_hlsl_buf);
1770      }
1771   }
1772
1773   // if we don't have a lock, grab it now
1774   if (m_lockedbuf == NULL)
1775   {
1776      result = (*d3dintf->vertexbuf.lock)(m_vertexbuf, 0, 0, (VOID **)&m_lockedbuf, D3DLOCK_DISCARD);
1777      if (result != D3D_OK)
1778         return NULL;
1779   }
1780
1781   // if we already have the lock and enough room, just return a pointer
1782   if (m_lockedbuf != NULL && m_numverts + numverts < VERTEX_BUFFER_SIZE)
1783   {
1784      int oldverts = m_numverts;
1785      m_numverts += numverts;
1786      return &m_lockedbuf[oldverts];
1787   }
1788   return NULL;
1789}
1790
1791
1792
1793//============================================================
1794//  primitive_flush_pending
1795//============================================================
1796
1797void renderer::primitive_flush_pending()
1798{
1799   // ignore if we're not locked
1800   if (m_lockedbuf == NULL)
1801   {
1802      return;
1803   }
1804
1805   // unlock the buffer
1806   HRESULT result = (*d3dintf->vertexbuf.unlock)(m_vertexbuf);
1807   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result);
1808   m_lockedbuf = NULL;
1809
1810   // set the stream
1811   result = (*d3dintf->device.set_stream_source)(m_device, 0, m_vertexbuf, sizeof(vertex));
1812   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_stream_source call\n", (int)result);
1813
1814   m_shaders->begin_draw();
1815
1816   int vertnum = 0;
1817   if (m_shaders->enabled())
1818   {
1819      vertnum = 6;
1820   }
1821
1822   // now do the polys
1823   for (int polynum = 0; polynum < m_numpolys; polynum++)
1824   {
1825      UINT32 flags = m_poly[polynum].get_flags();
1826      texture_info *texture = m_poly[polynum].get_texture();
1827      int newfilter;
1828
1829      // set the texture if different
1830      set_texture(texture);
1831
1832      // set filtering if different
1833      if (texture != NULL)
1834      {
1835         newfilter = FALSE;
1836         if (PRIMFLAG_GET_SCREENTEX(flags))
1837            newfilter = video_config.filter;
1838         set_filter(newfilter);
1839         set_wrap(PRIMFLAG_GET_TEXWRAP(flags) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
1840         set_modmode(m_poly[polynum].get_modmode());
1841
1842         m_shaders->init_effect_info(&m_poly[polynum]);
1843      }
1844
1845      // set the blendmode if different
1846      set_blendmode(PRIMFLAG_GET_BLENDMODE(flags));
1847
1848      if (vertnum + m_poly[polynum].get_vertcount() > m_numverts)
1849      {
1850         osd_printf_error("Error: vertnum (%d) plus poly vertex count (%d) > %d\n", vertnum, m_poly[polynum].get_vertcount(), m_numverts);
1851         fflush(stdout);
1852      }
1853
1854      assert(vertnum + m_poly[polynum].get_vertcount() <= m_numverts);
1855
1856      if(m_shaders->enabled() && d3dintf->post_fx_available)
1857      {
1858         m_shaders->render_quad(&m_poly[polynum], vertnum);
1859      }
1860      else
1861      {
1862         // add the primitives
1863         result = (*d3dintf->device.draw_primitive)(m_device, m_poly[polynum].get_type(), vertnum,
1864                                          m_poly[polynum].get_count());
1865         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1866      }
1867
1868      vertnum += m_poly[polynum].get_vertcount();
1869   }
1870
1871   m_shaders->end_draw();
1872
1873   // reset the vertex count
1874   m_numverts = 0;
1875   m_numpolys = 0;
1876}
1877
1878//============================================================
1879//  texture_info destructor
1880//============================================================
1881
1882texture_info::~texture_info()
1883{
1884   if (m_d3dfinaltex != NULL)
1885   {
1886      if (m_d3dtex == m_d3dfinaltex)
1887      {
1888         m_d3dtex = NULL;
1889      }
1890      (*d3dintf->texture.release)(m_d3dfinaltex);
1891      m_d3dfinaltex = NULL;
1892   }
1893   if (m_d3dtex != NULL)
1894   {
1895      (*d3dintf->texture.release)(m_d3dtex);
1896      m_d3dtex = NULL;
1897   }
1898   if (m_d3dsurface != NULL)
1899   {
1900      (*d3dintf->surface.release)(m_d3dsurface);
1901      m_d3dsurface = NULL;
1902   }
1903}
1904
1905//============================================================
1906//  texture_info constructor
1907//============================================================
1908
1909texture_info::texture_info(texture_manager *manager, const render_texinfo* texsource, int prescale, UINT32 flags)
1910{
1911   HRESULT result;
1912
1913   // fill in the core data
1914   m_texture_manager = manager;
1915   m_renderer = m_texture_manager->get_d3d();
1916   m_hash = m_texture_manager->texture_compute_hash(texsource, flags);
1917   m_flags = flags;
1918   m_texinfo = *texsource;
1919   m_xprescale = prescale;
1920   m_yprescale = prescale;
1921
1922   m_d3dtex = NULL;
1923   m_d3dsurface = NULL;
1924   m_d3dfinaltex = NULL;
1925
1926   // compute the size
1927   compute_size(texsource->width, texsource->height);
1928
1929   // non-screen textures are easy
1930   if (!PRIMFLAG_GET_SCREENTEX(flags))
1931   {
1932      assert(PRIMFLAG_TEXFORMAT(flags) != TEXFORMAT_YUY16);
1933      result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex);
1934      if (result != D3D_OK)
1935         goto error;
1936      m_d3dfinaltex = m_d3dtex;
1937      m_type = TEXTURE_TYPE_PLAIN;
1938   }
1939
1940   // screen textures are allocated differently
1941   else
1942   {
1943      D3DFORMAT format;
1944      DWORD usage = m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0;
1945      D3DPOOL pool = m_texture_manager->is_dynamic_supported() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
1946      int maxdim = MAX(m_renderer->get_presentation()->BackBufferWidth, m_renderer->get_presentation()->BackBufferHeight);
1947
1948      // pick the format
1949      if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_YUY16)
1950      {
1951         format = m_texture_manager->get_yuv_format();
1952      }
1953      else if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_PALETTEA16)
1954      {
1955         format = D3DFMT_A8R8G8B8;
1956      }
1957      else
1958      {
1959         format = m_renderer->get_screen_format();
1960      }
1961
1962      // don't prescale above screen size
1963      while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale >= 2 * maxdim)
1964      {
1965         m_xprescale--;
1966      }
1967      while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale > manager->get_max_texture_width())
1968      {
1969         m_xprescale--;
1970      }
1971      while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale >= 2 * maxdim)
1972      {
1973         m_yprescale--;
1974      }
1975      while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale > manager->get_max_texture_height())
1976      {
1977         m_yprescale--;
1978      }
1979
1980      int prescale = m_renderer->window().prescale();
1981      if (m_xprescale != prescale || m_yprescale != prescale)
1982      {
1983         osd_printf_verbose("Direct3D: adjusting prescale from %dx%d to %dx%d\n", prescale, prescale, m_xprescale, m_yprescale);
1984      }
1985
1986      // loop until we allocate something or error
1987      for (int attempt = 0; attempt < 2; attempt++)
1988      {
1989         // second attempt is always 1:1
1990         if (attempt == 1)
1991         {
1992            m_xprescale = m_yprescale = 1;
1993         }
1994
1995         // screen textures with no prescaling are pretty easy
1996         if (m_xprescale == 1 && m_yprescale == 1)
1997         {
1998            result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex);
1999            if (result == D3D_OK)
2000            {
2001               m_d3dfinaltex = m_d3dtex;
2002               m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
2003               if (m_renderer->get_shaders()->enabled() && !m_renderer->get_shaders()->register_texture(this))
2004               {
2005                  goto error;
2006               }
2007
2008               break;
2009            }
2010         }
2011
2012         // screen textures with prescaling require two allocations
2013         else
2014         {
2015            // use an offscreen plain surface for stretching if supported
2016            // (won't work for YUY textures)
2017            if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16)
2018            {
2019               result = (*d3dintf->device.create_offscreen_plain_surface)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, format, D3DPOOL_DEFAULT, &m_d3dsurface);
2020               if (result != D3D_OK)
2021               {
2022                  continue;
2023               }
2024               m_type = TEXTURE_TYPE_SURFACE;
2025            }
2026
2027            // otherwise, we allocate a dynamic texture for the source
2028            else
2029            {
2030               result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex);
2031               if (result != D3D_OK)
2032               {
2033                  continue;
2034               }
2035               m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
2036            }
2037
2038            // for the target surface, we allocate a render target texture
2039            int scwidth = m_rawdims.c.x * m_xprescale;
2040            int scheight = m_rawdims.c.y * m_yprescale;
2041
2042            // target surfaces typically cannot be YCbCr, so we always pick RGB in that case
2043            D3DFORMAT finalfmt = (format != m_texture_manager->get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
2044            result = (*d3dintf->device.create_texture)(m_renderer->get_device(), scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex);
2045            if (result == D3D_OK)
2046            {
2047               if (m_renderer->get_shaders()->enabled() && !m_renderer->get_shaders()->register_prescaled_texture(this))
2048               {
2049                  goto error;
2050               }
2051               break;
2052            }
2053            (*d3dintf->texture.release)(m_d3dtex);
2054            m_d3dtex = NULL;
2055         }
2056      }
2057   }
2058
2059   // copy the data to the texture
2060   set_data(texsource, flags);
2061
2062   //texsource->osdhandle = (void*)this;
2063   // add us to the texture list
2064   if(m_texture_manager->get_texlist() != NULL)
2065      m_texture_manager->get_texlist()->m_prev = this;
2066   m_prev = NULL;
2067   m_next = m_texture_manager->get_texlist();
2068   m_texture_manager->set_texlist(this);
2069   return;
2070
2071error:
2072   d3dintf->post_fx_available = false;
2073   osd_printf_error("Direct3D: Critical warning: A texture failed to allocate. Expect things to get bad quickly.\n");
2074   if (m_d3dsurface != NULL)
2075      (*d3dintf->surface.release)(m_d3dsurface);
2076   if (m_d3dtex != NULL)
2077      (*d3dintf->texture.release)(m_d3dtex);
2078}
2079
2080
2081
2082//============================================================
2083//  texture_info::compute_size
2084//============================================================
2085
2086void texture_info::compute_size(int texwidth, int texheight)
2087{
2088   int finalheight = texheight;
2089   int finalwidth = texwidth;
2090
2091   // if we're not wrapping, add a 1-2 pixel border on all sides
2092   m_xborderpix = 0;
2093   m_yborderpix = 0;
2094   if (ENABLE_BORDER_PIX && !(m_flags & PRIMFLAG_TEXWRAP_MASK))
2095   {
2096      // note we need 2 pixels in X for YUY textures
2097      m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
2098      m_yborderpix = 1;
2099   }
2100
2101   // compute final texture size
2102   finalwidth += 2 * m_xborderpix;
2103   finalheight += 2 * m_yborderpix;
2104
2105   // round width/height up to nearest power of 2 if we need to
2106   if (!(m_texture_manager->get_texture_caps() & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
2107   {
2108      // first the width
2109      if (finalwidth & (finalwidth - 1))
2110      {
2111         finalwidth |= finalwidth >> 1;
2112         finalwidth |= finalwidth >> 2;
2113         finalwidth |= finalwidth >> 4;
2114         finalwidth |= finalwidth >> 8;
2115         finalwidth++;
2116      }
2117
2118      // then the height
2119      if (finalheight & (finalheight - 1))
2120      {
2121         finalheight |= finalheight >> 1;
2122         finalheight |= finalheight >> 2;
2123         finalheight |= finalheight >> 4;
2124         finalheight |= finalheight >> 8;
2125         finalheight++;
2126      }
2127   }
2128
2129   // round up to square if we need to
2130   if (m_texture_manager->get_texture_caps() & D3DPTEXTURECAPS_SQUAREONLY)
2131   {
2132      if (finalwidth < finalheight)
2133         finalwidth = finalheight;
2134      else
2135         finalheight = finalwidth;
2136   }
2137
2138   // adjust the aspect ratio if we need to
2139   while (finalwidth < finalheight && finalheight / finalwidth > m_texture_manager->get_max_texture_aspect())
2140   {
2141      finalwidth *= 2;
2142   }
2143   while (finalheight < finalwidth && finalwidth / finalheight > m_texture_manager->get_max_texture_aspect())
2144   {
2145      finalheight *= 2;
2146   }
2147
2148   // if we added pixels for the border, and that just barely pushed us over, take it back
2149   if ((finalwidth > m_texture_manager->get_max_texture_width() && finalwidth - 2 * m_xborderpix <= m_texture_manager->get_max_texture_width()) ||
2150      (finalheight > m_texture_manager->get_max_texture_height() && finalheight - 2 * m_yborderpix <= m_texture_manager->get_max_texture_height()))
2151   {
2152      finalwidth -= 2 * m_xborderpix;
2153      finalheight -= 2 * m_yborderpix;
2154      m_xborderpix = 0;
2155      m_yborderpix = 0;
2156   }
2157
2158   // if we're above the max width/height, do what?
2159   if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
2160   {
2161      static int printed = FALSE;
2162      if (!printed) osd_printf_warning("Texture too big! (wanted: %dx%d, max is %dx%d)\n", finalwidth, finalheight, (int)m_texture_manager->get_max_texture_width(), (int)m_texture_manager->get_max_texture_height());
2163      printed = TRUE;
2164   }
2165
2166   // compute the U/V scale factors
2167   m_start.c.x = (float)m_xborderpix / (float)finalwidth;
2168   m_start.c.y = (float)m_yborderpix / (float)finalheight;
2169   m_stop.c.x = (float)(texwidth + m_xborderpix) / (float)finalwidth;
2170   m_stop.c.y = (float)(texheight + m_yborderpix) / (float)finalheight;
2171
2172   // set the final values
2173   m_rawdims.c.x = finalwidth;
2174   m_rawdims.c.y = finalheight;
2175}
2176
2177
2178
2179//============================================================
2180//  copyline_palette16
2181//============================================================
2182
2183INLINE void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2184{
2185   int x;
2186
2187   assert(xborderpix == 0 || xborderpix == 1);
2188   if (xborderpix)
2189      *dst++ = 0xff000000 | palette[*src];
2190   for (x = 0; x < width; x++)
2191      *dst++ = 0xff000000 | palette[*src++];
2192   if (xborderpix)
2193      *dst++ = 0xff000000 | palette[*--src];
2194}
2195
2196
2197
2198//============================================================
2199//  copyline_palettea16
2200//============================================================
2201
2202INLINE void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2203{
2204   int x;
2205
2206   assert(xborderpix == 0 || xborderpix == 1);
2207   if (xborderpix)
2208      *dst++ = palette[*src];
2209   for (x = 0; x < width; x++)
2210      *dst++ = palette[*src++];
2211   if (xborderpix)
2212      *dst++ = palette[*--src];
2213}
2214
2215
2216
2217//============================================================
2218//  copyline_rgb32
2219//============================================================
2220
2221INLINE void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix)
2222{
2223   int x;
2224
2225   assert(xborderpix == 0 || xborderpix == 1);
2226
2227   // palette (really RGB map) case
2228   if (palette != NULL)
2229   {
2230      if (xborderpix)
2231      {
2232         rgb_t srcpix = *src;
2233         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2234      }
2235      for (x = 0; x < width; x++)
2236      {
2237         rgb_t srcpix = *src++;
2238         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2239      }
2240      if (xborderpix)
2241      {
2242         rgb_t srcpix = *--src;
2243         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2244      }
2245   }
2246
2247   // direct case
2248   else
2249   {
2250      if (xborderpix)
2251         *dst++ = 0xff000000 | *src;
2252      for (x = 0; x < width; x++)
2253         *dst++ = 0xff000000 | *src++;
2254      if (xborderpix)
2255         *dst++ = 0xff000000 | *--src;
2256   }
2257}
2258
2259
2260
2261//============================================================
2262//  copyline_argb32
2263//============================================================
2264
2265INLINE void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix)
2266{
2267   int x;
2268
2269   assert(xborderpix == 0 || xborderpix == 1);
2270
2271   // palette (really RGB map) case
2272   if (palette != NULL)
2273   {
2274      if (xborderpix)
2275      {
2276         rgb_t srcpix = *src;
2277         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2278      }
2279      for (x = 0; x < width; x++)
2280      {
2281         rgb_t srcpix = *src++;
2282         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2283      }
2284      if (xborderpix)
2285      {
2286         rgb_t srcpix = *--src;
2287         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2288      }
2289   }
2290
2291   // direct case
2292   else
2293   {
2294      if (xborderpix)
2295         *dst++ = *src;
2296      for (x = 0; x < width; x++)
2297         *dst++ = *src++;
2298      if (xborderpix)
2299         *dst++ = *--src;
2300   }
2301}
2302
2303
2304
2305//============================================================
2306//  copyline_yuy16_to_yuy2
2307//============================================================
2308
2309INLINE void copyline_yuy16_to_yuy2(UINT16 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2310{
2311   int x;
2312
2313   assert(xborderpix == 0 || xborderpix == 2);
2314   assert(width % 2 == 0);
2315
2316   // palette (really RGB map) case
2317   if (palette != NULL)
2318   {
2319      if (xborderpix)
2320      {
2321         UINT16 srcpix0 = *src++;
2322         UINT16 srcpix1 = *src--;
2323         *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix0 << 8);
2324         *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix1 << 8);
2325      }
2326      for (x = 0; x < width; x += 2)
2327      {
2328         UINT16 srcpix0 = *src++;
2329         UINT16 srcpix1 = *src++;
2330         *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix0 << 8);
2331         *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix1 << 8);
2332      }
2333      if (xborderpix)
2334      {
2335         UINT16 srcpix1 = *--src;
2336         UINT16 srcpix0 = *--src;
2337         *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix0 << 8);
2338         *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix1 << 8);
2339      }
2340   }
2341
2342   // direct case
2343   else
2344   {
2345      if (xborderpix)
2346      {
2347         UINT16 srcpix0 = *src++;
2348         UINT16 srcpix1 = *src--;
2349         *dst++ = (srcpix0 >> 8) | (srcpix0 << 8);
2350         *dst++ = (srcpix0 >> 8) | (srcpix1 << 8);
2351      }
2352      for (x = 0; x < width; x += 2)
2353      {
2354         UINT16 srcpix0 = *src++;
2355         UINT16 srcpix1 = *src++;
2356         *dst++ = (srcpix0 >> 8) | (srcpix0 << 8);
2357         *dst++ = (srcpix1 >> 8) | (srcpix1 << 8);
2358      }
2359      if (xborderpix)
2360      {
2361         UINT16 srcpix1 = *--src;
2362         UINT16 srcpix0 = *--src;
2363         *dst++ = (srcpix1 >> 8) | (srcpix0 << 8);
2364         *dst++ = (srcpix1 >> 8) | (srcpix1 << 8);
2365      }
2366   }
2367}
2368
2369
2370
2371//============================================================
2372//  copyline_yuy16_to_uyvy
2373//============================================================
2374
2375INLINE void copyline_yuy16_to_uyvy(UINT16 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2376{
2377   int x;
2378
2379   assert(xborderpix == 0 || xborderpix == 2);
2380   assert(width % 2 == 0);
2381
2382   // palette (really RGB map) case
2383   if (palette != NULL)
2384   {
2385      if (xborderpix)
2386      {
2387         UINT16 srcpix0 = *src++;
2388         UINT16 srcpix1 = *src--;
2389         *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix0 & 0xff);
2390         *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix1 & 0xff);
2391      }
2392      for (x = 0; x < width; x += 2)
2393      {
2394         UINT16 srcpix0 = *src++;
2395         UINT16 srcpix1 = *src++;
2396         *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix0 & 0xff);
2397         *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix1 & 0xff);
2398      }
2399      if (xborderpix)
2400      {
2401         UINT16 srcpix1 = *--src;
2402         UINT16 srcpix0 = *--src;
2403         *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix0 & 0xff);
2404         *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix1 & 0xff);
2405      }
2406   }
2407
2408   // direct case
2409   else
2410   {
2411      if (xborderpix)
2412      {
2413         UINT16 srcpix0 = src[0];
2414         UINT16 srcpix1 = src[1];
2415         *dst++ = srcpix0;
2416         *dst++ = (srcpix0 & 0xff00) | (srcpix1 & 0x00ff);
2417      }
2418      for (x = 0; x < width; x += 2)
2419      {
2420         *dst++ = *src++;
2421         *dst++ = *src++;
2422      }
2423      if (xborderpix)
2424      {
2425         UINT16 srcpix1 = *--src;
2426         UINT16 srcpix0 = *--src;
2427         *dst++ = (srcpix1 & 0xff00) | (srcpix0 & 0x00ff);
2428         *dst++ = srcpix1;
2429      }
2430   }
2431}
2432
2433
2434
2435//============================================================
2436//  copyline_yuy16_to_argb
2437//============================================================
2438
2439INLINE void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2440{
2441   int x;
2442
2443   assert(xborderpix == 0 || xborderpix == 2);
2444   assert(width % 2 == 0);
2445
2446   // palette (really RGB map) case
2447   if (palette != NULL)
2448   {
2449      if (xborderpix)
2450      {
2451         UINT16 srcpix0 = src[0];
2452         UINT16 srcpix1 = src[1];
2453         UINT8 cb = srcpix0 & 0xff;
2454         UINT8 cr = srcpix1 & 0xff;
2455         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2456         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2457      }
2458      for (x = 0; x < width / 2; x++)
2459      {
2460         UINT16 srcpix0 = *src++;
2461         UINT16 srcpix1 = *src++;
2462         UINT8 cb = srcpix0 & 0xff;
2463         UINT8 cr = srcpix1 & 0xff;
2464         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2465         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2466      }
2467      if (xborderpix)
2468      {
2469         UINT16 srcpix1 = *--src;
2470         UINT16 srcpix0 = *--src;
2471         UINT8 cb = srcpix0 & 0xff;
2472         UINT8 cr = srcpix1 & 0xff;
2473         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2474         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2475      }
2476   }
2477
2478   // direct case
2479   else
2480   {
2481      if (xborderpix)
2482      {
2483         UINT16 srcpix0 = src[0];
2484         UINT16 srcpix1 = src[1];
2485         UINT8 cb = srcpix0 & 0xff;
2486         UINT8 cr = srcpix1 & 0xff;
2487         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2488         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2489      }
2490      for (x = 0; x < width; x += 2)
2491      {
2492         UINT16 srcpix0 = *src++;
2493         UINT16 srcpix1 = *src++;
2494         UINT8 cb = srcpix0 & 0xff;
2495         UINT8 cr = srcpix1 & 0xff;
2496         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2497         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2498      }
2499      if (xborderpix)
2500      {
2501         UINT16 srcpix1 = *--src;
2502         UINT16 srcpix0 = *--src;
2503         UINT8 cb = srcpix0 & 0xff;
2504         UINT8 cr = srcpix1 & 0xff;
2505         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2506         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2507      }
2508   }
2509}
2510
2511
2512
2513//============================================================
2514//  texture_set_data
2515//============================================================
2516
2517void texture_info::set_data(const render_texinfo *texsource, UINT32 flags)
2518{
2519   D3DLOCKED_RECT rect;
2520   HRESULT result;
2521
2522   // lock the texture
2523   switch (m_type)
2524   {
2525      default:
2526      case TEXTURE_TYPE_PLAIN:    result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, NULL, 0);                 break;
2527      case TEXTURE_TYPE_DYNAMIC:  result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, NULL, D3DLOCK_DISCARD);   break;
2528      case TEXTURE_TYPE_SURFACE:  result = (*d3dintf->surface.lock_rect)(m_d3dsurface, &rect, NULL, D3DLOCK_DISCARD);  break;
2529   }
2530   if (result != D3D_OK)
2531   {
2532      return;
2533   }
2534
2535   // loop over Y
2536   int miny = 0 - m_yborderpix;
2537   int maxy = texsource->height + m_yborderpix;
2538   for (int dsty = miny; dsty < maxy; dsty++)
2539   {
2540      int srcy = (dsty < 0) ? 0 : (dsty >= texsource->height) ? texsource->height - 1 : dsty;
2541      void *dst = (BYTE *)rect.pBits + (dsty + m_yborderpix) * rect.Pitch;
2542
2543      // switch off of the format and
2544      switch (PRIMFLAG_GET_TEXFORMAT(flags))
2545      {
2546         case TEXFORMAT_PALETTE16:
2547            copyline_palette16((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2548            break;
2549
2550         case TEXFORMAT_PALETTEA16:
2551            copyline_palettea16((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2552            break;
2553
2554         case TEXFORMAT_RGB32:
2555            copyline_rgb32((UINT32 *)dst, (UINT32 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2556            break;
2557
2558         case TEXFORMAT_ARGB32:
2559            copyline_argb32((UINT32 *)dst, (UINT32 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2560            break;
2561
2562         case TEXFORMAT_YUY16:
2563            if (m_texture_manager->get_yuv_format() == D3DFMT_YUY2)
2564               copyline_yuy16_to_yuy2((UINT16 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2565            else if (m_texture_manager->get_yuv_format() == D3DFMT_UYVY)
2566               copyline_yuy16_to_uyvy((UINT16 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2567            else
2568               copyline_yuy16_to_argb((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2569            break;
2570
2571         default:
2572            osd_printf_error("Unknown texture blendmode=%d format=%d\n", PRIMFLAG_GET_BLENDMODE(flags), PRIMFLAG_GET_TEXFORMAT(flags));
2573            break;
2574      }
2575   }
2576
2577   // unlock
2578   switch (m_type)
2579   {
2580      default:
2581      case TEXTURE_TYPE_PLAIN:    result = (*d3dintf->texture.unlock_rect)(m_d3dtex, 0);   break;
2582      case TEXTURE_TYPE_DYNAMIC:  result = (*d3dintf->texture.unlock_rect)(m_d3dtex, 0);   break;
2583      case TEXTURE_TYPE_SURFACE:  result = (*d3dintf->surface.unlock_rect)(m_d3dsurface);  break;
2584   }
2585   if (result != D3D_OK)
2586   {
2587      osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
2588   }
2589
2590   // prescale
2591   prescale();
2592}
2593
2594
2595
2596//============================================================
2597//  texture_info::prescale
2598//============================================================
2599
2600void texture_info::prescale()
2601{
2602   surface *scale_surface;
2603   HRESULT result;
2604   int i;
2605
2606   // if we don't need to, just skip it
2607   if (m_d3dtex == m_d3dfinaltex)
2608      return;
2609
2610   // for all cases, we need to get the surface of the render target
2611   result = (*d3dintf->texture.get_surface_level)(m_d3dfinaltex, 0, &scale_surface);
2612   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture get_surface_level call\n", (int)result);
2613
2614   // if we have an offscreen plain surface, we can just StretchRect to it
2615   if (m_type == TEXTURE_TYPE_SURFACE)
2616   {
2617      assert(m_d3dsurface != NULL);
2618
2619      // set the source bounds
2620      RECT source;
2621      source.left = source.top = 0;
2622      source.right = m_texinfo.width + 2 * m_xborderpix;
2623      source.bottom = m_texinfo.height + 2 * m_yborderpix;
2624
2625      // set the target bounds
2626      RECT dest;
2627      dest = source;
2628      dest.right *= m_xprescale;
2629      dest.bottom *= m_yprescale;
2630
2631      // do the stretchrect
2632      result = (*d3dintf->device.stretch_rect)(m_renderer->get_device(), m_d3dsurface, &source, scale_surface, &dest, D3DTEXF_POINT);
2633      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device stretct_rect call\n", (int)result);
2634   }
2635
2636   // if we are using a texture render target, we need to do more preparations
2637   else
2638   {
2639      surface *backbuffer;
2640
2641      assert(m_d3dtex != NULL);
2642
2643      // first remember the original render target and set the new one
2644      result = (*d3dintf->device.get_render_target)(m_renderer->get_device(), 0, &backbuffer);
2645      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
2646      result = (*d3dintf->device.set_render_target)(m_renderer->get_device(), 0, scale_surface);
2647      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 1\n", (int)result);
2648      m_renderer->reset_render_states();
2649
2650      // start the scene
2651      result = (*d3dintf->device.begin_scene)(m_renderer->get_device());
2652      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
2653
2654      // configure the rendering pipeline
2655      m_renderer->set_filter(FALSE);
2656      m_renderer->set_blendmode(BLENDMODE_NONE);
2657      result = (*d3dintf->device.set_texture)(m_renderer->get_device(), 0, m_d3dtex);
2658      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result);
2659
2660      // lock the vertex buffer
2661      result = (*d3dintf->vertexbuf.lock)(m_renderer->get_vertex_buffer(), 0, 0, m_renderer->get_locked_buffer_ptr(), D3DLOCK_DISCARD);
2662      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer lock call\n", (int)result);
2663
2664      // configure the X/Y coordinates on the target surface
2665      vertex *lockedbuf = m_renderer->get_locked_buffer();
2666      lockedbuf[0].x = -0.5f;
2667      lockedbuf[0].y = -0.5f;
2668      lockedbuf[1].x = (float)((m_texinfo.width + 2 * m_xborderpix) * m_xprescale) - 0.5f;
2669      lockedbuf[1].y = -0.5f;
2670      lockedbuf[2].x = -0.5f;
2671      lockedbuf[2].y = (float)((m_texinfo.height + 2 * m_yborderpix) * m_yprescale) - 0.5f;
2672      lockedbuf[3].x = (float)((m_texinfo.width + 2 * m_xborderpix) * m_xprescale) - 0.5f;
2673      lockedbuf[3].y = (float)((m_texinfo.height + 2 * m_yborderpix) * m_yprescale) - 0.5f;
2674
2675      // configure the U/V coordintes on the source texture
2676      lockedbuf[0].u0 = 0.0f;
2677      lockedbuf[0].v0 = 0.0f;
2678      lockedbuf[1].u0 = (float)(m_texinfo.width + 2 * m_xborderpix) / (float)m_rawdims.c.x;
2679      lockedbuf[1].v0 = 0.0f;
2680      lockedbuf[2].u0 = 0.0f;
2681      lockedbuf[2].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
2682      lockedbuf[3].u0 = (float)(m_texinfo.width + 2 * m_xborderpix) / (float)m_rawdims.c.x;
2683      lockedbuf[3].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
2684
2685      // reset the remaining vertex parameters
2686      for (i = 0; i < 4; i++)
2687      {
2688         lockedbuf[i].z = 0.0f;
2689         lockedbuf[i].rhw = 1.0f;
2690         lockedbuf[i].color = D3DCOLOR_ARGB(0xff,0xff,0xff,0xff);
2691      }
2692
2693      // unlock the vertex buffer
2694      result = (*d3dintf->vertexbuf.unlock)(m_renderer->get_vertex_buffer());
2695      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result);
2696      m_renderer->set_locked_buffer(NULL);
2697
2698      // set the stream and draw the triangle strip
2699      result = (*d3dintf->device.set_stream_source)(m_renderer->get_device(), 0, m_renderer->get_vertex_buffer(), sizeof(vertex));
2700      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_stream_source call\n", (int)result);
2701      result = (*d3dintf->device.draw_primitive)(m_renderer->get_device(), D3DPT_TRIANGLESTRIP, 0, 2);
2702      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
2703
2704      // end the scene
2705      result = (*d3dintf->device.end_scene)(m_renderer->get_device());
2706      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result);
2707
2708      // reset the render target and release our reference to the backbuffer
2709      result = (*d3dintf->device.set_render_target)(m_renderer->get_device(), 0, backbuffer);
2710      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 2\n", (int)result);
2711      (*d3dintf->surface.release)(backbuffer);
2712      m_renderer->reset_render_states();
2713   }
2714
2715   // release our reference to the target surface
2716   (*d3dintf->surface.release)(scale_surface);
2717}
2718
2719
2720//============================================================
2721//  cache_target::~cache_target
2722//============================================================
2723
2724cache_target::~cache_target()
2725{
2726   for (int index = 0; index < 11; index++)
2727   {
2728      if (bloom_texture[index] != NULL)
2729      {
2730         (*d3dintf->texture.release)(bloom_texture[index]);
2731         bloom_texture[index] = NULL;
2732      }
2733      if (bloom_target[index] != NULL)
2734      {
2735         (*d3dintf->surface.release)(bloom_target[index]);
2736         bloom_target[index] = NULL;
2737      }
2738   }
2739
2740   if (last_texture != NULL)
2741   {
2742      (*d3dintf->texture.release)(last_texture);
2743      last_texture = NULL;
2744   }
2745   if (last_target != NULL)
2746   {
2747      (*d3dintf->surface.release)(last_target);
2748      last_target = NULL;
2749   }
2750}
2751
2752
2753//============================================================
2754//  cache_target::init - initializes a target cache
2755//============================================================
2756
2757bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y)
2758{
2759   int bloom_size = (width < height) ? width : height;
2760   int bloom_index = 0;
2761   int bloom_width = width;
2762   int bloom_height = height;
2763   for (; bloom_size >= 2 && bloom_index < 11; bloom_size >>= 1)
2764   {
2765      bloom_width >>= 1;
2766      bloom_height >>= 1;
2767      HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), bloom_width, bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
2768      if (result != D3D_OK)
2769      {
2770         return false;
2771      }
2772      (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]);
2773      bloom_index++;
2774   }
2775
2776   HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
2777   if (result != D3D_OK)
2778      return false;
2779   (*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target);
2780
2781   target_width = width * prescale_x;
2782   target_height = height * prescale_y;
2783
2784   return true;
2785}
2786
2787//============================================================
2788//  render_target::~render_target
2789//============================================================
2790
2791render_target::~render_target()
2792{
2793   for (int index = 0; index < 11; index++)
2794   {
2795      if (bloom_texture[index] != NULL)
2796      {
2797         (*d3dintf->texture.release)(bloom_texture[index]);
2798         bloom_texture[index] = NULL;
2799      }
2800      if (bloom_target[index] != NULL)
2801      {
2802         (*d3dintf->surface.release)(bloom_target[index]);
2803         bloom_target[index] = NULL;
2804      }
2805   }
2806
2807   for (int index = 0; index < 5; index++)
2808   {
2809      if (render_texture[index] != NULL)
2810      {
2811         (*d3dintf->texture.release)(render_texture[index]);
2812         render_texture[index] = NULL;
2813      }
2814      if (target[index] != NULL)
2815      {
2816         (*d3dintf->surface.release)(target[index]);
2817         target[index] = NULL;
2818      }
2819   }
2820
2821   if (prescaletexture != NULL)
2822   {
2823      (*d3dintf->texture.release)(prescaletexture);
2824      prescaletexture = NULL;
2825   }
2826   if (prescaletarget != NULL)
2827   {
2828      (*d3dintf->surface.release)(prescaletarget);
2829      prescaletarget = NULL;
2830   }
2831
2832   if (smalltexture != NULL)
2833   {
2834      (*d3dintf->texture.release)(smalltexture);
2835      smalltexture = NULL;
2836   }
2837   if (smalltarget != NULL)
2838   {
2839      (*d3dintf->surface.release)(smalltarget);
2840      smalltarget = NULL;
2841   }
2842}
2843
2844
2845//============================================================
2846//  render_target::init - initializes a render target
2847//============================================================
2848
2849bool render_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y)
2850{
2851   D3DFORMAT format = D3DFMT_A8R8G8B8;
2852
2853   HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[0]);
2854   if (result != D3D_OK)
2855      return false;
2856   (*d3dintf->texture.get_surface_level)(render_texture[0], 0, &target[0]);
2857
2858   result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[1]);
2859   if (result != D3D_OK)
2860      return false;
2861   (*d3dintf->texture.get_surface_level)(render_texture[1], 0, &target[1]);
2862
2863   result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[2]);
2864   if (result != D3D_OK)
2865      return false;
2866   (*d3dintf->texture.get_surface_level)(render_texture[2], 0, &target[2]);
2867
2868   result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &render_texture[3]);
2869   if (result != D3D_OK)
2870      return false;
2871   (*d3dintf->texture.get_surface_level)(render_texture[3], 0, &target[3]);
2872
2873   result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &render_texture[4]);
2874   if (result != D3D_OK)
2875      return false;
2876   (*d3dintf->texture.get_surface_level)(render_texture[4], 0, &target[4]);
2877
2878   result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &smalltexture);
2879   if (result != D3D_OK)
2880      return false;
2881   (*d3dintf->texture.get_surface_level)(smalltexture, 0, &smalltarget);
2882
2883   result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescaletexture);
2884   if (result != D3D_OK)
2885      return false;
2886   (*d3dintf->texture.get_surface_level)(prescaletexture, 0, &prescaletarget);
2887
2888   float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
2889   int bloom_index = 0;
2890   float bloom_width = d3d->get_width();
2891   float bloom_height = d3d->get_height();
2892   for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
2893   {
2894      bloom_width *= 0.5f;
2895      bloom_height *= 0.5f;
2896      result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
2897      if (result != D3D_OK)
2898         return false;
2899      (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]);
2900      bloom_index++;
2901   }
2902
2903   this->width = width;
2904   this->height = height;
2905
2906   target_width = width * prescale_x;
2907   target_height = height * prescale_y;
2908
2909   return true;
2910}
2911
2912};
trunk/src/osd/modules/render/drawd3d.h
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawd3d.h - Win32 Direct3D header
6//
7//============================================================
8
9#ifndef __WIN_DRAWD3D__
10#define __WIN_DRAWD3D__
11
12
13#include "modules/render/d3d/d3dhlsl.h"
14
15
16//============================================================
17//  CONSTANTS
18//============================================================
19
20#define VERTEX_BASE_FORMAT  (D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEX2)
21#define VERTEX_BUFFER_SIZE  (40960*4+4)
22
23//============================================================
24//  TYPE DEFINITIONS
25//============================================================
26
27namespace d3d
28{
29class cache_target;
30class render_target;
31class renderer;
32
33/* cache_target is a simple linked list containing only a rednerable target and texture, used for phosphor effects */
34class cache_target
35{
36public:
37   // construction/destruction
38   cache_target() { }
39   ~cache_target();
40
41   bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y);
42
43   surface *last_target;
44   texture *last_texture;
45
46   int target_width;
47   int target_height;
48
49   int width;
50   int height;
51
52   int screen_index;
53
54   cache_target *next;
55   cache_target *prev;
56
57   surface *bloom_target[11];
58   texture *bloom_texture[11];
59};
60
61/* render_target is the information about a Direct3D render target chain */
62class render_target
63{
64public:
65   // construction/destruction
66   render_target() { }
67   ~render_target();
68
69   bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y);
70
71   int target_width;
72   int target_height;
73
74   int prescale_x;
75   int prescale_y;
76
77   int width;
78   int height;
79
80   int screen_index;
81   int page_index;
82
83   surface *prescaletarget;
84   texture *prescaletexture;
85   surface *smalltarget;
86   texture *smalltexture;
87   surface *target[5];
88   texture *render_texture[5];
89
90   render_target *next;
91   render_target *prev;
92
93   surface *bloom_target[11];
94   texture *bloom_texture[11];
95};
96
97/* renderer is the information about Direct3D for the current screen */
98class renderer : public osd_renderer
99{
100public:
101   //renderer() { }
102   renderer(osd_window *window);
103   virtual ~renderer();
104
105   virtual int create();
106   virtual render_primitive_list *get_primitives();
107   virtual int draw(const int update);
108   virtual void save();
109   virtual void record();
110   virtual void toggle_fsfx();
111   virtual void destroy();
112
113   int                     initialize();
114
115   int                     device_create(HWND device_HWND);
116   int                     device_create_resources();
117   void                    device_delete();
118   void                    device_delete_resources();
119
120   int                     device_verify_caps();
121   int                     device_test_cooperative();
122
123   int                     config_adapter_mode();
124   void                    pick_best_mode();
125   int                     get_adapter_for_monitor();
126
127   int                     update_window_size();
128
129   int                     pre_window_draw_check();
130   void                    begin_frame();
131   void                    end_frame();
132
133   void                    draw_line(const render_primitive *prim);
134   void                    draw_quad(const render_primitive *prim);
135   void                    batch_vector(const render_primitive *prim, float line_time);
136   void                    batch_vectors();
137
138   vertex *                mesh_alloc(int numverts);
139
140   void                    update_textures();
141
142   void                    process_primitives();
143   void                    primitive_flush_pending();
144
145   void                    set_texture(texture_info *texture);
146   void                    set_filter(int filter);
147   void                    set_wrap(D3DTEXTUREADDRESS wrap);
148   void                    set_modmode(DWORD modmode);
149   void                    set_blendmode(int blendmode);
150   void                    reset_render_states();
151
152   // Setters / getters
153   int                     get_adapter() { return m_adapter; }
154   int                     get_width() { return m_width; }
155   vec2f                   get_dims() { return vec2f(m_width, m_height); }
156   int                     get_height() { return m_height; }
157   int                     get_refresh() { return m_refresh; }
158
159   device *                get_device() { return m_device; }
160   present_parameters *    get_presentation() { return &m_presentation; }
161
162   vertex_buffer *         get_vertex_buffer() { return m_vertexbuf; }
163   vertex *                get_locked_buffer() { return m_lockedbuf; }
164   VOID **                 get_locked_buffer_ptr() { return (VOID **)&m_lockedbuf; }
165   void                    set_locked_buffer(vertex *lockedbuf) { m_lockedbuf = lockedbuf; }
166
167   void                    set_restarting(bool restarting) { m_restarting = restarting; }
168   bool                    is_mod2x_supported() { return (bool)m_mod2x_supported; }
169   bool                    is_mod4x_supported() { return (bool)m_mod4x_supported; }
170
171   D3DFORMAT               get_screen_format() { return m_screen_format; }
172   D3DFORMAT               get_pixel_format() { return m_pixformat; }
173   D3DDISPLAYMODE          get_origmode() { return m_origmode; }
174
175   UINT32                  get_last_texture_flags() { return m_last_texture_flags; }
176
177   texture_manager *       get_texture_manager() { return m_texture_manager; }
178   texture_info *          get_default_texture() { return m_texture_manager->get_default_texture(); }
179   texture_info *          get_vector_texture() { return m_texture_manager->get_vector_texture(); }
180
181   shaders *               get_shaders() { return m_shaders; }
182
183private:
184   int                     m_adapter;                  // ordinal adapter number
185   int                     m_width;                    // current width
186   int                     m_height;                   // current height
187   int                     m_refresh;                  // current refresh rate
188   int                     m_create_error_count;       // number of consecutive create errors
189
190   device *                m_device;                   // pointer to the Direct3DDevice object
191   int                     m_gamma_supported;          // is full screen gamma supported?
192   present_parameters      m_presentation;             // set of presentation parameters
193   D3DDISPLAYMODE          m_origmode;                 // original display mode for the adapter
194   D3DFORMAT               m_pixformat;                // pixel format we are using
195
196   vertex_buffer *         m_vertexbuf;                // pointer to the vertex buffer object
197   vertex *                m_lockedbuf;                // pointer to the locked vertex buffer
198   int                     m_numverts;                 // number of accumulated vertices
199
200   vertex *                m_vectorbatch;              // pointer to the vector batch buffer
201   int                     m_batchindex;               // current index into the vector batch
202
203   poly_info               m_poly[VERTEX_BUFFER_SIZE/3];// array to hold polygons as they are created
204   int                     m_numpolys;                 // number of accumulated polygons
205
206   bool                    m_restarting;               // if we're restarting
207
208   int                     m_mod2x_supported;          // is D3DTOP_MODULATE2X supported?
209   int                     m_mod4x_supported;          // is D3DTOP_MODULATE4X supported?
210   D3DFORMAT               m_screen_format;            // format to use for screen textures
211
212   texture_info *          m_last_texture;             // previous texture
213   UINT32                  m_last_texture_flags;       // previous texture flags
214   int                     m_last_blendenable;         // previous blendmode
215   int                     m_last_blendop;             // previous blendmode
216   int                     m_last_blendsrc;            // previous blendmode
217   int                     m_last_blenddst;            // previous blendmode
218   int                     m_last_filter;              // previous texture filter
219   D3DTEXTUREADDRESS       m_last_wrap;                // previous wrap state
220   DWORD                   m_last_modmode;             // previous texture modulation
221
222   void *                  m_hlsl_buf;                 // HLSL vertex data
223   shaders *               m_shaders;                  // HLSL interface
224
225   texture_manager *       m_texture_manager;          // texture manager
226
227   int                     m_line_count;
228};
229
230};
231
232#endif
trunk/src/osd/modules/render/drawdd.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawdd.c - Win32 DirectDraw implementation
6//
7//============================================================
8
9// standard windows headers
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12#include <mmsystem.h>
13#include <ddraw.h>
14#undef interface
15
16// MAME headers
17#include "emu.h"
18#include "render.h"
19#include "rendutil.h"
20#include "options.h"
21#include "rendersw.inc"
22
23// MAMEOS headers
24#include "winmain.h"
25#include "window.h"
26#include "config.h"
27
28
29
30//============================================================
31//  TYPE DEFINITIONS
32//============================================================
33
34typedef HRESULT (WINAPI *directdrawcreateex_ptr)(GUID FAR *lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkOuter);
35typedef HRESULT (WINAPI *directdrawenumerateex_ptr)(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
36
37
38/* dd_info is the information about DirectDraw for the current screen */
39class renderer_dd : public osd_renderer
40{
41public:
42   renderer_dd(osd_window *window)
43   : osd_renderer(window, FLAG_NONE),
44      //adapter(0),
45      adapter_ptr(NULL),
46      clearouter(0),
47      blitwidth(0), blitheight(0),
48      //lastdest
49      ddraw(NULL),
50      primary(NULL),
51      back(NULL),
52      blit(NULL),
53      clipper(NULL),
54      gamma(NULL),
55      //DDSURFACEDESC2          primarydesc;
56      //DDSURFACEDESC2          blitdesc;
57      //DDSURFACEDESC2          origmode;
58      //ddcaps(0),
59      //helcaps(0),
60      membuffer(NULL),
61      membuffersize(0)
62   { }
63
64   virtual ~renderer_dd() { }
65
66   virtual int create();
67   virtual render_primitive_list *get_primitives();
68   virtual int draw(const int update);
69   virtual void save() {};
70   virtual void record() {};
71   virtual void toggle_fsfx() {};
72   virtual void destroy();
73
74   int                     width, height;              // current width, height
75   int                     refresh;                    // current refresh rate
76
77private:
78
79   inline void update_outer_rects();
80
81   // surface management
82   int ddraw_create();
83   int ddraw_create_surfaces();
84   void ddraw_delete();
85   void ddraw_delete_surfaces();
86   int ddraw_verify_caps();
87   int ddraw_test_cooperative();
88   HRESULT create_surface(DDSURFACEDESC2 *desc, IDirectDrawSurface7 **surface, const char *type);
89   int create_clipper();
90
91   // drawing helpers
92   void compute_blit_surface_size();
93   void blit_to_primary(int srcwidth, int srcheight);
94
95   // video modes
96   int config_adapter_mode();
97   void get_adapter_for_monitor(win_monitor_info *monitor);
98   void pick_best_mode();
99
100   // various
101   void calc_fullscreen_margins(DWORD desc_width, DWORD desc_height, RECT *margins);
102
103
104   GUID                    adapter;                    // current display adapter
105   GUID *                  adapter_ptr;                // pointer to current display adapter
106   int                     clearouter;                 // clear the outer areas?
107
108   INT32                   blitwidth, blitheight;      // current blit width/height values
109   RECT                    lastdest;                   // last destination rectangle
110
111   IDirectDraw7 *          ddraw;                      // pointer to the DirectDraw object
112   IDirectDrawSurface7 *   primary;                    // pointer to the primary surface object
113   IDirectDrawSurface7 *   back;                       // pointer to the back buffer surface object
114   IDirectDrawSurface7 *   blit;                       // pointer to the blit surface object
115   IDirectDrawClipper *    clipper;                    // pointer to the clipper object
116   IDirectDrawGammaControl *gamma;                     // pointer to the gamma control object
117
118   DDSURFACEDESC2          primarydesc;                // description of the primary surface
119   DDSURFACEDESC2          blitdesc;                   // description of the blitting surface
120   DDSURFACEDESC2          origmode;                   // original video mode
121
122   DDCAPS                  ddcaps;                     // capabilities of the device
123   DDCAPS                  helcaps;                    // capabilities of the hardware
124
125   UINT8 *                 membuffer;                  // memory buffer for complex rendering
126   UINT32                  membuffersize;              // current size of the memory buffer
127};
128
129
130/* monitor_enum_info holds information during a monitor enumeration */
131struct monitor_enum_info
132{
133   win_monitor_info *      monitor;                    // pointer to monitor we want
134   GUID                    guid;                       // GUID of the one we found
135   GUID *                  guid_ptr;                   // pointer to our GUID
136   int                     foundit;                    // TRUE if we found what we wanted
137};
138
139
140/* mode_enum_info holds information during a display mode enumeration */
141struct mode_enum_info
142{
143   renderer_dd *           renderer;
144   osd_window  *           window;
145   INT32                   minimum_width, minimum_height;
146   INT32                   target_width, target_height;
147   double                  target_refresh;
148   float                   best_score;
149};
150
151
152
153//============================================================
154//  GLOBALS
155//============================================================
156
157static HINSTANCE dllhandle;
158static directdrawcreateex_ptr directdrawcreateex;
159static directdrawenumerateex_ptr directdrawenumerateex;
160
161
162
163//============================================================
164//  INLINES
165//============================================================
166
167inline void renderer_dd::update_outer_rects()
168{
169   clearouter = (back != NULL) ? 3 : 1;
170}
171
172
173INLINE int better_mode(int width0, int height0, int width1, int height1, float desired_aspect)
174{
175   float aspect0 = (float)width0 / (float)height0;
176   float aspect1 = (float)width1 / (float)height1;
177   return (fabs(desired_aspect - aspect0) < fabs(desired_aspect - aspect1)) ? 0 : 1;
178}
179
180
181
182//============================================================
183//  PROTOTYPES
184//============================================================
185
186// core functions
187static void drawdd_exit(void);
188
189
190
191//============================================================
192//  drawnone_create
193//============================================================
194
195static osd_renderer *drawdd_create(osd_window *window)
196{
197   return global_alloc(renderer_dd(window));
198}
199
200
201//============================================================
202//  drawdd_init
203//============================================================
204
205int drawdd_init(running_machine &machine, osd_draw_callbacks *callbacks)
206{
207   // dynamically grab the create function from ddraw.dll
208   dllhandle = LoadLibrary(TEXT("ddraw.dll"));
209   if (dllhandle == NULL)
210   {
211      osd_printf_verbose("DirectDraw: Unable to access ddraw.dll\n");
212      return 1;
213   }
214
215   // import the create function
216   directdrawcreateex = (directdrawcreateex_ptr)GetProcAddress(dllhandle, "DirectDrawCreateEx");
217   if (directdrawcreateex == NULL)
218   {
219      osd_printf_verbose("DirectDraw: Unable to find DirectDrawCreateEx\n");
220      FreeLibrary(dllhandle);
221      dllhandle = NULL;
222      return 1;
223   }
224
225   // import the enumerate function
226   directdrawenumerateex = (directdrawenumerateex_ptr)GetProcAddress(dllhandle, "DirectDrawEnumerateExA");
227   if (directdrawenumerateex == NULL)
228   {
229      osd_printf_verbose("DirectDraw: Unable to find DirectDrawEnumerateExA\n");
230      FreeLibrary(dllhandle);
231      dllhandle = NULL;
232      return 1;
233   }
234
235   // fill in the callbacks
236   memset(callbacks, 0, sizeof(*callbacks));
237   callbacks->exit = drawdd_exit;
238   callbacks->create = drawdd_create;
239
240   osd_printf_verbose("DirectDraw: Using DirectDraw 7\n");
241   return 0;
242}
243
244
245
246//============================================================
247//  drawdd_exit
248//============================================================
249
250static void drawdd_exit(void)
251{
252   if (dllhandle != NULL)
253      FreeLibrary(dllhandle);
254}
255
256
257
258//============================================================
259//  drawdd_window_init
260//============================================================
261
262int renderer_dd::create()
263{
264   // configure the adapter for the mode we want
265   if (config_adapter_mode())
266      goto error;
267
268   // create the ddraw object
269   if (ddraw_create())
270      goto error;
271
272   return 0;
273
274error:
275   destroy();
276   osd_printf_error("Unable to initialize DirectDraw.\n");
277   return 1;
278}
279
280
281
282//============================================================
283//  drawdd_window_destroy
284//============================================================
285
286void renderer_dd::destroy()
287{
288   // delete the ddraw object
289   ddraw_delete();
290}
291
292
293
294//============================================================
295//  drawdd_window_get_primitives
296//============================================================
297
298render_primitive_list *renderer_dd::get_primitives()
299{
300   compute_blit_surface_size();
301   window().target()->set_bounds(blitwidth, blitheight, 0);
302   window().target()->set_max_update_rate((refresh == 0) ? origmode.dwRefreshRate : refresh);
303
304   return &window().target()->get_primitives();
305}
306
307
308
309//============================================================
310//  drawdd_window_draw
311//============================================================
312
313int renderer_dd::draw(const int update)
314{
315   render_primitive *prim;
316   int usemembuffer = FALSE;
317   HRESULT result;
318
319   // if we're updating, remember to erase the outer stuff
320   if (update)
321      update_outer_rects();
322
323   // if we have a ddraw object, check the cooperative level
324   if (ddraw_test_cooperative())
325      return 1;
326
327   // get the size; if we're too small, delete the existing surfaces
328   if (blitwidth > blitdesc.dwWidth || blitheight > blitdesc.dwHeight)
329      ddraw_delete_surfaces();
330
331   // if we need to create surfaces, do it now
332   if (blit == NULL && ddraw_create_surfaces() != 0)
333      return 1;
334
335   // select our surface and lock it
336   result = IDirectDrawSurface7_Lock(blit, NULL, &blitdesc, DDLOCK_WAIT, NULL);
337   if (result == DDERR_SURFACELOST)
338   {
339      osd_printf_verbose("DirectDraw: Lost surfaces; deleting and retrying next frame\n");
340      ddraw_delete_surfaces();
341      return 1;
342   }
343   if (result != DD_OK)
344   {
345      osd_printf_verbose("DirectDraw: Error %08X locking blit surface\n", (int)result);
346      return 1;
347   }
348
349   // render to it
350   window().m_primlist->acquire_lock();
351
352   // scan the list of primitives for tricky stuff
353   for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
354      if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE ||
355         (prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32))
356      {
357         usemembuffer = TRUE;
358         break;
359      }
360
361   // if we're using the memory buffer, draw offscreen first and then copy
362   if (usemembuffer)
363   {
364      int x, y;
365
366      // based on the target format, use one of our standard renderers
367      switch (blitdesc.ddpfPixelFormat.dwRBitMask)
368      {
369         case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
370         case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
371         case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
372         case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
373         default:
374            osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
375            break;
376      }
377
378      // handle copying to both 16bpp and 32bpp destinations
379      for (y = 0; y < blitheight; y++)
380      {
381         if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 32)
382         {
383            UINT32 *src = (UINT32 *)membuffer + y * blitwidth;
384            UINT32 *dst = (UINT32 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
385            for (x = 0; x < blitwidth; x++)
386               *dst++ = *src++;
387         }
388         else if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 16)
389         {
390            UINT16 *src = (UINT16 *)membuffer + y * blitwidth;
391            UINT16 *dst = (UINT16 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
392            for (x = 0; x < blitwidth; x++)
393               *dst++ = *src++;
394         }
395      }
396
397   }
398
399   // otherwise, draw directly
400   else
401   {
402      // based on the target format, use one of our standard renderers
403      switch (blitdesc.ddpfPixelFormat.dwRBitMask)
404      {
405         case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
406         case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
407         case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
408         case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
409         default:
410            osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
411            break;
412      }
413   }
414   window().m_primlist->release_lock();
415
416   // unlock and blit
417   result = IDirectDrawSurface7_Unlock(blit, NULL);
418   if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X unlocking blit surface\n", (int)result);
419
420   // sync to VBLANK
421   if ((video_config.waitvsync || video_config.syncrefresh) && window().machine().video().throttled() && (!window().fullscreen() || back == NULL))
422   {
423      result = IDirectDraw7_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKBEGIN, NULL);
424      if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
425   }
426
427   // complete the blitting
428   blit_to_primary(blitwidth, blitheight);
429   return 0;
430}
431
432
433
434//============================================================
435//  ddraw_create
436//============================================================
437
438int renderer_dd::ddraw_create()
439{
440   HRESULT result;
441   int verify;
442
443   // if a device exists, free it
444   if (ddraw != NULL)
445      ddraw_delete();
446
447   // create the DirectDraw object
448   result = (*directdrawcreateex)(adapter_ptr, (LPVOID *)&ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
449   if (result != DD_OK)
450   {
451      osd_printf_verbose("DirectDraw: Error %08X during DirectDrawCreateEx call\n", (int)result);
452      goto error;
453   }
454
455   // verify the caps
456   verify = ddraw_verify_caps();
457   if (verify == 2)
458   {
459      osd_printf_error("DirectDraw: Error - Device does not meet minimum requirements for DirectDraw rendering\n");
460      goto error;
461   }
462   if (verify == 1)
463      osd_printf_verbose("DirectDraw: Warning - Device may not perform well for DirectDraw rendering\n");
464
465   // set the cooperative level
466   // for non-window modes, we will use full screen here
467   result = IDirectDraw7_SetCooperativeLevel(ddraw, win_window_list->m_hwnd, DDSCL_SETFOCUSWINDOW);
468   if (result != DD_OK)
469   {
470      osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_SetCooperativeLevel(FOCUSWINDOW) call\n", (int)result);
471      goto error;
472   }
473   result = IDirectDraw7_SetCooperativeLevel(ddraw, window().m_hwnd, DDSCL_SETDEVICEWINDOW | (window().fullscreen() ? DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE : DDSCL_NORMAL));
474   if (result != DD_OK)
475   {
476      osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_SetCooperativeLevel(DEVICEWINDOW) call\n", (int)result);
477      goto error;
478   }
479
480   // full screen mode: set the resolution
481   if (window().fullscreen() && video_config.switchres)
482   {
483      result = IDirectDraw7_SetDisplayMode(ddraw, width, height, 32, refresh, 0);
484      if (result != DD_OK)
485      {
486         osd_printf_verbose("DirectDraw: Error %08X attempting to set video mode %dx%d@%d call\n", (int)result, width, height, refresh);
487         goto error;
488      }
489   }
490
491   return ddraw_create_surfaces();
492
493error:
494   ddraw_delete();
495   return 1;
496}
497
498
499
500//============================================================
501//  ddraw_create_surfaces
502//============================================================
503
504int renderer_dd::ddraw_create_surfaces()
505{
506   HRESULT result;
507
508   // make a description of the primary surface
509   memset(&primarydesc, 0, sizeof(primarydesc));
510   primarydesc.dwSize = sizeof(primarydesc);
511   primarydesc.dwFlags = DDSD_CAPS;
512   primarydesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
513
514   // for triple-buffered full screen mode, allocate flipping surfaces
515   if (window().fullscreen() && video_config.triplebuf)
516   {
517      primarydesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
518      primarydesc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX;
519      primarydesc.dwBackBufferCount = 2;
520   }
521
522   // create the primary surface and report errors
523   result = create_surface(&primarydesc, &primary, "primary");
524   if (result != DD_OK) goto error;
525
526   // full screen mode: get the back surface
527   back = NULL;
528   if (window().fullscreen() && video_config.triplebuf)
529   {
530      DDSCAPS2 caps = { DDSCAPS_BACKBUFFER };
531      result = IDirectDrawSurface7_GetAttachedSurface(primary, &caps, &back);
532      if (result != DD_OK)
533      {
534         osd_printf_verbose("DirectDraw: Error %08X getting attached back surface\n", (int)result);
535         goto error;
536      }
537   }
538
539   // now make a description of our blit surface, based on the primary surface
540   if (blitwidth == 0 || blitheight == 0)
541      compute_blit_surface_size();
542   blitdesc = primarydesc;
543   blitdesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
544   blitdesc.dwWidth = blitwidth;
545   blitdesc.dwHeight = blitheight;
546   blitdesc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
547
548   // then create the blit surface, fall back to system memory if video mem doesn't work
549   result = create_surface(&blitdesc, &blit, "blit");
550   if (result != DD_OK)
551   {
552      blitdesc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
553      result = create_surface(&blitdesc, &blit, "blit");
554   }
555   if (result != DD_OK) goto error;
556
557   // create a memory buffer for offscreen drawing
558   if (membuffersize < blitwidth * blitheight * 4)
559   {
560      membuffersize = blitwidth * blitheight * 4;
561      global_free_array(membuffer);
562      membuffer = global_alloc_array(UINT8, membuffersize);
563   }
564   if (membuffer == NULL)
565      goto error;
566
567   // create a clipper for windowed mode
568   if (!window().fullscreen() && create_clipper())
569      goto error;
570
571   // full screen mode: set the gamma
572   if (window().fullscreen())
573   {
574      // only set the gamma if it's not 1.0f
575      windows_options &options = downcast<windows_options &>(window().machine().options());
576      float brightness = options.full_screen_brightness();
577      float contrast = options.full_screen_contrast();
578      float fgamma = options.full_screen_gamma();
579      if (brightness != 1.0f || contrast != 1.0f || fgamma != 1.0f)
580      {
581         // see if we can get a GammaControl object
582         result = IDirectDrawSurface_QueryInterface(primary, WRAP_REFIID(IID_IDirectDrawGammaControl), (void **)&gamma);
583         if (result != DD_OK)
584         {
585            osd_printf_warning("DirectDraw: Warning - device does not support full screen gamma correction.\n");
586            this->gamma = NULL;
587         }
588
589         // proceed if we can
590         if (this->gamma != NULL)
591         {
592            DDGAMMARAMP ramp;
593            int i;
594
595            // create a standard ramp and set it
596            for (i = 0; i < 256; i++)
597               ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, fgamma) << 8;
598
599            // attempt to set it
600            result = IDirectDrawGammaControl_SetGammaRamp(this->gamma, 0, &ramp);
601            if (result != DD_OK)
602               osd_printf_verbose("DirectDraw: Error %08X attempting to set gamma correction.\n", (int)result);
603         }
604      }
605   }
606
607   // force some updates
608   update_outer_rects();
609   return 0;
610
611error:
612   ddraw_delete_surfaces();
613   return 1;
614}
615
616
617
618//============================================================
619//  ddraw_delete
620//============================================================
621
622void renderer_dd::ddraw_delete()
623{
624   // free surfaces
625   ddraw_delete_surfaces();
626
627   // restore resolutions
628   if (ddraw != NULL)
629      IDirectDraw7_RestoreDisplayMode(ddraw);
630
631   // reset cooperative level
632   if (ddraw != NULL && window().m_hwnd != NULL)
633      IDirectDraw7_SetCooperativeLevel(ddraw, window().m_hwnd, DDSCL_NORMAL);
634
635   // release the DirectDraw object itself
636   if (ddraw != NULL)
637      IDirectDraw7_Release(ddraw);
638   ddraw = NULL;
639}
640
641
642
643//============================================================
644//  ddraw_delete_surfaces
645//============================================================
646
647void renderer_dd::ddraw_delete_surfaces()
648{
649   // release the gamma control
650   if (gamma != NULL)
651      IDirectDrawGammaControl_Release(gamma);
652   gamma = NULL;
653
654   // release the clipper
655   if (clipper != NULL)
656      IDirectDrawClipper_Release(clipper);
657   clipper = NULL;
658
659   // free the memory buffer
660   global_free_array(membuffer);
661   membuffer = NULL;
662   membuffersize = 0;
663
664   // release the blit surface
665   if (blit != NULL)
666      IDirectDrawSurface7_Release(blit);
667   blit = NULL;
668
669   // release the back surface
670   if (back != NULL)
671      IDirectDrawSurface7_Release(back);
672   back = NULL;
673
674   // release the primary surface
675   if (primary != NULL)
676      IDirectDrawSurface7_Release(primary);
677   primary = NULL;
678}
679
680
681
682//============================================================
683//  ddraw_verify_caps
684//============================================================
685
686int renderer_dd::ddraw_verify_caps()
687{
688   int retval = 0;
689   HRESULT result;
690
691   // get the capabilities
692   ddcaps.dwSize = sizeof(ddcaps);
693   helcaps.dwSize = sizeof(helcaps);
694   result = IDirectDraw7_GetCaps(ddraw, &ddcaps, &helcaps);
695   if (result != DD_OK)
696   {
697      osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_GetCaps call\n", (int)result);
698      return 1;
699   }
700
701   // determine if hardware stretching is available
702   if ((ddcaps.dwCaps & DDCAPS_BLTSTRETCH) == 0)
703   {
704      osd_printf_verbose("DirectDraw: Warning - Device does not support hardware stretching\n");
705      retval = 1;
706   }
707
708   return retval;
709}
710
711
712
713//============================================================
714//  ddraw_test_cooperative
715//============================================================
716
717int renderer_dd::ddraw_test_cooperative()
718{
719   HRESULT result;
720
721   // check our current status; if we lost the device, punt to GDI
722   result = IDirectDraw7_TestCooperativeLevel(ddraw);
723   switch (result)
724   {
725      // punt to GDI if someone else has exclusive mode
726      case DDERR_NOEXCLUSIVEMODE:
727      case DDERR_EXCLUSIVEMODEALREADYSET:
728         ddraw_delete_surfaces();
729         return 1;
730
731      // if we're ok, but we don't have a primary surface, create one
732      default:
733      case DD_OK:
734         if (primary == NULL)
735            return ddraw_create_surfaces();
736         return 0;
737   }
738}
739
740
741
742//============================================================
743//  create_surface
744//============================================================
745
746HRESULT renderer_dd::create_surface(DDSURFACEDESC2 *desc, IDirectDrawSurface7 **surface, const char *type)
747{
748   HRESULT result;
749
750   // create the surface as requested
751   result = IDirectDraw7_CreateSurface(ddraw, desc, surface, NULL);
752   if (result != DD_OK)
753   {
754      osd_printf_verbose("DirectDraw: Error %08X creating %s surface\n", (int)result, type);
755      return result;
756   }
757
758   // get a description of the primary surface
759   result = IDirectDrawSurface7_GetSurfaceDesc(*surface, desc);
760   if (result != DD_OK)
761   {
762      osd_printf_verbose("DirectDraw: Error %08X getting %s surface desciption\n", (int)result, type);
763      IDirectDrawSurface7_Release(*surface);
764      *surface = NULL;
765      return result;
766   }
767
768   // print out the good stuff
769   osd_printf_verbose("DirectDraw: %s surface created: %dx%dx%d (R=%08X G=%08X B=%08X)\n",
770            type,
771            (int)desc->dwWidth,
772            (int)desc->dwHeight,
773            (int)desc->ddpfPixelFormat.dwRGBBitCount,
774            (UINT32)desc->ddpfPixelFormat.dwRBitMask,
775            (UINT32)desc->ddpfPixelFormat.dwGBitMask,
776            (UINT32)desc->ddpfPixelFormat.dwBBitMask);
777   return result;
778}
779
780
781
782//============================================================
783//  create_clipper
784//============================================================
785
786int renderer_dd::create_clipper()
787{
788   HRESULT result;
789
790   // create a clipper for the primary surface
791   result = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL);
792   if (result != DD_OK)
793   {
794      osd_printf_verbose("DirectDraw: Error %08X creating clipper\n", (int)result);
795      return 1;
796   }
797
798   // set the clipper's hwnd
799   result = IDirectDrawClipper_SetHWnd(clipper, 0, window().m_hwnd);
800   if (result != DD_OK)
801   {
802      osd_printf_verbose("DirectDraw: Error %08X setting clipper hwnd\n", (int)result);
803      return 1;
804   }
805
806   // set the clipper on the primary surface
807   result = IDirectDrawSurface7_SetClipper(primary, clipper);
808   if (result != DD_OK)
809   {
810      osd_printf_verbose("DirectDraw: Error %08X setting clipper on primary surface\n", (int)result);
811      return 1;
812   }
813   return 0;
814}
815
816
817
818//============================================================
819//  compute_blit_surface_size
820//============================================================
821
822void renderer_dd::compute_blit_surface_size()
823{
824   INT32 newwidth, newheight;
825   int xscale, yscale;
826   RECT client;
827
828   // start with the minimum size
829   window().target()->compute_minimum_size(newwidth, newheight);
830
831   // get the window's client rectangle
832   GetClientRect(window().m_hwnd, &client);
833
834   // hardware stretch case: apply prescale
835   if (video_config.hwstretch)
836   {
837      int prescale = (window().prescale() < 1) ? 1 : window().prescale();
838
839      // clamp the prescale to something smaller than the target bounds
840      xscale = prescale;
841      while (xscale > 1 && newwidth * xscale > rect_width(&client))
842         xscale--;
843      yscale = prescale;
844      while (yscale > 1 && newheight * yscale > rect_height(&client))
845         yscale--;
846   }
847
848   // non stretch case
849   else
850   {
851      INT32 target_width = rect_width(&client);
852      INT32 target_height = rect_height(&client);
853      float desired_aspect = 1.0f;
854
855      // compute the appropriate visible area if we're trying to keepaspect
856      if (video_config.keepaspect)
857      {
858         win_monitor_info *monitor = window().winwindow_video_window_monitor(NULL);
859         window().target()->compute_visible_area(target_width, target_height, monitor->aspect(), window().target()->orientation(), target_width, target_height);
860         desired_aspect = (float)target_width / (float)target_height;
861      }
862
863      // compute maximum integral scaling to fit the window
864      xscale = (target_width + 2) / newwidth;
865      yscale = (target_height + 2) / newheight;
866
867      // try a little harder to keep the aspect ratio if desired
868      if (video_config.keepaspect)
869      {
870         // if we could stretch more in the X direction, and that makes a better fit, bump the xscale
871         while (newwidth * (xscale + 1) <= rect_width(&client) &&
872            better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale + 1), newheight * yscale, desired_aspect))
873            xscale++;
874
875         // if we could stretch more in the Y direction, and that makes a better fit, bump the yscale
876         while (newheight * (yscale + 1) <= rect_height(&client) &&
877            better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale + 1), desired_aspect))
878            yscale++;
879
880         // now that we've maxed out, see if backing off the maximally stretched one makes a better fit
881         if (rect_width(&client) - newwidth * xscale < rect_height(&client) - newheight * yscale)
882         {
883            while (xscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect))
884               xscale--;
885         }
886         else
887         {
888            while (yscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale - 1), desired_aspect))
889               yscale--;
890         }
891      }
892   }
893
894   // ensure at least a scale factor of 1
895   if (xscale == 0) xscale = 1;
896   if (yscale == 0) yscale = 1;
897
898   // apply the final scale
899   newwidth *= xscale;
900   newheight *= yscale;
901   if (newwidth != blitwidth || newheight != blitheight)
902   {
903      // force some updates
904      update_outer_rects();
905      osd_printf_verbose("DirectDraw: New blit size = %dx%d\n", newwidth, newheight);
906   }
907   blitwidth = newwidth;
908   blitheight = newheight;
909}
910
911
912
913//============================================================
914//  calc_fullscreen_margins
915//============================================================
916
917void renderer_dd::calc_fullscreen_margins(DWORD desc_width, DWORD desc_height, RECT *margins)
918{
919   margins->left = 0;
920   margins->top = 0;
921   margins->right = desc_width;
922   margins->bottom = desc_height;
923
924   if (window().win_has_menu())
925   {
926      static int height_with_menubar = 0;
927      if (height_with_menubar == 0)
928      {
929         RECT with_menu = { 100, 100, 200, 200 };
930         RECT without_menu = { 100, 100, 200, 200 };
931         AdjustWindowRect(&with_menu, WS_OVERLAPPED, TRUE);
932         AdjustWindowRect(&without_menu, WS_OVERLAPPED, FALSE);
933         height_with_menubar = (with_menu.bottom - with_menu.top) - (without_menu.bottom - without_menu.top);
934      }
935      margins->top = height_with_menubar;
936   }
937}
938
939
940
941//============================================================
942//  blit_to_primary
943//============================================================
944
945void renderer_dd::blit_to_primary(int srcwidth, int srcheight)
946{
947   IDirectDrawSurface7 *target = (back != NULL) ? back : primary;
948   win_monitor_info *monitor = window().winwindow_video_window_monitor(NULL);
949   DDBLTFX blitfx = { sizeof(DDBLTFX) };
950   RECT clear, outer, dest, source;
951   INT32 dstwidth, dstheight;
952   HRESULT result;
953
954   // compute source rect
955   source.left = source.top = 0;
956   source.right = srcwidth;
957   source.bottom = srcheight;
958
959   // compute outer rect -- windowed version
960   if (!window().fullscreen())
961   {
962      GetClientRect(window().m_hwnd, &outer);
963      ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[0]);
964      ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[1]);
965
966      // adjust to be relative to the monitor
967      osd_rect pos = monitor->position_size();
968      outer.left -= pos.left();
969      outer.right -= pos.left();
970      outer.top -= pos.top();
971      outer.bottom -= pos.top();
972   }
973
974   // compute outer rect -- full screen version
975   else
976   {
977      calc_fullscreen_margins(primarydesc.dwWidth, primarydesc.dwHeight, &outer);
978   }
979
980   // if we're respecting the aspect ratio, we need to adjust to fit
981   dstwidth = rect_width(&outer);
982   dstheight = rect_height(&outer);
983   if (!video_config.hwstretch)
984   {
985      // trim the source if necessary
986      if (rect_width(&outer) < srcwidth)
987      {
988         source.left += (srcwidth - rect_width(&outer)) / 2;
989         source.right = source.left + rect_width(&outer);
990      }
991      if (rect_height(&outer) < srcheight)
992      {
993         source.top += (srcheight - rect_height(&outer)) / 2;
994         source.bottom = source.top + rect_height(&outer);
995      }
996
997      // match the destination and source sizes
998      dstwidth = srcwidth = source.right - source.left;
999      dstheight = srcheight = source.bottom - source.top;
1000   }
1001   else if (video_config.keepaspect)
1002   {
1003      // compute the appropriate visible area
1004      window().target()->compute_visible_area(rect_width(&outer), rect_height(&outer), monitor->aspect(), window().target()->orientation(), dstwidth, dstheight);
1005   }
1006
1007   // center within
1008   dest.left = outer.left + (rect_width(&outer) - dstwidth) / 2;
1009   dest.right = dest.left + dstwidth;
1010   dest.top = outer.top + (rect_height(&outer) - dstheight) / 2;
1011   dest.bottom = dest.top + dstheight;
1012
1013   // compare against last destination; if different, force a redraw
1014   if (dest.left != lastdest.left || dest.right != lastdest.right || dest.top != lastdest.top || dest.bottom != lastdest.bottom)
1015   {
1016      lastdest = dest;
1017      update_outer_rects();
1018   }
1019
1020   // clear outer rects if we need to
1021   if (clearouter != 0)
1022   {
1023      clearouter--;
1024
1025      // clear the left edge
1026      if (dest.left > outer.left)
1027      {
1028         clear = outer;
1029         clear.right = dest.left;
1030         result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
1031         if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
1032      }
1033
1034      // clear the right edge
1035      if (dest.right < outer.right)
1036      {
1037         clear = outer;
1038         clear.left = dest.right;
1039         result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
1040         if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
1041      }
1042
1043      // clear the top edge
1044      if (dest.top > outer.top)
1045      {
1046         clear = outer;
1047         clear.bottom = dest.top;
1048         result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
1049         if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
1050      }
1051
1052      // clear the bottom edge
1053      if (dest.bottom < outer.bottom)
1054      {
1055         clear = outer;
1056         clear.top = dest.bottom;
1057         result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
1058         if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
1059      }
1060   }
1061
1062   // do the blit
1063   result = IDirectDrawSurface7_Blt(target, &dest, blit, &source, DDBLT_WAIT, NULL);
1064   if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X blitting to the screen\n", (int)result);
1065
1066   // page flip if triple buffered
1067   if (window().fullscreen() && back != NULL)
1068   {
1069      result = IDirectDrawSurface7_Flip(primary, NULL, DDFLIP_WAIT);
1070      if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
1071   }
1072}
1073
1074
1075
1076//============================================================
1077//  config_adapter_mode
1078//============================================================
1079
1080int renderer_dd::config_adapter_mode()
1081{
1082   DDDEVICEIDENTIFIER2 identifier;
1083   HRESULT result;
1084
1085   // choose the monitor number
1086   get_adapter_for_monitor(window().monitor());
1087
1088   // create a temporary DirectDraw object
1089   result = (*directdrawcreateex)(adapter_ptr, (LPVOID *)&ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
1090   if (result != DD_OK)
1091   {
1092      osd_printf_verbose("DirectDraw: Error %08X during DirectDrawCreateEx call\n", (int)result);
1093      return 1;
1094   }
1095
1096   // get the identifier
1097   result = IDirectDraw7_GetDeviceIdentifier(ddraw, &identifier, 0);
1098   if (result != DD_OK)
1099   {
1100      osd_printf_error("Error getting identifier for device\n");
1101      return 1;
1102   }
1103   osd_printf_verbose("DirectDraw: Configuring device %s\n", identifier.szDescription);
1104
1105   // get the current display mode
1106   memset(&origmode, 0, sizeof(origmode));
1107   origmode.dwSize = sizeof(origmode);
1108   result = IDirectDraw7_GetDisplayMode(ddraw, &origmode);
1109   if (result != DD_OK)
1110   {
1111      osd_printf_verbose("DirectDraw: Error %08X getting current display mode\n", (int)result);
1112      IDirectDraw7_Release(ddraw);
1113      return 1;
1114   }
1115
1116   // choose a resolution: full screen mode case
1117   if (window().fullscreen())
1118   {
1119      // default to the current mode exactly
1120      width = origmode.dwWidth;
1121      height = origmode.dwHeight;
1122      refresh = origmode.dwRefreshRate;
1123
1124      // if we're allowed to switch resolutions, override with something better
1125      if (video_config.switchres)
1126         pick_best_mode();
1127   }
1128
1129   // release the DirectDraw object
1130   IDirectDraw7_Release(ddraw);
1131   ddraw = NULL;
1132
1133   // if we're not changing resolutions, make sure we have a resolution we can handle
1134   if (!window().fullscreen() || !video_config.switchres)
1135   {
1136      switch (origmode.ddpfPixelFormat.dwRBitMask)
1137      {
1138         case 0x00ff0000:
1139         case 0x000000ff:
1140         case 0xf800:
1141         case 0x7c00:
1142            break;
1143
1144         default:
1145            osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)origmode.ddpfPixelFormat.dwRBitMask, (int)origmode.ddpfPixelFormat.dwGBitMask, (int)origmode.ddpfPixelFormat.dwBBitMask);
1146            return 1;
1147      }
1148   }
1149
1150   return 0;
1151}
1152
1153
1154
1155//============================================================
1156//  monitor_enum_callback
1157//============================================================
1158
1159static BOOL WINAPI monitor_enum_callback(GUID FAR *guid, LPSTR description, LPSTR name, LPVOID context, HMONITOR hmonitor)
1160{
1161   monitor_enum_info *einfo = (monitor_enum_info *)context;
1162
1163   // do we match the desired monitor?
1164   if (hmonitor == einfo->monitor->handle() || (hmonitor == NULL && einfo->monitor->is_primary()))
1165   {
1166      einfo->guid_ptr = (guid != NULL) ? &einfo->guid : NULL;
1167      if (guid != NULL)
1168         einfo->guid = *guid;
1169      einfo->foundit = TRUE;
1170   }
1171   return 1;
1172}
1173
1174
1175
1176//============================================================
1177//  get_adapter_for_monitor
1178//============================================================
1179
1180void renderer_dd::get_adapter_for_monitor(win_monitor_info *monitor)
1181{
1182   monitor_enum_info einfo;
1183   HRESULT result;
1184
1185   // try to find our monitor
1186   memset(&einfo, 0, sizeof(einfo));
1187   einfo.monitor = monitor;
1188   result = (*directdrawenumerateex)(monitor_enum_callback, &einfo, DDENUM_ATTACHEDSECONDARYDEVICES);
1189   if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X during DirectDrawEnumerateEx call\n", (int)result);
1190
1191   // set up the adapter
1192   if (einfo.foundit && einfo.guid_ptr != NULL)
1193   {
1194      adapter = einfo.guid;
1195      adapter_ptr = &adapter;
1196   }
1197   else
1198      adapter_ptr = NULL;
1199}
1200
1201
1202
1203//============================================================
1204//  enum_modes_callback
1205//============================================================
1206
1207static HRESULT WINAPI enum_modes_callback(LPDDSURFACEDESC2 desc, LPVOID context)
1208{
1209   float size_score, refresh_score, final_score;
1210   mode_enum_info *einfo = (mode_enum_info *)context;
1211   renderer_dd *dd = einfo->renderer;
1212
1213   // skip non-32 bit modes
1214   if (desc->ddpfPixelFormat.dwRGBBitCount != 32)
1215      return DDENUMRET_OK;
1216
1217   // compute initial score based on difference between target and current
1218   size_score = 1.0f / (1.0f + fabs((float)((INT32)desc->dwWidth - einfo->target_width)) + fabs((float)((INT32)desc->dwHeight - einfo->target_height)));
1219
1220   // if the mode is too small, give a big penalty
1221   if (desc->dwWidth < einfo->minimum_width || desc->dwHeight < einfo->minimum_height)
1222      size_score *= 0.01f;
1223
1224   // if mode is smaller than we'd like, it only scores up to 0.1
1225   if (desc->dwWidth < einfo->target_width || desc->dwHeight < einfo->target_height)
1226      size_score *= 0.1f;
1227
1228   // if we're looking for a particular mode, that's a winner
1229   if (desc->dwWidth == einfo->window->m_win_config.width && desc->dwHeight == einfo->window->m_win_config.height)
1230      size_score = 2.0f;
1231
1232   // compute refresh score
1233   refresh_score = 1.0f / (1.0f + fabs((double)desc->dwRefreshRate - einfo->target_refresh));
1234
1235   // if refresh is smaller than we'd like, it only scores up to 0.1
1236   if ((double)desc->dwRefreshRate < einfo->target_refresh)
1237      refresh_score *= 0.1f;
1238
1239   // if we're looking for a particular refresh, make sure it matches
1240   if (desc->dwRefreshRate == einfo->window->m_win_config.refresh)
1241      refresh_score = 2.0f;
1242
1243   // weight size and refresh equally
1244   final_score = size_score + refresh_score;
1245
1246   // best so far?
1247   osd_printf_verbose("  %4dx%4d@%3dHz -> %f\n", (int)desc->dwWidth, (int)desc->dwHeight, (int)desc->dwRefreshRate, final_score * 1000.0f);
1248   if (final_score > einfo->best_score)
1249   {
1250      einfo->best_score = final_score;
1251      dd->width = desc->dwWidth;
1252      dd->height = desc->dwHeight;
1253      dd->refresh = desc->dwRefreshRate;
1254   }
1255   return DDENUMRET_OK;
1256}
1257
1258
1259
1260//============================================================
1261//  pick_best_mode
1262//============================================================
1263
1264void renderer_dd::pick_best_mode()
1265{
1266   mode_enum_info einfo;
1267   HRESULT result;
1268
1269   // determine the minimum width/height for the selected target
1270   // note: technically we should not be calling this from an alternate window
1271   // thread; however, it is only done during init time, and the init code on
1272   // the main thread is waiting for us to finish, so it is safe to do so here
1273   window().target()->compute_minimum_size(einfo.minimum_width, einfo.minimum_height);
1274
1275   // use those as the target for now
1276   einfo.target_width = einfo.minimum_width * MAX(1, window().prescale());
1277   einfo.target_height = einfo.minimum_height * MAX(1, window().prescale());
1278
1279   // determine the refresh rate of the primary screen
1280   einfo.target_refresh = 60.0;
1281   const screen_device *primary_screen = window().machine().config().first_screen();
1282   if (primary_screen != NULL)
1283      einfo.target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
1284   printf("Target refresh = %f\n", einfo.target_refresh);
1285
1286   // if we're not stretching, allow some slop on the minimum since we can handle it
1287   if (!video_config.hwstretch)
1288   {
1289      einfo.minimum_width -= 4;
1290      einfo.minimum_height -= 4;
1291   }
1292
1293   // if we are stretching, aim for a mode approximately 2x the game's resolution
1294   else if (window().prescale() <= 1)
1295   {
1296      einfo.target_width *= 2;
1297      einfo.target_height *= 2;
1298   }
1299
1300   // fill in the rest of the data
1301   einfo.window = &window();
1302   einfo.renderer = this;
1303   einfo.best_score = 0.0f;
1304
1305   // enumerate the modes
1306   osd_printf_verbose("DirectDraw: Selecting video mode...\n");
1307   result = IDirectDraw7_EnumDisplayModes(ddraw, DDEDM_REFRESHRATES, NULL, &einfo, enum_modes_callback);
1308   if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X during EnumDisplayModes call\n", (int)result);
1309   osd_printf_verbose("DirectDraw: Mode selected = %4dx%4d@%3dHz\n", width, height, refresh);
1310}
trunk/src/osd/modules/render/drawgdi.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawgdi.c - Win32 GDI drawing
6//
7//============================================================
8
9// standard windows headers
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12
13// MAME headers
14#include "emu.h"
15#include "rendersw.inc"
16
17// MAMEOS headers
18#include "window.h"
19
20
21//============================================================
22//  TYPE DEFINITIONS
23//============================================================
24
25class renderer_gdi : public osd_renderer
26{
27public:
28   renderer_gdi(osd_window *window)
29   : osd_renderer(window, FLAG_NONE), bmdata(NULL), bmsize(0) { }
30
31   virtual ~renderer_gdi() { }
32
33   virtual int create();
34   virtual render_primitive_list *get_primitives();
35   virtual int draw(const int update);
36   virtual void save() {};
37   virtual void record() {};
38   virtual void toggle_fsfx() {};
39   virtual void destroy();
40
41private:
42   /* gdi_info is the information for the current screen */
43   BITMAPINFO              bminfo;
44   UINT8 *                 bmdata;
45   size_t                  bmsize;
46};
47
48
49//============================================================
50//  PROTOTYPES
51//============================================================
52
53// core functions
54static void drawgdi_exit(void);
55
56//============================================================
57//  drawnone_create
58//============================================================
59
60static osd_renderer *drawgdi_create(osd_window *window)
61{
62   return global_alloc(renderer_gdi(window));
63}
64
65
66//============================================================
67//  drawgdi_init
68//============================================================
69
70int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks)
71{
72   // fill in the callbacks
73   memset(callbacks, 0, sizeof(*callbacks));
74   callbacks->exit = drawgdi_exit;
75   callbacks->create = drawgdi_create;
76   return 0;
77}
78
79
80
81//============================================================
82//  drawgdi_exit
83//============================================================
84
85static void drawgdi_exit(void)
86{
87}
88
89
90
91//============================================================
92//  drawgdi_window_init
93//============================================================
94
95int renderer_gdi::create()
96{
97   // fill in the bitmap info header
98   bminfo.bmiHeader.biSize            = sizeof(bminfo.bmiHeader);
99   bminfo.bmiHeader.biPlanes          = 1;
100   bminfo.bmiHeader.biBitCount        = 32;
101   bminfo.bmiHeader.biCompression     = BI_RGB;
102   bminfo.bmiHeader.biSizeImage       = 0;
103   bminfo.bmiHeader.biXPelsPerMeter   = 0;
104   bminfo.bmiHeader.biYPelsPerMeter   = 0;
105   bminfo.bmiHeader.biClrUsed         = 0;
106   bminfo.bmiHeader.biClrImportant    = 0;
107
108   return 0;
109}
110
111
112
113//============================================================
114//  drawgdi_window_destroy
115//============================================================
116
117void renderer_gdi::destroy()
118{
119   // free the bitmap memory
120   if (bmdata != NULL)
121      global_free_array(bmdata);
122}
123
124
125
126//============================================================
127//  drawgdi_window_get_primitives
128//============================================================
129
130render_primitive_list *renderer_gdi::get_primitives()
131{
132   RECT client;
133   GetClientRect(window().m_hwnd, &client);
134   window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
135   return &window().target()->get_primitives();
136}
137
138
139
140//============================================================
141//  drawgdi_window_draw
142//============================================================
143
144int renderer_gdi::draw(const int update)
145{
146   int width, height, pitch;
147   RECT bounds;
148
149   // we don't have any special resize behaviors
150   if (window().m_resize_state == RESIZE_STATE_PENDING)
151      window().m_resize_state = RESIZE_STATE_NORMAL;
152
153   // get the target bounds
154   GetClientRect(window().m_hwnd, &bounds);
155
156   // compute width/height/pitch of target
157   width = rect_width(&bounds);
158   height = rect_height(&bounds);
159   pitch = (width + 3) & ~3;
160
161   // make sure our temporary bitmap is big enough
162   if (pitch * height * 4 > bmsize)
163   {
164      bmsize = pitch * height * 4 * 2;
165      global_free_array(bmdata);
166      bmdata = global_alloc_array(UINT8, bmsize);
167   }
168
169   // draw the primitives to the bitmap
170   window().m_primlist->acquire_lock();
171   software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, bmdata, width, height, pitch);
172   window().m_primlist->release_lock();
173
174   // fill in bitmap-specific info
175   bminfo.bmiHeader.biWidth = pitch;
176   bminfo.bmiHeader.biHeight = -height;
177
178   // blit to the screen
179   StretchDIBits(window().m_dc, 0, 0, width, height,
180            0, 0, width, height,
181            bmdata, &bminfo, DIB_RGB_COLORS, SRCCOPY);
182   return 0;
183}
trunk/src/osd/modules/render/drawnone.c
r0r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawnone.c - stub "nothing" drawer
6//
7//============================================================
8
9// standard windows headers
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12
13// MAME headers
14#include "emu.h"
15
16// MAMEOS headers
17#include "window.h"
18
19
20class renderer_none : public osd_renderer
21{
22public:
23   renderer_none(osd_window *window)
24   : osd_renderer(window, FLAG_NONE) { }
25
26   virtual ~renderer_none() { }
27
28   virtual int create();
29   virtual render_primitive_list *get_primitives();
30   virtual int draw(const int update);
31   virtual void save() { };
32   virtual void record() { };
33   virtual void toggle_fsfx() { };
34   virtual void destroy();
35
36private:
37};
38
39//============================================================
40//  PROTOTYPES
41//============================================================
42
43// core functions
44static void drawnone_exit(void);
45
46//============================================================
47//  drawnone_create
48//============================================================
49
50osd_renderer *drawnone_create(osd_window *window)
51{
52   return global_alloc(renderer_none(window));
53}
54
55//============================================================
56//  drawnone_init
57//============================================================
58
59int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks)
60{
61   // fill in the callbacks
62   memset(callbacks, 0, sizeof(*callbacks));
63   callbacks->exit = drawnone_exit;
64   callbacks->create = drawnone_create;
65   return 0;
66}
67
68
69
70//============================================================
71//  drawnone_exit
72//============================================================
73
74static void drawnone_exit(void)
75{
76}
77
78
79
80//============================================================
81//  drawnone_window_init
82//============================================================
83
84int renderer_none::create()
85{
86   return 0;
87}
88
89
90
91//============================================================
92//  drawnone_window_destroy
93//============================================================
94
95void renderer_none::destroy()
96{
97}
98
99
100
101//============================================================
102//  drawnone_window_get_primitives
103//============================================================
104
105render_primitive_list *renderer_none::get_primitives()
106{
107   RECT client;
108   GetClientRect(window().m_hwnd, &client);
109   window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
110   return &window().target()->get_primitives();
111}
112
113
114
115//============================================================
116//  drawnone_window_draw
117//============================================================
118
119int renderer_none::draw(const int update)
120{
121   return 0;
122}
trunk/src/osd/modules/render/drawogl.c
r0r244652
1//============================================================
2//
3//  drawogl.c - SDL software and OpenGL implementation
4//
5//  Copyright (c) 1996-2014, Nicola Salmoria and the MAME Team.
6//  Visit http://mamedev.org for licensing and usage restrictions.
7//
8//  SDLMAME by Olivier Galibert and R. Belmont
9//
10//  Note: D3D9 goes to a lot of trouble to fiddle with MODULATE
11//        mode on textures.  That is the default in OpenGL so we
12//        don't have to touch it.
13//
14//============================================================
15
16// standard C headers
17#include <math.h>
18#include <stdio.h>
19
20// MAME headers
21#include "osdcomm.h"
22#include "emu.h"
23#include "options.h"
24#include "emuopts.h"
25
26#ifndef OSD_WINDOWS
27// standard SDL headers
28#define TOBEMIGRATED 1
29#include "sdlinc.h"
30#endif
31
32// OpenGL headers
33#include "modules/opengl/osd_opengl.h"
34
35#ifdef OSD_WINDOWS
36#define SDLMAME_SDL2 1
37#ifndef USE_DISPATCH_GL
38#include "GL/wglext.h"
39#endif
40#endif
41
42#include "modules/lib/osdlib.h"
43#include "modules/lib/osdobj_common.h"
44
45
46#include "modules/opengl/gl_shader_tool.h"
47#include "modules/opengl/gl_shader_mgr.h"
48
49#if defined(SDLMAME_MACOSX)
50#ifndef APIENTRY
51#define APIENTRY
52#endif
53#ifndef APIENTRYP
54#define APIENTRYP APIENTRY *
55#endif
56
57typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
58typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum, GLuint);
59typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum, GLsizeiptr, const GLvoid *, GLenum);
60typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum, GLintptr, GLsizeiptr, const GLvoid *);
61typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum, GLenum);
62typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum);
63typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei, const GLuint *);
64typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
65typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
66typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum m_target, GLuint framebuffer);
67typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
68typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
69typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum m_target);
70typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum m_target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
71typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
72typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum m_target, GLuint renderbuffer);
73typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum m_target, GLenum internalformat, GLsizei width, GLsizei height);
74typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum m_target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
75typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
76#endif
77
78// make sure the extensions compile OK everywhere
79#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
80#define GL_TEXTURE_STORAGE_HINT_APPLE     0x85bc
81#endif
82
83#ifndef GL_STORAGE_CACHED_APPLE
84#define GL_STORAGE_CACHED_APPLE           0x85be
85#endif
86
87#ifndef GL_UNPACK_CLIENT_STORAGE_APPLE
88#define GL_UNPACK_CLIENT_STORAGE_APPLE    0x85b2
89#endif
90
91#ifndef GL_TEXTURE_RECTANGLE_ARB
92#define GL_TEXTURE_RECTANGLE_ARB          0x84F5
93#endif
94
95#ifndef GL_PIXEL_UNPACK_BUFFER_ARB
96#define GL_PIXEL_UNPACK_BUFFER_ARB        0x88EC
97#endif
98
99#ifndef GL_STREAM_DRAW
100#define GL_STREAM_DRAW                    0x88E0
101#endif
102
103#ifndef GL_WRITE_ONLY
104#define GL_WRITE_ONLY                     0x88B9
105#endif
106
107#ifndef GL_ARRAY_BUFFER_ARB
108#define GL_ARRAY_BUFFER_ARB               0x8892
109#endif
110
111#ifndef GL_PIXEL_UNPACK_BUFFER_ARB
112#define GL_PIXEL_UNPACK_BUFFER_ARB        0x88EC
113#endif
114
115#ifndef GL_FRAMEBUFFER_EXT
116#define GL_FRAMEBUFFER_EXT              0x8D40
117#define GL_FRAMEBUFFER_COMPLETE_EXT         0x8CD5
118#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT    0x8CD6
119#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT    0x8CD7
120#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT  0x8CD8
121#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT        0x8CD9
122#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT       0x8CDA
123#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT   0x8CDB
124#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT   0x8CDC
125#define GL_FRAMEBUFFER_UNSUPPORTED_EXT          0x8CDD
126#define GL_RENDERBUFFER_EXT             0x8D41
127#define GL_DEPTH_COMPONENT16                0x81A5
128#define GL_DEPTH_COMPONENT24                0x81A6
129#define GL_DEPTH_COMPONENT32                0x81A7
130#endif
131
132#define HASH_SIZE       ((1<<10)+1)
133#define OVERFLOW_SIZE   (1<<10)
134
135// OSD headers
136#ifndef OSD_WINDOWS
137#include "osdsdl.h"
138#include "window.h"
139#else
140#include "../windows/window.h"
141typedef UINT64 HashT;
142#endif
143
144//============================================================
145//  DEBUGGING
146//============================================================
147
148#define DEBUG_MODE_SCORES   0
149#define USE_WIN32_STYLE_LINES   0   // use the same method baseline does - yields somewhat nicer vectors but a little buggy
150
151//============================================================
152//  CONSTANTS
153//============================================================
154
155enum
156{
157   TEXTURE_TYPE_NONE,
158   TEXTURE_TYPE_PLAIN,
159   TEXTURE_TYPE_DYNAMIC,
160   TEXTURE_TYPE_SHADER,
161   TEXTURE_TYPE_SURFACE
162};
163
164
165//============================================================
166//  MACROS
167//============================================================
168
169#ifdef OSD_WINDOWS
170// texture formats
171// This used to be an enum, but these are now defines so we can use them as
172// preprocessor conditionals
173#define SDL_TEXFORMAT_ARGB32            (0) // non-16-bit textures or specials
174#define SDL_TEXFORMAT_RGB32             (1)
175#define SDL_TEXFORMAT_RGB32_PALETTED    (2)
176#define SDL_TEXFORMAT_YUY16             (3)
177#define SDL_TEXFORMAT_YUY16_PALETTED    (4)
178#define SDL_TEXFORMAT_PALETTE16         (5)
179#define SDL_TEXFORMAT_RGB15             (6)
180#define SDL_TEXFORMAT_RGB15_PALETTED    (7)
181#define SDL_TEXFORMAT_PALETTE16A        (8)
182// special texture formats for 16bpp texture destination support, do not use
183// to address the tex properties / tex functions arrays!
184#define SDL_TEXFORMAT_PALETTE16_ARGB1555    (16)
185#define SDL_TEXFORMAT_RGB15_ARGB1555        (17)
186#define SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555   (18)
187#endif
188
189#define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0)
190#define GL_NO_PRIMITIVE -1
191
192//============================================================
193//  TYPES
194//============================================================
195
196#if (SDLMAME_SDL2)
197
198#ifdef OSD_WINDOWS
199class win_gl_context : public osd_gl_context
200{
201public:
202   win_gl_context(HWND window) : osd_gl_context(), m_context(0), m_window(NULL), m_hdc(0)
203   {
204      m_error[0] = 0;
205
206      this->wglGetProcAddress = (PROC WINAPI (*)(LPCSTR lpszProc)) GetProcAddress(m_module, "wglGetProcAddress");
207      this->wglCreateContext = (HGLRC WINAPI (*)(HDC hdc)) GetProcAddress(m_module, "wglCreateContext");
208      this->wglDeleteContext = (BOOL WINAPI (*)(HGLRC hglrc)) GetProcAddress(m_module, "wglDeleteContext");
209      this->wglMakeCurrent = (BOOL WINAPI (*)(HDC hdc, HGLRC hglrc)) GetProcAddress(m_module, "wglMakeCurrent");
210
211      m_hdc = GetDC(window);
212      if (!setupPixelFormat(m_hdc))
213      {
214         m_context = wglCreateContext(m_hdc);
215         if  (!m_context)
216         {
217            FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, m_error, 255, NULL);
218            return;
219         }
220         wglMakeCurrent(m_hdc, m_context);
221      }
222   }
223
224   virtual ~win_gl_context()
225   {
226      wglDeleteContext(m_context);
227      ReleaseDC(m_window, m_hdc);
228   }
229
230   virtual void MakeCurrent()
231   {
232      wglMakeCurrent(m_hdc, m_context);
233   }
234
235   virtual const char *LastErrorMsg()
236   {
237      if (m_error[0] == 0)
238         return NULL;
239      else
240         return m_error;
241   }
242
243   virtual void *getProcAddress(const char *proc)
244   {
245      void *ret = (void *) GetProcAddress(m_module, proc);
246      if (ret == NULL)
247         ret = (void *) wglGetProcAddress(proc);
248      return ret;
249   }
250
251   virtual int SetSwapInterval(const int swap)
252   {
253      // FIXME: Missing!
254      return 0;
255   }
256
257   virtual void SwapBuffer()
258   {
259      SwapBuffers(m_hdc);
260      //wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE);
261   }
262
263   static void load_library()
264   {
265      m_module = LoadLibraryA("opengl32.dll");
266   }
267
268private:
269
270   int setupPixelFormat(HDC hDC)
271   {
272       PIXELFORMATDESCRIPTOR pfd = {
273           sizeof(PIXELFORMATDESCRIPTOR),  /* size */
274           1,                              /* version */
275           PFD_SUPPORT_OPENGL |
276           PFD_DRAW_TO_WINDOW |
277           PFD_DOUBLEBUFFER,               /* support double-buffering */
278           PFD_TYPE_RGBA,                  /* color type */
279           32,                             /* prefered color depth */
280           0, 0, 0, 0, 0, 0,               /* color bits (ignored) */
281           0,                              /* no alpha buffer */
282           0,                              /* alpha bits (ignored) */
283           0,                              /* no accumulation buffer */
284           0, 0, 0, 0,                     /* accum bits (ignored) */
285           16,                             /* depth buffer */
286           0,                              /* no stencil buffer */
287           0,                              /* no auxiliary buffers */
288           PFD_MAIN_PLANE,                 /* main layer */
289           0,                              /* reserved */
290           0, 0, 0,                        /* no layer, visible, damage masks */
291       };
292       int pixelFormat;
293
294       pixelFormat = ChoosePixelFormat(hDC, &pfd);
295       if (pixelFormat == 0) {
296           strcpy(m_error, "ChoosePixelFormat failed");
297           return 1;
298       }
299
300       if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) {
301           strcpy(m_error, "SetPixelFormat failed.");
302           return 1;
303       }
304       return 0;
305   }
306
307
308   HGLRC m_context;
309   HWND m_window;
310   HDC m_hdc;
311   char m_error[256];
312
313   PROC WINAPI (*wglGetProcAddress)(LPCSTR lpszProc);
314   HGLRC WINAPI (*wglCreateContext)(HDC hdc);
315   BOOL WINAPI (*wglDeleteContext)(HGLRC hglrc);
316   BOOL WINAPI (*wglMakeCurrent)(HDC hdc, HGLRC hglrc);
317
318   static HMODULE m_module;
319};
320
321HMODULE win_gl_context::m_module;
322
323
324#else
325class sdl_gl_context : public osd_gl_context
326{
327public:
328   sdl_gl_context(SDL_Window *window) : osd_gl_context(), m_context(0), m_window(window)
329   {
330      m_error[0] = 0;
331      m_context = SDL_GL_CreateContext(window);
332      if  (!m_context)
333      {
334         snprintf(m_error,255, "OpenGL not supported on this driver: %s", SDL_GetError());
335      }
336   }
337   virtual ~sdl_gl_context()
338   {
339      SDL_GL_DeleteContext(m_context);
340   }
341   virtual void MakeCurrent()
342   {
343      SDL_GL_MakeCurrent(m_window, m_context);
344   }
345
346   virtual int SetSwapInterval(const int swap)
347   {
348      return SDL_GL_SetSwapInterval(swap);
349   }
350
351   virtual const char *LastErrorMsg()
352   {
353      if (m_error[0] == 0)
354         return NULL;
355      else
356         return m_error;
357   }
358   virtual void *getProcAddress(const char *proc)
359   {
360      return SDL_GL_GetProcAddress(proc);
361   }
362
363   virtual void SwapBuffer()
364   {
365      SDL_GL_SwapWindow(m_window);
366   }
367
368private:
369   SDL_GLContext m_context;
370   SDL_Window *m_window;
371   char m_error[256];
372};
373#endif
374#else
375// SDL 1.2
376class sdl12_gl_context : public osd_gl_context
377{
378public:
379   sdl12_gl_context(SDL_Surface *window) : osd_gl_context(), m_window(window)
380   {
381      m_error[0] = 0;
382   }
383   virtual ~sdl12_gl_context()
384   {
385   }
386   virtual void MakeCurrent()
387   {
388   }
389
390   virtual int SetSwapInterval(const int swap)
391   {
392      // Not supported on 1.2
393      return 0;
394   }
395
396   virtual const char *LastErrorMsg()
397   {
398      if (m_error[0] == 0)
399         return NULL;
400      else
401         return m_error;
402   }
403
404   virtual void *getProcAddress(const char *proc)
405   {
406      return SDL_GL_GetProcAddress(proc);
407   }
408
409   virtual void SwapBuffer()
410   {
411      SDL_GL_SwapBuffers();
412   }
413
414private:
415   SDL_Surface *m_window;
416   char m_error[256];
417};
418
419
420#endif
421
422//============================================================
423//  Textures
424//============================================================
425
426/* texture_info holds information about a texture */
427class texture_info
428{
429public:
430   texture_info()
431   :   hash(0), flags(0), rawwidth(0), rawheight(0),
432      rawwidth_create(0), rawheight_create(0),
433      type(0), format(0), borderpix(0), xprescale(0), yprescale(0), nocopy(0),
434      texture(0), texTarget(0), texpow2(0), mpass_dest_idx(0), pbo(0), data(NULL),
435      data_own(0), texCoordBufferName(0)
436   {
437      for (int i=0; i<2; i++)
438      {
439         mpass_textureunit[i] = 0;
440         mpass_texture_mamebm[i] = 0;
441         mpass_fbo_mamebm[i] = 0;
442         mpass_texture_scrn[i] = 0;
443         mpass_fbo_scrn[i] = 0;
444      }
445      for (int i=0; i<8; i++)
446         texCoord[i] = 0.0f;
447   }
448
449   HashT               hash;               // hash value for the texture (must be >= pointer size)
450   UINT32              flags;              // rendering flags
451   render_texinfo      texinfo;            // copy of the texture info
452   int                 rawwidth, rawheight;    // raw width/height of the texture
453   int                 rawwidth_create;    // raw width/height, pow2 compatible, if needed
454   int                 rawheight_create;   // (create and initial set the texture, not for copy!)
455   int                 type;               // what type of texture are we?
456   int                 format;             // texture format
457   int                 borderpix;          // do we have a 1 pixel border?
458   int                 xprescale;          // what is our X prescale factor?
459   int                 yprescale;          // what is our Y prescale factor?
460   int                 nocopy;             // must the texture date be copied?
461
462   UINT32              texture;            // OpenGL texture "name"/ID
463
464   GLenum              texTarget;          // OpenGL texture target
465   int                 texpow2;            // Is this texture pow2
466
467   UINT32              mpass_dest_idx;         // Multipass dest idx [0..1]
468   UINT32              mpass_textureunit[2];   // texture unit names for GLSL
469
470   UINT32              mpass_texture_mamebm[2];// Multipass OpenGL texture "name"/ID for the shader
471   UINT32              mpass_fbo_mamebm[2];    // framebuffer object for this texture, multipass
472   UINT32              mpass_texture_scrn[2];  // Multipass OpenGL texture "name"/ID for the shader
473   UINT32              mpass_fbo_scrn[2];      // framebuffer object for this texture, multipass
474
475   UINT32              pbo;                    // pixel buffer object for this texture (DYNAMIC only!)
476   UINT32              *data;                  // pixels for the texture
477   int                 data_own;               // do we own / allocated it ?
478   GLfloat             texCoord[8];
479   GLuint              texCoordBufferName;
480
481};
482
483/* sdl_info is the information about SDL for the current screen */
484class sdl_info_ogl : public osd_renderer
485{
486public:
487   sdl_info_ogl(osd_window *window)
488   : osd_renderer(window, FLAG_NEEDS_OPENGL), m_blittimer(0),
489      m_width(0), m_height(0),
490      m_blit_dim(0, 0),
491      m_gl_context(NULL),
492      m_initialized(0),
493      m_last_blendmode(0),
494      m_texture_max_width(0),
495      m_texture_max_height(0),
496      m_texpoweroftwo(0),
497      m_usevbo(0), m_usepbo(0), m_usefbo(0), m_useglsl(0), m_glsl(NULL),
498      m_glsl_program_num(0),
499      m_glsl_program_mb2sc(0),
500      m_usetexturerect(0),
501      m_init_context(0),
502      m_last_hofs(0.0f),
503      m_last_vofs(0.0f),
504      m_surf_w(0),
505      m_surf_h(0)
506   {
507      for (int i=0; i < HASH_SIZE + OVERFLOW_SIZE; i++)
508         m_texhash[i] = NULL;
509      for (int i=0; i < 2*GLSL_SHADER_MAX; i++)
510         m_glsl_program[i] = 0;
511      for (int i=0; i < 8; i++)
512         m_texVerticex[i] = 0.0f;
513   }
514
515   /* virtual */ int create();
516   /* virtual */ int draw(const int update);
517
518   /* virtual */ int xy_to_render_target(const int x, const int y, int *xt, int *yt);
519   /* virtual */ void destroy();
520   /* virtual */ render_primitive_list *get_primitives()
521   {
522#ifdef OSD_WINDOWS
523      osd_dim nd = window().get_size();
524#else
525      osd_dim nd = window().blit_surface_size();
526#endif
527      if (nd != m_blit_dim)
528      {
529         m_blit_dim = nd;
530         notify_changed();
531      }
532      window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
533      return &window().target()->get_primitives();
534   }
535
536   /* virtual */ void save() { }
537   /* virtual */ void record() { }
538   /* virtual */ void toggle_fsfx() { }
539
540private:
541   void destroy_all_textures();
542
543   void loadGLExtensions();
544   void initialize_gl();
545   void set_blendmode(int blendmode);
546   void texture_compute_type_subroutine(const render_texinfo *texsource, texture_info *texture, UINT32 flags);
547   void texture_compute_size_subroutine(texture_info *texture, UINT32 flags,
548            UINT32 width, UINT32 height,
549            int* p_width, int* p_height, int* p_width_create, int* p_height_create);
550   void texture_compute_size_type(const render_texinfo *texsource, texture_info *texture, UINT32 flags);
551   texture_info *texture_create(const render_texinfo *texsource, UINT32 flags);
552   int texture_shader_create(const render_texinfo *texsource, texture_info *texture, UINT32 flags);
553   texture_info *texture_find(const render_primitive *prim);
554   void texture_coord_update(texture_info *texture, const render_primitive *prim, int shaderIdx);
555   void texture_mpass_flip(texture_info *texture, int shaderIdx);
556   void texture_shader_update(texture_info *texture, render_container *container,  int shaderIdx);
557   texture_info * texture_update(const render_primitive *prim, int shaderIdx);
558   void texture_disable(texture_info * texture);
559   void texture_all_disable();
560
561   INT32           m_blittimer;
562   int             m_width;
563   int             m_height;
564   osd_dim         m_blit_dim;
565
566   osd_gl_context   *m_gl_context;
567
568   int             m_initialized;        // is everything well initialized, i.e. all GL stuff etc.
569   // 3D info (GL mode only)
570   texture_info *  m_texhash[HASH_SIZE + OVERFLOW_SIZE];
571   int             m_last_blendmode;     // previous blendmode
572   INT32           m_texture_max_width;      // texture maximum width
573   INT32           m_texture_max_height;     // texture maximum height
574   int             m_texpoweroftwo;          // must textures be power-of-2 sized?
575   int             m_usevbo;         // runtime check if VBO is available
576   int             m_usepbo;         // runtime check if PBO is available
577   int             m_usefbo;         // runtime check if FBO is available
578   int             m_useglsl;        // runtime check if GLSL is available
579
580   glsl_shader_info *m_glsl;             // glsl_shader_info
581
582   GLhandleARB     m_glsl_program[2*GLSL_SHADER_MAX];  // GLSL programs, or 0
583   int             m_glsl_program_num;   // number of GLSL programs
584   int             m_glsl_program_mb2sc; // GLSL program idx, which transforms
585                              // the mame-bitmap. screen-bitmap (size/rotation/..)
586                              // All progs <= glsl_program_mb2sc using the mame bitmap
587                              // as input, otherwise the screen bitmap.
588                              // All progs >= glsl_program_mb2sc using the screen bitmap
589                              // as output, otherwise the mame bitmap.
590   int             m_usetexturerect;     // use ARB_texture_rectangle for non-power-of-2, general use
591
592   int             m_init_context;       // initialize context before next draw
593
594   float           m_last_hofs;
595   float           m_last_vofs;
596
597   // Static vars from draogl_window_dra
598   INT32           m_surf_w;
599   INT32           m_surf_h;
600   GLfloat         m_texVerticex[8];
601};
602
603/* line_aa_step is used for drawing antialiased lines */
604struct line_aa_step
605{
606   float       xoffs, yoffs;               // X/Y deltas
607   float       weight;                 // weight contribution
608};
609
610#if 0
611static const line_aa_step line_aa_1step[] =
612{
613   {  0.00f,  0.00f,  1.00f  },
614   { 0 }
615};
616
617static const line_aa_step line_aa_4step[] =
618{
619   { -0.25f,  0.00f,  0.25f  },
620   {  0.25f,  0.00f,  0.25f  },
621   {  0.00f, -0.25f,  0.25f  },
622   {  0.00f,  0.25f,  0.25f  },
623   { 0 }
624};
625#endif
626
627//============================================================
628//  INLINES
629//============================================================
630
631INLINE HashT texture_compute_hash(const render_texinfo *texture, UINT32 flags)
632{
633   HashT h = (HashT)texture->base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK));
634   //printf("hash %d\n", (int) h % HASH_SIZE);
635   return (h >> 8) % HASH_SIZE;
636}
637
638void sdl_info_ogl::set_blendmode(int blendmode)
639{
640   // try to minimize texture state changes
641   if (blendmode != m_last_blendmode)
642   {
643      switch (blendmode)
644      {
645         case BLENDMODE_NONE:
646            glDisable(GL_BLEND);
647            break;
648         case BLENDMODE_ALPHA:
649            glEnable(GL_BLEND);
650            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
651            break;
652         case BLENDMODE_RGB_MULTIPLY:
653            glEnable(GL_BLEND);
654            glBlendFunc(GL_DST_COLOR, GL_ZERO);
655            break;
656         case BLENDMODE_ADD:
657            glEnable(GL_BLEND);
658            glBlendFunc(GL_SRC_ALPHA, GL_ONE);
659            break;
660      }
661
662      m_last_blendmode = blendmode;
663   }
664}
665
666//============================================================
667//  PROTOTYPES
668//============================================================
669
670// core functions
671
672//============================================================
673//  STATIC VARIABLES
674//============================================================
675
676static void drawogl_exit(void);
677static void load_gl_lib(running_machine &machine);
678
679
680
681// OGL 1.3
682#ifdef GL_ARB_multitexture
683static PFNGLACTIVETEXTUREARBPROC pfn_glActiveTexture    = NULL;
684#else
685static PFNGLACTIVETEXTUREPROC pfn_glActiveTexture   = NULL;
686#endif
687
688// VBO
689static PFNGLGENBUFFERSPROC pfn_glGenBuffers     = NULL;
690static PFNGLDELETEBUFFERSPROC pfn_glDeleteBuffers   = NULL;
691static PFNGLBINDBUFFERPROC pfn_glBindBuffer     = NULL;
692static PFNGLBUFFERDATAPROC pfn_glBufferData     = NULL;
693static PFNGLBUFFERSUBDATAPROC pfn_glBufferSubData   = NULL;
694
695// PBO
696static PFNGLMAPBUFFERPROC     pfn_glMapBuffer       = NULL;
697static PFNGLUNMAPBUFFERPROC   pfn_glUnmapBuffer     = NULL;
698
699// FBO
700static PFNGLISFRAMEBUFFEREXTPROC   pfn_glIsFramebuffer          = NULL;
701static PFNGLBINDFRAMEBUFFEREXTPROC pfn_glBindFramebuffer        = NULL;
702static PFNGLDELETEFRAMEBUFFERSEXTPROC pfn_glDeleteFramebuffers      = NULL;
703static PFNGLGENFRAMEBUFFERSEXTPROC pfn_glGenFramebuffers        = NULL;
704static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pfn_glCheckFramebufferStatus  = NULL;
705static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pfn_glFramebufferTexture2D  = NULL;
706
707static int glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
708
709//============================================================
710//  Textures
711//============================================================
712
713static void texture_set_data(texture_info *texture, const render_texinfo *texsource, UINT32 flags);
714
715//============================================================
716//  Static Variables
717//============================================================
718
719static int shown_video_info = 0;
720static int dll_loaded = 0;
721
722//============================================================
723//  drawsdl_init
724//============================================================
725
726static osd_renderer *drawogl_create(osd_window *window)
727{
728   return global_alloc(sdl_info_ogl(window));
729}
730
731int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks)
732{
733   // fill in the callbacks
734   callbacks->exit = drawogl_exit;
735   callbacks->create = drawogl_create;
736
737   dll_loaded = 0;
738
739   load_gl_lib(machine);
740   if (SDLMAME_SDL2)
741   {
742      osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
743   }
744   else
745      osd_printf_verbose("Using SDL single-window OpenGL driver (SDL 1.2)\n");
746
747   return 0;
748}
749
750//============================================================
751// Load the OGL function addresses
752//============================================================
753
754static void loadgl_functions(osd_gl_context *context)
755{
756#ifdef USE_DISPATCH_GL
757
758   int err_count = 0;
759
760   /* the following is tricky ... #func will be expanded to glBegin
761    * while func will be expanded to disp_p->glBegin
762    */
763
764   #define OSD_GL(ret,func,params) \
765   if (!( func = (ret (APIENTRY *)params) context->getProcAddress( #func ) )) \
766      { err_count++; osd_printf_error("GL function %s not found!\n", #func ); }
767
768   #define OSD_GL_UNUSED(ret,func,params)
769
770   #define GET_GLFUNC 1
771   #include "modules/opengl/osd_opengl.h"
772   #undef GET_GLFUNC
773
774   if (err_count)
775      fatalerror("Error loading GL library functions, giving up\n");
776
777#endif
778}
779
780//============================================================
781// Load GL library
782//============================================================
783
784#ifdef USE_DISPATCH_GL
785osd_gl_dispatch *gl_dispatch;
786#endif
787
788static void load_gl_lib(running_machine &machine)
789{
790   if (!dll_loaded)
791   {
792#ifdef OSD_WINDOWS
793      win_gl_context::load_library();
794#else
795#ifdef USE_DISPATCH_GL
796      /*
797       *  directfb and and x11 use this env var
798       *   SDL_VIDEO_GL_DRIVER
799       */
800      const char *stemp;
801
802      stemp = downcast<sdl_options &>(machine.options()).gl_lib();
803      if (stemp != NULL && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
804         stemp = NULL;
805
806      if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==NULL
807      {
808         fatalerror("Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
809      }
810      osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
811      /* FIXME: must be freed as well */
812#endif
813#endif
814#ifdef USE_DISPATCH_GL
815      gl_dispatch = (osd_gl_dispatch *) osd_malloc(sizeof(osd_gl_dispatch));
816#endif
817      dll_loaded=1;
818   }
819}
820
821void sdl_info_ogl::initialize_gl()
822{
823   int has_and_allow_texturerect = 0;
824
825   char *extstr = (char *)glGetString(GL_EXTENSIONS);
826   char *vendor = (char *)glGetString(GL_VENDOR);
827
828   //printf("%p\n", extstr);
829#ifdef OSD_WINDOWS
830   if (!extstr)
831      extstr = (char *)"";
832#endif
833   // print out the driver info for debugging
834   if (!shown_video_info)
835   {
836      osd_printf_verbose("OpenGL: %s\nOpenGL: %s\nOpenGL: %s\n", vendor, (char *)glGetString(GL_RENDERER), (char *)glGetString(GL_VERSION));
837   }
838
839   m_usetexturerect = 0;
840   m_texpoweroftwo = 1;
841   m_usevbo = 0;
842   m_usepbo = 0;
843   m_usefbo = 0;
844   m_useglsl = 0;
845
846   if ( video_config.allowtexturerect &&
847         ( strstr(extstr, "GL_ARB_texture_rectangle") ||  strstr(extstr, "GL_EXT_texture_rectangle") )
848      )
849   {
850      has_and_allow_texturerect = 1;
851               if (!shown_video_info)
852               {
853                     osd_printf_verbose("OpenGL: texture rectangle supported\n");
854               }
855   }
856
857   // does this card support non-power-of-two sized textures?  (they're faster, so use them if possible)
858   if ( !video_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two"))
859   {
860      if (!shown_video_info)
861      {
862         osd_printf_verbose("OpenGL: non-power-of-2 textures supported (new method)\n");
863      }
864               m_texpoweroftwo = 0;
865   }
866   else
867   {
868      // second chance: GL_ARB_texture_rectangle or GL_EXT_texture_rectangle (old version)
869      if (has_and_allow_texturerect)
870      {
871         if (!shown_video_info)
872         {
873            osd_printf_verbose("OpenGL: non-power-of-2 textures supported (old method)\n");
874         }
875         m_usetexturerect = 1;
876      }
877      else
878      {
879         if (!shown_video_info)
880         {
881            osd_printf_verbose("OpenGL: forcing power-of-2 textures (creation, not copy)\n");
882         }
883      }
884   }
885
886   if (strstr(extstr, "GL_ARB_vertex_buffer_object"))
887   {
888               m_usevbo = video_config.vbo;
889      if (!shown_video_info)
890      {
891         if(m_usevbo)
892            osd_printf_verbose("OpenGL: vertex buffer supported\n");
893         else
894            osd_printf_verbose("OpenGL: vertex buffer supported, but disabled\n");
895      }
896   }
897
898   if (strstr(extstr, "GL_ARB_pixel_buffer_object"))
899   {
900      if( m_usevbo )
901      {
902         m_usepbo = video_config.pbo;
903         if (!shown_video_info)
904         {
905            if(m_usepbo)
906               osd_printf_verbose("OpenGL: pixel buffers supported\n");
907            else
908               osd_printf_verbose("OpenGL: pixel buffers supported, but disabled\n");
909         }
910      } else {
911         if (!shown_video_info)
912         {
913            osd_printf_verbose("OpenGL: pixel buffers supported, but disabled due to disabled vbo\n");
914         }
915      }
916   }
917   else
918   {
919      if (!shown_video_info)
920      {
921         osd_printf_verbose("OpenGL: pixel buffers not supported\n");
922      }
923   }
924
925   if (strstr(extstr, "GL_EXT_framebuffer_object"))
926   {
927      m_usefbo = 1;
928      if (!shown_video_info)
929      {
930         if(m_usefbo)
931            osd_printf_verbose("OpenGL: framebuffer object supported\n");
932         else
933            osd_printf_verbose("OpenGL: framebuffer object not supported\n");
934      }
935   }
936
937   if (strstr(extstr, "GL_ARB_shader_objects") &&
938      strstr(extstr, "GL_ARB_shading_language_100") &&
939      strstr(extstr, "GL_ARB_vertex_shader") &&
940      strstr(extstr, "GL_ARB_fragment_shader")
941      )
942   {
943      m_useglsl = video_config.glsl;
944      if (!shown_video_info)
945      {
946         if(m_useglsl)
947            osd_printf_verbose("OpenGL: GLSL supported\n");
948         else
949            osd_printf_verbose("OpenGL: GLSL supported, but disabled\n");
950      }
951   } else {
952      if (!shown_video_info)
953      {
954         osd_printf_verbose("OpenGL: GLSL not supported\n");
955      }
956   }
957
958#ifdef TOBEMIGRATED
959   if (osd_getenv(SDLENV_VMWARE) != NULL)
960   {
961      m_usetexturerect = 1;
962      m_texpoweroftwo = 1;
963   }
964#endif
965   glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&m_texture_max_width);
966   glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&m_texture_max_height);
967   if (!shown_video_info)
968   {
969      osd_printf_verbose("OpenGL: max texture size %d x %d\n", m_texture_max_width, m_texture_max_height);
970   }
971
972   shown_video_info = 1;
973
974}
975//============================================================
976//  sdl_info::create
977// a
978// a
979// a
980// a
981// a
982// a
983// a
984// a
985// a
986// a
987// a
988// a
989// a
990// a
991// a
992// a
993// a
994// a
995// a
996// a
997// a
998// a
999// a
1000// a
1001// a
1002// a
1003//============================================================
1004
1005int sdl_info_ogl::create()
1006{
1007#if (SDLMAME_SDL2)
1008   // create renderer
1009#ifdef OSD_WINDOWS
1010   m_gl_context = global_alloc(win_gl_context(window().m_hwnd));
1011#else
1012   m_gl_context = global_alloc(sdl_gl_context(window().sdl_window()));
1013#endif
1014#else
1015   m_gl_context = global_alloc(sdl12_gl_context(window().sdl_surface()));
1016#endif
1017   if  (m_gl_context->LastErrorMsg() != NULL)
1018   {
1019      osd_printf_error("%s\n", m_gl_context->LastErrorMsg());
1020      return 1;
1021   }
1022   m_gl_context->SetSwapInterval(video_config.waitvsync ? 1 : 0);
1023
1024
1025   m_blittimer = 0;
1026   m_surf_w = 0;
1027   m_surf_h = 0;
1028
1029   m_initialized = 0;
1030
1031   // in case any textures try to come up before these are validated,
1032   // OpenGL guarantees all implementations can handle something this size.
1033   m_texture_max_width = 64;
1034   m_texture_max_height = 64;
1035
1036   /* load any GL function addresses
1037    * this must be done here because we need a context
1038    */
1039   loadgl_functions(m_gl_context);
1040   initialize_gl();
1041
1042
1043   m_init_context = 0;
1044
1045   osd_printf_verbose("Leave sdl_info_ogl::create\n");
1046   return 0;
1047}
1048
1049
1050//============================================================
1051//  sdl_info::destroy
1052//============================================================
1053
1054void sdl_info_ogl::destroy()
1055{
1056   // free the memory in the window
1057
1058   destroy_all_textures();
1059
1060   global_free(m_gl_context);
1061   m_gl_context = NULL;
1062}
1063
1064
1065//============================================================
1066//  drawsdl_xy_to_render_target
1067//============================================================
1068
1069int sdl_info_ogl::xy_to_render_target(int x, int y, int *xt, int *yt)
1070{
1071   *xt = x - m_last_hofs;
1072   *yt = y - m_last_vofs;
1073   if (*xt<0 || *xt >= m_blit_dim.width())
1074      return 0;
1075   if (*yt<0 || *yt >= m_blit_dim.height())
1076      return 0;
1077   return 1;
1078}
1079
1080//============================================================
1081//  drawsdl_destroy_all_textures
1082//============================================================
1083
1084void sdl_info_ogl::destroy_all_textures()
1085{
1086   texture_info *texture = NULL;
1087   int lock=FALSE;
1088   int i;
1089
1090   if ( !m_initialized )
1091      return;
1092
1093   m_gl_context->MakeCurrent();
1094
1095   if(window().m_primlist)
1096   {
1097      lock=TRUE;
1098      window().m_primlist->acquire_lock();
1099   }
1100
1101   glFinish();
1102
1103   texture_all_disable();
1104   glFinish();
1105   glDisableClientState(GL_VERTEX_ARRAY);
1106
1107   i=0;
1108   while (i<HASH_SIZE+OVERFLOW_SIZE)
1109   {
1110      texture = m_texhash[i];
1111      m_texhash[i] = NULL;
1112      if (texture != NULL)
1113      {
1114         if(m_usevbo)
1115         {
1116            pfn_glDeleteBuffers( 1, &(texture->texCoordBufferName) );
1117            texture->texCoordBufferName=0;
1118         }
1119
1120         if(m_usepbo && texture->pbo)
1121         {
1122            pfn_glDeleteBuffers( 1, (GLuint *)&(texture->pbo) );
1123            texture->pbo=0;
1124         }
1125
1126         if( m_glsl_program_num > 1 )
1127         {
1128            assert(m_usefbo);
1129            pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
1130            glDeleteTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
1131         }
1132
1133         if ( m_glsl_program_mb2sc < m_glsl_program_num - 1 )
1134         {
1135            assert(m_usefbo);
1136            pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
1137            glDeleteTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
1138         }
1139
1140         glDeleteTextures(1, (GLuint *)&texture->texture);
1141         if ( texture->data_own )
1142         {
1143            free(texture->data);
1144            texture->data=NULL;
1145            texture->data_own=FALSE;
1146         }
1147         global_free(texture);
1148      }
1149      i++;
1150   }
1151   if ( m_useglsl )
1152   {
1153      glsl_shader_free(m_glsl);
1154      m_glsl = NULL;
1155   }
1156
1157   m_initialized = 0;
1158
1159   if (lock)
1160      window().m_primlist->release_lock();
1161}
1162//============================================================
1163//  loadGLExtensions
1164//============================================================
1165
1166void sdl_info_ogl::loadGLExtensions()
1167{
1168   static int _once = 1;
1169
1170   // usevbo=FALSE; // You may want to switch VBO and PBO off, by uncommenting this statement
1171   // usepbo=FALSE; // You may want to switch PBO off, by uncommenting this statement
1172   // useglsl=FALSE; // You may want to switch GLSL off, by uncommenting this statement
1173
1174   if (! m_usevbo)
1175   {
1176      if(m_usepbo) // should never ever happen ;-)
1177      {
1178         if (_once)
1179         {
1180            osd_printf_warning("OpenGL: PBO not supported, no VBO support. (sdlmame error)\n");
1181         }
1182         m_usepbo=FALSE;
1183      }
1184      if(m_useglsl) // should never ever happen ;-)
1185      {
1186         if (_once)
1187         {
1188            osd_printf_warning("OpenGL: GLSL not supported, no VBO support. (sdlmame error)\n");
1189         }
1190         m_useglsl=FALSE;
1191      }
1192   }
1193
1194   // Get Pointers To The GL Functions
1195   // VBO:
1196   if( m_usevbo )
1197   {
1198      pfn_glGenBuffers = (PFNGLGENBUFFERSPROC) m_gl_context->getProcAddress("glGenBuffers");
1199      pfn_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) m_gl_context->getProcAddress("glDeleteBuffers");
1200      pfn_glBindBuffer = (PFNGLBINDBUFFERPROC) m_gl_context->getProcAddress("glBindBuffer");
1201      pfn_glBufferData = (PFNGLBUFFERDATAPROC) m_gl_context->getProcAddress("glBufferData");
1202      pfn_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) m_gl_context->getProcAddress("glBufferSubData");
1203   }
1204   // PBO:
1205   if ( m_usepbo )
1206   {
1207      pfn_glMapBuffer  = (PFNGLMAPBUFFERPROC) m_gl_context->getProcAddress("glMapBuffer");
1208      pfn_glUnmapBuffer= (PFNGLUNMAPBUFFERPROC) m_gl_context->getProcAddress("glUnmapBuffer");
1209   }
1210   // FBO:
1211   if ( m_usefbo )
1212   {
1213      pfn_glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glIsFramebufferEXT");
1214      pfn_glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glBindFramebufferEXT");
1215      pfn_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glDeleteFramebuffersEXT");
1216      pfn_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glGenFramebuffersEXT");
1217      pfn_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) m_gl_context->getProcAddress("glCheckFramebufferStatusEXT");
1218      pfn_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) m_gl_context->getProcAddress("glFramebufferTexture2DEXT");
1219   }
1220
1221   if ( m_usevbo &&
1222         ( !pfn_glGenBuffers || !pfn_glDeleteBuffers ||
1223         !pfn_glBindBuffer || !pfn_glBufferData || !pfn_glBufferSubData
1224      ) )
1225   {
1226      m_usepbo=FALSE;
1227      if (_once)
1228      {
1229         osd_printf_warning("OpenGL: VBO not supported, missing: ");
1230         if (!pfn_glGenBuffers)
1231         {
1232            osd_printf_warning("glGenBuffers, ");
1233         }
1234         if (!pfn_glDeleteBuffers)
1235         {
1236            osd_printf_warning("glDeleteBuffers");
1237         }
1238         if (!pfn_glBindBuffer)
1239         {
1240            osd_printf_warning("glBindBuffer, ");
1241         }
1242         if (!pfn_glBufferData)
1243         {
1244            osd_printf_warning("glBufferData, ");
1245         }
1246         if (!pfn_glBufferSubData)
1247         {
1248            osd_printf_warning("glBufferSubData, ");
1249         }
1250         osd_printf_warning("\n");
1251      }
1252      if ( m_usevbo )
1253      {
1254         if (_once)
1255         {
1256            osd_printf_warning("OpenGL: PBO not supported, no VBO support.\n");
1257         }
1258         m_usepbo=FALSE;
1259      }
1260   }
1261
1262   if ( m_usepbo && ( !pfn_glMapBuffer || !pfn_glUnmapBuffer ) )
1263   {
1264      m_usepbo=FALSE;
1265      if (_once)
1266      {
1267         osd_printf_warning("OpenGL: PBO not supported, missing: ");
1268         if (!pfn_glMapBuffer)
1269         {
1270            osd_printf_warning("glMapBuffer, ");
1271         }
1272         if (!pfn_glUnmapBuffer)
1273         {
1274            osd_printf_warning("glUnmapBuffer, ");
1275         }
1276         osd_printf_warning("\n");
1277      }
1278   }
1279
1280   if ( m_usefbo &&
1281      ( !pfn_glIsFramebuffer || !pfn_glBindFramebuffer || !pfn_glDeleteFramebuffers ||
1282         !pfn_glGenFramebuffers || !pfn_glCheckFramebufferStatus || !pfn_glFramebufferTexture2D
1283      ))
1284   {
1285      m_usefbo=FALSE;
1286      if (_once)
1287      {
1288         osd_printf_warning("OpenGL: FBO not supported, missing: ");
1289         if (!pfn_glIsFramebuffer)
1290         {
1291            osd_printf_warning("pfn_glIsFramebuffer, ");
1292         }
1293         if (!pfn_glBindFramebuffer)
1294         {
1295            osd_printf_warning("pfn_glBindFramebuffer, ");
1296         }
1297         if (!pfn_glDeleteFramebuffers)
1298         {
1299            osd_printf_warning("pfn_glDeleteFramebuffers, ");
1300         }
1301         if (!pfn_glGenFramebuffers)
1302         {
1303            osd_printf_warning("pfn_glGenFramebuffers, ");
1304         }
1305         if (!pfn_glCheckFramebufferStatus)
1306         {
1307            osd_printf_warning("pfn_glCheckFramebufferStatus, ");
1308         }
1309         if (!pfn_glFramebufferTexture2D)
1310         {
1311            osd_printf_warning("pfn_glFramebufferTexture2D, ");
1312         }
1313         osd_printf_warning("\n");
1314      }
1315   }
1316
1317   if (_once)
1318   {
1319      if ( m_usevbo )
1320      {
1321         osd_printf_verbose("OpenGL: VBO supported\n");
1322      }
1323      else
1324      {
1325         osd_printf_warning("OpenGL: VBO not supported\n");
1326      }
1327
1328      if ( m_usepbo )
1329      {
1330         osd_printf_verbose("OpenGL: PBO supported\n");
1331      }
1332      else
1333      {
1334         osd_printf_warning("OpenGL: PBO not supported\n");
1335      }
1336
1337      if ( m_usefbo )
1338      {
1339         osd_printf_verbose("OpenGL: FBO supported\n");
1340      }
1341      else
1342      {
1343         osd_printf_warning("OpenGL: FBO not supported\n");
1344      }
1345   }
1346
1347   if ( m_useglsl )
1348   {
1349      #ifdef GL_ARB_multitexture
1350      pfn_glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) m_gl_context->getProcAddress("glActiveTextureARB");
1351      #else
1352      pfn_glActiveTexture = (PFNGLACTIVETEXTUREPROC) m_gl_context->getProcAddress("glActiveTexture");
1353      #endif
1354      if (!pfn_glActiveTexture)
1355      {
1356         if (_once)
1357         {
1358            osd_printf_warning("OpenGL: GLSL disabled, glActiveTexture(ARB) not supported\n");
1359         }
1360         m_useglsl = 0;
1361      }
1362   }
1363
1364   if ( m_useglsl )
1365   {
1366      m_glsl = glsl_shader_init(m_gl_context);
1367      m_useglsl = (m_glsl != NULL ? 1 : 0);
1368
1369      if ( ! m_useglsl )
1370      {
1371         if (_once)
1372         {
1373            osd_printf_warning("OpenGL: GLSL supported, but shader instantiation failed - disabled\n");
1374         }
1375      }
1376   }
1377
1378   if ( m_useglsl )
1379   {
1380      if ( window().prescale() != 1 )
1381      {
1382         m_useglsl = 0;
1383         if (_once)
1384         {
1385            osd_printf_warning("OpenGL: GLSL supported, but disabled due to: prescale !=1 \n");
1386         }
1387      }
1388   }
1389
1390   if ( m_useglsl )
1391   {
1392      int i;
1393      video_config.filter = FALSE;
1394      glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
1395      m_glsl_program_num = 0;
1396      m_glsl_program_mb2sc = 0;
1397
1398      for(i=0; i<video_config.glsl_shader_mamebm_num; i++)
1399      {
1400         if ( !m_usefbo && m_glsl_program_num==1 )
1401         {
1402            if (_once)
1403            {
1404               osd_printf_verbose("OpenGL: GLSL multipass not supported, due to unsupported FBO. Skipping followup shader\n");
1405            }
1406            break;
1407         }
1408
1409         if ( glsl_shader_add_mamebm(m_glsl, video_config.glsl_shader_mamebm[i], m_glsl_program_num) )
1410         {
1411            osd_printf_error("OpenGL: GLSL loading mame bitmap shader %d failed (%s)\n",
1412               i, video_config.glsl_shader_mamebm[i]);
1413         } else {
1414            glsl_shader_feature = GLSL_SHADER_FEAT_CUSTOM;
1415            if (_once)
1416            {
1417               osd_printf_verbose("OpenGL: GLSL using mame bitmap shader filter %d: '%s'\n",
1418                  m_glsl_program_num, video_config.glsl_shader_mamebm[i]);
1419            }
1420            m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
1421            m_glsl_program_num++;
1422         }
1423      }
1424
1425      if ( video_config.glsl_shader_scrn_num > 0 && m_glsl_program_num==0 )
1426      {
1427         osd_printf_verbose("OpenGL: GLSL cannot use screen bitmap shader without bitmap shader\n");
1428      }
1429
1430      for(i=0; m_usefbo && m_glsl_program_num>0 && i<video_config.glsl_shader_scrn_num; i++)
1431      {
1432         if ( glsl_shader_add_scrn(m_glsl, video_config.glsl_shader_scrn[i],
1433                                 m_glsl_program_num-1-m_glsl_program_mb2sc) )
1434         {
1435            osd_printf_error("OpenGL: GLSL loading screen bitmap shader %d failed (%s)\n",
1436               i, video_config.glsl_shader_scrn[i]);
1437         } else {
1438            if (_once)
1439            {
1440               osd_printf_verbose("OpenGL: GLSL using screen bitmap shader filter %d: '%s'\n",
1441                  m_glsl_program_num, video_config.glsl_shader_scrn[i]);
1442            }
1443            m_glsl_program_num++;
1444         }
1445      }
1446
1447      if ( 0==m_glsl_program_num &&
1448            0 <= video_config.glsl_filter && video_config.glsl_filter < GLSL_SHADER_FEAT_INT_NUMBER )
1449      {
1450         m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
1451         m_glsl_program_num++;
1452         glsl_shader_feature = video_config.glsl_filter;
1453
1454         if (_once)
1455         {
1456            osd_printf_verbose("OpenGL: GLSL using shader filter '%s', idx: %d, num %d (vid filter: %d)\n",
1457               glsl_shader_get_filter_name_mamebm(glsl_shader_feature),
1458               glsl_shader_feature, m_glsl_program_num, video_config.filter);
1459         }
1460      }
1461
1462   } else {
1463      if (_once)
1464      {
1465         osd_printf_verbose("OpenGL: using vid filter: %d\n", video_config.filter);
1466      }
1467   }
1468
1469   _once = 0;
1470}
1471
1472//============================================================
1473//  sdl_info::draw
1474//============================================================
1475
1476int sdl_info_ogl::draw(const int update)
1477{
1478   render_primitive *prim;
1479   texture_info *texture=NULL;
1480   float vofs, hofs;
1481   int  pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE;
1482
1483#ifdef TOBEMIGRATED
1484   if (video_config.novideo)
1485   {
1486      return 0;
1487   }
1488#endif
1489
1490   osd_dim wdim = window().get_size();
1491
1492   if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
1493   {
1494      destroy_all_textures();
1495      m_width = wdim.width();
1496      m_height = wdim.height();
1497      m_blittimer = 3;
1498      m_init_context = 1;
1499      clear_flags(FI_CHANGED);
1500   }
1501
1502   m_gl_context->MakeCurrent();
1503
1504   if (m_init_context)
1505   {
1506      // do some one-time OpenGL setup
1507#if (SDLMAME_SDL2)
1508      // FIXME: SRGB conversion is working on SDL2, may be of use
1509      // when we eventually target gamma and monitor profiles.
1510      //glEnable(GL_FRAMEBUFFER_SRGB);
1511#endif
1512      glShadeModel(GL_SMOOTH);
1513      glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1514      glClearDepth(1.0f);
1515      glEnable(GL_DEPTH_TEST);
1516      glDepthFunc(GL_LEQUAL);
1517      glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1518   }
1519
1520   // only clear if the geometry changes (and for 2 frames afterward to clear double and triple buffers)
1521   if ((m_blittimer > 0) || has_flags(FLAG_HAS_VECTOR_SCREEN))
1522   {
1523      glClear(GL_COLOR_BUFFER_BIT);
1524      m_blittimer--;
1525   }
1526
1527   // FIXME: remove m_surf_w and m_surf_h
1528   if ( !m_initialized ||
1529         m_width != m_surf_w || m_height != m_surf_h )
1530   {
1531      // FIXME:: this can be done in create!
1532      if ( !m_initialized )
1533      {
1534         loadGLExtensions();
1535      }
1536
1537#if (!SDLMAME_SDL2)
1538      // force all textures to be regenerated
1539      destroy_all_textures();
1540#endif
1541
1542      m_surf_w = m_width;
1543      m_surf_h = m_height;
1544
1545      // we're doing nothing 3d, so the Z-buffer is currently not interesting
1546      glDisable(GL_DEPTH_TEST);
1547
1548      if (window().machine().options().antialias())
1549      {
1550         // enable antialiasing for lines
1551         glEnable(GL_LINE_SMOOTH);
1552         // enable antialiasing for points
1553         glEnable(GL_POINT_SMOOTH);
1554
1555         // prefer quality to speed
1556         glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
1557         glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
1558      }
1559      else
1560      {
1561         glDisable(GL_LINE_SMOOTH);
1562         glDisable(GL_POINT_SMOOTH);
1563      }
1564
1565      // enable blending
1566      glEnable(GL_BLEND);
1567      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1568      m_last_blendmode = BLENDMODE_ALPHA;
1569
1570#ifdef TOBEMIGRATED
1571      // set lines and points just barely above normal size to get proper results
1572      glLineWidth(video_config.beamwidth);
1573      glPointSize(video_config.beamwidth);
1574#endif
1575
1576      // set up a nice simple 2D coordinate system, so GL behaves exactly how we'd like.
1577      //
1578      // (0,0)     (w,0)
1579      //   |~~~~~~~~~|
1580      //   |         |
1581      //   |         |
1582      //   |         |
1583      //   |_________|
1584      // (0,h)     (w,h)
1585
1586      glViewport(0.0, 0.0, (GLsizei) m_width, (GLsizei) m_height);
1587      glMatrixMode(GL_PROJECTION);
1588      glLoadIdentity();
1589      glOrtho(0.0, (GLdouble) m_width, (GLdouble) m_height, 0.0, 0.0, -1.0);
1590      glMatrixMode(GL_MODELVIEW);
1591      glLoadIdentity();
1592
1593      if ( ! m_initialized )
1594      {
1595         glEnableClientState(GL_VERTEX_ARRAY);
1596         glVertexPointer(2, GL_FLOAT, 0, m_texVerticex); // no VBO, since it's too volatile
1597
1598         m_initialized = 1;
1599      }
1600   }
1601
1602   // compute centering parameters
1603   vofs = hofs = 0.0f;
1604
1605#ifdef TOBEMIGRATED
1606   if (video_config.centerv || video_config.centerh)
1607   {
1608      int ch, cw;
1609
1610      ch = m_height;
1611      cw = m_width;
1612
1613      if (video_config.centerv)
1614      {
1615         vofs = (ch - m_blit_dim.height()) / 2.0f;
1616      }
1617      if (video_config.centerh)
1618      {
1619         hofs = (cw - m_blit_dim.width()) / 2.0f;
1620      }
1621   }
1622#else
1623#endif
1624
1625   m_last_hofs = hofs;
1626   m_last_vofs = vofs;
1627
1628   window().m_primlist->acquire_lock();
1629
1630   // now draw
1631   for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
1632   {
1633      int i;
1634
1635      switch (prim->type)
1636      {
1637         /**
1638          * Try to stay in one Begin/End block as long as possible,
1639          * since entering and leaving one is most expensive..
1640          */
1641         case render_primitive::LINE:
1642            #if !USE_WIN32_STYLE_LINES
1643            // check if it's really a point
1644            if (((prim->bounds.x1 - prim->bounds.x0) == 0) && ((prim->bounds.y1 - prim->bounds.y0) == 0))
1645            {
1646               curPrimitive=GL_POINTS;
1647            } else {
1648               curPrimitive=GL_LINES;
1649            }
1650
1651            if(pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
1652            {
1653               glEnd();
1654               pendingPrimitive=GL_NO_PRIMITIVE;
1655            }
1656
1657                  if ( pendingPrimitive==GL_NO_PRIMITIVE )
1658            {
1659                     set_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags));
1660            }
1661
1662            glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
1663
1664            if(pendingPrimitive!=curPrimitive)
1665            {
1666               glBegin(curPrimitive);
1667               pendingPrimitive=curPrimitive;
1668            }
1669
1670            // check if it's really a point
1671            if (curPrimitive==GL_POINTS)
1672            {
1673               glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
1674            }
1675            else
1676            {
1677               glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
1678               glVertex2f(prim->bounds.x1+hofs, prim->bounds.y1+vofs);
1679            }
1680            #else
1681            {
1682               const line_aa_step *step = line_aa_4step;
1683               render_bounds b0, b1;
1684               float r, g, b, a;
1685               float effwidth;
1686
1687               // we're not gonna play fancy here.  close anything pending and let's go.
1688               if (pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
1689               {
1690                  glEnd();
1691                  pendingPrimitive=GL_NO_PRIMITIVE;
1692               }
1693
1694               set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags));
1695
1696               // compute the effective width based on the direction of the line
1697               effwidth = prim->width();
1698               if (effwidth < 0.5f)
1699                  effwidth = 0.5f;
1700
1701               // determine the bounds of a quad to draw this line
1702               render_line_to_quad(&prim->bounds, effwidth, &b0, &b1);
1703
1704               // fix window position
1705               b0.x0 += hofs;
1706               b0.x1 += hofs;
1707               b1.x0 += hofs;
1708               b1.x1 += hofs;
1709               b0.y0 += vofs;
1710               b0.y1 += vofs;
1711               b1.y0 += vofs;
1712               b1.y1 += vofs;
1713
1714               // iterate over AA steps
1715               for (step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
1716               {
1717                  glBegin(GL_TRIANGLE_STRIP);
1718
1719                  // rotate the unit vector by 135 degrees and add to point 0
1720                  glVertex2f(b0.x0 + step->xoffs, b0.y0 + step->yoffs);
1721
1722                  // rotate the unit vector by -135 degrees and add to point 0
1723                  glVertex2f(b0.x1 + step->xoffs, b0.y1 + step->yoffs);
1724
1725                  // rotate the unit vector by 45 degrees and add to point 1
1726                  glVertex2f(b1.x0 + step->xoffs, b1.y0 + step->yoffs);
1727
1728                  // rotate the unit vector by -45 degrees and add to point 1
1729                  glVertex2f(b1.x1 + step->xoffs, b1.y1 + step->yoffs);
1730
1731                  // determine the color of the line
1732                  r = (prim->color.r * step->weight);
1733                  g = (prim->color.g * step->weight);
1734                  b = (prim->color.b * step->weight);
1735                  a = (prim->color.a * 255.0f);
1736                  if (r > 1.0) r = 1.0;
1737                  if (g > 1.0) g = 1.0;
1738                  if (b > 1.0) b = 1.0;
1739                  if (a > 1.0) a = 1.0;
1740                  glColor4f(r, g, b, a);
1741
1742//                      texture = texture_update(window, prim, 0);
1743//                      if (texture) printf("line has texture!\n");
1744
1745                  // if we have a texture to use for the vectors, use it here
1746                  #if 0
1747                  if (d3d->vector_texture != NULL)
1748                  {
1749                     printf("SDL: textured lines unsupported\n");
1750                     vertex[0].u0 = d3d->vector_texture->ustart;
1751                     vertex[0].v0 = d3d->vector_texture->vstart;
1752
1753                     vertex[2].u0 = d3d->vector_texture->ustop;
1754                     vertex[2].v0 = d3d->vector_texture->vstart;
1755
1756                     vertex[1].u0 = d3d->vector_texture->ustart;
1757                     vertex[1].v0 = d3d->vector_texture->vstop;
1758
1759                     vertex[3].u0 = d3d->vector_texture->ustop;
1760                     vertex[3].v0 = d3d->vector_texture->vstop;
1761                  }
1762                  #endif
1763                  glEnd();
1764               }
1765            }
1766            #endif
1767            break;
1768
1769         case render_primitive::QUAD:
1770
1771            if(pendingPrimitive!=GL_NO_PRIMITIVE)
1772            {
1773               glEnd();
1774               pendingPrimitive=GL_NO_PRIMITIVE;
1775            }
1776
1777            glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
1778
1779            set_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags));
1780
1781            texture = texture_update(prim, 0);
1782
1783            if ( texture && texture->type==TEXTURE_TYPE_SHADER )
1784            {
1785               for(i=0; i<m_glsl_program_num; i++)
1786               {
1787                  if ( i==m_glsl_program_mb2sc )
1788                  {
1789                     // i==glsl_program_mb2sc -> transformation mamebm->scrn
1790                     m_texVerticex[0]=prim->bounds.x0 + hofs;
1791                     m_texVerticex[1]=prim->bounds.y0 + vofs;
1792                     m_texVerticex[2]=prim->bounds.x1 + hofs;
1793                     m_texVerticex[3]=prim->bounds.y0 + vofs;
1794                     m_texVerticex[4]=prim->bounds.x1 + hofs;
1795                     m_texVerticex[5]=prim->bounds.y1 + vofs;
1796                     m_texVerticex[6]=prim->bounds.x0 + hofs;
1797                     m_texVerticex[7]=prim->bounds.y1 + vofs;
1798                  } else {
1799                     // 1:1 tex coord CCW (0/0) (1/0) (1/1) (0/1) on texture dimensions
1800                     m_texVerticex[0]=(GLfloat)0.0;
1801                     m_texVerticex[1]=(GLfloat)0.0;
1802                     m_texVerticex[2]=(GLfloat)m_width;
1803                     m_texVerticex[3]=(GLfloat)0.0;
1804                     m_texVerticex[4]=(GLfloat)m_width;
1805                     m_texVerticex[5]=(GLfloat)m_height;
1806                     m_texVerticex[6]=(GLfloat)0.0;
1807                     m_texVerticex[7]=(GLfloat)m_height;
1808                  }
1809
1810                  if(i>0) // first fetch already done
1811                  {
1812                     texture = texture_update(prim, i);
1813                  }
1814                  glDrawArrays(GL_QUADS, 0, 4);
1815               }
1816            } else {
1817               m_texVerticex[0]=prim->bounds.x0 + hofs;
1818               m_texVerticex[1]=prim->bounds.y0 + vofs;
1819               m_texVerticex[2]=prim->bounds.x1 + hofs;
1820               m_texVerticex[3]=prim->bounds.y0 + vofs;
1821               m_texVerticex[4]=prim->bounds.x1 + hofs;
1822               m_texVerticex[5]=prim->bounds.y1 + vofs;
1823               m_texVerticex[6]=prim->bounds.x0 + hofs;
1824               m_texVerticex[7]=prim->bounds.y1 + vofs;
1825
1826               glDrawArrays(GL_QUADS, 0, 4);
1827            }
1828
1829            if ( texture )
1830            {
1831               texture_disable(texture);
1832               texture=NULL;
1833            }
1834            break;
1835
1836         default:
1837            throw emu_fatalerror("Unexpected render_primitive type");
1838      }
1839   }
1840
1841   if(pendingPrimitive!=GL_NO_PRIMITIVE)
1842   {
1843      glEnd();
1844      pendingPrimitive=GL_NO_PRIMITIVE;
1845   }
1846
1847   window().m_primlist->release_lock();
1848   m_init_context = 0;
1849
1850   m_gl_context->SwapBuffer();
1851
1852   return 0;
1853}
1854
1855//============================================================
1856//  texture handling
1857//============================================================
1858
1859static const char * texfmt_to_string[9] = {
1860      "ARGB32",
1861      "RGB32",
1862      "RGB32_PALETTED",
1863      "YUV16",
1864      "YUV16_PALETTED",
1865      "PALETTE16",
1866      "RGB15",
1867      "RGB15_PALETTE",
1868      "PALETTE16A"
1869      };
1870
1871//
1872// Note: if you change the following array order, change the matching defines in texsrc.h
1873//
1874
1875enum { SDL_TEXFORMAT_SRC_EQUALS_DEST, SDL_TEXFORMAT_SRC_HAS_PALETTE };
1876
1877static const GLint texture_copy_properties[9][2] = {
1878   { TRUE,  FALSE },   // SDL_TEXFORMAT_ARGB32
1879   { TRUE,  FALSE },   // SDL_TEXFORMAT_RGB32
1880   { TRUE,  TRUE  },   // SDL_TEXFORMAT_RGB32_PALETTED
1881   { FALSE, FALSE },   // SDL_TEXFORMAT_YUY16
1882   { FALSE, TRUE  },   // SDL_TEXFORMAT_YUY16_PALETTED
1883   { FALSE, TRUE  },   // SDL_TEXFORMAT_PALETTE16
1884   { TRUE,  FALSE },   // SDL_TEXFORMAT_RGB15
1885   { TRUE,  TRUE  },   // SDL_TEXFORMAT_RGB15_PALETTED
1886   { FALSE, TRUE  }    // SDL_TEXFORMAT_PALETTE16A
1887};
1888
1889//============================================================
1890//  drawogl_exit
1891//============================================================
1892
1893static void drawogl_exit(void)
1894{
1895   int i;
1896
1897   for(i=0; i<video_config.glsl_shader_mamebm_num; i++)
1898   {
1899      if ( NULL!=video_config.glsl_shader_mamebm[i])
1900      {
1901         free(video_config.glsl_shader_mamebm[i]);
1902         video_config.glsl_shader_mamebm[i] = NULL;
1903      }
1904   }
1905   for(i=0; i<video_config.glsl_shader_scrn_num; i++)
1906   {
1907      if ( NULL!=video_config.glsl_shader_scrn[i])
1908      {
1909         free(video_config.glsl_shader_scrn[i]);
1910         video_config.glsl_shader_scrn[i] = NULL;
1911      }
1912   }
1913}
1914
1915//============================================================
1916//  texture_compute_size and type
1917//============================================================
1918
1919//
1920// glBufferData to push a nocopy texture to the GPU is slower than TexSubImage2D,
1921// so don't use PBO here
1922//
1923// we also don't want to use PBO's in the case of nocopy==TRUE,
1924// since we now might have GLSL shaders - this decision simplifies out life ;-)
1925//
1926void sdl_info_ogl::texture_compute_type_subroutine(const render_texinfo *texsource, texture_info *texture, UINT32 flags)
1927{
1928   texture->type = TEXTURE_TYPE_NONE;
1929   texture->nocopy = FALSE;
1930
1931   if ( texture->type == TEXTURE_TYPE_NONE &&
1932         !PRIMFLAG_GET_SCREENTEX(flags))
1933   {
1934      texture->type = TEXTURE_TYPE_PLAIN;
1935            texture->texTarget = (m_usetexturerect)?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D;
1936            texture->texpow2   = (m_usetexturerect)?0:m_texpoweroftwo;
1937   }
1938
1939   if ( texture->type == TEXTURE_TYPE_NONE && m_useglsl &&
1940         texture->xprescale == 1 && texture->yprescale == 1 &&
1941         texsource->rowpixels <= m_texture_max_width )
1942      {
1943         texture->type      = TEXTURE_TYPE_SHADER;
1944         texture->texTarget = GL_TEXTURE_2D;
1945         texture->texpow2   = m_texpoweroftwo;
1946      }
1947
1948   // determine if we can skip the copy step
1949   // if this was not already decided by the shader condition above
1950   if    ( texture_copy_properties[texture->format][SDL_TEXFORMAT_SRC_EQUALS_DEST] &&
1951         !texture_copy_properties[texture->format][SDL_TEXFORMAT_SRC_HAS_PALETTE] &&
1952         texture->xprescale == 1 && texture->yprescale == 1 &&
1953         !texture->borderpix && !texsource->palette &&
1954         texsource->rowpixels <= m_texture_max_width )
1955   {
1956      texture->nocopy = TRUE;
1957   }
1958
1959   if( texture->type == TEXTURE_TYPE_NONE &&
1960      m_usepbo && !texture->nocopy )
1961   {
1962      texture->type      = TEXTURE_TYPE_DYNAMIC;
1963      texture->texTarget = (m_usetexturerect)?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D;
1964      texture->texpow2   = (m_usetexturerect)?0:m_texpoweroftwo;
1965   }
1966
1967   if( texture->type == TEXTURE_TYPE_NONE )
1968   {
1969      texture->type      = TEXTURE_TYPE_SURFACE;
1970      texture->texTarget = (m_usetexturerect)?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D;
1971      texture->texpow2   = (m_usetexturerect)?0:m_texpoweroftwo;
1972   }
1973}
1974
1975INLINE int get_valid_pow2_value(int v, int needPow2)
1976{
1977   return (needPow2)?gl_round_to_pow2(v):v;
1978}
1979
1980void sdl_info_ogl::texture_compute_size_subroutine(texture_info *texture, UINT32 flags,
1981                                 UINT32 width, UINT32 height,
1982                                 int* p_width, int* p_height, int* p_width_create, int* p_height_create)
1983{
1984   int width_create;
1985   int height_create;
1986
1987   if ( texture->texpow2 )
1988      {
1989            width_create  = gl_round_to_pow2 (width);
1990            height_create = gl_round_to_pow2 (height);
1991      } else if ( texture->type==TEXTURE_TYPE_SHADER )
1992      {
1993            /**
1994             * at least use a multiple of 8 for shader .. just in case
1995             */
1996            width_create  = ( width  & ~0x07 ) + ( (width  & 0x07)? 8 : 0 ) ;
1997            height_create = ( height & ~0x07 ) + ( (height & 0x07)? 8 : 0 ) ;
1998      } else {
1999            width_create  = width  ;
2000            height_create = height ;
2001      }
2002
2003   // don't prescale above max texture size
2004   while (texture->xprescale > 1 && width_create * texture->xprescale > m_texture_max_width)
2005      texture->xprescale--;
2006   while (texture->yprescale > 1 && height_create * texture->yprescale > m_texture_max_height)
2007      texture->yprescale--;
2008   if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != window().prescale() || texture->yprescale != window().prescale()))
2009      osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", window().prescale(), window().prescale(), texture->xprescale, texture->yprescale);
2010
2011   width  *= texture->xprescale;
2012   height *= texture->yprescale;
2013   width_create  *= texture->xprescale;
2014   height_create *= texture->yprescale;
2015
2016   // adjust the size for the border (must do this *after* the power of 2 clamp to satisfy
2017   // OpenGL semantics)
2018   if (texture->borderpix)
2019   {
2020      width += 2;
2021      height += 2;
2022      width_create += 2;
2023      height_create += 2;
2024   }
2025      *p_width=width;
2026      *p_height=height;
2027      *p_width_create=width_create;
2028      *p_height_create=height_create;
2029}
2030
2031void sdl_info_ogl::texture_compute_size_type(const render_texinfo *texsource, texture_info *texture, UINT32 flags)
2032{
2033   int finalheight, finalwidth;
2034   int finalheight_create, finalwidth_create;
2035
2036   // if we're not wrapping, add a 1 pixel border on all sides
2037   texture->borderpix = 0; //!(texture->flags & PRIMFLAG_TEXWRAP_MASK);
2038   if (PRIMFLAG_GET_SCREENTEX(flags))
2039   {
2040      texture->borderpix = 0; // don't border the screen right now, there's a bug
2041   }
2042
2043   texture_compute_type_subroutine(texsource, texture, flags);
2044
2045   texture_compute_size_subroutine(texture, flags, texsource->width, texsource->height,
2046                           &finalwidth, &finalheight, &finalwidth_create, &finalheight_create);
2047
2048   // if we added pixels for the border, and that just barely pushed us over, take it back
2049   if (texture->borderpix &&
2050      ((finalwidth > m_texture_max_width && finalwidth - 2 <= m_texture_max_width) ||
2051         (finalheight > m_texture_max_height && finalheight - 2 <= m_texture_max_height)))
2052   {
2053      texture->borderpix = FALSE;
2054
2055      texture_compute_type_subroutine(texsource, texture, flags);
2056
2057      texture_compute_size_subroutine(texture, flags, texsource->width, texsource->height,
2058                              &finalwidth, &finalheight, &finalwidth_create, &finalheight_create);
2059   }
2060
2061   // if we're above the max width/height, do what?
2062   if (finalwidth_create > m_texture_max_width || finalheight_create > m_texture_max_height)
2063   {
2064      static int printed = FALSE;
2065      if (!printed)
2066         osd_printf_warning("Texture too big! (wanted: %dx%d, max is %dx%d)\n", finalwidth_create, finalheight_create, m_texture_max_width, m_texture_max_height);
2067      printed = TRUE;
2068   }
2069
2070   if(!texture->nocopy || texture->type==TEXTURE_TYPE_DYNAMIC || texture->type==TEXTURE_TYPE_SHADER ||
2071      // any of the mame core's device generated bitmap types:
2072      texture->format==SDL_TEXFORMAT_RGB32  ||
2073      texture->format==SDL_TEXFORMAT_RGB32_PALETTED  ||
2074      texture->format==SDL_TEXFORMAT_RGB15  ||
2075      texture->format==SDL_TEXFORMAT_RGB15_PALETTED  ||
2076      texture->format==SDL_TEXFORMAT_PALETTE16  ||
2077      texture->format==SDL_TEXFORMAT_PALETTE16A
2078      )
2079   {
2080      osd_printf_verbose("GL texture: copy %d, shader %d, dynamic %d, %dx%d %dx%d [%s, Equal: %d, Palette: %d,\n"
2081               "            scale %dx%d, border %d, pitch %d,%d/%d], bytes/pix %d\n",
2082         !texture->nocopy, texture->type==TEXTURE_TYPE_SHADER, texture->type==TEXTURE_TYPE_DYNAMIC,
2083         finalwidth, finalheight, finalwidth_create, finalheight_create,
2084         texfmt_to_string[texture->format],
2085         (int)texture_copy_properties[texture->format][SDL_TEXFORMAT_SRC_EQUALS_DEST],
2086         (int)texture_copy_properties[texture->format][SDL_TEXFORMAT_SRC_HAS_PALETTE],
2087         texture->xprescale, texture->yprescale,
2088         texture->borderpix, texsource->rowpixels, finalwidth, m_texture_max_width,
2089         (int)sizeof(UINT32)
2090         );
2091   }
2092
2093   // set the final values
2094   texture->rawwidth = finalwidth;
2095   texture->rawheight = finalheight;
2096   texture->rawwidth_create = finalwidth_create;
2097   texture->rawheight_create = finalheight_create;
2098}
2099
2100//============================================================
2101//  texture_create
2102//============================================================
2103
2104static int gl_checkFramebufferStatus(void)
2105{
2106   GLenum status;
2107   status=(GLenum)pfn_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
2108   switch(status) {
2109      case GL_FRAMEBUFFER_COMPLETE_EXT:
2110         return 0;
2111      case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
2112         osd_printf_error("GL FBO: incomplete,incomplete attachment\n");
2113         return -1;
2114      case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
2115         osd_printf_error("GL FBO: Unsupported framebuffer format\n");
2116         return -1;
2117      case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
2118         osd_printf_error("GL FBO: incomplete,missing attachment\n");
2119         return -1;
2120      case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
2121         osd_printf_error("GL FBO: incomplete,attached images must have same dimensions\n");
2122         return -1;
2123      case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
2124            osd_printf_error("GL FBO: incomplete,attached images must have same format\n");
2125         return -1;
2126      case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
2127         osd_printf_error("GL FBO: incomplete,missing draw buffer\n");
2128         return -1;
2129      case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
2130         osd_printf_error("GL FBO: incomplete,missing read buffer\n");
2131         return -1;
2132#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
2133      case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
2134         osd_printf_error("GL FBO: incomplete, duplicate attachment\n");
2135         return -1;
2136#endif
2137      case 0:
2138         osd_printf_error("GL FBO: incomplete, implementation fault\n");
2139         return -1;
2140      default:
2141         osd_printf_error("GL FBO: incomplete, implementation ERROR\n");
2142         /* fall through */
2143   }
2144   return -1;
2145}
2146
2147static int texture_fbo_create(UINT32 text_unit, UINT32 text_name, UINT32 fbo_name, int width, int height)
2148{
2149   pfn_glActiveTexture(text_unit);
2150   pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_name);
2151   glBindTexture(GL_TEXTURE_2D, text_name);
2152   {
2153      GLint _width, _height;
2154      if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
2155                  0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &_width, &_height, 1) )
2156      {
2157         osd_printf_error("cannot create fbo texture, req: %dx%d, avail: %dx%d - bail out\n",
2158                  width, height, (int)_width, (int)_height);
2159         return -1;
2160      }
2161
2162      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
2163            0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL );
2164   }
2165   // non-screen textures will never be filtered
2166   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2167   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2168
2169   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
2170   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
2171
2172   pfn_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
2173               GL_TEXTURE_2D, text_name, 0);
2174
2175   if ( gl_checkFramebufferStatus() )
2176   {
2177      osd_printf_error("FBO error fbo texture - bail out\n");
2178      return -1;
2179   }
2180
2181   return 0;
2182}
2183
2184int sdl_info_ogl::texture_shader_create(const render_texinfo *texsource, texture_info *texture, UINT32 flags)
2185{
2186   int uniform_location;
2187   int i;
2188   int surf_w_pow2  = get_valid_pow2_value (m_blit_dim.width(), texture->texpow2);
2189   int surf_h_pow2  = get_valid_pow2_value (m_blit_dim.height(), texture->texpow2);
2190
2191   assert ( texture->type==TEXTURE_TYPE_SHADER );
2192
2193   GL_CHECK_ERROR_QUIET();
2194
2195   if( m_glsl_program_num > 1 )
2196   {
2197      // multipass mode
2198      assert(m_usefbo);
2199
2200      // GL_TEXTURE3 GLSL Uniforms
2201      texture->mpass_dest_idx = 0;
2202      texture->mpass_textureunit[0] = GL_TEXTURE3;
2203      texture->mpass_textureunit[1] = GL_TEXTURE2;
2204   }
2205
2206   for(i=0; i<m_glsl_program_num; i++)
2207   {
2208      if ( i<=m_glsl_program_mb2sc )
2209      {
2210         m_glsl_program[i] = glsl_shader_get_program_mamebm(glsl_shader_feature, i);
2211      } else {
2212         m_glsl_program[i] = glsl_shader_get_program_scrn(i-1-m_glsl_program_mb2sc);
2213      }
2214      pfn_glUseProgramObjectARB(m_glsl_program[i]);
2215
2216      if ( i<=m_glsl_program_mb2sc )
2217      {
2218         // GL_TEXTURE0 GLSL Uniforms
2219         uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture");
2220         pfn_glUniform1iARB(uniform_location, 0);
2221         GL_CHECK_ERROR_NORMAL();
2222      }
2223
2224      {
2225         GLfloat color_texture_sz[2] = { (GLfloat)texture->rawwidth, (GLfloat)texture->rawheight };
2226         uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_sz");
2227         pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_sz[0]));
2228         GL_CHECK_ERROR_NORMAL();
2229      }
2230
2231      GLfloat color_texture_pow2_sz[2] = { (GLfloat)texture->rawwidth_create, (GLfloat)texture->rawheight_create };
2232      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_pow2_sz");
2233      pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_pow2_sz[0]));
2234      GL_CHECK_ERROR_NORMAL();
2235
2236      GLfloat screen_texture_sz[2] = { (GLfloat) m_blit_dim.width(), (GLfloat) m_blit_dim.height() };
2237      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_sz");
2238      pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_sz[0]));
2239      GL_CHECK_ERROR_NORMAL();
2240
2241      GLfloat screen_texture_pow2_sz[2] = { (GLfloat)surf_w_pow2, (GLfloat)surf_h_pow2 };
2242      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_pow2_sz");
2243      pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_pow2_sz[0]));
2244      GL_CHECK_ERROR_NORMAL();
2245   }
2246
2247   pfn_glUseProgramObjectARB(m_glsl_program[0]); // start with 1st shader
2248
2249   if( m_glsl_program_num > 1 )
2250   {
2251      // multipass mode
2252      // GL_TEXTURE2/GL_TEXTURE3
2253      pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
2254      glGenTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
2255
2256      for (i=0; i<2; i++)
2257      {
2258         if ( texture_fbo_create(texture->mpass_textureunit[i],
2259                           texture->mpass_texture_mamebm[i],
2260                  texture->mpass_fbo_mamebm[i],
2261                  texture->rawwidth_create, texture->rawheight_create) )
2262         {
2263            return -1;
2264         }
2265      }
2266
2267      pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
2268
2269      osd_printf_verbose("GL texture: mpass mame-bmp   2x %dx%d (pow2 %dx%d)\n",
2270         texture->rawwidth, texture->rawheight, texture->rawwidth_create, texture->rawheight_create);
2271   }
2272
2273   if( m_glsl_program_num > 1 && m_glsl_program_mb2sc < m_glsl_program_num - 1 )
2274   {
2275      // multipass mode
2276      // GL_TEXTURE2/GL_TEXTURE3
2277      pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
2278      glGenTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
2279
2280      for (i=0; i<2; i++)
2281      {
2282         if ( texture_fbo_create(texture->mpass_textureunit[i],
2283                           texture->mpass_texture_scrn[i],
2284                  texture->mpass_fbo_scrn[i],
2285                  surf_w_pow2, surf_h_pow2) )
2286         {
2287            return -1;
2288         }
2289      }
2290
2291      osd_printf_verbose("GL texture: mpass screen-bmp 2x %dx%d (pow2 %dx%d)\n",
2292         m_width, m_height, surf_w_pow2, surf_h_pow2);
2293   }
2294
2295   // GL_TEXTURE0
2296   // get a name for this texture
2297   glGenTextures(1, (GLuint *)&texture->texture);
2298   pfn_glActiveTexture(GL_TEXTURE0);
2299   glBindTexture(GL_TEXTURE_2D, texture->texture);
2300
2301   glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth_create);
2302
2303   UINT32 * dummy = NULL;
2304   GLint _width, _height;
2305   if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8,
2306               texture->rawwidth_create, texture->rawheight_create,
2307               0,
2308               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
2309               &_width, &_height, 1) )
2310   {
2311      osd_printf_error("cannot create bitmap texture, req: %dx%d, avail: %dx%d - bail out\n",
2312         texture->rawwidth_create, texture->rawheight_create, (int)_width, (int)_height);
2313      return -1;
2314   }
2315
2316   dummy = (UINT32 *) malloc(texture->rawwidth_create * texture->rawheight_create * sizeof(UINT32));
2317   memset(dummy, 0, texture->rawwidth_create * texture->rawheight_create * sizeof(UINT32));
2318   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
2319         texture->rawwidth_create, texture->rawheight_create,
2320         0,
2321         GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, dummy);
2322         glFinish(); // should not be necessary, .. but make sure we won't access the memory after free
2323   free(dummy);
2324
2325   if ((PRIMFLAG_GET_SCREENTEX(flags)) && video_config.filter)
2326   {
2327      assert( glsl_shader_feature == GLSL_SHADER_FEAT_PLAIN );
2328
2329      // screen textures get the user's choice of filtering
2330      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2331      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2332   }
2333   else
2334   {
2335      // non-screen textures will never be filtered
2336      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2337      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2338   }
2339
2340   // set wrapping mode appropriately
2341   if (texture->flags & PRIMFLAG_TEXWRAP_MASK)
2342   {
2343      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2344      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2345   }
2346   else
2347   {
2348      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
2349      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
2350   }
2351
2352   GL_CHECK_ERROR_NORMAL();
2353
2354   return 0;
2355}
2356
2357texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, UINT32 flags)
2358{
2359   texture_info *texture;
2360
2361   // allocate a new texture
2362   texture = global_alloc(texture_info);
2363
2364   // fill in the core data
2365   texture->hash = texture_compute_hash(texsource, flags);
2366   texture->flags = flags;
2367   texture->texinfo = *texsource;
2368   texture->texinfo.seqid = -1; // force set data
2369   if (PRIMFLAG_GET_SCREENTEX(flags))
2370   {
2371      texture->xprescale = window().prescale();
2372      texture->yprescale = window().prescale();
2373   }
2374   else
2375   {
2376      texture->xprescale = 1;
2377      texture->yprescale = 1;
2378   }
2379
2380   // set the texture_format
2381      //
2382      // src/emu/validity.c:validate_display() states,
2383      // an emulated driver can only produce
2384      //      BITMAP_FORMAT_IND16 and BITMAP_FORMAT_RGB32
2385      // where only the first original paletted.
2386      //
2387      // other paletted formats, i.e.:
2388      //   SDL_TEXFORMAT_RGB32_PALETTED, SDL_TEXFORMAT_RGB15_PALETTED and SDL_TEXFORMAT_YUY16_PALETTED
2389      // add features like brightness etc by the mame core
2390      //
2391      // all palette lookup may be implemented using shaders later on ..
2392      // that's why we keep the EQUAL flag TRUE, for all original true color bitmaps.
2393      //
2394   switch (PRIMFLAG_GET_TEXFORMAT(flags))
2395   {
2396      case TEXFORMAT_ARGB32:
2397         texture->format = SDL_TEXFORMAT_ARGB32;
2398         break;
2399      case TEXFORMAT_RGB32:
2400         if (texsource->palette != NULL)
2401            texture->format = SDL_TEXFORMAT_RGB32_PALETTED;
2402         else
2403            texture->format = SDL_TEXFORMAT_RGB32;
2404         break;
2405      case TEXFORMAT_PALETTE16:
2406         texture->format = SDL_TEXFORMAT_PALETTE16;
2407         break;
2408      case TEXFORMAT_PALETTEA16:
2409         texture->format = SDL_TEXFORMAT_PALETTE16A;
2410         break;
2411      case TEXFORMAT_YUY16:
2412         if (texsource->palette != NULL)
2413            texture->format = SDL_TEXFORMAT_YUY16_PALETTED;
2414         else
2415            texture->format = SDL_TEXFORMAT_YUY16;
2416         break;
2417
2418      default:
2419         osd_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags));
2420   }
2421
2422   // compute the size
2423   texture_compute_size_type(texsource, texture, flags);
2424
2425   texture->pbo=0;
2426
2427   if ( texture->type != TEXTURE_TYPE_SHADER && m_useglsl)
2428   {
2429      pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
2430   }
2431
2432   if ( texture->type==TEXTURE_TYPE_SHADER )
2433   {
2434      if ( texture_shader_create(texsource, texture, flags) )
2435      {
2436         global_free(texture);
2437         return NULL;
2438      }
2439   }
2440   else
2441   {
2442      // get a name for this texture
2443      glGenTextures(1, (GLuint *)&texture->texture);
2444
2445      glEnable(texture->texTarget);
2446
2447      // make sure we're operating on *this* texture
2448      glBindTexture(texture->texTarget, texture->texture);
2449
2450      // this doesn't actually upload, it just sets up the PBO's parameters
2451      glTexImage2D(texture->texTarget, 0, GL_RGBA8,
2452            texture->rawwidth_create, texture->rawheight_create,
2453            texture->borderpix ? 1 : 0,
2454            GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
2455
2456      if ((PRIMFLAG_GET_SCREENTEX(flags)) && video_config.filter)
2457      {
2458         // screen textures get the user's choice of filtering
2459         glTexParameteri(texture->texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2460         glTexParameteri(texture->texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2461      }
2462      else
2463      {
2464         // non-screen textures will never be filtered
2465         glTexParameteri(texture->texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2466         glTexParameteri(texture->texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2467      }
2468
2469      if( texture->texTarget==GL_TEXTURE_RECTANGLE_ARB )
2470      {
2471         // texture rectangles can't wrap
2472         glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
2473         glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
2474      } else {
2475         // set wrapping mode appropriately
2476         if (texture->flags & PRIMFLAG_TEXWRAP_MASK)
2477         {
2478            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2479            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2480         }
2481         else
2482         {
2483            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
2484            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
2485         }
2486      }
2487   }
2488
2489   if ( texture->type == TEXTURE_TYPE_DYNAMIC )
2490   {
2491      assert(m_usepbo);
2492
2493      // create the PBO
2494      pfn_glGenBuffers(1, (GLuint *)&texture->pbo);
2495
2496      pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
2497
2498      // set up the PBO dimension, ..
2499      pfn_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
2500                     texture->rawwidth * texture->rawheight * sizeof(UINT32),
2501               NULL, GL_STREAM_DRAW);
2502   }
2503
2504   if ( !texture->nocopy && texture->type!=TEXTURE_TYPE_DYNAMIC )
2505   {
2506      texture->data = (UINT32 *) malloc(texture->rawwidth* texture->rawheight * sizeof(UINT32));
2507      texture->data_own=TRUE;
2508   }
2509
2510   // add us to the texture list
2511   if (m_texhash[texture->hash] == NULL)
2512      m_texhash[texture->hash] = texture;
2513   else
2514   {
2515      int i;
2516      for (i = HASH_SIZE; i < HASH_SIZE + OVERFLOW_SIZE; i++)
2517         if (m_texhash[i] == NULL)
2518         {
2519            m_texhash[i] = texture;
2520            break;
2521         }
2522      assert_always(i < HASH_SIZE + OVERFLOW_SIZE, "texture hash exhausted ...");
2523   }
2524
2525   if(m_usevbo)
2526   {
2527      // Generate And Bind The Texture Coordinate Buffer
2528      pfn_glGenBuffers( 1, &(texture->texCoordBufferName) );
2529      pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
2530      // Load The Data
2531      pfn_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW );
2532      glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // we are using ARB VBO buffers
2533   }
2534   else
2535   {
2536      glTexCoordPointer(2, GL_FLOAT, 0, texture->texCoord);
2537   }
2538
2539   return texture;
2540}
2541
2542//============================================================
2543//  copyline_palette16
2544//============================================================
2545
2546INLINE void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2547{
2548   int x;
2549
2550   assert(xborderpix == 0 || xborderpix == 1);
2551   if (xborderpix)
2552      *dst++ = 0xff000000 | palette[*src];
2553   for (x = 0; x < width; x++)
2554   {
2555      int srcpix = *src++;
2556      for (int x2 = 0; x2 < xprescale; x2++)
2557         *dst++ = 0xff000000 | palette[srcpix];
2558   }
2559   if (xborderpix)
2560      *dst++ = 0xff000000 | palette[*--src];
2561}
2562
2563
2564
2565//============================================================
2566//  copyline_palettea16
2567//============================================================
2568
2569INLINE void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2570{
2571   int x;
2572
2573   assert(xborderpix == 0 || xborderpix == 1);
2574   if (xborderpix)
2575      *dst++ = palette[*src];
2576   for (x = 0; x < width; x++)
2577   {
2578      int srcpix = *src++;
2579      for (int x2 = 0; x2 < xprescale; x2++)
2580         *dst++ = palette[srcpix];
2581   }
2582   if (xborderpix)
2583      *dst++ = palette[*--src];
2584}
2585
2586
2587
2588//============================================================
2589//  copyline_rgb32
2590//============================================================
2591
2592INLINE void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2593{
2594   int x;
2595
2596   assert(xborderpix == 0 || xborderpix == 1);
2597
2598   // palette (really RGB map) case
2599   if (palette != NULL)
2600   {
2601      if (xborderpix)
2602      {
2603         rgb_t srcpix = *src;
2604         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2605      }
2606      for (x = 0; x < width; x++)
2607      {
2608         rgb_t srcpix = *src++;
2609         for (int x2 = 0; x2 < xprescale; x2++)
2610         {
2611            *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2612         }
2613      }
2614      if (xborderpix)
2615      {
2616         rgb_t srcpix = *--src;
2617         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2618      }
2619   }
2620
2621   // direct case
2622   else
2623   {
2624      if (xborderpix)
2625         *dst++ = 0xff000000 | *src;
2626      for (x = 0; x < width; x++)
2627      {
2628         rgb_t srcpix = *src++;
2629
2630         for (int x2 = 0; x2 < xprescale; x2++)
2631         {
2632            *dst++ = 0xff000000 | srcpix;
2633         }
2634      }
2635      if (xborderpix)
2636         *dst++ = 0xff000000 | *--src;
2637   }
2638}
2639
2640//============================================================
2641//  copyline_argb32
2642//============================================================
2643
2644INLINE void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2645{
2646   int x;
2647
2648   assert(xborderpix == 0 || xborderpix == 1);
2649
2650   // palette (really RGB map) case
2651   if (palette != NULL)
2652   {
2653      if (xborderpix)
2654      {
2655         rgb_t srcpix = *src;
2656         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2657      }
2658      for (x = 0; x < width; x++)
2659      {
2660         rgb_t srcpix = *src++;
2661         for (int x2 = 0; x2 < xprescale; x2++)
2662            *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2663      }
2664      if (xborderpix)
2665      {
2666         rgb_t srcpix = *--src;
2667         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2668      }
2669   }
2670
2671   // direct case
2672   else
2673   {
2674      if (xborderpix)
2675         *dst++ = *src;
2676      for (x = 0; x < width; x++)
2677      {
2678         rgb_t srcpix = *src++;
2679         for (int x2 = 0; x2 < xprescale; x2++)
2680            *dst++ = srcpix;
2681      }
2682      if (xborderpix)
2683         *dst++ = *--src;
2684   }
2685}
2686
2687INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr)
2688{
2689   /* original equations:
2690
2691       C = Y - 16
2692       D = Cb - 128
2693       E = Cr - 128
2694
2695       R = clip(( 298 * C           + 409 * E + 128) >> 8)
2696       G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
2697       B = clip(( 298 * C + 516 * D           + 128) >> 8)
2698
2699       R = clip(( 298 * (Y - 16)                    + 409 * (Cr - 128) + 128) >> 8)
2700       G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8)
2701       B = clip(( 298 * (Y - 16) + 516 * (Cb - 128)                    + 128) >> 8)
2702
2703       R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
2704       G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
2705       B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
2706
2707       R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
2708       G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
2709       B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
2710   */
2711   int r, g, b, common;
2712
2713   common = 298 * y - 298 * 16;
2714   r = (common +                        409 * cr - 409 * 128 + 128) >> 8;
2715   g = (common - 100 * cb + 100 * 128 - 208 * cr + 208 * 128 + 128) >> 8;
2716   b = (common + 516 * cb - 516 * 128                        + 128) >> 8;
2717
2718   if (r < 0) r = 0;
2719   else if (r > 255) r = 255;
2720   if (g < 0) g = 0;
2721   else if (g > 255) g = 255;
2722   if (b < 0) b = 0;
2723   else if (b > 255) b = 255;
2724
2725   return rgb_t(0xff, r, g, b);
2726}
2727
2728//============================================================
2729//  copyline_yuy16_to_argb
2730//============================================================
2731
2732INLINE void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2733{
2734   int x;
2735
2736   assert(xborderpix == 0 || xborderpix == 2);
2737   assert(width % 2 == 0);
2738
2739   // palette (really RGB map) case
2740   if (palette != NULL)
2741   {
2742      if (xborderpix)
2743      {
2744         UINT16 srcpix0 = src[0];
2745         UINT16 srcpix1 = src[1];
2746         UINT8 cb = srcpix0 & 0xff;
2747         UINT8 cr = srcpix1 & 0xff;
2748         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2749         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2750      }
2751      for (x = 0; x < width / 2; x++)
2752      {
2753         UINT16 srcpix0 = *src++;
2754         UINT16 srcpix1 = *src++;
2755         UINT8 cb = srcpix0 & 0xff;
2756         UINT8 cr = srcpix1 & 0xff;
2757         for (int x2 = 0; x2 < xprescale/2; x2++)
2758         {
2759            *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2760            *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2761         }
2762      }
2763      if (xborderpix)
2764      {
2765         UINT16 srcpix1 = *--src;
2766         UINT16 srcpix0 = *--src;
2767         UINT8 cb = srcpix0 & 0xff;
2768         UINT8 cr = srcpix1 & 0xff;
2769         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2770         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2771      }
2772   }
2773
2774   // direct case
2775   else
2776   {
2777      if (xborderpix)
2778      {
2779         UINT16 srcpix0 = src[0];
2780         UINT16 srcpix1 = src[1];
2781         UINT8 cb = srcpix0 & 0xff;
2782         UINT8 cr = srcpix1 & 0xff;
2783         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2784         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2785      }
2786      for (x = 0; x < width; x += 2)
2787      {
2788         UINT16 srcpix0 = *src++;
2789         UINT16 srcpix1 = *src++;
2790         UINT8 cb = srcpix0 & 0xff;
2791         UINT8 cr = srcpix1 & 0xff;
2792         for (int x2 = 0; x2 < xprescale/2; x2++)
2793         {
2794            *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2795            *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2796         }
2797      }
2798      if (xborderpix)
2799      {
2800         UINT16 srcpix1 = *--src;
2801         UINT16 srcpix0 = *--src;
2802         UINT8 cb = srcpix0 & 0xff;
2803         UINT8 cr = srcpix1 & 0xff;
2804         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2805         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2806      }
2807   }
2808}
2809
2810//============================================================
2811//  texture_set_data
2812//============================================================
2813
2814static void texture_set_data(texture_info *texture, const render_texinfo *texsource, UINT32 flags)
2815{
2816   if ( texture->type == TEXTURE_TYPE_DYNAMIC )
2817   {
2818      assert(texture->pbo);
2819      assert(!texture->nocopy);
2820
2821      texture->data = (UINT32 *) pfn_glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
2822   }
2823
2824   // note that nocopy and borderpix are mutually exclusive, IOW
2825   // they cannot be both true, thus this cannot lead to the
2826   // borderpix code below writing to texsource->base .
2827   if (texture->nocopy)
2828   {
2829      texture->data = (UINT32 *) texsource->base;
2830   }
2831
2832   // always fill non-wrapping textures with an extra pixel on the top
2833   if (texture->borderpix)
2834   {
2835      memset(texture->data, 0,
2836            (texsource->width * texture->xprescale + 2) * sizeof(UINT32));
2837   }
2838
2839   // when nescesarry copy (and convert) the data
2840   if (!texture->nocopy)
2841   {
2842      int y, y2;
2843      UINT8 *dst;
2844
2845      for (y = 0; y < texsource->height; y++)
2846      {
2847         for (y2 = 0; y2 < texture->yprescale; y2++)
2848         {
2849            dst = (UINT8 *)(texture->data + (y * texture->yprescale + texture->borderpix + y2) * texture->rawwidth);
2850
2851            switch (PRIMFLAG_GET_TEXFORMAT(flags))
2852            {
2853               case TEXFORMAT_PALETTE16:
2854                  copyline_palette16((UINT32 *)dst, (UINT16 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2855                  break;
2856
2857               case TEXFORMAT_PALETTEA16:
2858                  copyline_palettea16((UINT32 *)dst, (UINT16 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2859                  break;
2860
2861               case TEXFORMAT_RGB32:
2862                  copyline_rgb32((UINT32 *)dst, (UINT32 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2863                  break;
2864
2865               case TEXFORMAT_ARGB32:
2866                  copyline_argb32((UINT32 *)dst, (UINT32 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2867                  break;
2868
2869               case TEXFORMAT_YUY16:
2870                  copyline_yuy16_to_argb((UINT32 *)dst, (UINT16 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2871                  break;
2872
2873               default:
2874                  osd_printf_error("Unknown texture blendmode=%d format=%d\n", PRIMFLAG_GET_BLENDMODE(flags), PRIMFLAG_GET_TEXFORMAT(flags));
2875                  break;
2876            }
2877         }
2878      }
2879   }
2880
2881   // always fill non-wrapping textures with an extra pixel on the bottom
2882   if (texture->borderpix)
2883   {
2884      memset((UINT8 *)texture->data +
2885            (texsource->height + 1) * texture->rawwidth * sizeof(UINT32),
2886            0,
2887         (texsource->width * texture->xprescale + 2) * sizeof(UINT32));
2888   }
2889
2890   if ( texture->type == TEXTURE_TYPE_SHADER )
2891   {
2892      pfn_glActiveTexture(GL_TEXTURE0);
2893      glBindTexture(texture->texTarget, texture->texture);
2894
2895      if (texture->nocopy)
2896         glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->texinfo.rowpixels);
2897      else
2898         glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
2899
2900      // and upload the image
2901      glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
2902            GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texture->data);
2903   }
2904   else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
2905   {
2906      glBindTexture(texture->texTarget, texture->texture);
2907
2908      glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
2909
2910      // unmap the buffer from the CPU space so it can DMA
2911      pfn_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
2912
2913      // kick off the DMA
2914      glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
2915               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
2916   }
2917   else
2918   {
2919      glBindTexture(texture->texTarget, texture->texture);
2920
2921      // give the card a hint
2922      if (texture->nocopy)
2923         glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->texinfo.rowpixels);
2924      else
2925         glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
2926
2927      // and upload the image
2928      glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
2929                  GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texture->data);
2930   }
2931}
2932
2933//============================================================
2934//  texture_find
2935//============================================================
2936
2937static int compare_texture_primitive(const texture_info *texture, const render_primitive *prim)
2938{
2939   if (texture->texinfo.base == prim->texture.base &&
2940      texture->texinfo.width == prim->texture.width &&
2941      texture->texinfo.height == prim->texture.height &&
2942      texture->texinfo.rowpixels == prim->texture.rowpixels &&
2943      /* texture->texinfo.palette == prim->texture.palette && */
2944      ((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0)
2945      return 1;
2946   else
2947      return 0;
2948}
2949
2950texture_info *sdl_info_ogl::texture_find(const render_primitive *prim)
2951{
2952   HashT texhash = texture_compute_hash(&prim->texture, prim->flags);
2953   texture_info *texture;
2954
2955   texture = m_texhash[texhash];
2956   if (texture != NULL)
2957   {
2958      int i;
2959      if (compare_texture_primitive(texture, prim))
2960         return texture;
2961      for (i=HASH_SIZE; i<HASH_SIZE + OVERFLOW_SIZE; i++)
2962      {
2963         texture = m_texhash[i];
2964         if (texture != NULL && compare_texture_primitive(texture, prim))
2965            return texture;
2966      }
2967   }
2968   return NULL;
2969}
2970
2971//============================================================
2972//  texture_update
2973//============================================================
2974
2975void sdl_info_ogl::texture_coord_update(texture_info *texture, const render_primitive *prim, int shaderIdx)
2976{
2977   float ustart = 0.0f, ustop = 0.0f;            // beginning/ending U coordinates
2978   float vstart = 0.0f, vstop = 0.0f;            // beginning/ending V coordinates
2979   float du, dv;
2980
2981   if ( texture->type != TEXTURE_TYPE_SHADER ||
2982         ( texture->type == TEXTURE_TYPE_SHADER && shaderIdx<=m_glsl_program_mb2sc ) )
2983   {
2984      // compute the U/V scale factors
2985      if (texture->borderpix)
2986      {
2987         int unscaledwidth = (texture->rawwidth_create-2) / texture->xprescale + 2;
2988         int unscaledheight = (texture->rawheight_create-2) / texture->yprescale + 2;
2989         ustart = 1.0f / (float)(unscaledwidth);
2990         ustop = (float)(prim->texture.width + 1) / (float)(unscaledwidth);
2991         vstart = 1.0f / (float)(unscaledheight);
2992         vstop = (float)(prim->texture.height + 1) / (float)(unscaledheight);
2993      }
2994      else
2995      {
2996         ustop  = (float)(prim->texture.width*texture->xprescale) / (float)texture->rawwidth_create;
2997         vstop  = (float)(prim->texture.height*texture->yprescale) / (float)texture->rawheight_create;
2998      }
2999   }
3000   else if ( texture->type == TEXTURE_TYPE_SHADER && shaderIdx>m_glsl_program_mb2sc )
3001   {
3002      int surf_w_pow2  = get_valid_pow2_value (m_width, texture->texpow2);
3003      int surf_h_pow2  = get_valid_pow2_value (m_height, texture->texpow2);
3004
3005      ustop  = (float)(m_width) / (float)surf_w_pow2;
3006      vstop  = (float)(m_height) / (float)surf_h_pow2;
3007
3008   }
3009   else
3010   {
3011      assert(0); // ??
3012   }
3013
3014   du = ustop - ustart;
3015   dv = vstop - vstart;
3016
3017   if ( texture->texTarget == GL_TEXTURE_RECTANGLE_ARB )
3018   {
3019      // texture coordinates for TEXTURE_RECTANGLE are 0,0 -> w,h
3020      // rather than 0,0 -> 1,1 as with normal OpenGL texturing
3021      du *= (float)texture->rawwidth;
3022      dv *= (float)texture->rawheight;
3023   }
3024
3025   if ( texture->type == TEXTURE_TYPE_SHADER && shaderIdx!=m_glsl_program_mb2sc )
3026   {
3027      // 1:1 tex coord CCW (0/0) (1/0) (1/1) (0/1)
3028      // we must go CW here due to the mame bitmap order
3029      texture->texCoord[0]=ustart + du * 0.0f;
3030      texture->texCoord[1]=vstart + dv * 1.0f;
3031      texture->texCoord[2]=ustart + du * 1.0f;
3032      texture->texCoord[3]=vstart + dv * 1.0f;
3033      texture->texCoord[4]=ustart + du * 1.0f;
3034      texture->texCoord[5]=vstart + dv * 0.0f;
3035      texture->texCoord[6]=ustart + du * 0.0f;
3036      texture->texCoord[7]=vstart + dv * 0.0f;
3037   }
3038   else
3039   {
3040      // transformation: mamebm -> scrn
3041      texture->texCoord[0]=ustart + du * prim->texcoords.tl.u;
3042      texture->texCoord[1]=vstart + dv * prim->texcoords.tl.v;
3043      texture->texCoord[2]=ustart + du * prim->texcoords.tr.u;
3044      texture->texCoord[3]=vstart + dv * prim->texcoords.tr.v;
3045      texture->texCoord[4]=ustart + du * prim->texcoords.br.u;
3046      texture->texCoord[5]=vstart + dv * prim->texcoords.br.v;
3047      texture->texCoord[6]=ustart + du * prim->texcoords.bl.u;
3048      texture->texCoord[7]=vstart + dv * prim->texcoords.bl.v;
3049   }
3050}
3051
3052void sdl_info_ogl::texture_mpass_flip(texture_info *texture, int shaderIdx)
3053{
3054   UINT32 mpass_src_idx = texture->mpass_dest_idx;
3055
3056   texture->mpass_dest_idx = (mpass_src_idx+1) % 2;
3057
3058   if ( shaderIdx>0 )
3059   {
3060      int uniform_location;
3061      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "mpass_texture");
3062      pfn_glUniform1iARB(uniform_location, texture->mpass_textureunit[mpass_src_idx]-GL_TEXTURE0);
3063      GL_CHECK_ERROR_NORMAL();
3064   }
3065
3066   pfn_glActiveTexture(texture->mpass_textureunit[mpass_src_idx]);
3067   if ( shaderIdx<=m_glsl_program_mb2sc )
3068   {
3069      glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[mpass_src_idx]);
3070   }
3071   else
3072   {
3073      glBindTexture(texture->texTarget, texture->mpass_texture_scrn[mpass_src_idx]);
3074   }
3075   pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
3076   glBindTexture(texture->texTarget, 0);
3077
3078   pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
3079
3080   if ( shaderIdx<m_glsl_program_num-1 )
3081   {
3082      if ( shaderIdx>=m_glsl_program_mb2sc )
3083      {
3084         glBindTexture(texture->texTarget, texture->mpass_texture_scrn[texture->mpass_dest_idx]);
3085         pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_scrn[texture->mpass_dest_idx]);
3086      }
3087      else
3088      {
3089         glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[texture->mpass_dest_idx]);
3090         pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_mamebm[texture->mpass_dest_idx]);
3091      }
3092
3093      if ( shaderIdx==0 )
3094      {
3095         glPushAttrib(GL_VIEWPORT_BIT);
3096         GL_CHECK_ERROR_NORMAL();
3097         glViewport(0.0, 0.0, (GLsizei)texture->rawwidth, (GLsizei)texture->rawheight);
3098      }
3099      else if ( shaderIdx==m_glsl_program_mb2sc )
3100      {
3101         assert ( m_glsl_program_mb2sc < m_glsl_program_num-1 );
3102         glPopAttrib(); // glViewport(0.0, 0.0, (GLsizei)window().width, (GLsizei)window().height)
3103         GL_CHECK_ERROR_NORMAL();
3104      }
3105      glClear(GL_COLOR_BUFFER_BIT); // make sure the whole texture is redrawn ..
3106   }
3107   else
3108   {
3109      glBindTexture(texture->texTarget, 0);
3110      pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3111
3112      if ( m_glsl_program_mb2sc == m_glsl_program_num-1 )
3113      {
3114         glPopAttrib(); // glViewport(0.0, 0.0, (GLsizei)window().width, (GLsizei)window().height)
3115         GL_CHECK_ERROR_NORMAL();
3116      }
3117
3118      pfn_glActiveTexture(GL_TEXTURE0);
3119      glBindTexture(texture->texTarget, 0);
3120   }
3121}
3122
3123void sdl_info_ogl::texture_shader_update(texture_info *texture, render_container *container, int shaderIdx)
3124{
3125   int uniform_location;
3126   GLfloat vid_attributes[4];
3127
3128   if (container!=NULL)
3129   {
3130      render_container::user_settings settings;
3131      container->get_user_settings(settings);
3132      /* FIXME: the code below is in just for illustration issue on
3133       * how to set shader variables. gamma, contrast and brightness are
3134       * handled already by the core
3135       */
3136      vid_attributes[0] = settings.m_gamma;
3137      vid_attributes[1] = settings.m_contrast;
3138      vid_attributes[2] = settings.m_brightness;
3139      vid_attributes[3] = 0.0f;
3140      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "vid_attributes");
3141      pfn_glUniform4fvARB(uniform_location, 1, &(vid_attributes[shaderIdx]));
3142      if ( GL_CHECK_ERROR_QUIET() ) {
3143         osd_printf_verbose("GLSL: could not set 'vid_attributes' for shader prog idx %d\n", shaderIdx);
3144      }
3145   }
3146}
3147
3148texture_info * sdl_info_ogl::texture_update(const render_primitive *prim, int shaderIdx)
3149{
3150   texture_info *texture = texture_find(prim);
3151   int texBound = 0;
3152
3153   // if we didn't find one, create a new texture
3154   if (texture == NULL && prim->texture.base != NULL)
3155   {
3156      texture = texture_create(&prim->texture, prim->flags);
3157   }
3158   else if (texture != NULL)
3159   {
3160      if ( texture->type == TEXTURE_TYPE_SHADER )
3161      {
3162         pfn_glUseProgramObjectARB(m_glsl_program[shaderIdx]); // back to our shader
3163      }
3164      else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
3165      {
3166         assert ( m_usepbo ) ;
3167         pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
3168         glEnable(texture->texTarget);
3169      }
3170      else
3171      {
3172         glEnable(texture->texTarget);
3173      }
3174   }
3175
3176   if (texture != NULL)
3177   {
3178      if ( texture->type == TEXTURE_TYPE_SHADER )
3179      {
3180         texture_shader_update(texture, prim->container, shaderIdx);
3181         if ( m_glsl_program_num>1 )
3182         {
3183            texture_mpass_flip(texture, shaderIdx);
3184         }
3185      }
3186
3187      if ( shaderIdx==0 ) // redundant for subsequent multipass shader
3188      {
3189         if (prim->texture.base != NULL && texture->texinfo.seqid != prim->texture.seqid)
3190         {
3191            texture->texinfo.seqid = prim->texture.seqid;
3192
3193            // if we found it, but with a different seqid, copy the data
3194            texture_set_data(texture, &prim->texture, prim->flags);
3195            texBound=1;
3196         }
3197      }
3198
3199      if (!texBound) {
3200         glBindTexture(texture->texTarget, texture->texture);
3201      }
3202      texture_coord_update(texture, prim, shaderIdx);
3203
3204      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3205      if(m_usevbo)
3206      {
3207         pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
3208         // Load The Data
3209         pfn_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord );
3210         glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // we are using ARB VBO buffers
3211      }
3212      else
3213      {
3214         glTexCoordPointer(2, GL_FLOAT, 0, texture->texCoord);
3215      }
3216   }
3217
3218      return texture;
3219}
3220
3221void sdl_info_ogl::texture_disable(texture_info * texture)
3222{
3223   if ( texture->type == TEXTURE_TYPE_SHADER )
3224   {
3225      assert ( m_useglsl );
3226      pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
3227   } else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
3228   {
3229      pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
3230      glDisable(texture->texTarget);
3231   } else {
3232      glDisable(texture->texTarget);
3233   }
3234}
3235
3236void sdl_info_ogl::texture_all_disable()
3237{
3238   if ( m_useglsl )
3239   {
3240      pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
3241
3242      pfn_glActiveTexture(GL_TEXTURE3);
3243      glBindTexture(GL_TEXTURE_2D, 0);
3244      if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3245      pfn_glActiveTexture(GL_TEXTURE2);
3246      glBindTexture(GL_TEXTURE_2D, 0);
3247      if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3248      pfn_glActiveTexture(GL_TEXTURE1);
3249      glBindTexture(GL_TEXTURE_2D, 0);
3250      if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3251      pfn_glActiveTexture(GL_TEXTURE0);
3252      glBindTexture(GL_TEXTURE_2D, 0);
3253      if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3254   }
3255   glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
3256
3257   if(m_usetexturerect)
3258   {
3259      glDisable(GL_TEXTURE_RECTANGLE_ARB);
3260   }
3261   glDisable(GL_TEXTURE_2D);
3262
3263   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3264   if(m_usevbo)
3265   {
3266      pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); // unbind ..
3267   }
3268   if ( m_usepbo )
3269   {
3270      pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
3271   }
3272}
trunk/src/osd/modules/render/drawsdl.c
r0r244652
1//============================================================
2//
3//  drawsdl.c - SDL software and OpenGL implementation
4//
5//  Copyright (c) 1996-2011, Nicola Salmoria and the MAME Team.
6//  Visit http://mamedev.org for licensing and usage restrictions.
7//
8//  SDLMAME by Olivier Galibert and R. Belmont
9//
10//============================================================
11
12// standard C headers
13#include <math.h>
14#include <stdio.h>
15
16// MAME headers
17#include "emu.h"
18#include "ui/ui.h"
19#include "rendersw.inc"
20
21// standard SDL headers
22#include "sdlinc.h"
23
24// OSD headers
25#include "osdsdl.h"
26#include "window.h"
27
28//============================================================
29//  DEBUGGING
30//============================================================
31
32//============================================================
33//  CONSTANTS
34//============================================================
35
36//============================================================
37//  TYPES
38//============================================================
39
40struct sdl_scale_mode;
41
42#if (SDLMAME_SDL2)
43#define DRAW2_SCALEMODE_NEAREST "0"
44#define DRAW2_SCALEMODE_LINEAR  "1"
45#define DRAW2_SCALEMODE_BEST    "2"
46#endif
47
48/* sdl_info is the information about SDL for the current screen */
49class sdl_info : public osd_renderer
50{
51public:
52
53   sdl_info(osd_window *w, int extra_flags)
54   : osd_renderer(w, extra_flags),
55   #if (SDLMAME_SDL2)
56   m_sdl_renderer(NULL),
57   m_texture_id(NULL),
58   #else
59   m_yuvsurf(NULL),
60   #endif
61   m_yuv_lookup(NULL),
62   m_yuv_bitmap(NULL),
63   //m_hw_scale_width(0),
64   //m_hw_scale_height(0),
65   m_last_hofs(0),
66   m_last_vofs(0),
67   m_blit_dim(0, 0),
68   m_last_dim(0, 0)
69   { }
70
71   /* virtual */ int create();
72   /* virtual */ int draw(const int update);
73   /* virtual */ int xy_to_render_target(const int x, const int y, int *xt, int *yt);
74   /* virtual */ void destroy();
75   /* virtual */ render_primitive_list *get_primitives()
76   {
77      osd_dim nd = window().blit_surface_size();
78      if (nd != m_blit_dim)
79      {
80         m_blit_dim = nd;
81         notify_changed();
82      }
83      window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
84      return &window().target()->get_primitives();
85   }
86
87private:
88   void destroy_all_textures();
89   void yuv_init();
90#if (SDLMAME_SDL2)
91   void setup_texture(const osd_dim &size);
92#endif
93   void yuv_lookup_set(unsigned int pen, unsigned char red,
94            unsigned char green, unsigned char blue);
95
96#if (!SDLMAME_SDL2)
97   void yuv_overlay_init();
98#endif
99
100   INT32               m_blittimer;
101
102#if (SDLMAME_SDL2)
103   SDL_Renderer        *m_sdl_renderer;
104   SDL_Texture         *m_texture_id;
105#else
106   SDL_Overlay         *m_yuvsurf;
107#endif
108
109   // YUV overlay
110   UINT32              *m_yuv_lookup;
111   UINT16              *m_yuv_bitmap;
112
113   // if we leave scaling to SDL and the underlying driver, this
114   // is the render_target_width/height to use
115
116   int                 m_last_hofs;
117   int                 m_last_vofs;
118   osd_dim             m_blit_dim;
119   osd_dim             m_last_dim;
120};
121
122struct sdl_scale_mode
123{
124   const char      *name;
125   int             is_scale;           /* Scale mode?           */
126   int             is_yuv;             /* Yuv mode?             */
127   int             mult_w;             /* Width multiplier      */
128   int             mult_h;             /* Height multiplier     */
129#if (!SDLMAME_SDL2)
130   int             m_extra_flags;        /* Texture/surface flags */
131#else
132   const char      *sdl_scale_mode;        /* what to use as a hint ? */
133#endif
134   int             pixel_format;       /* Pixel/Overlay format  */
135   void            (*yuv_blit)(const UINT16 *bitmap, UINT8 *ptr, const int pitch, const UINT32 *lookup, const int width, const int height);
136};
137
138//============================================================
139//  INLINES
140//============================================================
141
142//============================================================
143//  PROTOTYPES
144//============================================================
145
146// core functions
147static void drawsdl_exit(void);
148
149// YUV overlays
150
151static void yuv_RGB_to_YV12(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
152      const UINT32 *lookup, const int width, const int height);
153static void yuv_RGB_to_YV12X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
154      const UINT32 *lookup, const int width, const int height);
155static void yuv_RGB_to_YUY2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
156      const UINT32 *lookup, const int width, const int height);
157static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
158      const UINT32 *lookup, const int width, const int height);
159
160// Static declarations
161
162#if (!SDLMAME_SDL2)
163static int shown_video_info = 0;
164
165static const sdl_scale_mode scale_modes[] =
166{
167      { "none",    0, 0, 1, 1, osd_renderer::FLAG_NEEDS_DOUBLEBUF, 0, 0 },
168      { "async",   0, 0, 1, 1, osd_renderer::FLAG_NEEDS_DOUBLEBUF | osd_renderer::FLAG_NEEDS_ASYNCBLIT, 0, 0 },
169      { "yv12",    1, 1, 1, 1, 0,              SDL_YV12_OVERLAY, yuv_RGB_to_YV12 },
170      { "yv12x2",  1, 1, 2, 2, 0,              SDL_YV12_OVERLAY, yuv_RGB_to_YV12X2 },
171      { "yuy2",    1, 1, 1, 1, 0,              SDL_YUY2_OVERLAY, yuv_RGB_to_YUY2 },
172      { "yuy2x2",  1, 1, 2, 1, 0,              SDL_YUY2_OVERLAY, yuv_RGB_to_YUY2X2 },
173      { NULL }
174};
175#else
176static const sdl_scale_mode scale_modes[] =
177{
178      { "none",    0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, 0 },
179      { "hwblit",  1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, 0 },
180      { "hwbest",  1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, 0 },
181      /* SDL1.2 uses interpolation as well */
182      { "yv12",    1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
183      { "yv12x2",  1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
184      { "yuy2",    1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
185      { "yuy2x2",  1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
186      { NULL }
187};
188#endif
189
190//============================================================
191//  drawsdl_scale_mode
192//============================================================
193
194const char *drawsdl_scale_mode_str(int index)
195{
196   const sdl_scale_mode *sm = scale_modes;
197
198   while (index>0)
199   {
200      if (sm->name == NULL)
201         return NULL;
202      index--;
203      sm++;
204   }
205   return sm->name;
206};
207
208int drawsdl_scale_mode(const char *s)
209{
210   const sdl_scale_mode *sm = scale_modes;
211   int index;
212
213   index = 0;
214   while (sm->name != NULL)
215   {
216      if (strcmp(sm->name, s) == 0)
217         return index;
218      index++;
219      sm++;
220   }
221   return -1;
222}
223
224
225static osd_renderer *drawsdl_create(osd_window *window)
226{
227   // FIXME: QUALITY HINTS
228#if (SDLMAME_SDL2)
229   return global_alloc(sdl_info(window, osd_renderer::FLAG_NONE));
230#else
231   const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
232   return global_alloc(sdl_info(window, sm->m_extra_flags));
233#endif
234}
235
236//============================================================
237//  drawsdl_init
238//============================================================
239
240int drawsdl_init(osd_draw_callbacks *callbacks)
241{
242   // fill in the callbacks
243   callbacks->create = drawsdl_create;
244   callbacks->exit = drawsdl_exit;
245
246   if (SDLMAME_SDL2)
247      osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
248   else
249      osd_printf_verbose("Using SDL single-window soft driver (SDL 1.2)\n");
250
251   return 0;
252}
253
254//============================================================
255//  drawsdl_exit
256//============================================================
257
258static void drawsdl_exit(void)
259{
260}
261
262//============================================================
263//  setup_texture for window
264//============================================================
265
266#if (SDLMAME_SDL2)
267void sdl_info::setup_texture(const osd_dim &size)
268{
269   const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
270   SDL_DisplayMode mode;
271   UINT32 fmt;
272
273   // Determine preferred pixelformat and set up yuv if necessary
274   SDL_GetCurrentDisplayMode(window().monitor()->handle(), &mode);
275
276   if (m_yuv_bitmap)
277   {
278      global_free_array(m_yuv_bitmap);
279      m_yuv_bitmap = NULL;
280   }
281
282   fmt = (sdl_sm->pixel_format ? sdl_sm->pixel_format : mode.format);
283
284   if (sdl_sm->is_scale)
285   {
286      int m_hw_scale_width = 0;
287      int m_hw_scale_height = 0;
288
289      window().target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
290      if (window().prescale())
291      {
292         m_hw_scale_width *= window().prescale();
293         m_hw_scale_height *= window().prescale();
294
295         /* This must be a multiple of 2 */
296         m_hw_scale_width = (m_hw_scale_width + 1) & ~1;
297      }
298      if (sdl_sm->is_yuv)
299         m_yuv_bitmap = global_alloc_array(UINT16, m_hw_scale_width * m_hw_scale_height);
300
301      int w = m_hw_scale_width * sdl_sm->mult_w;
302      int h = m_hw_scale_height * sdl_sm->mult_h;
303
304      m_texture_id = SDL_CreateTexture(m_sdl_renderer, fmt, SDL_TEXTUREACCESS_STREAMING, w, h);
305
306   }
307   else
308   {
309      m_texture_id = SDL_CreateTexture(m_sdl_renderer,fmt, SDL_TEXTUREACCESS_STREAMING,
310            size.width(), size.height());
311   }
312}
313#endif
314
315//============================================================
316//  yuv_overlay_init
317//============================================================
318
319#if (!SDLMAME_SDL2)
320void sdl_info::yuv_overlay_init()
321{
322   const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
323   int minimum_width, minimum_height;
324
325   window().target()->compute_minimum_size(minimum_width, minimum_height);
326
327   if (window().prescale())
328   {
329      minimum_width *= window().prescale();
330      minimum_height *= window().prescale();
331   }
332
333   if (m_yuvsurf != NULL)
334   {
335      SDL_FreeYUVOverlay(m_yuvsurf);
336      m_yuvsurf = NULL;
337   }
338
339   if (m_yuv_bitmap != NULL)
340   {
341      global_free_array(m_yuv_bitmap);
342   }
343
344   osd_printf_verbose("SDL: Creating %d x %d YUV-Overlay ...\n", minimum_width, minimum_height);
345
346   m_yuv_bitmap = global_alloc_array(UINT16, minimum_width*minimum_height);
347
348   m_yuvsurf = SDL_CreateYUVOverlay(minimum_width * sdl_sm->mult_w, minimum_height * sdl_sm->mult_h,
349         sdl_sm->pixel_format, window().sdl_surface());
350
351   if ( m_yuvsurf == NULL ) {
352      osd_printf_error("SDL: Couldn't create SDL_yuv_overlay: %s\n", SDL_GetError());
353      //return 1;
354   }
355
356   if (!shown_video_info)
357   {
358      osd_printf_verbose("YUV Mode         : %s\n", sdl_sm->name);
359      osd_printf_verbose("YUV Overlay Size : %d x %d\n", minimum_width, minimum_height);
360      osd_printf_verbose("YUV Acceleration : %s\n", m_yuvsurf->hw_overlay ? "Hardware" : "Software");
361      shown_video_info = 1;
362   }
363}
364#endif
365
366//============================================================
367//  drawsdl_show_info
368//============================================================
369
370#if (SDLMAME_SDL2)
371static void drawsdl_show_info(struct SDL_RendererInfo *render_info)
372{
373#define RF_ENTRY(x) {x, #x }
374   static struct {
375      int flag;
376      const char *name;
377   } rflist[] =
378      {
379#if 0
380         RF_ENTRY(SDL_RENDERER_SINGLEBUFFER),
381         RF_ENTRY(SDL_RENDERER_PRESENTCOPY),
382         RF_ENTRY(SDL_RENDERER_PRESENTFLIP2),
383         RF_ENTRY(SDL_RENDERER_PRESENTFLIP3),
384         RF_ENTRY(SDL_RENDERER_PRESENTDISCARD),
385#endif
386         RF_ENTRY(SDL_RENDERER_PRESENTVSYNC),
387         RF_ENTRY(SDL_RENDERER_ACCELERATED),
388         {-1, NULL}
389      };
390   int i;
391
392   osd_printf_verbose("window: using renderer %s\n", render_info->name ? render_info->name : "<unknown>");
393   for (i = 0; rflist[i].name != NULL; i++)
394      if (render_info->flags & rflist[i].flag)
395         osd_printf_verbose("renderer: flag %s\n", rflist[i].name);
396}
397#endif
398
399//============================================================
400//  sdl_info::create
401// a
402// a
403// a
404// a
405// a
406// a
407// a
408// a
409// a
410// a
411// a
412// a
413// a
414// a
415// a
416// a
417// a
418// a
419// a
420// a
421// a
422// a
423// a
424// a
425// a
426// a
427//============================================================
428
429
430int sdl_info::create()
431{
432#if (SDLMAME_SDL2)
433   const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
434
435   // create renderer
436
437   /* set hints ... */
438   SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, sm->sdl_scale_mode);
439
440
441   if (video_config.waitvsync)
442      m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
443   else
444      m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_ACCELERATED);
445
446   if (!m_sdl_renderer)
447   {
448      fatalerror("Error on creating renderer: %s\n", SDL_GetError());
449   }
450
451   {
452      struct SDL_RendererInfo render_info;
453
454      SDL_GetRendererInfo(m_sdl_renderer, &render_info);
455      drawsdl_show_info(&render_info);
456
457      // Check scale mode
458
459      if (sm->pixel_format)
460      {
461         int i;
462         int found = 0;
463
464         for (i=0; i < render_info.num_texture_formats; i++)
465            if (sm->pixel_format == render_info.texture_formats[i])
466               found = 1;
467
468         if (!found)
469         {
470            fatalerror("window: Scale mode %s not supported!", sm->name);
471         }
472      }
473   }
474
475#if 0
476   int w = 0, h = 0;
477   window().get_size(w, h);
478   setup_texture(w, h);
479#endif
480#else
481#endif
482
483   m_yuv_lookup = NULL;
484   m_blittimer = 0;
485
486   yuv_init();
487   osd_printf_verbose("Leave sdl_info::create\n");
488   return 0;
489}
490
491//============================================================
492//  sdl_info::destroy
493//============================================================
494
495void sdl_info::destroy()
496{
497   // free the memory in the window
498
499   destroy_all_textures();
500
501   if (m_yuv_lookup != NULL)
502   {
503      global_free_array(m_yuv_lookup);
504      m_yuv_lookup = NULL;
505   }
506   if (m_yuv_bitmap != NULL)
507   {
508      global_free_array(m_yuv_bitmap);
509      m_yuv_bitmap = NULL;
510   }
511}
512
513//============================================================
514//  drawsdl_xy_to_render_target
515//============================================================
516
517int sdl_info::xy_to_render_target(int x, int y, int *xt, int *yt)
518{
519   *xt = x - m_last_hofs;
520   *yt = y - m_last_vofs;
521   if (*xt<0 || *xt >= m_blit_dim.width())
522      return 0;
523   if (*yt<0 || *yt >= m_blit_dim.height())
524      return 0;
525   return 1;
526}
527
528//============================================================
529//  drawsdl_destroy_all_textures
530//============================================================
531
532void sdl_info::destroy_all_textures()
533{
534#if (SDLMAME_SDL2)
535   SDL_DestroyTexture(m_texture_id);
536   m_texture_id = NULL;
537#else
538   if (m_yuvsurf != NULL)
539   {
540      SDL_FreeYUVOverlay(m_yuvsurf);
541      m_yuvsurf = NULL;
542   }
543#endif
544}
545
546
547//============================================================
548//  sdl_info::draw
549//============================================================
550
551int sdl_info::draw(int update)
552{
553   const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
554   UINT8 *surfptr;
555   INT32 pitch;
556   Uint32 rmask, gmask, bmask;
557#if (SDLMAME_SDL2)
558   Uint32 amask;
559#endif
560   INT32 vofs, hofs, blitwidth, blitheight, ch, cw;
561   int bpp;
562
563   if (video_config.novideo)
564   {
565      return 0;
566   }
567
568   osd_dim wdim = window().get_size();
569   if (has_flags(FI_CHANGED) || (wdim != m_last_dim))
570   {
571      destroy_all_textures();
572      clear_flags(FI_CHANGED);
573      m_blittimer = 3;
574      m_last_dim = wdim;
575#if (SDLMAME_SDL2)
576      SDL_RenderSetViewport(m_sdl_renderer, NULL);
577      if (m_texture_id != NULL)
578         SDL_DestroyTexture(m_texture_id);
579      setup_texture(m_blit_dim);
580      m_blittimer = 3;
581#else
582      const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
583      if (sdl_sm->is_yuv)
584      {
585         yuv_overlay_init();
586      }
587#endif
588   }
589
590   // lock it if we need it
591#if (!SDLMAME_SDL2)
592
593   pitch = window().sdl_surface()->pitch;
594   bpp = window().sdl_surface()->format->BytesPerPixel;
595   rmask = window().sdl_surface()->format->Rmask;
596   gmask = window().sdl_surface()->format->Gmask;
597   bmask = window().sdl_surface()->format->Bmask;
598//  amask = sdlsurf->format->Amask;
599#if 0
600   if (window().blitwidth() != m_old_blitwidth || window().blitheight() != m_old_blitheight)
601   {
602      if (sm->is_yuv)
603         yuv_overlay_init();
604      m_old_blitwidth = window().blitwidth();
605      m_old_blitheight = window().blitheight();
606      m_blittimer = 3;
607   }
608#endif
609   if (SDL_MUSTLOCK(window().sdl_surface()))
610      SDL_LockSurface(window().sdl_surface());
611
612   // Clear if necessary
613   if (m_blittimer > 0)
614   {
615      memset(window().sdl_surface()->pixels, 0, wdim.height() * window().sdl_surface()->pitch);
616      m_blittimer--;
617   }
618
619
620   if (sm->is_yuv)
621   {
622      SDL_LockYUVOverlay(m_yuvsurf);
623      surfptr = m_yuvsurf->pixels[0]; // (UINT8 *) m_yuv_bitmap;
624      pitch = m_yuvsurf->pitches[0]; // (UINT8 *) m_yuv_bitmap;
625#if 0
626      printf("abcd %d\n", m_yuvsurf->h);
627      printf("abcd %d %d %d\n", m_yuvsurf->pitches[0], m_yuvsurf->pitches[1], m_yuvsurf->pitches[2]);
628      printf("abcd %p %p %p\n", m_yuvsurf->pixels[0], m_yuvsurf->pixels[1], m_yuvsurf->pixels[2]);
629      printf("abcd %ld %ld\n", m_yuvsurf->pixels[1] - m_yuvsurf->pixels[0], m_yuvsurf->pixels[2] - m_yuvsurf->pixels[1]);
630#endif
631   }
632   else
633      surfptr = (UINT8 *)window().sdl_surface()->pixels;
634#else
635   //SDL_SelectRenderer(window().sdl_window);
636
637
638   {
639      Uint32 format;
640      int access, w, h;
641
642      SDL_QueryTexture(m_texture_id, &format, &access, &w, &h);
643      SDL_PixelFormatEnumToMasks(format, &bpp, &rmask, &gmask, &bmask, &amask);
644      bpp = bpp / 8; /* convert to bytes per pixels */
645   }
646
647   // Clear if necessary
648   if (m_blittimer > 0)
649   {
650      /* SDL Underlays need alpha = 0 ! */
651      SDL_SetRenderDrawColor(m_sdl_renderer,0,0,0,0);
652      SDL_RenderFillRect(m_sdl_renderer,NULL);
653      //SDL_RenderFill(0,0,0,0 /*255*/,NULL);
654      m_blittimer--;
655   }
656
657   SDL_LockTexture(m_texture_id, NULL, (void **) &surfptr, &pitch);
658
659#endif
660   // get ready to center the image
661   vofs = hofs = 0;
662   blitwidth = m_blit_dim.width();
663   blitheight = m_blit_dim.height();
664
665   ch = wdim.height();
666   cw = wdim.width();
667
668   // do not crash if the window's smaller than the blit area
669   if (blitheight > ch)
670   {
671         blitheight = ch;
672   }
673   else if (video_config.centerv)
674   {
675      vofs = (ch - m_blit_dim.height()) / 2;
676   }
677
678   if (blitwidth > cw)
679   {
680         blitwidth = cw;
681   }
682   else if (video_config.centerh)
683   {
684      hofs = (cw - m_blit_dim.width()) / 2;
685   }
686
687   m_last_hofs = hofs;
688   m_last_vofs = vofs;
689
690   window().m_primlist->acquire_lock();
691
692   int mamewidth, mameheight;
693
694#if !SDLMAME_SDL2
695      if (!sm->is_yuv)
696      {
697         surfptr += ((vofs * pitch) + (hofs * bpp));
698         mamewidth = blitwidth; //sdl_surface()->w;
699         mameheight = blitheight; //sdl_surface()->h;
700      }
701      else
702      {
703         mamewidth = m_yuvsurf->w / sm->mult_w;
704         mameheight = m_yuvsurf->h / sm->mult_h;
705      }
706#else
707      Uint32 fmt = 0;
708      int access = 0;
709      SDL_QueryTexture(m_texture_id, &fmt, &access, &mamewidth, &mameheight);
710      mamewidth /= sm->mult_w;
711      mameheight /= sm->mult_h;
712#endif
713   //printf("w h %d %d %d %d\n", mamewidth, mameheight, blitwidth, blitheight);
714
715   // rescale bounds
716   float fw = (float) mamewidth / (float) blitwidth;
717   float fh = (float) mameheight / (float) blitheight;
718
719   // FIXME: this could be a lot easier if we get the primlist here!
720   //          Bounds would be set fit for purpose and done!
721
722   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
723   {
724      prim->bounds.x0 = floor(fw * prim->bounds.x0 + 0.5f);
725      prim->bounds.x1 = floor(fw * prim->bounds.x1 + 0.5f);
726      prim->bounds.y0 = floor(fh * prim->bounds.y0 + 0.5f);
727      prim->bounds.y1 = floor(fh * prim->bounds.y1 + 0.5f);
728   }
729
730   // render to it
731   if (!sm->is_yuv)
732   {
733      switch (rmask)
734      {
735         case 0x0000ff00:
736            software_renderer<UINT32, 0,0,0, 8,16,24>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
737            break;
738
739         case 0x00ff0000:
740            software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
741            break;
742
743         case 0x000000ff:
744            software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
745            break;
746
747         case 0xf800:
748            software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
749            break;
750
751         case 0x7c00:
752            software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
753            break;
754
755         default:
756            osd_printf_error("SDL: ERROR! Unknown video mode: R=%08X G=%08X B=%08X\n", rmask, gmask, bmask);
757            break;
758      }
759   }
760   else
761   {
762      assert (m_yuv_bitmap != NULL);
763      assert (surfptr != NULL);
764      software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, m_yuv_bitmap, mamewidth, mameheight, mamewidth);
765      sm->yuv_blit((UINT16 *)m_yuv_bitmap, surfptr, pitch, m_yuv_lookup, mamewidth, mameheight);
766   }
767
768   window().m_primlist->release_lock();
769
770   // unlock and flip
771#if (!SDLMAME_SDL2)
772   if (SDL_MUSTLOCK(window().sdl_surface())) SDL_UnlockSurface(window().sdl_surface());
773   if (!sm->is_yuv)
774   {
775      SDL_Flip(window().sdl_surface());
776   }
777   else
778   {
779      SDL_Rect r;
780
781      SDL_UnlockYUVOverlay(m_yuvsurf);
782      r.x = hofs;
783      r.y = vofs;
784      r.w = blitwidth;
785      r.h = blitheight;
786      SDL_DisplayYUVOverlay(m_yuvsurf, &r);
787   }
788#else
789   SDL_UnlockTexture(m_texture_id);
790   {
791      SDL_Rect r;
792
793      r.x=hofs;
794      r.y=vofs;
795      r.w=blitwidth;
796      r.h=blitheight;
797      //printf("blitwidth %d %d - %d %d\n", blitwidth, blitheight, window().width, window().height);
798      //SDL_UpdateTexture(sdltex, NULL, sdlsurf->pixels, pitch);
799      SDL_RenderCopy(m_sdl_renderer,m_texture_id, NULL, &r);
800      SDL_RenderPresent(m_sdl_renderer);
801   }
802#endif
803   return 0;
804}
805//============================================================
806// YUV Blitting
807//============================================================
808
809#define CU_CLAMP(v, a, b)   ((v < a)? a: ((v > b)? b: v))
810#define RGB2YUV_F(r,g,b,y,u,v) \
811      (y) = (0.299*(r) + 0.587*(g) + 0.114*(b) ); \
812      (u) = (-0.169*(r) - 0.331*(g) + 0.5*(b) + 128); \
813      (v) = (0.5*(r) - 0.419*(g) - 0.081*(b) + 128); \
814   (y) = CU_CLAMP(y,0,255); \
815   (u) = CU_CLAMP(u,0,255); \
816   (v) = CU_CLAMP(v,0,255)
817
818#define RGB2YUV(r,g,b,y,u,v) \
819      (y) = ((  8453*(r) + 16594*(g) +  3223*(b) +  524288) >> 15); \
820      (u) = (( -4878*(r) -  9578*(g) + 14456*(b) + 4210688) >> 15); \
821      (v) = (( 14456*(r) - 12105*(g) -  2351*(b) + 4210688) >> 15)
822
823#ifdef LSB_FIRST
824#define Y1MASK  0x000000FF
825#define  UMASK  0x0000FF00
826#define Y2MASK  0x00FF0000
827#define  VMASK  0xFF000000
828#define Y1SHIFT  0
829#define  USHIFT  8
830#define Y2SHIFT 16
831#define  VSHIFT 24
832#else
833#define Y1MASK  0xFF000000
834#define  UMASK  0x00FF0000
835#define Y2MASK  0x0000FF00
836#define  VMASK  0x000000FF
837#define Y1SHIFT 24
838#define  USHIFT 16
839#define Y2SHIFT  8
840#define  VSHIFT  0
841#endif
842
843#define YMASK  (Y1MASK|Y2MASK)
844#define UVMASK (UMASK|VMASK)
845
846void sdl_info::yuv_lookup_set(unsigned int pen, unsigned char red,
847         unsigned char green, unsigned char blue)
848{
849   UINT32 y,u,v;
850
851   RGB2YUV(red,green,blue,y,u,v);
852
853   /* Storing this data in YUYV order simplifies using the data for
854      YUY2, both with and without smoothing... */
855   m_yuv_lookup[pen]=(y<<Y1SHIFT)|(u<<USHIFT)|(y<<Y2SHIFT)|(v<<VSHIFT);
856}
857
858void sdl_info::yuv_init()
859{
860   unsigned char r,g,b;
861   if (m_yuv_lookup == NULL)
862      m_yuv_lookup = global_alloc_array(UINT32, 65536);
863   for (r = 0; r < 32; r++)
864      for (g = 0; g < 32; g++)
865         for (b = 0; b < 32; b++)
866         {
867            int idx = (r << 10) | (g << 5) | b;
868            yuv_lookup_set(idx,
869               (r << 3) | (r >> 2),
870               (g << 3) | (g >> 2),
871               (b << 3) | (b >> 2));
872         }
873}
874
875//UINT32 *lookup = sdl->m_yuv_lookup;
876
877static void yuv_RGB_to_YV12(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
878      const UINT32 *lookup, const int width, const int height)
879{
880   int x, y;
881   UINT8 *pixels[3];
882   int u1,v1,y1,u2,v2,y2,u3,v3,y3,u4,v4,y4;      /* 12 */
883
884   pixels[0] = ptr;
885   pixels[1] = ptr + pitch * height;
886   pixels[2] = pixels[1] + pitch * height / 4;
887
888   for(y=0;y<height;y+=2)
889   {
890      const UINT16 *src=bitmap + (y * width) ;
891      const UINT16 *src2=src + width;
892
893      UINT8 *dest_y = pixels[0] + y * pitch;
894      UINT8 *dest_v = pixels[1] + (y>>1) * pitch / 2;
895      UINT8 *dest_u = pixels[2] + (y>>1) * pitch / 2;
896
897      for(x=0;x<width;x+=2)
898      {
899         v1 = lookup[src[x]];
900         y1 = (v1>>Y1SHIFT) & 0xff;
901         u1 = (v1>>USHIFT)  & 0xff;
902         v1 = (v1>>VSHIFT)  & 0xff;
903
904         v2 = lookup[src[x+1]];
905         y2 = (v2>>Y1SHIFT) & 0xff;
906         u2 = (v2>>USHIFT)  & 0xff;
907         v2 = (v2>>VSHIFT)  & 0xff;
908
909         v3 = lookup[src2[x]];
910         y3 = (v3>>Y1SHIFT) & 0xff;
911         u3 = (v3>>USHIFT)  & 0xff;
912         v3 = (v3>>VSHIFT)  & 0xff;
913
914         v4 = lookup[src2[x+1]];
915         y4 = (v4>>Y1SHIFT) & 0xff;
916         u4 = (v4>>USHIFT)  & 0xff;
917         v4 = (v4>>VSHIFT)  & 0xff;
918
919         dest_y[x] = y1;
920         dest_y[x+pitch] = y3;
921         dest_y[x+1] = y2;
922         dest_y[x+pitch+1] = y4;
923
924         dest_u[x>>1] = (u1+u2+u3+u4)/4;
925         dest_v[x>>1] = (v1+v2+v3+v4)/4;
926
927      }
928   }
929}
930
931static void yuv_RGB_to_YV12X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
932      const UINT32 *lookup, const int width, const int height)
933{
934   /* this one is used when scale==2 */
935   unsigned int x,y;
936   int u1,v1,y1;
937   UINT8 *pixels[3];
938
939   pixels[0] = ptr;
940   pixels[1] = ptr + pitch * height * 2;
941#if (SDLMAME_SDL2)
942   int p2 = (pitch >> 1);
943#else
944   int p2 = (pitch + 7) & ~ 7;;
945   p2 = (p2 >> 1);
946#endif
947   pixels[2] = pixels[1] + p2 * height;
948
949   for(y=0;y<height;y++)
950   {
951      const UINT16 *src = bitmap + (y * width) ;
952
953      UINT16 *dest_y = (UINT16 *)(pixels[0] + 2 * y * pitch);
954      UINT8 *dest_v = pixels[1] + y * p2;
955      UINT8 *dest_u = pixels[2] + y * p2;
956      for(x=0;x<width;x++)
957      {
958         v1 = lookup[src[x]];
959         y1 = (v1 >> Y1SHIFT) & 0xff;
960         u1 = (v1 >> USHIFT)  & 0xff;
961         v1 = (v1 >> VSHIFT)  & 0xff;
962
963         dest_y[x + pitch/2] = y1 << 8 | y1;
964         dest_y[x] = y1 << 8 | y1;
965         dest_u[x] = u1;
966         dest_v[x] = v1;
967      }
968   }
969}
970
971static void yuv_RGB_to_YUY2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
972      const UINT32 *lookup, const int width, const int height)
973{
974   /* this one is used when scale==2 */
975   unsigned int y;
976   UINT32 p1,p2,uv;
977   const int yuv_pitch = pitch/4;
978
979   for(y=0;y<height;y++)
980   {
981      const UINT16 *src=bitmap + (y * width) ;
982      const UINT16 *end=src+width;
983
984      UINT32 *dest = (UINT32 *) ptr;
985      dest += y * yuv_pitch;
986      for(; src<end; src+=2)
987      {
988         p1  = lookup[src[0]];
989         p2  = lookup[src[1]];
990         uv = (p1&UVMASK)>>1;
991         uv += (p2&UVMASK)>>1;
992         *dest++ = (p1&Y1MASK)|(p2&Y2MASK)|(uv&UVMASK);
993      }
994   }
995}
996
997static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
998      const UINT32 *lookup, const int width, const int height)
999{
1000   /* this one is used when scale==2 */
1001   unsigned int y;
1002   int yuv_pitch = pitch / 4;
1003
1004   for(y=0;y<height;y++)
1005   {
1006      const UINT16 *src=bitmap + (y * width) ;
1007      const UINT16 *end=src+width;
1008
1009      UINT32 *dest = (UINT32 *) ptr;
1010      dest += (y * yuv_pitch);
1011      for(; src<end; src++)
1012      {
1013         dest[0] = lookup[src[0]];
1014         dest++;
1015      }
1016   }
1017}
trunk/src/osd/modules/sync/osdsync.h
r244651r244652
1010#ifndef __OSDSYNC__
1111#define __OSDSYNC__
1212
13#include "osdcomm.h"
14#include "osdcore.h"
15
1316/***************************************************************************
1417    SYNCHRONIZATION INTERFACES - Events
1518***************************************************************************/
trunk/src/osd/sdl/blit13.h
r244651r244652
1
2
3
4//============================================================
5//  INLINE
6//============================================================
7
8inline UINT32 premult32(const UINT32 pixel)
9{
10   const UINT16 a = (pixel >> 24) & 0xff;
11   const UINT16 r = (pixel >> 16) & 0xff;
12   const UINT16 g = (pixel >> 8) & 0xff;
13   const UINT16 b = (pixel >> 0) & 0xff;
14
15   return 0xFF000000 |
16      ((r * a) / 255) << 16 |
17      ((g * a) / 255) << 8 |
18      ((b * a) / 255);
19}
20
21inline UINT32 CLUL(const UINT32 x)
22{
23   return ((INT32) x < 0) ? 0 : ((x > 65535) ? 255 : x >> 8);
24}
25
26inline UINT32 ycc_to_rgb(const UINT8 y, const UINT8 cb, const UINT8 cr)
27{
28   const UINT32 common = 298 * y - 56992;
29   const UINT32 r = (common +            409 * cr);
30   const UINT32 g = (common - 100 * cb - 208 * cr + 91776);
31   const UINT32 b = (common + 516 * cb - 13696);
32
33   return 0xff000000 | (CLUL(r)<<16) | (CLUL(g)<<8) | (CLUL(b));
34}
35
36inline UINT32 pixel_ycc_to_rgb(const UINT16 *pixel)
37{
38   const UINT32 p = *(UINT32 *)((FPTR) pixel & ~3);
39   return ycc_to_rgb((*pixel >> 8) & 0xff, (p) & 0xff, (p>>16) & 0xff);
40}
41
42inline UINT32 pixel_ycc_to_rgb_pal(const UINT16 *pixel, const rgb_t *palette)
43{
44   const UINT32 p = *(UINT32 *)((FPTR) pixel & ~3);
45   return ycc_to_rgb(palette[(*pixel >> 8) & 0xff], (p) & 0xff, (p>>16) & 0xff);
46}
47
48//============================================================
49//  Pixel conversions
50//============================================================
51
52
53#define FUNC_DEF(source) op(const source &src, const rgb_t *palbase) const
54#define FUNCTOR(name, x...) \
55   template<typename _source, typename _dest> \
56   struct name { _dest FUNC_DEF(_source) { x } };
57
58FUNCTOR(op_argb32_argb32, return src; )
59FUNCTOR(op_rgb32_argb32,  return src | 0xff000000; )
60FUNCTOR(op_pal16_argb32,  return 0xff000000 |palbase[src]; )
61FUNCTOR(op_pal16_rgb32,   return palbase[src]; )
62FUNCTOR(op_rgb32pal_argb32,
63   return palbase[0x200 + (((src) >> 16) & 0xff) ] |
64      palbase[0x100 + (((src) >> 8) & 0xff) ] |
65      palbase[((src) & 0xff) ] | 0xff000000; )
66
67FUNCTOR(op_pal16a_argb32, return palbase[src]; )
68
69FUNCTOR(op_rgb15_argb32,
70      return 0xff000000 | ((src & 0x7c00) << 9) | ((src & 0x03e0) << 6)
71            | ((src & 0x001f) << 3) | ((((src & 0x7c00) << 9)
72            | ((src & 0x03e0) << 6) | ((src & 0x001f) << 3) >> 5) & 0x070707); )
73
74FUNCTOR(op_rgb15pal_argb32,
75      return 0xff000000 | palbase[0x40 + ((src >> 10) & 0x1f)] |
76      palbase[0x20 + ((src >> 5) & 0x1f)] | palbase[0x00 + ((src >> 0) & 0x1f)]; )
77
78FUNCTOR(op_argb32_rgb32, return premult32(src); )
79FUNCTOR(op_pal16a_rgb32, return premult32(palbase[src]); )
80FUNCTOR(op_pal16_argb1555,
81      return (palbase[src]&0xf80000) >> 9 |
82         (palbase[src]&0x00f800) >> 6 |
83         (palbase[src]&0x0000f8) >> 3 | 0x8000; )
84
85FUNCTOR(op_rgb15_argb1555, return src | 0x8000; )
86
87FUNCTOR(op_rgb15pal_argb1555,
88      return (palbase[src >> 10] & 0xf8) << 7 |
89         (palbase[(src >> 5) & 0x1f] & 0xf8) << 2 |
90         (palbase[src & 0x1f] & 0xf8) >> 3 | 0x8000; )
91
92FUNCTOR(op_yuv16_uyvy, return src; )
93FUNCTOR(op_yuv16pal_uyvy, return (palbase[(src >> 8) & 0xff] << 8) | (src & 0x00ff); )
94
95// FIXME: wrong ... see non_pal version
96FUNCTOR(op_yuv16pal_yvyu, return (palbase[(src >> 8) & 0xff] & 0xff) | ((src & 0xff) << 8); )
97FUNCTOR(op_yuv16_yvyu, return ((src & 0xff00ff00) >> 8 ) | (src << 24) | ((src >> 8) & 0x00ff00); )
98
99FUNCTOR(op_yuv16_yuy2, return ((src & 0xff00ff00) >> 8) | ((src & 0x00ff00ff) << 8); )
100
101FUNCTOR(op_yuv16pal_yuy2,
102      return  (palbase[(src>>8) & 0xff]) |
103            (palbase[(src>>24) & 0xff]<<16) |
104            ((src<<8)&0xff00ff00);)
105
106FUNCTOR(op_yuv16_argb32,
107      return (UINT64) ycc_to_rgb((src >>  8) & 0xff, src & 0xff , (src>>16) & 0xff)
108   | ((UINT64)ycc_to_rgb((src >> 24) & 0xff, src & 0xff , (src>>16) & 0xff) << 32); )
109
110FUNCTOR(op_yuv16pal_argb32,
111      return (UINT64)ycc_to_rgb(palbase[(src >>  8) & 0xff], src & 0xff , (src>>16) & 0xff)
112   | ((UINT64)ycc_to_rgb(palbase[(src >> 24) & 0xff], src & 0xff , (src>>16) & 0xff) << 32);)
113
114FUNCTOR(op_yuv16_argb32rot, return pixel_ycc_to_rgb(&src) ; )
115
116FUNCTOR(op_yuv16pal_argb32rot, return pixel_ycc_to_rgb_pal(&src, palbase); )
117
118//============================================================
119//  Copy and rotation
120//============================================================
121
122struct blit_base {
123   blit_base(int dest_bpp, bool is_rot, bool is_passthrough)
124   : m_dest_bpp(dest_bpp), m_is_rot(is_rot), m_is_passthrough(is_passthrough)
125   { }
126   virtual ~blit_base() { }
127
128   virtual void texop(const texture_info *texture, const render_texinfo *texsource) const = 0;
129   int m_dest_bpp;
130   bool m_is_rot;
131   bool m_is_passthrough;
132};
133
134template<typename _src_type, typename _dest_type, typename _op, int _len_div>
135struct blit_texcopy : public blit_base
136{
137   blit_texcopy() : blit_base(sizeof(_dest_type) / _len_div, false, false) { }
138   void texop(const texture_info *texture, const render_texinfo *texsource) const
139   {
140      ATTR_UNUSED const rgb_t *palbase = texsource->palette;
141      int x, y;
142      /* loop over Y */
143      for (y = 0; y < texsource->height; y++) {
144         _src_type *src = (_src_type *)texsource->base + y * texsource->rowpixels / (_len_div);
145         _dest_type *dst = (_dest_type *)((UINT8 *)texture->m_pixels + y * texture->m_pitch);
146         x = texsource->width / (_len_div);
147         while (x > 0) {
148            *dst++ = m_op.op(*src, palbase);
149            src++;
150            x--;
151         }
152      }
153   }
154private:
155   _op m_op;
156};
157
158#define TEXCOPYA(a, b, c, d) \
159      const struct blit_texcopy<b, c, op_ ## a <b, c>, d> texcopy_ ## a;
160
161template<typename _src_type, typename _dest_type, typename _op>
162struct blit_texrot : public blit_base
163{
164   blit_texrot() : blit_base(sizeof(_dest_type), true, false) { }
165   void texop(const texture_info *texture, const render_texinfo *texsource) const
166   {
167      ATTR_UNUSED const rgb_t *palbase = texsource->palette;
168      int x, y;
169      const quad_setup_data *setup = &texture->m_setup;
170      int dudx = setup->dudx;
171      int dvdx = setup->dvdx;
172      /* loop over Y */
173      for (y = 0; y < setup->rotheight; y++) {
174         INT32 curu = setup->startu + y * setup->dudy;
175         INT32 curv = setup->startv + y * setup->dvdy;
176         _dest_type *dst = (_dest_type *)((UINT8 *)texture->m_pixels + y * texture->m_pitch);
177         x = setup->rotwidth;
178         while (x>0) {
179            _src_type *src = (_src_type *) texsource->base + (curv >> 16) * texsource->rowpixels + (curu >> 16);
180            *dst++ = m_op.op(*src, palbase);
181            curu += dudx;
182            curv += dvdx;
183            x--;
184         }
185      }
186   }
187private:
188   _op m_op;
189};
190
191#define TEXROTA(a, b, c) \
192      const struct blit_texrot<b, c, op_ ## a <b, c> > texcopy_rot_ ## a;
193
194template<typename _src_type, typename _dest_type>
195struct blit_texpass : public blit_base
196{
197   blit_texpass() : blit_base(sizeof(_dest_type), false, true) { }
198   void texop(const texture_info *texture, const render_texinfo *texsource) const
199   {
200   }
201};
202
203#define TEXCOPYP(a, b, c) \
204      const struct blit_texpass<b, c> texcopy_ ## a;
205
206
207TEXCOPYA(rgb32_argb32,  UINT32, UINT32, 1)
208TEXCOPYP(rgb32_rgb32,   UINT32, UINT32)
209
210TEXCOPYA(rgb32pal_argb32,  UINT32, UINT32, 1)
211TEXCOPYA(pal16_argb32,  UINT16, UINT32, 1)
212TEXCOPYA(pal16a_argb32,  UINT16, UINT32, 1)
213TEXCOPYA(rgb15_argb32,  UINT16, UINT32, 1)
214TEXCOPYA(rgb15pal_argb32,  UINT16, UINT32, 1)
215
216TEXCOPYA(pal16_argb1555,  UINT16, UINT16, 1)
217TEXCOPYA(rgb15_argb1555,  UINT16, UINT16, 1)
218TEXCOPYA(rgb15pal_argb1555,  UINT16, UINT16, 1)
219
220TEXCOPYP(argb32_argb32,  UINT32, UINT32)
221TEXCOPYA(argb32_rgb32, UINT32, UINT32, 1)
222TEXCOPYA(pal16a_rgb32,  UINT16, UINT32, 1)
223
224TEXCOPYA(yuv16_argb32, UINT32, UINT64, 2)
225TEXCOPYA(yuv16pal_argb32, UINT32, UINT64, 2)
226
227TEXCOPYP(yuv16_uyvy, UINT16, UINT16)
228TEXCOPYP(rgb15_rgb555, UINT16, UINT16)
229
230TEXCOPYA(yuv16pal_uyvy, UINT16, UINT16, 1)
231
232TEXCOPYA(yuv16_yvyu, UINT32, UINT32, 2)
233TEXCOPYA(yuv16pal_yvyu, UINT16, UINT16, 1)
234
235TEXCOPYA(yuv16_yuy2, UINT32, UINT32, 2)
236TEXCOPYA(yuv16pal_yuy2, UINT32, UINT32, 2)
237
238
239
240TEXROTA(argb32_argb32, UINT32, UINT32)
241TEXROTA(rgb32_argb32,  UINT32, UINT32)
242TEXROTA(pal16_argb32,  UINT16, UINT32)
243TEXROTA(pal16_rgb32,  UINT16, UINT32)
244
245TEXROTA(rgb32pal_argb32,  UINT32, UINT32)
246TEXROTA(pal16a_argb32,  UINT16, UINT32)
247TEXROTA(rgb15_argb32,  UINT16, UINT32)
248TEXROTA(rgb15pal_argb32,  UINT16, UINT32)
249
250TEXROTA(pal16_argb1555,  UINT16, UINT16)
251TEXROTA(rgb15_argb1555,  UINT16, UINT16)
252TEXROTA(rgb15pal_argb1555,  UINT16, UINT16)
253
254TEXROTA(argb32_rgb32, UINT32, UINT32)
255TEXROTA(pal16a_rgb32,  UINT16, UINT32)
256
257TEXROTA(yuv16_argb32rot, UINT16, UINT32)
258TEXROTA(yuv16pal_argb32rot, UINT16, UINT32)
trunk/src/osd/sdl/draw13.c
r244651r244652
1//============================================================
2//
3//  draw13.c - SDL 2.0 drawing implementation
4//
5//  Copyright (c) 1996-2014, Nicola Salmoria and the MAME Team.
6//  Visit http://mamedev.org for licensing and usage restrictions.
7//
8//  SDLMAME by Olivier Galibert and R. Belmont
9//
10//============================================================
11
12// standard C headers
13#include <math.h>
14#include <stdio.h>
15
16// MAME headers
17#include "emu.h"
18#include "options.h"
19
20// standard SDL headers
21#include "sdlinc.h"
22
23// OSD headers
24#include "osdsdl.h"
25#include "window.h"
26
27
28//============================================================
29//  DEBUGGING
30//============================================================
31
32//============================================================
33//  CONSTANTS
34//============================================================
35
36#define STAT_PIXEL_THRESHOLD (150*150)
37
38enum
39{
40   TEXTURE_TYPE_NONE,
41   TEXTURE_TYPE_PLAIN,
42   TEXTURE_TYPE_SURFACE
43};
44
45
46//============================================================
47//  Inline functions
48//============================================================
49
50static inline bool is_opaque(const float &a)
51{
52   return (a >= 1.0f);
53}
54
55static inline bool is_transparent(const float &a)
56{
57   return (a <  0.0001f);
58}
59
60//============================================================
61//  TYPES
62//============================================================
63
64
65struct quad_setup_data
66{
67   quad_setup_data()
68   : dudx(0), dvdx(0), dudy(0), dvdy(0), startu(0), startv(0),
69      rotwidth(0), rotheight(0)
70   {}
71   void compute(const render_primitive &prim, const int prescale);
72
73   INT32           dudx, dvdx, dudy, dvdy;
74   INT32           startu, startv;
75   INT32           rotwidth, rotheight;
76};
77
78//============================================================
79//  Textures
80//============================================================
81
82class sdl_info13;
83struct copy_info_t;
84
85/* texture_info holds information about a texture */
86class texture_info
87{
88   friend class simple_list<texture_info>;
89public:
90   texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const UINT32 flags);
91   ~texture_info();
92
93   void set_data(const render_texinfo &texsource, const UINT32 flags);
94   void render_quad(const render_primitive *prim, const int x, const int y);
95   bool matches(const render_primitive &prim, const quad_setup_data &setup);
96
97   copy_info_t *compute_size_type();
98
99   void                *m_pixels;            // pixels for the texture
100   int                 m_pitch;
101
102   copy_info_t         *m_copyinfo;
103   quad_setup_data     m_setup;
104
105   osd_ticks_t         m_last_access;
106
107   int raw_width() const { return m_texinfo.width; }
108   int raw_height() const { return m_texinfo.height; }
109
110   texture_info *next() { return m_next; }
111   const render_texinfo &texinfo() const { return m_texinfo; }
112   render_texinfo &texinfo() { return m_texinfo; }
113
114   const HashT hash() const { return m_hash; }
115   const UINT32 flags() const { return m_flags; }
116   // FIXME:
117   const bool is_pixels_owned() const;
118
119private:
120   Uint32              m_sdl_access;
121   SDL_Renderer *      m_sdl_renderer;
122   render_texinfo      m_texinfo;            // copy of the texture info
123   HashT               m_hash;               // hash value for the texture (must be >= pointer size)
124   UINT32              m_flags;              // rendering flags
125
126   SDL_Texture *       m_texture_id;
127   bool                m_is_rotated;
128
129   int                 m_format;             // texture format
130   SDL_BlendMode       m_sdl_blendmode;
131
132   texture_info *      m_next;               // next texture in the list
133};
134
135//============================================================
136//  TEXCOPY FUNCS
137//============================================================
138
139#include "blit13.h"
140
141/* sdl_info is the information about SDL for the current screen */
142class sdl_info13 : public osd_renderer
143{
144public:
145   sdl_info13(osd_window *w)
146   : osd_renderer(w, FLAG_NONE), m_blittimer(0), m_sdl_renderer(NULL),
147      m_last_hofs(0), m_last_vofs(0),
148      m_width(0), m_height(0),
149      m_blit_dim(0,0),
150      m_last_blit_time(0), m_last_blit_pixels(0)
151   {}
152
153   /* virtual */ int create();
154   /* virtual */ int draw(const int update);
155   /* virtual */ int xy_to_render_target(const int x, const int y, int *xt, int *yt);
156   /* virtual */ void destroy();
157   /* virtual */ render_primitive_list *get_primitives()
158   {
159      osd_dim nd = window().blit_surface_size();
160      if (nd != m_blit_dim)
161      {
162         m_blit_dim = nd;
163         notify_changed();
164      }
165      window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
166      return &window().target()->get_primitives();
167   }
168
169private:
170   void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y);
171
172   texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
173   texture_info *texture_update(const render_primitive &prim);
174
175   void destroy_all_textures();
176
177   INT32           m_blittimer;
178
179#if (SDLMAME_SDL2)
180   //SDL_GLContext   m_gl_context_id;
181#else
182   // SDL surface
183   SDL_Surface         *m_sdlsurf;
184#endif
185
186   SDL_Renderer *  m_sdl_renderer;
187   simple_list<texture_info>  m_texlist;                // list of active textures
188
189   float           m_last_hofs;
190   float           m_last_vofs;
191
192   int             m_width;
193   int             m_height;
194
195   osd_dim         m_blit_dim;
196
197   // Stats
198   INT64           m_last_blit_time;
199   INT64           m_last_blit_pixels;
200};
201
202struct copy_info_t {
203   int                 src_fmt;
204   Uint32              dst_fmt;
205   const blit_base     *blitter;
206   Uint32              bm_mask;
207   const char          *srcname;
208   const char          *dstname;
209   /* Statistics */
210   UINT64              pixel_count;
211   INT64               time;
212   int                 samples;
213   int                 perf;
214   /* list */
215   copy_info_t           *next;
216};
217
218
219//============================================================
220//  PROTOTYPES
221//============================================================
222
223// core functions
224
225static void drawsdl2_exit(void);
226
227//============================================================
228//  STATIC VARIABLES
229//============================================================
230
231#define SDL_TEXFORMAT_LAST SDL_TEXFORMAT_PALETTE16A
232#define BM_ALL (-1)
233//( SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD)
234
235#define ENTRY(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, 0}
236#define ENTRY_BM(a,b,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0}
237#define ENTRY_LR(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1}
238
239static copy_info_t blit_info_default[] =
240{
241   /* no rotation */
242   ENTRY(ARGB32,           ARGB8888,   argb32_argb32),
243   ENTRY_LR(ARGB32,        RGB888,     argb32_rgb32),
244   /* Entry primarily for directfb */
245   ENTRY_BM(ARGB32,        RGB888,     argb32_rgb32, SDL_BLENDMODE_ADD),
246   ENTRY_BM(ARGB32,        RGB888,     argb32_rgb32, SDL_BLENDMODE_MOD),
247   ENTRY_BM(ARGB32,        RGB888,     argb32_rgb32, SDL_BLENDMODE_NONE),
248
249   ENTRY(RGB32,            ARGB8888,   rgb32_argb32),
250   ENTRY(RGB32,            RGB888,     rgb32_rgb32),
251
252   ENTRY(RGB32_PALETTED,   ARGB8888,   rgb32pal_argb32),
253   ENTRY(RGB32_PALETTED,   RGB888,     rgb32pal_argb32),
254
255   ENTRY(YUY16,            UYVY,       yuv16_uyvy),
256   ENTRY(YUY16,            YUY2,       yuv16_yuy2),
257   ENTRY(YUY16,            YVYU,       yuv16_yvyu),
258   ENTRY(YUY16,            ARGB8888,   yuv16_argb32),
259   ENTRY(YUY16,            RGB888,     yuv16_argb32),
260
261   ENTRY(YUY16_PALETTED,   UYVY,       yuv16pal_uyvy),
262   ENTRY(YUY16_PALETTED,   YUY2,       yuv16pal_yuy2),
263   ENTRY(YUY16_PALETTED,   YVYU,       yuv16pal_yvyu),
264   ENTRY(YUY16_PALETTED,   ARGB8888,   yuv16pal_argb32),
265   ENTRY(YUY16_PALETTED,   RGB888,     yuv16pal_argb32),
266
267   ENTRY(PALETTE16,        ARGB8888,   pal16_argb32),
268   ENTRY(PALETTE16,        RGB888,     pal16_argb32),
269
270   ENTRY(RGB15,            RGB555,     rgb15_rgb555),
271   ENTRY(RGB15,            ARGB1555,   rgb15_argb1555),
272   ENTRY(RGB15,            ARGB8888,   rgb15_argb32),
273   ENTRY(RGB15,            RGB888,     rgb15_argb32),
274
275   ENTRY(RGB15_PALETTED,   ARGB8888,   rgb15pal_argb32),
276   ENTRY(RGB15_PALETTED,   RGB888,     rgb15pal_argb32),
277
278   ENTRY(PALETTE16A,       ARGB8888,   pal16a_argb32),
279   ENTRY(PALETTE16A,       RGB888,     pal16a_rgb32),
280
281   /* rotation */
282   ENTRY(ARGB32,           ARGB8888,   rot_argb32_argb32),
283   ENTRY_LR(ARGB32,        RGB888,     rot_argb32_rgb32),
284   /* Entry primarily for directfb */
285   ENTRY_BM(ARGB32,        RGB888,     rot_argb32_rgb32, SDL_BLENDMODE_ADD),
286   ENTRY_BM(ARGB32,        RGB888,     rot_argb32_rgb32, SDL_BLENDMODE_MOD),
287   ENTRY_BM(ARGB32,        RGB888,     rot_argb32_rgb32, SDL_BLENDMODE_NONE),
288
289   ENTRY(RGB32,            ARGB8888,   rot_rgb32_argb32),
290   ENTRY(RGB32,            RGB888,     rot_argb32_argb32),
291
292   ENTRY(RGB32_PALETTED,   ARGB8888,   rot_rgb32pal_argb32),
293   ENTRY(RGB32_PALETTED,   RGB888,     rot_rgb32pal_argb32),
294
295   ENTRY(YUY16,            ARGB8888,   rot_yuv16_argb32rot),
296   ENTRY(YUY16,            RGB888,     rot_yuv16_argb32rot),
297
298   ENTRY(YUY16_PALETTED,   ARGB8888,   rot_yuv16pal_argb32rot),
299   ENTRY(YUY16_PALETTED,   RGB888,     rot_yuv16pal_argb32rot),
300
301   ENTRY(PALETTE16,        ARGB8888,   rot_pal16_argb32),
302   ENTRY(PALETTE16,        RGB888,     rot_pal16_argb32),
303
304   ENTRY(RGB15,            RGB555,     rot_rgb15_argb1555),
305   ENTRY(RGB15,            ARGB1555,   rot_rgb15_argb1555),
306   ENTRY(RGB15,            ARGB8888,   rot_rgb15_argb32),
307   ENTRY(RGB15,            RGB888,     rot_rgb15_argb32),
308
309   ENTRY(RGB15_PALETTED,   ARGB8888,   rot_rgb15pal_argb32),
310   ENTRY(RGB15_PALETTED,   RGB888,     rot_rgb15pal_argb32),
311
312   ENTRY(PALETTE16A,       ARGB8888,   rot_pal16a_argb32),
313   ENTRY(PALETTE16A,       RGB888,     rot_pal16a_rgb32),
314
315{ -1 },
316};
317
318static copy_info_t *blit_info[SDL_TEXFORMAT_LAST+1];
319
320static struct
321{
322   Uint32  format;
323   int     status;
324} fmt_support[30] = { { 0, 0 } };
325
326
327//============================================================
328//  INLINES
329//============================================================
330
331
332INLINE float round_nearest(float f)
333{
334   return floor(f + 0.5f);
335}
336
337INLINE HashT texture_compute_hash(const render_texinfo &texture, const UINT32 flags)
338{
339   return (HashT)texture.base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK));
340}
341
342INLINE SDL_BlendMode map_blendmode(const int blendmode)
343{
344   switch (blendmode)
345   {
346      case BLENDMODE_NONE:
347         return SDL_BLENDMODE_NONE;
348      case BLENDMODE_ALPHA:
349         return SDL_BLENDMODE_BLEND;
350      case BLENDMODE_RGB_MULTIPLY:
351         return SDL_BLENDMODE_MOD;
352      case BLENDMODE_ADD:
353         return SDL_BLENDMODE_ADD;
354      default:
355         osd_printf_warning("Unknown Blendmode %d", blendmode);
356   }
357   return SDL_BLENDMODE_NONE;
358}
359
360INLINE void set_coloralphamode(SDL_Texture  *texture_id, const render_color *color)
361{
362   UINT32 sr = (UINT32)(255.0f * color->r);
363   UINT32 sg = (UINT32)(255.0f * color->g);
364   UINT32 sb = (UINT32)(255.0f * color->b);
365   UINT32 sa = (UINT32)(255.0f * color->a);
366
367
368   if (color->r >= 1.0f && color->g >= 1.0f && color->b >= 1.0f && is_opaque(color->a))
369   {
370      SDL_SetTextureColorMod(texture_id, 0xFF, 0xFF, 0xFF);
371      SDL_SetTextureAlphaMod(texture_id, 0xFF);
372   }
373   /* coloring-only case */
374   else if (is_opaque(color->a))
375   {
376      SDL_SetTextureColorMod(texture_id, sr, sg, sb);
377      SDL_SetTextureAlphaMod(texture_id, 0xFF);
378   }
379   /* alpha and/or coloring case */
380   else if (!is_transparent(color->a))
381   {
382      SDL_SetTextureColorMod(texture_id, sr, sg, sb);
383      SDL_SetTextureAlphaMod(texture_id, sa);
384   }
385   else
386   {
387      SDL_SetTextureColorMod(texture_id, 0xFF, 0xFF, 0xFF);
388      SDL_SetTextureAlphaMod(texture_id, 0x00);
389   }
390}
391
392void texture_info::render_quad(const render_primitive *prim, const int x, const int y)
393{
394   SDL_Rect target_rect;
395
396   target_rect.x = x;
397   target_rect.y = y;
398   target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0);
399   target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0);
400
401   SDL_SetTextureBlendMode(m_texture_id, m_sdl_blendmode);
402   set_coloralphamode(m_texture_id, &prim->color);
403   SDL_RenderCopy(m_sdl_renderer,  m_texture_id, NULL, &target_rect);
404}
405
406void sdl_info13::render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y)
407{
408   SDL_Rect target_rect;
409
410   target_rect.x = x;
411   target_rect.y = y;
412   target_rect.w = round_nearest(prim->bounds.x1 - prim->bounds.x0);
413   target_rect.h = round_nearest(prim->bounds.y1 - prim->bounds.y0);
414
415   if (texture)
416   {
417      copy_info_t *copyinfo = texture->m_copyinfo;
418      copyinfo->time -= osd_ticks();
419      texture->render_quad(prim, x, y);
420      copyinfo->time += osd_ticks();
421
422      copyinfo->pixel_count += MAX(STAT_PIXEL_THRESHOLD , (texture->raw_width() * texture->raw_height()));
423      if (m_last_blit_pixels)
424      {
425         copyinfo->time += (m_last_blit_time * (INT64) (texture->raw_width() * texture->raw_height())) / (INT64) m_last_blit_pixels;
426      }
427      copyinfo->samples++;
428      copyinfo->perf = ( texture->m_copyinfo->pixel_count * (osd_ticks_per_second()/1000)) / texture->m_copyinfo->time;
429   }
430   else
431   {
432      UINT32 sr = (UINT32)(255.0f * prim->color.r);
433      UINT32 sg = (UINT32)(255.0f * prim->color.g);
434      UINT32 sb = (UINT32)(255.0f * prim->color.b);
435      UINT32 sa = (UINT32)(255.0f * prim->color.a);
436
437      SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)));
438      SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa);
439      SDL_RenderFillRect(m_sdl_renderer, &target_rect);
440   }
441}
442
443static int RendererSupportsFormat(SDL_Renderer *renderer, Uint32 format, Uint32 access, const char *sformat)
444{
445   int i;
446   SDL_Texture *texid;
447   for (i=0; fmt_support[i].format != 0; i++)
448   {
449      if (format == fmt_support[i].format)
450      {
451         return fmt_support[i].status;
452      }
453   }
454   /* not tested yet */
455   fmt_support[i].format = format;
456   fmt_support[i + 1].format = 0;
457   texid = SDL_CreateTexture(renderer, format, access, 16, 16);
458   if (texid)
459   {
460      fmt_support[i].status = 1;
461      SDL_DestroyTexture(texid);
462      return 1;
463   }
464   osd_printf_verbose("Pixelformat <%s> error %s \n", sformat, SDL_GetError());
465   osd_printf_verbose("Pixelformat <%s> not supported\n", sformat);
466   fmt_support[i].status = 0;
467   return 0;
468}
469
470//============================================================
471//  drawsdl_init
472//============================================================
473
474static void add_list(copy_info_t **head, copy_info_t *element, Uint32 bm)
475{
476   copy_info_t *newci = global_alloc(copy_info_t);
477   *newci = *element;
478
479   newci->bm_mask = bm;
480   newci->next = *head;
481   *head = newci;
482}
483
484static void expand_copy_info(copy_info_t *list)
485{
486   copy_info_t   *bi;
487
488   for (bi = list; bi->src_fmt != -1; bi++)
489   {
490      if (bi->bm_mask == BM_ALL)
491      {
492         add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_NONE);
493         add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_ADD);
494         add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_MOD);
495         add_list(&blit_info[bi->src_fmt], bi, SDL_BLENDMODE_BLEND);
496      }
497      else
498         add_list(&blit_info[bi->src_fmt], bi, bi->bm_mask);
499   }
500}
501
502static osd_renderer *drawsdl2_create(osd_window *window)
503{
504   return global_alloc(sdl_info13(window));
505}
506
507// FIXME: machine only used to access options.
508int drawsdl2_init(running_machine &machine, osd_draw_callbacks *callbacks)
509{
510   const char *stemp;
511
512   // fill in the callbacks
513   callbacks->exit = drawsdl2_exit;
514   callbacks->create = drawsdl2_create;
515
516   osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n");
517
518   expand_copy_info(blit_info_default);
519
520#if USE_OPENGL
521   // Load the GL library now - else MT will fail
522   stemp = downcast<sdl_options &>(machine.options()).gl_lib();
523#else
524   stemp = NULL;
525#endif
526   if (stemp != NULL && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
527      stemp = NULL;
528
529   // No fatalerror here since not all video drivers support GL !
530   if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==NULL
531      osd_printf_warning("Warning: Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
532   else
533      osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
534
535   return 0;
536}
537
538
539//============================================================
540//  drawsdl_exit
541//============================================================
542
543static void drawsdl2_exit(void)
544{
545   int i;
546   copy_info_t *bi, *freeme;
547   for (i = 0; i <= SDL_TEXFORMAT_LAST; i++)
548      for (bi = blit_info[i]; bi != NULL; )
549      {
550         if (bi->pixel_count)
551            osd_printf_verbose("%s -> %s %s blendmode 0x%02x, %d samples: %d KPixel/sec\n", bi->srcname, bi->dstname,
552                  bi->blitter->m_is_rot ? "rot" : "norot", bi->bm_mask, bi->samples,
553                  (int) bi->perf);
554         freeme = bi;
555         bi = bi->next;
556         global_free(freeme);
557      }
558}
559
560//============================================================
561//  sdl_info::create
562// a
563// a
564// a
565// a
566// a
567// a
568// a
569// a
570// a
571// a
572// a
573// a
574// a
575// a
576// a
577// a
578// a
579// a
580// a
581// a
582// a
583// a
584// a
585// a
586// a
587// a
588//============================================================
589
590int sdl_info13::create()
591{
592#if (SDLMAME_SDL2)
593   // create renderer
594
595   /* Enable bilinear filtering in case it is supported.
596    * This applies to all texture operations. However, artwort is pre-scaled
597    * and thus shouldn't be affected.
598    */
599   if (video_config.filter)
600   {
601      SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
602   }
603   else
604   {
605      SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
606   }
607
608   if (video_config.waitvsync)
609      m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
610   else
611      m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_ACCELERATED);
612
613   if (!m_sdl_renderer)
614   {
615      fatalerror("Error on creating renderer: %s\n", SDL_GetError());
616   }
617
618   //SDL_SelectRenderer(window().sdl_window);
619
620   m_blittimer = 3;
621
622   SDL_RenderPresent(m_sdl_renderer);
623   osd_printf_verbose("Leave sdl_info13::create\n");
624
625#else
626
627#endif
628   return 0;
629}
630
631
632//============================================================
633//  sdl_info::destroy
634//============================================================
635
636void sdl_info13::destroy()
637{
638   destroy_all_textures();
639}
640
641
642//============================================================
643//  drawsdl_xy_to_render_target
644//============================================================
645
646int sdl_info13::xy_to_render_target(int x, int y, int *xt, int *yt)
647{
648   *xt = x - m_last_hofs;
649   *yt = y - m_last_vofs;
650   if (*xt<0 || *xt >= m_blit_dim.width())
651      return 0;
652   if (*yt<0 || *yt >= m_blit_dim.height())
653      return 0;
654   return 1;
655}
656
657//============================================================
658//  drawsdl_destroy_all_textures
659//============================================================
660
661void sdl_info13::destroy_all_textures()
662{
663   if(window().m_primlist)
664   {
665      window().m_primlist->acquire_lock();
666      m_texlist.reset();
667      window().m_primlist->release_lock();
668   }
669   else
670      m_texlist.reset();
671}
672
673//============================================================
674//  sdl_info::draw
675//============================================================
676
677int sdl_info13::draw(int update)
678{
679   render_primitive *prim;
680   texture_info *texture=NULL;
681   float vofs, hofs;
682   int blit_pixels = 0;
683
684   if (video_config.novideo)
685   {
686      return 0;
687   }
688
689   osd_dim wdim = window().get_size();
690
691   if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
692   {
693      destroy_all_textures();
694      m_width = wdim.width();
695      m_height = wdim.height();
696      SDL_RenderSetViewport(m_sdl_renderer, NULL);
697      m_blittimer = 3;
698      clear_flags(FI_CHANGED);
699   }
700
701   //SDL_SelectRenderer(window().sdl_window);
702
703   if (m_blittimer > 0)
704   {
705      /* SDL Underlays need alpha = 0 ! */
706      SDL_SetRenderDrawBlendMode(m_sdl_renderer, SDL_BLENDMODE_NONE);
707      //SDL_SetRenderDrawColor(0,0,0,255);
708      SDL_SetRenderDrawColor(m_sdl_renderer, 0,0,0,0);
709      SDL_RenderFillRect(m_sdl_renderer, NULL);
710      m_blittimer--;
711   }
712
713   // compute centering parameters
714   vofs = hofs = 0.0f;
715
716   if (video_config.centerv || video_config.centerh)
717   {
718      int ch, cw;
719
720      ch = wdim.height();
721      cw = wdim.width();
722
723      if (video_config.centerv)
724      {
725         vofs = (ch - m_blit_dim.height()) / 2.0f;
726      }
727      if (video_config.centerh)
728      {
729         hofs = (cw - m_blit_dim.width()) / 2.0f;
730      }
731   }
732
733   m_last_hofs = hofs;
734   m_last_vofs = vofs;
735
736   window().m_primlist->acquire_lock();
737
738   // now draw
739   for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
740   {
741      Uint8 sr, sg, sb, sa;
742
743      switch (prim->type)
744      {
745         case render_primitive::LINE:
746            sr = (int)(255.0f * prim->color.r);
747            sg = (int)(255.0f * prim->color.g);
748            sb = (int)(255.0f * prim->color.b);
749            sa = (int)(255.0f * prim->color.a);
750
751            SDL_SetRenderDrawBlendMode(m_sdl_renderer, map_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags)));
752            SDL_SetRenderDrawColor(m_sdl_renderer, sr, sg, sb, sa);
753            SDL_RenderDrawLine(m_sdl_renderer, prim->bounds.x0 + hofs, prim->bounds.y0 + vofs,
754                  prim->bounds.x1 + hofs, prim->bounds.y1 + vofs);
755            break;
756         case render_primitive::QUAD:
757            texture = texture_update(*prim);
758            if (texture)
759               blit_pixels += (texture->raw_height() * texture->raw_width());
760            render_quad(texture, prim,
761                  round_nearest(hofs + prim->bounds.x0),
762                  round_nearest(vofs + prim->bounds.y0));
763            break;
764         default:
765            throw emu_fatalerror("Unexpected render_primitive type\n");
766      }
767   }
768
769   window().m_primlist->release_lock();
770
771   m_last_blit_pixels = blit_pixels;
772   m_last_blit_time = -osd_ticks();
773   SDL_RenderPresent(m_sdl_renderer);
774   m_last_blit_time += osd_ticks();
775
776   return 0;
777}
778
779
780//============================================================
781//  texture handling
782//============================================================
783
784//============================================================
785//  texture_compute_size and type
786//============================================================
787
788copy_info_t *texture_info::compute_size_type()
789{
790   copy_info_t *bi;
791   copy_info_t *result = NULL;
792   int maxperf = 0;
793
794   for (bi = blit_info[m_format]; bi != NULL; bi = bi->next)
795   {
796      if ((m_is_rotated == bi->blitter->m_is_rot)
797            && (m_sdl_blendmode == bi->bm_mask))
798      {
799         if (RendererSupportsFormat(m_sdl_renderer, bi->dst_fmt, m_sdl_access, bi->dstname))
800         {
801            int perf = bi->perf;
802            if (perf == 0)
803               return bi;
804            else if (perf > (maxperf * 102) / 100)
805            {
806               result = bi;
807               maxperf = perf;
808            }
809         }
810      }
811   }
812   if (result)
813      return result;
814   /* try last resort handlers */
815   for (bi = blit_info[m_format]; bi != NULL; bi = bi->next)
816   {
817      if ((m_is_rotated == bi->blitter->m_is_rot)
818         && (m_sdl_blendmode == bi->bm_mask))
819         if (RendererSupportsFormat(m_sdl_renderer, bi->dst_fmt, m_sdl_access, bi->dstname))
820            return bi;
821   }
822   //FIXME: crash implement a -do nothing handler */
823   return NULL;
824}
825
826// FIXME:
827const bool texture_info::is_pixels_owned() const
828{ // do we own / allocated it ?
829   return ((m_sdl_access == SDL_TEXTUREACCESS_STATIC)
830         && (m_copyinfo->blitter->m_is_passthrough));
831}
832
833//============================================================
834//  texture_info::matches
835//============================================================
836
837bool texture_info::matches(const render_primitive &prim, const quad_setup_data &setup)
838{
839   return  texinfo().base == prim.texture.base &&
840         texinfo().width == prim.texture.width &&
841         texinfo().height == prim.texture.height &&
842         texinfo().rowpixels == prim.texture.rowpixels &&
843         m_setup.dudx == setup.dudx &&
844         m_setup.dvdx == setup.dvdx &&
845         m_setup.dudy == setup.dudy &&
846         m_setup.dvdy == setup.dvdy &&
847         ((flags() ^ prim.flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0;
848}
849
850//============================================================
851//  texture_create
852//============================================================
853
854texture_info::texture_info(SDL_Renderer *renderer, const render_texinfo &texsource, const quad_setup_data &setup, UINT32 flags)
855{
856   // fill in the core data
857   m_sdl_renderer = renderer;
858   m_hash = texture_compute_hash(texsource, flags);
859   m_flags = flags;
860   m_texinfo = texsource;
861   m_texinfo.seqid = -1; // force set data
862   m_is_rotated = false;
863   m_setup = setup;
864   m_sdl_blendmode = map_blendmode(PRIMFLAG_GET_BLENDMODE(flags));
865   m_pitch = 0;
866
867   switch (PRIMFLAG_GET_TEXFORMAT(flags))
868   {
869      case TEXFORMAT_ARGB32:
870         m_format = SDL_TEXFORMAT_ARGB32;
871         break;
872      case TEXFORMAT_RGB32:
873         m_format = texsource.palette ? SDL_TEXFORMAT_RGB32_PALETTED : SDL_TEXFORMAT_RGB32;
874         break;
875      case TEXFORMAT_PALETTE16:
876         m_format = SDL_TEXFORMAT_PALETTE16;
877         break;
878      case TEXFORMAT_PALETTEA16:
879         m_format = SDL_TEXFORMAT_PALETTE16A;
880         break;
881      case TEXFORMAT_YUY16:
882         m_format = texsource.palette ? SDL_TEXFORMAT_YUY16_PALETTED : SDL_TEXFORMAT_YUY16;
883         break;
884
885      default:
886         osd_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags));
887   }
888
889   if (setup.rotwidth != m_texinfo.width || setup.rotheight != m_texinfo.height
890         || setup.dudx < 0 || setup.dvdy < 0)
891      m_is_rotated = true;
892   else
893      m_is_rotated = false;
894
895   //m_sdl_access = SDL_TEXTUREACCESS_STATIC;
896   m_sdl_access = SDL_TEXTUREACCESS_STREAMING;
897
898   // Watch out for 0x0 textures ...
899   if (!m_setup.rotwidth || !m_setup.rotheight)
900      osd_printf_warning("Trying to create texture with zero dim\n");
901
902   // set copy_info
903
904   m_copyinfo = compute_size_type();
905
906   m_texture_id = SDL_CreateTexture(m_sdl_renderer, m_copyinfo->dst_fmt, m_sdl_access,
907         m_setup.rotwidth, m_setup.rotheight);
908
909   if (!m_texture_id)
910      osd_printf_error("Error creating texture: %d x %d, pixelformat %s error: %s\n", m_setup.rotwidth, m_setup.rotheight,
911            m_copyinfo->dstname, SDL_GetError());
912
913   if (m_sdl_access == SDL_TEXTUREACCESS_STATIC)
914   {
915      if (m_copyinfo->blitter->m_is_passthrough)
916         m_pixels = NULL;
917      else
918         m_pixels = malloc(m_setup.rotwidth * m_setup.rotheight * m_copyinfo->blitter->m_dest_bpp);
919   }
920   m_last_access = osd_ticks();
921
922}
923
924texture_info::~texture_info()
925{
926   if ( is_pixels_owned() && (m_pixels != NULL) )
927      free(m_pixels);
928   SDL_DestroyTexture(m_texture_id);
929}
930
931//============================================================
932//  texture_set_data
933//============================================================
934
935void texture_info::set_data(const render_texinfo &texsource, const UINT32 flags)
936{
937   m_copyinfo->time -= osd_ticks();
938   if (m_sdl_access == SDL_TEXTUREACCESS_STATIC)
939   {
940      if ( m_copyinfo->blitter->m_is_passthrough )
941      {
942         m_pixels = texsource.base;
943         m_pitch = m_texinfo.rowpixels * m_copyinfo->blitter->m_dest_bpp;
944      }
945      else
946      {
947         m_pitch = m_setup.rotwidth * m_copyinfo->blitter->m_dest_bpp;
948         m_copyinfo->blitter->texop(this, &texsource);
949      }
950      SDL_UpdateTexture(m_texture_id, NULL, m_pixels, m_pitch);
951   }
952   else
953   {
954      SDL_LockTexture(m_texture_id, NULL, (void **) &m_pixels, &m_pitch);
955      if ( m_copyinfo->blitter->m_is_passthrough )
956      {
957         UINT8 *src = (UINT8 *) texsource.base;
958         UINT8 *dst = (UINT8 *) m_pixels;
959         int spitch = texsource.rowpixels * m_copyinfo->blitter->m_dest_bpp;
960         int num = texsource.width * m_copyinfo->blitter->m_dest_bpp;
961         int h = texsource.height;
962         while (h--) {
963            memcpy(dst, src, num);
964            src += spitch;
965            dst += m_pitch;
966         }
967      }
968      else
969         m_copyinfo->blitter->texop(this, &texsource);
970      SDL_UnlockTexture(m_texture_id);
971   }
972   m_copyinfo->time += osd_ticks();
973}
974
975//============================================================
976//  compute rotation setup
977//============================================================
978
979void quad_setup_data::compute(const render_primitive &prim, const int prescale)
980{
981   const render_quad_texuv *texcoords = &prim.texcoords;
982   int texwidth = prim.texture.width;
983   int texheight = prim.texture.height;
984   float fdudx, fdvdx, fdudy, fdvdy;
985   float width, height;
986   float fscale;
987   /* determine U/V deltas */
988   if ((PRIMFLAG_GET_SCREENTEX(prim.flags)))
989      fscale = (float) prescale;
990   else
991      fscale = 1.0f;
992
993   fdudx = (texcoords->tr.u - texcoords->tl.u) / fscale; // a a11
994   fdvdx = (texcoords->tr.v - texcoords->tl.v) / fscale; // c a21
995   fdudy = (texcoords->bl.u - texcoords->tl.u) / fscale; // b a12
996   fdvdy = (texcoords->bl.v - texcoords->tl.v) / fscale; // d a22
997
998#if 0
999   printf("tl.u %f tl.v %f\n", texcoords->tl.u, texcoords->tl.v);
1000   printf("tr.u %f tr.v %f\n", texcoords->tr.u, texcoords->tr.v);
1001   printf("bl.u %f bl.v %f\n", texcoords->bl.u, texcoords->bl.v);
1002   printf("br.u %f br.v %f\n", texcoords->br.u, texcoords->br.v);
1003   /* compute start and delta U,V coordinates now */
1004#endif
1005
1006   dudx = round_nearest(65536.0f * fdudx);
1007   dvdx = round_nearest(65536.0f * fdvdx);
1008   dudy = round_nearest(65536.0f * fdudy);
1009   dvdy = round_nearest(65536.0f * fdvdy);
1010   startu = round_nearest(65536.0f * (float) texwidth * texcoords->tl.u);
1011   startv = round_nearest(65536.0f * (float) texheight * texcoords->tl.v);
1012
1013   /* clamp to integers */
1014
1015   width = fabs((fdudx * (float) (texwidth) + fdvdx * (float) (texheight)) * fscale * fscale);
1016   height = fabs((fdudy * (float)(texwidth) + fdvdy * (float) (texheight)) * fscale * fscale);
1017
1018   rotwidth = width;
1019   rotheight = height;
1020
1021   startu += (dudx + dudy) / 2;
1022   startv += (dvdx + dvdy) / 2;
1023
1024}
1025
1026//============================================================
1027//  texture_find
1028//============================================================
1029
1030texture_info *sdl_info13::texture_find(const render_primitive &prim, const quad_setup_data &setup)
1031{
1032   HashT texhash = texture_compute_hash(prim.texture, prim.flags);
1033   texture_info *texture;
1034   osd_ticks_t now = osd_ticks();
1035
1036   // find a match
1037   for (texture = m_texlist.first(); texture != NULL; )
1038      if (texture->hash() == texhash &&
1039         texture->matches(prim, setup))
1040      {
1041         /* would we choose another blitter based on performance ? */
1042         if ((texture->m_copyinfo->samples & 0x7f) == 0x7f)
1043         {
1044            if (texture->m_copyinfo != texture->compute_size_type())
1045               return NULL;
1046         }
1047         texture->m_last_access = now;
1048         return texture;
1049      }
1050      else
1051      {
1052         /* free resources not needed any longer? */
1053         texture_info *expire = texture;
1054         texture = texture->next();
1055         if (now - expire->m_last_access > osd_ticks_per_second())
1056            m_texlist.remove(*expire);
1057      }
1058
1059   // nothing found
1060   return NULL;
1061}
1062
1063//============================================================
1064//  texture_update
1065//============================================================
1066
1067texture_info * sdl_info13::texture_update(const render_primitive &prim)
1068{
1069   quad_setup_data setup;
1070   texture_info *texture;
1071
1072   setup.compute(prim, window().prescale());
1073
1074   texture = texture_find(prim, setup);
1075
1076   // if we didn't find one, create a new texture
1077   if (texture == NULL && prim.texture.base != NULL)
1078   {
1079      texture = global_alloc(texture_info(m_sdl_renderer, prim.texture, setup, prim.flags));
1080      /* add us to the texture list */
1081      m_texlist.prepend(*texture);
1082
1083   }
1084
1085   if (texture != NULL)
1086   {
1087      if (prim.texture.base != NULL && texture->texinfo().seqid != prim.texture.seqid)
1088      {
1089         texture->texinfo().seqid = prim.texture.seqid;
1090         // if we found it, but with a different seqid, copy the data
1091         texture->set_data(prim.texture, prim.flags);
1092      }
1093
1094   }
1095   return texture;
1096}
trunk/src/osd/sdl/drawbgfx.c
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Miodrag Milanovic
3//============================================================
4//
5//  drawbgfx.c - BGFX drawer
6//
7//============================================================
8
9#ifdef SDLMAME_WIN32
10// standard windows headers
11#define __STDC_LIMIT_MACROS
12#define __STDC_FORMAT_MACROS
13#define __STDC_CONSTANT_MACROS
14#define WIN32_LEAN_AND_MEAN
15#include <windows.h>
16#endif
17
18// standard C headers
19#include <math.h>
20#include <stdio.h>
21
22// MAME headers
23#include "osdcomm.h"
24#include "emu.h"
25#include "options.h"
26#include "emuopts.h"
27
28// standard SDL headers
29#include "sdlinc.h"
30#include "modules/lib/osdlib.h"
31
32// OSD headers
33#include "osdsdl.h"
34#include "window.h"
35
36#include <bgfxplatform.h>
37#include <bgfx.h>
38
39//============================================================
40//  DEBUGGING
41//============================================================
42
43//============================================================
44//  CONSTANTS
45//============================================================
46
47//============================================================
48//  MACROS
49//============================================================
50
51//============================================================
52//  TYPES
53//============================================================
54
55//============================================================
56//  INLINES
57//============================================================
58
59
60//============================================================
61//  PROTOTYPES
62//============================================================
63
64// core functions
65
66static void drawbgfx_exit(void);
67
68//============================================================
69//  Textures
70//============================================================
71
72/* sdl_info is the information about SDL for the current screen */
73class sdl_info_bgfx : public osd_renderer
74{
75public:
76   sdl_info_bgfx(osd_window *w)
77   : osd_renderer(w, FLAG_NONE), m_blittimer(0), m_renderer(NULL),
78      m_blitwidth(0), m_blitheight(0),
79      m_last_hofs(0), m_last_vofs(0),
80      m_last_blit_time(0), m_last_blit_pixels(0)
81   {}
82
83   /* virtual */ int create();
84   /* virtual */ int draw(const int update);
85   /* virtual */ int xy_to_render_target(const int x, const int y, int *xt, int *yt);
86   /* virtual */ void destroy();
87   /* virtual */ render_primitive_list *get_primitives()
88   {
89      int nw = 0; int nh = 0;
90      window().blit_surface_size(nw, nh);
91      if (nw != m_blitwidth || nh != m_blitheight)
92      {
93         m_blitwidth = nw; m_blitheight = nh;
94         notify_changed();
95      }
96      window().target()->set_bounds(m_blitwidth, m_blitheight, window().aspect());
97      return &window().target()->get_primitives();
98   }
99
100   // void render_quad(texture_info *texture, const render_primitive *prim, const int x, const int y);
101
102   //texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
103   //texture_info *texture_update(const render_primitive &prim);
104
105   INT32           m_blittimer;
106
107   SDL_Renderer *  m_renderer;
108   //simple_list<texture_info>  m_texlist;                // list of active textures
109
110   int             m_blitwidth;
111   int             m_blitheight;
112   float           m_last_hofs;
113   float           m_last_vofs;
114
115   // Stats
116   INT64           m_last_blit_time;
117   INT64           m_last_blit_pixels;
118
119   // Original display_mode
120   SDL_DisplayMode m_original_mode;
121};
122
123//============================================================
124//  Static Variables
125//============================================================
126
127//============================================================
128//  drawbgfx_init
129//============================================================
130
131static osd_renderer *drawbgfx_create(osd_window *window)
132{
133   return global_alloc(sdl_info_bgfx(window));
134}
135
136
137int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks)
138{
139   // fill in the callbacks
140   callbacks->exit = drawbgfx_exit;
141   callbacks->create = drawbgfx_create;
142
143   return 0;
144}
145
146//============================================================
147//  sdl_info_bgfx::create
148//============================================================
149
150int sdl_info_bgfx::create()
151{
152   // create renderer
153
154   int width = 0; int height = 0;
155
156   window().get_size(width, height);
157   m_blittimer = 3;
158
159   bgfx::sdlSetWindow(window().sdl_window());
160   bgfx::init();
161   bgfx::reset(width, height, BGFX_RESET_VSYNC);
162
163   // Enable debug text.
164   bgfx::setDebug(BGFX_DEBUG_STATS);// BGFX_DEBUG_TEXT);
165   osd_printf_verbose("Leave drawsdl2_window_create\n");
166   return 0;
167}
168
169//============================================================
170//  drawsdl_xy_to_render_target
171//============================================================
172
173int sdl_info_bgfx::xy_to_render_target(int x, int y, int *xt, int *yt)
174{
175   *xt = x - m_last_hofs;
176   *yt = y - m_last_vofs;
177   if (*xt<0 || *xt >= m_blitwidth)
178      return 0;
179   if (*yt<0 || *yt >= m_blitheight)
180      return 0;
181   return 1;
182}
183
184//============================================================
185//  sdl_info_bgfx::draw
186//============================================================
187
188int sdl_info_bgfx::draw(int update)
189{
190   //if (has_flags(FI_CHANGED) || (window().width() != m_last_width) || (window().height() != m_last_height))
191      // do something
192   //clear_flags(FI_CHANGED);
193
194   bgfx::setViewClear(0
195      , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
196      , 0x000000ff
197      , 1.0f
198      , 0
199      );
200   // Set view 0 default viewport.
201   bgfx::setViewRect(0, 0, 0, m_blitwidth, m_blitheight);
202
203   // This dummy draw call is here to make sure that view 0 is cleared
204   // if no other draw calls are submitted to view 0.
205   bgfx::submit(0);
206
207   window().m_primlist->acquire_lock();
208   window().m_primlist->release_lock();
209   // Advance to next frame. Rendering thread will be kicked to
210   // process submitted rendering primitives.
211   bgfx::frame();
212
213   return 0;
214}
215
216//============================================================
217//  drawbgfx_exit
218//============================================================
219
220static void drawbgfx_exit(void)
221{
222}
223
224//============================================================
225//  sdl_info_bgfx::destroy
226//============================================================
227
228void sdl_info_bgfx::destroy()
229{
230   // free the memory in the window
231
232   // destroy_all_textures();
233
234   // Shutdown bgfx.
235   bgfx::shutdown();
236}
trunk/src/osd/sdl/drawogl.c
r244651r244652
1//============================================================
2//
3//  drawogl.c - SDL software and OpenGL implementation
4//
5//  Copyright (c) 1996-2014, Nicola Salmoria and the MAME Team.
6//  Visit http://mamedev.org for licensing and usage restrictions.
7//
8//  SDLMAME by Olivier Galibert and R. Belmont
9//
10//  Note: D3D9 goes to a lot of trouble to fiddle with MODULATE
11//        mode on textures.  That is the default in OpenGL so we
12//        don't have to touch it.
13//
14//============================================================
15
16// standard C headers
17#include <math.h>
18#include <stdio.h>
19
20// MAME headers
21#include "osdcomm.h"
22#include "emu.h"
23#include "options.h"
24#include "emuopts.h"
25
26#ifndef OSD_WINDOWS
27// standard SDL headers
28#define TOBEMIGRATED 1
29#include "sdlinc.h"
30#endif
31
32// OpenGL headers
33#include "modules/opengl/osd_opengl.h"
34
35#ifdef OSD_WINDOWS
36#define SDLMAME_SDL2 1
37#ifndef USE_DISPATCH_GL
38#include "GL/wglext.h"
39#endif
40#endif
41
42#include "modules/lib/osdlib.h"
43#include "modules/lib/osdobj_common.h"
44
45
46#include "modules/opengl/gl_shader_tool.h"
47#include "modules/opengl/gl_shader_mgr.h"
48
49#if defined(SDLMAME_MACOSX)
50#ifndef APIENTRY
51#define APIENTRY
52#endif
53#ifndef APIENTRYP
54#define APIENTRYP APIENTRY *
55#endif
56
57typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
58typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum, GLuint);
59typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum, GLsizeiptr, const GLvoid *, GLenum);
60typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum, GLintptr, GLsizeiptr, const GLvoid *);
61typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum, GLenum);
62typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum);
63typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei, const GLuint *);
64typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
65typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
66typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum m_target, GLuint framebuffer);
67typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
68typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
69typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum m_target);
70typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum m_target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
71typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
72typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum m_target, GLuint renderbuffer);
73typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum m_target, GLenum internalformat, GLsizei width, GLsizei height);
74typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum m_target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
75typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
76#endif
77
78// make sure the extensions compile OK everywhere
79#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
80#define GL_TEXTURE_STORAGE_HINT_APPLE     0x85bc
81#endif
82
83#ifndef GL_STORAGE_CACHED_APPLE
84#define GL_STORAGE_CACHED_APPLE           0x85be
85#endif
86
87#ifndef GL_UNPACK_CLIENT_STORAGE_APPLE
88#define GL_UNPACK_CLIENT_STORAGE_APPLE    0x85b2
89#endif
90
91#ifndef GL_TEXTURE_RECTANGLE_ARB
92#define GL_TEXTURE_RECTANGLE_ARB          0x84F5
93#endif
94
95#ifndef GL_PIXEL_UNPACK_BUFFER_ARB
96#define GL_PIXEL_UNPACK_BUFFER_ARB        0x88EC
97#endif
98
99#ifndef GL_STREAM_DRAW
100#define GL_STREAM_DRAW                    0x88E0
101#endif
102
103#ifndef GL_WRITE_ONLY
104#define GL_WRITE_ONLY                     0x88B9
105#endif
106
107#ifndef GL_ARRAY_BUFFER_ARB
108#define GL_ARRAY_BUFFER_ARB               0x8892
109#endif
110
111#ifndef GL_PIXEL_UNPACK_BUFFER_ARB
112#define GL_PIXEL_UNPACK_BUFFER_ARB        0x88EC
113#endif
114
115#ifndef GL_FRAMEBUFFER_EXT
116#define GL_FRAMEBUFFER_EXT              0x8D40
117#define GL_FRAMEBUFFER_COMPLETE_EXT         0x8CD5
118#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT    0x8CD6
119#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT    0x8CD7
120#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT  0x8CD8
121#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT        0x8CD9
122#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT       0x8CDA
123#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT   0x8CDB
124#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT   0x8CDC
125#define GL_FRAMEBUFFER_UNSUPPORTED_EXT          0x8CDD
126#define GL_RENDERBUFFER_EXT             0x8D41
127#define GL_DEPTH_COMPONENT16                0x81A5
128#define GL_DEPTH_COMPONENT24                0x81A6
129#define GL_DEPTH_COMPONENT32                0x81A7
130#endif
131
132#define HASH_SIZE       ((1<<10)+1)
133#define OVERFLOW_SIZE   (1<<10)
134
135// OSD headers
136#ifndef OSD_WINDOWS
137#include "osdsdl.h"
138#include "window.h"
139#else
140#include "../windows/window.h"
141typedef UINT64 HashT;
142#endif
143
144//============================================================
145//  DEBUGGING
146//============================================================
147
148#define DEBUG_MODE_SCORES   0
149#define USE_WIN32_STYLE_LINES   0   // use the same method baseline does - yields somewhat nicer vectors but a little buggy
150
151//============================================================
152//  CONSTANTS
153//============================================================
154
155enum
156{
157   TEXTURE_TYPE_NONE,
158   TEXTURE_TYPE_PLAIN,
159   TEXTURE_TYPE_DYNAMIC,
160   TEXTURE_TYPE_SHADER,
161   TEXTURE_TYPE_SURFACE
162};
163
164
165//============================================================
166//  MACROS
167//============================================================
168
169#ifdef OSD_WINDOWS
170// texture formats
171// This used to be an enum, but these are now defines so we can use them as
172// preprocessor conditionals
173#define SDL_TEXFORMAT_ARGB32            (0) // non-16-bit textures or specials
174#define SDL_TEXFORMAT_RGB32             (1)
175#define SDL_TEXFORMAT_RGB32_PALETTED    (2)
176#define SDL_TEXFORMAT_YUY16             (3)
177#define SDL_TEXFORMAT_YUY16_PALETTED    (4)
178#define SDL_TEXFORMAT_PALETTE16         (5)
179#define SDL_TEXFORMAT_RGB15             (6)
180#define SDL_TEXFORMAT_RGB15_PALETTED    (7)
181#define SDL_TEXFORMAT_PALETTE16A        (8)
182// special texture formats for 16bpp texture destination support, do not use
183// to address the tex properties / tex functions arrays!
184#define SDL_TEXFORMAT_PALETTE16_ARGB1555    (16)
185#define SDL_TEXFORMAT_RGB15_ARGB1555        (17)
186#define SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555   (18)
187#endif
188
189#define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0)
190#define GL_NO_PRIMITIVE -1
191
192//============================================================
193//  TYPES
194//============================================================
195
196#if (SDLMAME_SDL2)
197
198#ifdef OSD_WINDOWS
199class win_gl_context : public osd_gl_context
200{
201public:
202   win_gl_context(HWND window) : osd_gl_context(), m_context(0), m_window(NULL), m_hdc(0)
203   {
204      m_error[0] = 0;
205
206      this->wglGetProcAddress = (PROC WINAPI (*)(LPCSTR lpszProc)) GetProcAddress(m_module, "wglGetProcAddress");
207      this->wglCreateContext = (HGLRC WINAPI (*)(HDC hdc)) GetProcAddress(m_module, "wglCreateContext");
208      this->wglDeleteContext = (BOOL WINAPI (*)(HGLRC hglrc)) GetProcAddress(m_module, "wglDeleteContext");
209      this->wglMakeCurrent = (BOOL WINAPI (*)(HDC hdc, HGLRC hglrc)) GetProcAddress(m_module, "wglMakeCurrent");
210
211      m_hdc = GetDC(window);
212      if (!setupPixelFormat(m_hdc))
213      {
214         m_context = wglCreateContext(m_hdc);
215         if  (!m_context)
216         {
217            FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, m_error, 255, NULL);
218            return;
219         }
220         wglMakeCurrent(m_hdc, m_context);
221      }
222   }
223
224   virtual ~win_gl_context()
225   {
226      wglDeleteContext(m_context);
227      ReleaseDC(m_window, m_hdc);
228   }
229
230   virtual void MakeCurrent()
231   {
232      wglMakeCurrent(m_hdc, m_context);
233   }
234
235   virtual const char *LastErrorMsg()
236   {
237      if (m_error[0] == 0)
238         return NULL;
239      else
240         return m_error;
241   }
242
243   virtual void *getProcAddress(const char *proc)
244   {
245      void *ret = (void *) GetProcAddress(m_module, proc);
246      if (ret == NULL)
247         ret = (void *) wglGetProcAddress(proc);
248      return ret;
249   }
250
251   virtual int SetSwapInterval(const int swap)
252   {
253      // FIXME: Missing!
254      return 0;
255   }
256
257   virtual void SwapBuffer()
258   {
259      SwapBuffers(m_hdc);
260      //wglSwapLayerBuffers(GetDC(window().m_hwnd), WGL_SWAP_MAIN_PLANE);
261   }
262
263   static void load_library()
264   {
265      m_module = LoadLibraryA("opengl32.dll");
266   }
267
268private:
269
270   int setupPixelFormat(HDC hDC)
271   {
272       PIXELFORMATDESCRIPTOR pfd = {
273           sizeof(PIXELFORMATDESCRIPTOR),  /* size */
274           1,                              /* version */
275           PFD_SUPPORT_OPENGL |
276           PFD_DRAW_TO_WINDOW |
277           PFD_DOUBLEBUFFER,               /* support double-buffering */
278           PFD_TYPE_RGBA,                  /* color type */
279           32,                             /* prefered color depth */
280           0, 0, 0, 0, 0, 0,               /* color bits (ignored) */
281           0,                              /* no alpha buffer */
282           0,                              /* alpha bits (ignored) */
283           0,                              /* no accumulation buffer */
284           0, 0, 0, 0,                     /* accum bits (ignored) */
285           16,                             /* depth buffer */
286           0,                              /* no stencil buffer */
287           0,                              /* no auxiliary buffers */
288           PFD_MAIN_PLANE,                 /* main layer */
289           0,                              /* reserved */
290           0, 0, 0,                        /* no layer, visible, damage masks */
291       };
292       int pixelFormat;
293
294       pixelFormat = ChoosePixelFormat(hDC, &pfd);
295       if (pixelFormat == 0) {
296           strcpy(m_error, "ChoosePixelFormat failed");
297           return 1;
298       }
299
300       if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) {
301           strcpy(m_error, "SetPixelFormat failed.");
302           return 1;
303       }
304       return 0;
305   }
306
307
308   HGLRC m_context;
309   HWND m_window;
310   HDC m_hdc;
311   char m_error[256];
312
313   PROC WINAPI (*wglGetProcAddress)(LPCSTR lpszProc);
314   HGLRC WINAPI (*wglCreateContext)(HDC hdc);
315   BOOL WINAPI (*wglDeleteContext)(HGLRC hglrc);
316   BOOL WINAPI (*wglMakeCurrent)(HDC hdc, HGLRC hglrc);
317
318   static HMODULE m_module;
319};
320
321HMODULE win_gl_context::m_module;
322
323
324#else
325class sdl_gl_context : public osd_gl_context
326{
327public:
328   sdl_gl_context(SDL_Window *window) : osd_gl_context(), m_context(0), m_window(window)
329   {
330      m_error[0] = 0;
331      m_context = SDL_GL_CreateContext(window);
332      if  (!m_context)
333      {
334         snprintf(m_error,255, "OpenGL not supported on this driver: %s", SDL_GetError());
335      }
336   }
337   virtual ~sdl_gl_context()
338   {
339      SDL_GL_DeleteContext(m_context);
340   }
341   virtual void MakeCurrent()
342   {
343      SDL_GL_MakeCurrent(m_window, m_context);
344   }
345
346   virtual int SetSwapInterval(const int swap)
347   {
348      return SDL_GL_SetSwapInterval(swap);
349   }
350
351   virtual const char *LastErrorMsg()
352   {
353      if (m_error[0] == 0)
354         return NULL;
355      else
356         return m_error;
357   }
358   virtual void *getProcAddress(const char *proc)
359   {
360      return SDL_GL_GetProcAddress(proc);
361   }
362
363   virtual void SwapBuffer()
364   {
365      SDL_GL_SwapWindow(m_window);
366   }
367
368private:
369   SDL_GLContext m_context;
370   SDL_Window *m_window;
371   char m_error[256];
372};
373#endif
374#else
375// SDL 1.2
376class sdl12_gl_context : public osd_gl_context
377{
378public:
379   sdl12_gl_context(SDL_Surface *window) : osd_gl_context(), m_window(window)
380   {
381      m_error[0] = 0;
382   }
383   virtual ~sdl12_gl_context()
384   {
385   }
386   virtual void MakeCurrent()
387   {
388   }
389
390   virtual int SetSwapInterval(const int swap)
391   {
392      // Not supported on 1.2
393      return 0;
394   }
395
396   virtual const char *LastErrorMsg()
397   {
398      if (m_error[0] == 0)
399         return NULL;
400      else
401         return m_error;
402   }
403
404   virtual void *getProcAddress(const char *proc)
405   {
406      return SDL_GL_GetProcAddress(proc);
407   }
408
409   virtual void SwapBuffer()
410   {
411      SDL_GL_SwapBuffers();
412   }
413
414private:
415   SDL_Surface *m_window;
416   char m_error[256];
417};
418
419
420#endif
421
422//============================================================
423//  Textures
424//============================================================
425
426/* texture_info holds information about a texture */
427class texture_info
428{
429public:
430   texture_info()
431   :   hash(0), flags(0), rawwidth(0), rawheight(0),
432      rawwidth_create(0), rawheight_create(0),
433      type(0), format(0), borderpix(0), xprescale(0), yprescale(0), nocopy(0),
434      texture(0), texTarget(0), texpow2(0), mpass_dest_idx(0), pbo(0), data(NULL),
435      data_own(0), texCoordBufferName(0)
436   {
437      for (int i=0; i<2; i++)
438      {
439         mpass_textureunit[i] = 0;
440         mpass_texture_mamebm[i] = 0;
441         mpass_fbo_mamebm[i] = 0;
442         mpass_texture_scrn[i] = 0;
443         mpass_fbo_scrn[i] = 0;
444      }
445      for (int i=0; i<8; i++)
446         texCoord[i] = 0.0f;
447   }
448
449   HashT               hash;               // hash value for the texture (must be >= pointer size)
450   UINT32              flags;              // rendering flags
451   render_texinfo      texinfo;            // copy of the texture info
452   int                 rawwidth, rawheight;    // raw width/height of the texture
453   int                 rawwidth_create;    // raw width/height, pow2 compatible, if needed
454   int                 rawheight_create;   // (create and initial set the texture, not for copy!)
455   int                 type;               // what type of texture are we?
456   int                 format;             // texture format
457   int                 borderpix;          // do we have a 1 pixel border?
458   int                 xprescale;          // what is our X prescale factor?
459   int                 yprescale;          // what is our Y prescale factor?
460   int                 nocopy;             // must the texture date be copied?
461
462   UINT32              texture;            // OpenGL texture "name"/ID
463
464   GLenum              texTarget;          // OpenGL texture target
465   int                 texpow2;            // Is this texture pow2
466
467   UINT32              mpass_dest_idx;         // Multipass dest idx [0..1]
468   UINT32              mpass_textureunit[2];   // texture unit names for GLSL
469
470   UINT32              mpass_texture_mamebm[2];// Multipass OpenGL texture "name"/ID for the shader
471   UINT32              mpass_fbo_mamebm[2];    // framebuffer object for this texture, multipass
472   UINT32              mpass_texture_scrn[2];  // Multipass OpenGL texture "name"/ID for the shader
473   UINT32              mpass_fbo_scrn[2];      // framebuffer object for this texture, multipass
474
475   UINT32              pbo;                    // pixel buffer object for this texture (DYNAMIC only!)
476   UINT32              *data;                  // pixels for the texture
477   int                 data_own;               // do we own / allocated it ?
478   GLfloat             texCoord[8];
479   GLuint              texCoordBufferName;
480
481};
482
483/* sdl_info is the information about SDL for the current screen */
484class sdl_info_ogl : public osd_renderer
485{
486public:
487   sdl_info_ogl(osd_window *window)
488   : osd_renderer(window, FLAG_NEEDS_OPENGL), m_blittimer(0),
489      m_width(0), m_height(0),
490      m_blit_dim(0, 0),
491      m_gl_context(NULL),
492      m_initialized(0),
493      m_last_blendmode(0),
494      m_texture_max_width(0),
495      m_texture_max_height(0),
496      m_texpoweroftwo(0),
497      m_usevbo(0), m_usepbo(0), m_usefbo(0), m_useglsl(0), m_glsl(NULL),
498      m_glsl_program_num(0),
499      m_glsl_program_mb2sc(0),
500      m_usetexturerect(0),
501      m_init_context(0),
502      m_last_hofs(0.0f),
503      m_last_vofs(0.0f),
504      m_surf_w(0),
505      m_surf_h(0)
506   {
507      for (int i=0; i < HASH_SIZE + OVERFLOW_SIZE; i++)
508         m_texhash[i] = NULL;
509      for (int i=0; i < 2*GLSL_SHADER_MAX; i++)
510         m_glsl_program[i] = 0;
511      for (int i=0; i < 8; i++)
512         m_texVerticex[i] = 0.0f;
513   }
514
515   /* virtual */ int create();
516   /* virtual */ int draw(const int update);
517
518   /* virtual */ int xy_to_render_target(const int x, const int y, int *xt, int *yt);
519   /* virtual */ void destroy();
520   /* virtual */ render_primitive_list *get_primitives()
521   {
522#ifdef OSD_WINDOWS
523      osd_dim nd = window().get_size();
524#else
525      osd_dim nd = window().blit_surface_size();
526#endif
527      if (nd != m_blit_dim)
528      {
529         m_blit_dim = nd;
530         notify_changed();
531      }
532      window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
533      return &window().target()->get_primitives();
534   }
535
536   /* virtual */ void save() { }
537   /* virtual */ void record() { }
538   /* virtual */ void toggle_fsfx() { }
539
540private:
541   void destroy_all_textures();
542
543   void loadGLExtensions();
544   void initialize_gl();
545   void set_blendmode(int blendmode);
546   void texture_compute_type_subroutine(const render_texinfo *texsource, texture_info *texture, UINT32 flags);
547   void texture_compute_size_subroutine(texture_info *texture, UINT32 flags,
548            UINT32 width, UINT32 height,
549            int* p_width, int* p_height, int* p_width_create, int* p_height_create);
550   void texture_compute_size_type(const render_texinfo *texsource, texture_info *texture, UINT32 flags);
551   texture_info *texture_create(const render_texinfo *texsource, UINT32 flags);
552   int texture_shader_create(const render_texinfo *texsource, texture_info *texture, UINT32 flags);
553   texture_info *texture_find(const render_primitive *prim);
554   void texture_coord_update(texture_info *texture, const render_primitive *prim, int shaderIdx);
555   void texture_mpass_flip(texture_info *texture, int shaderIdx);
556   void texture_shader_update(texture_info *texture, render_container *container,  int shaderIdx);
557   texture_info * texture_update(const render_primitive *prim, int shaderIdx);
558   void texture_disable(texture_info * texture);
559   void texture_all_disable();
560
561   INT32           m_blittimer;
562   int             m_width;
563   int             m_height;
564   osd_dim         m_blit_dim;
565
566   osd_gl_context   *m_gl_context;
567
568   int             m_initialized;        // is everything well initialized, i.e. all GL stuff etc.
569   // 3D info (GL mode only)
570   texture_info *  m_texhash[HASH_SIZE + OVERFLOW_SIZE];
571   int             m_last_blendmode;     // previous blendmode
572   INT32           m_texture_max_width;      // texture maximum width
573   INT32           m_texture_max_height;     // texture maximum height
574   int             m_texpoweroftwo;          // must textures be power-of-2 sized?
575   int             m_usevbo;         // runtime check if VBO is available
576   int             m_usepbo;         // runtime check if PBO is available
577   int             m_usefbo;         // runtime check if FBO is available
578   int             m_useglsl;        // runtime check if GLSL is available
579
580   glsl_shader_info *m_glsl;             // glsl_shader_info
581
582   GLhandleARB     m_glsl_program[2*GLSL_SHADER_MAX];  // GLSL programs, or 0
583   int             m_glsl_program_num;   // number of GLSL programs
584   int             m_glsl_program_mb2sc; // GLSL program idx, which transforms
585                              // the mame-bitmap. screen-bitmap (size/rotation/..)
586                              // All progs <= glsl_program_mb2sc using the mame bitmap
587                              // as input, otherwise the screen bitmap.
588                              // All progs >= glsl_program_mb2sc using the screen bitmap
589                              // as output, otherwise the mame bitmap.
590   int             m_usetexturerect;     // use ARB_texture_rectangle for non-power-of-2, general use
591
592   int             m_init_context;       // initialize context before next draw
593
594   float           m_last_hofs;
595   float           m_last_vofs;
596
597   // Static vars from draogl_window_dra
598   INT32           m_surf_w;
599   INT32           m_surf_h;
600   GLfloat         m_texVerticex[8];
601};
602
603/* line_aa_step is used for drawing antialiased lines */
604struct line_aa_step
605{
606   float       xoffs, yoffs;               // X/Y deltas
607   float       weight;                 // weight contribution
608};
609
610#if 0
611static const line_aa_step line_aa_1step[] =
612{
613   {  0.00f,  0.00f,  1.00f  },
614   { 0 }
615};
616
617static const line_aa_step line_aa_4step[] =
618{
619   { -0.25f,  0.00f,  0.25f  },
620   {  0.25f,  0.00f,  0.25f  },
621   {  0.00f, -0.25f,  0.25f  },
622   {  0.00f,  0.25f,  0.25f  },
623   { 0 }
624};
625#endif
626
627//============================================================
628//  INLINES
629//============================================================
630
631INLINE HashT texture_compute_hash(const render_texinfo *texture, UINT32 flags)
632{
633   HashT h = (HashT)texture->base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK));
634   //printf("hash %d\n", (int) h % HASH_SIZE);
635   return (h >> 8) % HASH_SIZE;
636}
637
638void sdl_info_ogl::set_blendmode(int blendmode)
639{
640   // try to minimize texture state changes
641   if (blendmode != m_last_blendmode)
642   {
643      switch (blendmode)
644      {
645         case BLENDMODE_NONE:
646            glDisable(GL_BLEND);
647            break;
648         case BLENDMODE_ALPHA:
649            glEnable(GL_BLEND);
650            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
651            break;
652         case BLENDMODE_RGB_MULTIPLY:
653            glEnable(GL_BLEND);
654            glBlendFunc(GL_DST_COLOR, GL_ZERO);
655            break;
656         case BLENDMODE_ADD:
657            glEnable(GL_BLEND);
658            glBlendFunc(GL_SRC_ALPHA, GL_ONE);
659            break;
660      }
661
662      m_last_blendmode = blendmode;
663   }
664}
665
666//============================================================
667//  PROTOTYPES
668//============================================================
669
670// core functions
671
672//============================================================
673//  STATIC VARIABLES
674//============================================================
675
676static void drawogl_exit(void);
677static void load_gl_lib(running_machine &machine);
678
679
680
681// OGL 1.3
682#ifdef GL_ARB_multitexture
683static PFNGLACTIVETEXTUREARBPROC pfn_glActiveTexture    = NULL;
684#else
685static PFNGLACTIVETEXTUREPROC pfn_glActiveTexture   = NULL;
686#endif
687
688// VBO
689static PFNGLGENBUFFERSPROC pfn_glGenBuffers     = NULL;
690static PFNGLDELETEBUFFERSPROC pfn_glDeleteBuffers   = NULL;
691static PFNGLBINDBUFFERPROC pfn_glBindBuffer     = NULL;
692static PFNGLBUFFERDATAPROC pfn_glBufferData     = NULL;
693static PFNGLBUFFERSUBDATAPROC pfn_glBufferSubData   = NULL;
694
695// PBO
696static PFNGLMAPBUFFERPROC     pfn_glMapBuffer       = NULL;
697static PFNGLUNMAPBUFFERPROC   pfn_glUnmapBuffer     = NULL;
698
699// FBO
700static PFNGLISFRAMEBUFFEREXTPROC   pfn_glIsFramebuffer          = NULL;
701static PFNGLBINDFRAMEBUFFEREXTPROC pfn_glBindFramebuffer        = NULL;
702static PFNGLDELETEFRAMEBUFFERSEXTPROC pfn_glDeleteFramebuffers      = NULL;
703static PFNGLGENFRAMEBUFFERSEXTPROC pfn_glGenFramebuffers        = NULL;
704static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pfn_glCheckFramebufferStatus  = NULL;
705static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pfn_glFramebufferTexture2D  = NULL;
706
707static int glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
708
709//============================================================
710//  Textures
711//============================================================
712
713static void texture_set_data(texture_info *texture, const render_texinfo *texsource, UINT32 flags);
714
715//============================================================
716//  Static Variables
717//============================================================
718
719static int shown_video_info = 0;
720static int dll_loaded = 0;
721
722//============================================================
723//  drawsdl_init
724//============================================================
725
726static osd_renderer *drawogl_create(osd_window *window)
727{
728   return global_alloc(sdl_info_ogl(window));
729}
730
731int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks)
732{
733   // fill in the callbacks
734   callbacks->exit = drawogl_exit;
735   callbacks->create = drawogl_create;
736
737   dll_loaded = 0;
738
739   load_gl_lib(machine);
740   if (SDLMAME_SDL2)
741   {
742      osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
743   }
744   else
745      osd_printf_verbose("Using SDL single-window OpenGL driver (SDL 1.2)\n");
746
747   return 0;
748}
749
750//============================================================
751// Load the OGL function addresses
752//============================================================
753
754static void loadgl_functions(osd_gl_context *context)
755{
756#ifdef USE_DISPATCH_GL
757
758   int err_count = 0;
759
760   /* the following is tricky ... #func will be expanded to glBegin
761    * while func will be expanded to disp_p->glBegin
762    */
763
764   #define OSD_GL(ret,func,params) \
765   if (!( func = (ret (APIENTRY *)params) context->getProcAddress( #func ) )) \
766      { err_count++; osd_printf_error("GL function %s not found!\n", #func ); }
767
768   #define OSD_GL_UNUSED(ret,func,params)
769
770   #define GET_GLFUNC 1
771   #include "modules/opengl/osd_opengl.h"
772   #undef GET_GLFUNC
773
774   if (err_count)
775      fatalerror("Error loading GL library functions, giving up\n");
776
777#endif
778}
779
780//============================================================
781// Load GL library
782//============================================================
783
784#ifdef USE_DISPATCH_GL
785osd_gl_dispatch *gl_dispatch;
786#endif
787
788static void load_gl_lib(running_machine &machine)
789{
790   if (!dll_loaded)
791   {
792#ifdef OSD_WINDOWS
793      win_gl_context::load_library();
794#else
795#ifdef USE_DISPATCH_GL
796      /*
797       *  directfb and and x11 use this env var
798       *   SDL_VIDEO_GL_DRIVER
799       */
800      const char *stemp;
801
802      stemp = downcast<sdl_options &>(machine.options()).gl_lib();
803      if (stemp != NULL && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
804         stemp = NULL;
805
806      if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==NULL
807      {
808         fatalerror("Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
809      }
810      osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
811      /* FIXME: must be freed as well */
812#endif
813#endif
814      gl_dispatch = (osd_gl_dispatch *) osd_malloc(sizeof(osd_gl_dispatch));
815      dll_loaded=1;
816   }
817}
818
819void sdl_info_ogl::initialize_gl()
820{
821   int has_and_allow_texturerect = 0;
822
823   char *extstr = (char *)glGetString(GL_EXTENSIONS);
824   char *vendor = (char *)glGetString(GL_VENDOR);
825
826   //printf("%p\n", extstr);
827#ifdef OSD_WINDOWS
828   if (!extstr)
829      extstr = (char *)"";
830#endif
831   // print out the driver info for debugging
832   if (!shown_video_info)
833   {
834      osd_printf_verbose("OpenGL: %s\nOpenGL: %s\nOpenGL: %s\n", vendor, (char *)glGetString(GL_RENDERER), (char *)glGetString(GL_VERSION));
835   }
836
837   m_usetexturerect = 0;
838   m_texpoweroftwo = 1;
839   m_usevbo = 0;
840   m_usepbo = 0;
841   m_usefbo = 0;
842   m_useglsl = 0;
843
844   if ( video_config.allowtexturerect &&
845         ( strstr(extstr, "GL_ARB_texture_rectangle") ||  strstr(extstr, "GL_EXT_texture_rectangle") )
846      )
847   {
848      has_and_allow_texturerect = 1;
849               if (!shown_video_info)
850               {
851                     osd_printf_verbose("OpenGL: texture rectangle supported\n");
852               }
853   }
854
855   // does this card support non-power-of-two sized textures?  (they're faster, so use them if possible)
856   if ( !video_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two"))
857   {
858      if (!shown_video_info)
859      {
860         osd_printf_verbose("OpenGL: non-power-of-2 textures supported (new method)\n");
861      }
862               m_texpoweroftwo = 0;
863   }
864   else
865   {
866      // second chance: GL_ARB_texture_rectangle or GL_EXT_texture_rectangle (old version)
867      if (has_and_allow_texturerect)
868      {
869         if (!shown_video_info)
870         {
871            osd_printf_verbose("OpenGL: non-power-of-2 textures supported (old method)\n");
872         }
873         m_usetexturerect = 1;
874      }
875      else
876      {
877         if (!shown_video_info)
878         {
879            osd_printf_verbose("OpenGL: forcing power-of-2 textures (creation, not copy)\n");
880         }
881      }
882   }
883
884   if (strstr(extstr, "GL_ARB_vertex_buffer_object"))
885   {
886               m_usevbo = video_config.vbo;
887      if (!shown_video_info)
888      {
889         if(m_usevbo)
890            osd_printf_verbose("OpenGL: vertex buffer supported\n");
891         else
892            osd_printf_verbose("OpenGL: vertex buffer supported, but disabled\n");
893      }
894   }
895
896   if (strstr(extstr, "GL_ARB_pixel_buffer_object"))
897   {
898      if( m_usevbo )
899      {
900         m_usepbo = video_config.pbo;
901         if (!shown_video_info)
902         {
903            if(m_usepbo)
904               osd_printf_verbose("OpenGL: pixel buffers supported\n");
905            else
906               osd_printf_verbose("OpenGL: pixel buffers supported, but disabled\n");
907         }
908      } else {
909         if (!shown_video_info)
910         {
911            osd_printf_verbose("OpenGL: pixel buffers supported, but disabled due to disabled vbo\n");
912         }
913      }
914   }
915   else
916   {
917      if (!shown_video_info)
918      {
919         osd_printf_verbose("OpenGL: pixel buffers not supported\n");
920      }
921   }
922
923   if (strstr(extstr, "GL_EXT_framebuffer_object"))
924   {
925      m_usefbo = 1;
926      if (!shown_video_info)
927      {
928         if(m_usefbo)
929            osd_printf_verbose("OpenGL: framebuffer object supported\n");
930         else
931            osd_printf_verbose("OpenGL: framebuffer object not supported\n");
932      }
933   }
934
935   if (strstr(extstr, "GL_ARB_shader_objects") &&
936      strstr(extstr, "GL_ARB_shading_language_100") &&
937      strstr(extstr, "GL_ARB_vertex_shader") &&
938      strstr(extstr, "GL_ARB_fragment_shader")
939      )
940   {
941      m_useglsl = video_config.glsl;
942      if (!shown_video_info)
943      {
944         if(m_useglsl)
945            osd_printf_verbose("OpenGL: GLSL supported\n");
946         else
947            osd_printf_verbose("OpenGL: GLSL supported, but disabled\n");
948      }
949   } else {
950      if (!shown_video_info)
951      {
952         osd_printf_verbose("OpenGL: GLSL not supported\n");
953      }
954   }
955
956#ifdef TOBEMIGRATED
957   if (osd_getenv(SDLENV_VMWARE) != NULL)
958   {
959      m_usetexturerect = 1;
960      m_texpoweroftwo = 1;
961   }
962#endif
963   glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&m_texture_max_width);
964   glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&m_texture_max_height);
965   if (!shown_video_info)
966   {
967      osd_printf_verbose("OpenGL: max texture size %d x %d\n", m_texture_max_width, m_texture_max_height);
968   }
969
970   shown_video_info = 1;
971
972}
973//============================================================
974//  sdl_info::create
975// a
976// a
977// a
978// a
979// a
980// a
981// a
982// a
983// a
984// a
985// a
986// a
987// a
988// a
989// a
990// a
991// a
992// a
993// a
994// a
995// a
996// a
997// a
998// a
999// a
1000// a
1001//============================================================
1002
1003int sdl_info_ogl::create()
1004{
1005#if (SDLMAME_SDL2)
1006   // create renderer
1007#ifdef OSD_WINDOWS
1008   m_gl_context = global_alloc(win_gl_context(window().m_hwnd));
1009#else
1010   m_gl_context = global_alloc(sdl_gl_context(window().sdl_window()));
1011#endif
1012#else
1013   m_gl_context = global_alloc(sdl12_gl_context(window().sdl_surface()));
1014#endif
1015   if  (m_gl_context->LastErrorMsg() != NULL)
1016   {
1017      osd_printf_error("%s\n", m_gl_context->LastErrorMsg());
1018      return 1;
1019   }
1020   m_gl_context->SetSwapInterval(video_config.waitvsync ? 1 : 0);
1021
1022
1023   m_blittimer = 0;
1024   m_surf_w = 0;
1025   m_surf_h = 0;
1026
1027   m_initialized = 0;
1028
1029   // in case any textures try to come up before these are validated,
1030   // OpenGL guarantees all implementations can handle something this size.
1031   m_texture_max_width = 64;
1032   m_texture_max_height = 64;
1033
1034   /* load any GL function addresses
1035    * this must be done here because we need a context
1036    */
1037   loadgl_functions(m_gl_context);
1038   initialize_gl();
1039
1040
1041   m_init_context = 0;
1042
1043   osd_printf_verbose("Leave sdl_info_ogl::create\n");
1044   return 0;
1045}
1046
1047
1048//============================================================
1049//  sdl_info::destroy
1050//============================================================
1051
1052void sdl_info_ogl::destroy()
1053{
1054   // free the memory in the window
1055
1056   destroy_all_textures();
1057
1058   global_free(m_gl_context);
1059   m_gl_context = NULL;
1060}
1061
1062
1063//============================================================
1064//  drawsdl_xy_to_render_target
1065//============================================================
1066
1067int sdl_info_ogl::xy_to_render_target(int x, int y, int *xt, int *yt)
1068{
1069   *xt = x - m_last_hofs;
1070   *yt = y - m_last_vofs;
1071   if (*xt<0 || *xt >= m_blit_dim.width())
1072      return 0;
1073   if (*yt<0 || *yt >= m_blit_dim.height())
1074      return 0;
1075   return 1;
1076}
1077
1078//============================================================
1079//  drawsdl_destroy_all_textures
1080//============================================================
1081
1082void sdl_info_ogl::destroy_all_textures()
1083{
1084   texture_info *texture = NULL;
1085   int lock=FALSE;
1086   int i;
1087
1088   if ( !m_initialized )
1089      return;
1090
1091   m_gl_context->MakeCurrent();
1092
1093   if(window().m_primlist)
1094   {
1095      lock=TRUE;
1096      window().m_primlist->acquire_lock();
1097   }
1098
1099   glFinish();
1100
1101   texture_all_disable();
1102   glFinish();
1103   glDisableClientState(GL_VERTEX_ARRAY);
1104
1105   i=0;
1106   while (i<HASH_SIZE+OVERFLOW_SIZE)
1107   {
1108      texture = m_texhash[i];
1109      m_texhash[i] = NULL;
1110      if (texture != NULL)
1111      {
1112         if(m_usevbo)
1113         {
1114            pfn_glDeleteBuffers( 1, &(texture->texCoordBufferName) );
1115            texture->texCoordBufferName=0;
1116         }
1117
1118         if(m_usepbo && texture->pbo)
1119         {
1120            pfn_glDeleteBuffers( 1, (GLuint *)&(texture->pbo) );
1121            texture->pbo=0;
1122         }
1123
1124         if( m_glsl_program_num > 1 )
1125         {
1126            assert(m_usefbo);
1127            pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
1128            glDeleteTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
1129         }
1130
1131         if ( m_glsl_program_mb2sc < m_glsl_program_num - 1 )
1132         {
1133            assert(m_usefbo);
1134            pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
1135            glDeleteTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
1136         }
1137
1138         glDeleteTextures(1, (GLuint *)&texture->texture);
1139         if ( texture->data_own )
1140         {
1141            free(texture->data);
1142            texture->data=NULL;
1143            texture->data_own=FALSE;
1144         }
1145         global_free(texture);
1146      }
1147      i++;
1148   }
1149   if ( m_useglsl )
1150   {
1151      glsl_shader_free(m_glsl);
1152      m_glsl = NULL;
1153   }
1154
1155   m_initialized = 0;
1156
1157   if (lock)
1158      window().m_primlist->release_lock();
1159}
1160//============================================================
1161//  loadGLExtensions
1162//============================================================
1163
1164void sdl_info_ogl::loadGLExtensions()
1165{
1166   static int _once = 1;
1167
1168   // usevbo=FALSE; // You may want to switch VBO and PBO off, by uncommenting this statement
1169   // usepbo=FALSE; // You may want to switch PBO off, by uncommenting this statement
1170   // useglsl=FALSE; // You may want to switch GLSL off, by uncommenting this statement
1171
1172   if (! m_usevbo)
1173   {
1174      if(m_usepbo) // should never ever happen ;-)
1175      {
1176         if (_once)
1177         {
1178            osd_printf_warning("OpenGL: PBO not supported, no VBO support. (sdlmame error)\n");
1179         }
1180         m_usepbo=FALSE;
1181      }
1182      if(m_useglsl) // should never ever happen ;-)
1183      {
1184         if (_once)
1185         {
1186            osd_printf_warning("OpenGL: GLSL not supported, no VBO support. (sdlmame error)\n");
1187         }
1188         m_useglsl=FALSE;
1189      }
1190   }
1191
1192   // Get Pointers To The GL Functions
1193   // VBO:
1194   if( m_usevbo )
1195   {
1196      pfn_glGenBuffers = (PFNGLGENBUFFERSPROC) m_gl_context->getProcAddress("glGenBuffers");
1197      pfn_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) m_gl_context->getProcAddress("glDeleteBuffers");
1198      pfn_glBindBuffer = (PFNGLBINDBUFFERPROC) m_gl_context->getProcAddress("glBindBuffer");
1199      pfn_glBufferData = (PFNGLBUFFERDATAPROC) m_gl_context->getProcAddress("glBufferData");
1200      pfn_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) m_gl_context->getProcAddress("glBufferSubData");
1201   }
1202   // PBO:
1203   if ( m_usepbo )
1204   {
1205      pfn_glMapBuffer  = (PFNGLMAPBUFFERPROC) m_gl_context->getProcAddress("glMapBuffer");
1206      pfn_glUnmapBuffer= (PFNGLUNMAPBUFFERPROC) m_gl_context->getProcAddress("glUnmapBuffer");
1207   }
1208   // FBO:
1209   if ( m_usefbo )
1210   {
1211      pfn_glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glIsFramebufferEXT");
1212      pfn_glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glBindFramebufferEXT");
1213      pfn_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glDeleteFramebuffersEXT");
1214      pfn_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glGenFramebuffersEXT");
1215      pfn_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) m_gl_context->getProcAddress("glCheckFramebufferStatusEXT");
1216      pfn_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) m_gl_context->getProcAddress("glFramebufferTexture2DEXT");
1217   }
1218
1219   if ( m_usevbo &&
1220         ( !pfn_glGenBuffers || !pfn_glDeleteBuffers ||
1221         !pfn_glBindBuffer || !pfn_glBufferData || !pfn_glBufferSubData
1222      ) )
1223   {
1224      m_usepbo=FALSE;
1225      if (_once)
1226      {
1227         osd_printf_warning("OpenGL: VBO not supported, missing: ");
1228         if (!pfn_glGenBuffers)
1229         {
1230            osd_printf_warning("glGenBuffers, ");
1231         }
1232         if (!pfn_glDeleteBuffers)
1233         {
1234            osd_printf_warning("glDeleteBuffers");
1235         }
1236         if (!pfn_glBindBuffer)
1237         {
1238            osd_printf_warning("glBindBuffer, ");
1239         }
1240         if (!pfn_glBufferData)
1241         {
1242            osd_printf_warning("glBufferData, ");
1243         }
1244         if (!pfn_glBufferSubData)
1245         {
1246            osd_printf_warning("glBufferSubData, ");
1247         }
1248         osd_printf_warning("\n");
1249      }
1250      if ( m_usevbo )
1251      {
1252         if (_once)
1253         {
1254            osd_printf_warning("OpenGL: PBO not supported, no VBO support.\n");
1255         }
1256         m_usepbo=FALSE;
1257      }
1258   }
1259
1260   if ( m_usepbo && ( !pfn_glMapBuffer || !pfn_glUnmapBuffer ) )
1261   {
1262      m_usepbo=FALSE;
1263      if (_once)
1264      {
1265         osd_printf_warning("OpenGL: PBO not supported, missing: ");
1266         if (!pfn_glMapBuffer)
1267         {
1268            osd_printf_warning("glMapBuffer, ");
1269         }
1270         if (!pfn_glUnmapBuffer)
1271         {
1272            osd_printf_warning("glUnmapBuffer, ");
1273         }
1274         osd_printf_warning("\n");
1275      }
1276   }
1277
1278   if ( m_usefbo &&
1279      ( !pfn_glIsFramebuffer || !pfn_glBindFramebuffer || !pfn_glDeleteFramebuffers ||
1280         !pfn_glGenFramebuffers || !pfn_glCheckFramebufferStatus || !pfn_glFramebufferTexture2D
1281      ))
1282   {
1283      m_usefbo=FALSE;
1284      if (_once)
1285      {
1286         osd_printf_warning("OpenGL: FBO not supported, missing: ");
1287         if (!pfn_glIsFramebuffer)
1288         {
1289            osd_printf_warning("pfn_glIsFramebuffer, ");
1290         }
1291         if (!pfn_glBindFramebuffer)
1292         {
1293            osd_printf_warning("pfn_glBindFramebuffer, ");
1294         }
1295         if (!pfn_glDeleteFramebuffers)
1296         {
1297            osd_printf_warning("pfn_glDeleteFramebuffers, ");
1298         }
1299         if (!pfn_glGenFramebuffers)
1300         {
1301            osd_printf_warning("pfn_glGenFramebuffers, ");
1302         }
1303         if (!pfn_glCheckFramebufferStatus)
1304         {
1305            osd_printf_warning("pfn_glCheckFramebufferStatus, ");
1306         }
1307         if (!pfn_glFramebufferTexture2D)
1308         {
1309            osd_printf_warning("pfn_glFramebufferTexture2D, ");
1310         }
1311         osd_printf_warning("\n");
1312      }
1313   }
1314
1315   if (_once)
1316   {
1317      if ( m_usevbo )
1318      {
1319         osd_printf_verbose("OpenGL: VBO supported\n");
1320      }
1321      else
1322      {
1323         osd_printf_warning("OpenGL: VBO not supported\n");
1324      }
1325
1326      if ( m_usepbo )
1327      {
1328         osd_printf_verbose("OpenGL: PBO supported\n");
1329      }
1330      else
1331      {
1332         osd_printf_warning("OpenGL: PBO not supported\n");
1333      }
1334
1335      if ( m_usefbo )
1336      {
1337         osd_printf_verbose("OpenGL: FBO supported\n");
1338      }
1339      else
1340      {
1341         osd_printf_warning("OpenGL: FBO not supported\n");
1342      }
1343   }
1344
1345   if ( m_useglsl )
1346   {
1347      #ifdef GL_ARB_multitexture
1348      pfn_glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) m_gl_context->getProcAddress("glActiveTextureARB");
1349      #else
1350      pfn_glActiveTexture = (PFNGLACTIVETEXTUREPROC) m_gl_context->getProcAddress("glActiveTexture");
1351      #endif
1352      if (!pfn_glActiveTexture)
1353      {
1354         if (_once)
1355         {
1356            osd_printf_warning("OpenGL: GLSL disabled, glActiveTexture(ARB) not supported\n");
1357         }
1358         m_useglsl = 0;
1359      }
1360   }
1361
1362   if ( m_useglsl )
1363   {
1364      m_glsl = glsl_shader_init(m_gl_context);
1365      m_useglsl = (m_glsl != NULL ? 1 : 0);
1366
1367      if ( ! m_useglsl )
1368      {
1369         if (_once)
1370         {
1371            osd_printf_warning("OpenGL: GLSL supported, but shader instantiation failed - disabled\n");
1372         }
1373      }
1374   }
1375
1376   if ( m_useglsl )
1377   {
1378      if ( window().prescale() != 1 )
1379      {
1380         m_useglsl = 0;
1381         if (_once)
1382         {
1383            osd_printf_warning("OpenGL: GLSL supported, but disabled due to: prescale !=1 \n");
1384         }
1385      }
1386   }
1387
1388   if ( m_useglsl )
1389   {
1390      int i;
1391      video_config.filter = FALSE;
1392      glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
1393      m_glsl_program_num = 0;
1394      m_glsl_program_mb2sc = 0;
1395
1396      for(i=0; i<video_config.glsl_shader_mamebm_num; i++)
1397      {
1398         if ( !m_usefbo && m_glsl_program_num==1 )
1399         {
1400            if (_once)
1401            {
1402               osd_printf_verbose("OpenGL: GLSL multipass not supported, due to unsupported FBO. Skipping followup shader\n");
1403            }
1404            break;
1405         }
1406
1407         if ( glsl_shader_add_mamebm(m_glsl, video_config.glsl_shader_mamebm[i], m_glsl_program_num) )
1408         {
1409            osd_printf_error("OpenGL: GLSL loading mame bitmap shader %d failed (%s)\n",
1410               i, video_config.glsl_shader_mamebm[i]);
1411         } else {
1412            glsl_shader_feature = GLSL_SHADER_FEAT_CUSTOM;
1413            if (_once)
1414            {
1415               osd_printf_verbose("OpenGL: GLSL using mame bitmap shader filter %d: '%s'\n",
1416                  m_glsl_program_num, video_config.glsl_shader_mamebm[i]);
1417            }
1418            m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
1419            m_glsl_program_num++;
1420         }
1421      }
1422
1423      if ( video_config.glsl_shader_scrn_num > 0 && m_glsl_program_num==0 )
1424      {
1425         osd_printf_verbose("OpenGL: GLSL cannot use screen bitmap shader without bitmap shader\n");
1426      }
1427
1428      for(i=0; m_usefbo && m_glsl_program_num>0 && i<video_config.glsl_shader_scrn_num; i++)
1429      {
1430         if ( glsl_shader_add_scrn(m_glsl, video_config.glsl_shader_scrn[i],
1431                                 m_glsl_program_num-1-m_glsl_program_mb2sc) )
1432         {
1433            osd_printf_error("OpenGL: GLSL loading screen bitmap shader %d failed (%s)\n",
1434               i, video_config.glsl_shader_scrn[i]);
1435         } else {
1436            if (_once)
1437            {
1438               osd_printf_verbose("OpenGL: GLSL using screen bitmap shader filter %d: '%s'\n",
1439                  m_glsl_program_num, video_config.glsl_shader_scrn[i]);
1440            }
1441            m_glsl_program_num++;
1442         }
1443      }
1444
1445      if ( 0==m_glsl_program_num &&
1446            0 <= video_config.glsl_filter && video_config.glsl_filter < GLSL_SHADER_FEAT_INT_NUMBER )
1447      {
1448         m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
1449         m_glsl_program_num++;
1450         glsl_shader_feature = video_config.glsl_filter;
1451
1452         if (_once)
1453         {
1454            osd_printf_verbose("OpenGL: GLSL using shader filter '%s', idx: %d, num %d (vid filter: %d)\n",
1455               glsl_shader_get_filter_name_mamebm(glsl_shader_feature),
1456               glsl_shader_feature, m_glsl_program_num, video_config.filter);
1457         }
1458      }
1459
1460   } else {
1461      if (_once)
1462      {
1463         osd_printf_verbose("OpenGL: using vid filter: %d\n", video_config.filter);
1464      }
1465   }
1466
1467   _once = 0;
1468}
1469
1470//============================================================
1471//  sdl_info::draw
1472//============================================================
1473
1474int sdl_info_ogl::draw(const int update)
1475{
1476   render_primitive *prim;
1477   texture_info *texture=NULL;
1478   float vofs, hofs;
1479   int  pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE;
1480
1481#ifdef TOBEMIGRATED
1482   if (video_config.novideo)
1483   {
1484      return 0;
1485   }
1486#endif
1487
1488   osd_dim wdim = window().get_size();
1489
1490   if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
1491   {
1492      destroy_all_textures();
1493      m_width = wdim.width();
1494      m_height = wdim.height();
1495      m_blittimer = 3;
1496      m_init_context = 1;
1497      clear_flags(FI_CHANGED);
1498   }
1499
1500   m_gl_context->MakeCurrent();
1501
1502   if (m_init_context)
1503   {
1504      // do some one-time OpenGL setup
1505#if (SDLMAME_SDL2)
1506      // FIXME: SRGB conversion is working on SDL2, may be of use
1507      // when we eventually target gamma and monitor profiles.
1508      //glEnable(GL_FRAMEBUFFER_SRGB);
1509#endif
1510      glShadeModel(GL_SMOOTH);
1511      glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1512      glClearDepth(1.0f);
1513      glEnable(GL_DEPTH_TEST);
1514      glDepthFunc(GL_LEQUAL);
1515      glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1516   }
1517
1518   // only clear if the geometry changes (and for 2 frames afterward to clear double and triple buffers)
1519   if ((m_blittimer > 0) || has_flags(FLAG_HAS_VECTOR_SCREEN))
1520   {
1521      glClear(GL_COLOR_BUFFER_BIT);
1522      m_blittimer--;
1523   }
1524
1525   // FIXME: remove m_surf_w and m_surf_h
1526   if ( !m_initialized ||
1527         m_width != m_surf_w || m_height != m_surf_h )
1528   {
1529      // FIXME:: this can be done in create!
1530      if ( !m_initialized )
1531      {
1532         loadGLExtensions();
1533      }
1534
1535#if (!SDLMAME_SDL2)
1536      // force all textures to be regenerated
1537      destroy_all_textures();
1538#endif
1539
1540      m_surf_w = m_width;
1541      m_surf_h = m_height;
1542
1543      // we're doing nothing 3d, so the Z-buffer is currently not interesting
1544      glDisable(GL_DEPTH_TEST);
1545
1546      if (window().machine().options().antialias())
1547      {
1548         // enable antialiasing for lines
1549         glEnable(GL_LINE_SMOOTH);
1550         // enable antialiasing for points
1551         glEnable(GL_POINT_SMOOTH);
1552
1553         // prefer quality to speed
1554         glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
1555         glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
1556      }
1557      else
1558      {
1559         glDisable(GL_LINE_SMOOTH);
1560         glDisable(GL_POINT_SMOOTH);
1561      }
1562
1563      // enable blending
1564      glEnable(GL_BLEND);
1565      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1566      m_last_blendmode = BLENDMODE_ALPHA;
1567
1568#ifdef TOBEMIGRATED
1569      // set lines and points just barely above normal size to get proper results
1570      glLineWidth(video_config.beamwidth);
1571      glPointSize(video_config.beamwidth);
1572#endif
1573
1574      // set up a nice simple 2D coordinate system, so GL behaves exactly how we'd like.
1575      //
1576      // (0,0)     (w,0)
1577      //   |~~~~~~~~~|
1578      //   |         |
1579      //   |         |
1580      //   |         |
1581      //   |_________|
1582      // (0,h)     (w,h)
1583
1584      glViewport(0.0, 0.0, (GLsizei) m_width, (GLsizei) m_height);
1585      glMatrixMode(GL_PROJECTION);
1586      glLoadIdentity();
1587      glOrtho(0.0, (GLdouble) m_width, (GLdouble) m_height, 0.0, 0.0, -1.0);
1588      glMatrixMode(GL_MODELVIEW);
1589      glLoadIdentity();
1590
1591      if ( ! m_initialized )
1592      {
1593         glEnableClientState(GL_VERTEX_ARRAY);
1594         glVertexPointer(2, GL_FLOAT, 0, m_texVerticex); // no VBO, since it's too volatile
1595
1596         m_initialized = 1;
1597      }
1598   }
1599
1600   // compute centering parameters
1601   vofs = hofs = 0.0f;
1602
1603#ifdef TOBEMIGRATED
1604   if (video_config.centerv || video_config.centerh)
1605   {
1606      int ch, cw;
1607
1608      ch = m_height;
1609      cw = m_width;
1610
1611      if (video_config.centerv)
1612      {
1613         vofs = (ch - m_blit_dim.height()) / 2.0f;
1614      }
1615      if (video_config.centerh)
1616      {
1617         hofs = (cw - m_blit_dim.width()) / 2.0f;
1618      }
1619   }
1620#else
1621#endif
1622
1623   m_last_hofs = hofs;
1624   m_last_vofs = vofs;
1625
1626   window().m_primlist->acquire_lock();
1627
1628   // now draw
1629   for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
1630   {
1631      int i;
1632
1633      switch (prim->type)
1634      {
1635         /**
1636          * Try to stay in one Begin/End block as long as possible,
1637          * since entering and leaving one is most expensive..
1638          */
1639         case render_primitive::LINE:
1640            #if !USE_WIN32_STYLE_LINES
1641            // check if it's really a point
1642            if (((prim->bounds.x1 - prim->bounds.x0) == 0) && ((prim->bounds.y1 - prim->bounds.y0) == 0))
1643            {
1644               curPrimitive=GL_POINTS;
1645            } else {
1646               curPrimitive=GL_LINES;
1647            }
1648
1649            if(pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
1650            {
1651               glEnd();
1652               pendingPrimitive=GL_NO_PRIMITIVE;
1653            }
1654
1655                  if ( pendingPrimitive==GL_NO_PRIMITIVE )
1656            {
1657                     set_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags));
1658            }
1659
1660            glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
1661
1662            if(pendingPrimitive!=curPrimitive)
1663            {
1664               glBegin(curPrimitive);
1665               pendingPrimitive=curPrimitive;
1666            }
1667
1668            // check if it's really a point
1669            if (curPrimitive==GL_POINTS)
1670            {
1671               glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
1672            }
1673            else
1674            {
1675               glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
1676               glVertex2f(prim->bounds.x1+hofs, prim->bounds.y1+vofs);
1677            }
1678            #else
1679            {
1680               const line_aa_step *step = line_aa_4step;
1681               render_bounds b0, b1;
1682               float r, g, b, a;
1683               float effwidth;
1684
1685               // we're not gonna play fancy here.  close anything pending and let's go.
1686               if (pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
1687               {
1688                  glEnd();
1689                  pendingPrimitive=GL_NO_PRIMITIVE;
1690               }
1691
1692               set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags));
1693
1694               // compute the effective width based on the direction of the line
1695               effwidth = prim->width();
1696               if (effwidth < 0.5f)
1697                  effwidth = 0.5f;
1698
1699               // determine the bounds of a quad to draw this line
1700               render_line_to_quad(&prim->bounds, effwidth, &b0, &b1);
1701
1702               // fix window position
1703               b0.x0 += hofs;
1704               b0.x1 += hofs;
1705               b1.x0 += hofs;
1706               b1.x1 += hofs;
1707               b0.y0 += vofs;
1708               b0.y1 += vofs;
1709               b1.y0 += vofs;
1710               b1.y1 += vofs;
1711
1712               // iterate over AA steps
1713               for (step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
1714               {
1715                  glBegin(GL_TRIANGLE_STRIP);
1716
1717                  // rotate the unit vector by 135 degrees and add to point 0
1718                  glVertex2f(b0.x0 + step->xoffs, b0.y0 + step->yoffs);
1719
1720                  // rotate the unit vector by -135 degrees and add to point 0
1721                  glVertex2f(b0.x1 + step->xoffs, b0.y1 + step->yoffs);
1722
1723                  // rotate the unit vector by 45 degrees and add to point 1
1724                  glVertex2f(b1.x0 + step->xoffs, b1.y0 + step->yoffs);
1725
1726                  // rotate the unit vector by -45 degrees and add to point 1
1727                  glVertex2f(b1.x1 + step->xoffs, b1.y1 + step->yoffs);
1728
1729                  // determine the color of the line
1730                  r = (prim->color.r * step->weight);
1731                  g = (prim->color.g * step->weight);
1732                  b = (prim->color.b * step->weight);
1733                  a = (prim->color.a * 255.0f);
1734                  if (r > 1.0) r = 1.0;
1735                  if (g > 1.0) g = 1.0;
1736                  if (b > 1.0) b = 1.0;
1737                  if (a > 1.0) a = 1.0;
1738                  glColor4f(r, g, b, a);
1739
1740//                      texture = texture_update(window, prim, 0);
1741//                      if (texture) printf("line has texture!\n");
1742
1743                  // if we have a texture to use for the vectors, use it here
1744                  #if 0
1745                  if (d3d->vector_texture != NULL)
1746                  {
1747                     printf("SDL: textured lines unsupported\n");
1748                     vertex[0].u0 = d3d->vector_texture->ustart;
1749                     vertex[0].v0 = d3d->vector_texture->vstart;
1750
1751                     vertex[2].u0 = d3d->vector_texture->ustop;
1752                     vertex[2].v0 = d3d->vector_texture->vstart;
1753
1754                     vertex[1].u0 = d3d->vector_texture->ustart;
1755                     vertex[1].v0 = d3d->vector_texture->vstop;
1756
1757                     vertex[3].u0 = d3d->vector_texture->ustop;
1758                     vertex[3].v0 = d3d->vector_texture->vstop;
1759                  }
1760                  #endif
1761                  glEnd();
1762               }
1763            }
1764            #endif
1765            break;
1766
1767         case render_primitive::QUAD:
1768
1769            if(pendingPrimitive!=GL_NO_PRIMITIVE)
1770            {
1771               glEnd();
1772               pendingPrimitive=GL_NO_PRIMITIVE;
1773            }
1774
1775            glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
1776
1777            set_blendmode(PRIMFLAG_GET_BLENDMODE(prim->flags));
1778
1779            texture = texture_update(prim, 0);
1780
1781            if ( texture && texture->type==TEXTURE_TYPE_SHADER )
1782            {
1783               for(i=0; i<m_glsl_program_num; i++)
1784               {
1785                  if ( i==m_glsl_program_mb2sc )
1786                  {
1787                     // i==glsl_program_mb2sc -> transformation mamebm->scrn
1788                     m_texVerticex[0]=prim->bounds.x0 + hofs;
1789                     m_texVerticex[1]=prim->bounds.y0 + vofs;
1790                     m_texVerticex[2]=prim->bounds.x1 + hofs;
1791                     m_texVerticex[3]=prim->bounds.y0 + vofs;
1792                     m_texVerticex[4]=prim->bounds.x1 + hofs;
1793                     m_texVerticex[5]=prim->bounds.y1 + vofs;
1794                     m_texVerticex[6]=prim->bounds.x0 + hofs;
1795                     m_texVerticex[7]=prim->bounds.y1 + vofs;
1796                  } else {
1797                     // 1:1 tex coord CCW (0/0) (1/0) (1/1) (0/1) on texture dimensions
1798                     m_texVerticex[0]=(GLfloat)0.0;
1799                     m_texVerticex[1]=(GLfloat)0.0;
1800                     m_texVerticex[2]=(GLfloat)m_width;
1801                     m_texVerticex[3]=(GLfloat)0.0;
1802                     m_texVerticex[4]=(GLfloat)m_width;
1803                     m_texVerticex[5]=(GLfloat)m_height;
1804                     m_texVerticex[6]=(GLfloat)0.0;
1805                     m_texVerticex[7]=(GLfloat)m_height;
1806                  }
1807
1808                  if(i>0) // first fetch already done
1809                  {
1810                     texture = texture_update(prim, i);
1811                  }
1812                  glDrawArrays(GL_QUADS, 0, 4);
1813               }
1814            } else {
1815               m_texVerticex[0]=prim->bounds.x0 + hofs;
1816               m_texVerticex[1]=prim->bounds.y0 + vofs;
1817               m_texVerticex[2]=prim->bounds.x1 + hofs;
1818               m_texVerticex[3]=prim->bounds.y0 + vofs;
1819               m_texVerticex[4]=prim->bounds.x1 + hofs;
1820               m_texVerticex[5]=prim->bounds.y1 + vofs;
1821               m_texVerticex[6]=prim->bounds.x0 + hofs;
1822               m_texVerticex[7]=prim->bounds.y1 + vofs;
1823
1824               glDrawArrays(GL_QUADS, 0, 4);
1825            }
1826
1827            if ( texture )
1828            {
1829               texture_disable(texture);
1830               texture=NULL;
1831            }
1832            break;
1833
1834         default:
1835            throw emu_fatalerror("Unexpected render_primitive type");
1836      }
1837   }
1838
1839   if(pendingPrimitive!=GL_NO_PRIMITIVE)
1840   {
1841      glEnd();
1842      pendingPrimitive=GL_NO_PRIMITIVE;
1843   }
1844
1845   window().m_primlist->release_lock();
1846   m_init_context = 0;
1847
1848   m_gl_context->SwapBuffer();
1849
1850   return 0;
1851}
1852
1853//============================================================
1854//  texture handling
1855//============================================================
1856
1857static const char * texfmt_to_string[9] = {
1858      "ARGB32",
1859      "RGB32",
1860      "RGB32_PALETTED",
1861      "YUV16",
1862      "YUV16_PALETTED",
1863      "PALETTE16",
1864      "RGB15",
1865      "RGB15_PALETTE",
1866      "PALETTE16A"
1867      };
1868
1869//
1870// Note: if you change the following array order, change the matching defines in texsrc.h
1871//
1872
1873enum { SDL_TEXFORMAT_SRC_EQUALS_DEST, SDL_TEXFORMAT_SRC_HAS_PALETTE };
1874
1875static const GLint texture_copy_properties[9][2] = {
1876   { TRUE,  FALSE },   // SDL_TEXFORMAT_ARGB32
1877   { TRUE,  FALSE },   // SDL_TEXFORMAT_RGB32
1878   { TRUE,  TRUE  },   // SDL_TEXFORMAT_RGB32_PALETTED
1879   { FALSE, FALSE },   // SDL_TEXFORMAT_YUY16
1880   { FALSE, TRUE  },   // SDL_TEXFORMAT_YUY16_PALETTED
1881   { FALSE, TRUE  },   // SDL_TEXFORMAT_PALETTE16
1882   { TRUE,  FALSE },   // SDL_TEXFORMAT_RGB15
1883   { TRUE,  TRUE  },   // SDL_TEXFORMAT_RGB15_PALETTED
1884   { FALSE, TRUE  }    // SDL_TEXFORMAT_PALETTE16A
1885};
1886
1887//============================================================
1888//  drawogl_exit
1889//============================================================
1890
1891static void drawogl_exit(void)
1892{
1893   int i;
1894
1895   for(i=0; i<video_config.glsl_shader_mamebm_num; i++)
1896   {
1897      if ( NULL!=video_config.glsl_shader_mamebm[i])
1898      {
1899         free(video_config.glsl_shader_mamebm[i]);
1900         video_config.glsl_shader_mamebm[i] = NULL;
1901      }
1902   }
1903   for(i=0; i<video_config.glsl_shader_scrn_num; i++)
1904   {
1905      if ( NULL!=video_config.glsl_shader_scrn[i])
1906      {
1907         free(video_config.glsl_shader_scrn[i]);
1908         video_config.glsl_shader_scrn[i] = NULL;
1909      }
1910   }
1911}
1912
1913//============================================================
1914//  texture_compute_size and type
1915//============================================================
1916
1917//
1918// glBufferData to push a nocopy texture to the GPU is slower than TexSubImage2D,
1919// so don't use PBO here
1920//
1921// we also don't want to use PBO's in the case of nocopy==TRUE,
1922// since we now might have GLSL shaders - this decision simplifies out life ;-)
1923//
1924void sdl_info_ogl::texture_compute_type_subroutine(const render_texinfo *texsource, texture_info *texture, UINT32 flags)
1925{
1926   texture->type = TEXTURE_TYPE_NONE;
1927   texture->nocopy = FALSE;
1928
1929   if ( texture->type == TEXTURE_TYPE_NONE &&
1930         !PRIMFLAG_GET_SCREENTEX(flags))
1931   {
1932      texture->type = TEXTURE_TYPE_PLAIN;
1933            texture->texTarget = (m_usetexturerect)?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D;
1934            texture->texpow2   = (m_usetexturerect)?0:m_texpoweroftwo;
1935   }
1936
1937   if ( texture->type == TEXTURE_TYPE_NONE && m_useglsl &&
1938         texture->xprescale == 1 && texture->yprescale == 1 &&
1939         texsource->rowpixels <= m_texture_max_width )
1940      {
1941         texture->type      = TEXTURE_TYPE_SHADER;
1942         texture->texTarget = GL_TEXTURE_2D;
1943         texture->texpow2   = m_texpoweroftwo;
1944      }
1945
1946   // determine if we can skip the copy step
1947   // if this was not already decided by the shader condition above
1948   if    ( texture_copy_properties[texture->format][SDL_TEXFORMAT_SRC_EQUALS_DEST] &&
1949         !texture_copy_properties[texture->format][SDL_TEXFORMAT_SRC_HAS_PALETTE] &&
1950         texture->xprescale == 1 && texture->yprescale == 1 &&
1951         !texture->borderpix && !texsource->palette &&
1952         texsource->rowpixels <= m_texture_max_width )
1953   {
1954      texture->nocopy = TRUE;
1955   }
1956
1957   if( texture->type == TEXTURE_TYPE_NONE &&
1958      m_usepbo && !texture->nocopy )
1959   {
1960      texture->type      = TEXTURE_TYPE_DYNAMIC;
1961      texture->texTarget = (m_usetexturerect)?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D;
1962      texture->texpow2   = (m_usetexturerect)?0:m_texpoweroftwo;
1963   }
1964
1965   if( texture->type == TEXTURE_TYPE_NONE )
1966   {
1967      texture->type      = TEXTURE_TYPE_SURFACE;
1968      texture->texTarget = (m_usetexturerect)?GL_TEXTURE_RECTANGLE_ARB:GL_TEXTURE_2D;
1969      texture->texpow2   = (m_usetexturerect)?0:m_texpoweroftwo;
1970   }
1971}
1972
1973INLINE int get_valid_pow2_value(int v, int needPow2)
1974{
1975   return (needPow2)?gl_round_to_pow2(v):v;
1976}
1977
1978void sdl_info_ogl::texture_compute_size_subroutine(texture_info *texture, UINT32 flags,
1979                                 UINT32 width, UINT32 height,
1980                                 int* p_width, int* p_height, int* p_width_create, int* p_height_create)
1981{
1982   int width_create;
1983   int height_create;
1984
1985   if ( texture->texpow2 )
1986      {
1987            width_create  = gl_round_to_pow2 (width);
1988            height_create = gl_round_to_pow2 (height);
1989      } else if ( texture->type==TEXTURE_TYPE_SHADER )
1990      {
1991            /**
1992             * at least use a multiple of 8 for shader .. just in case
1993             */
1994            width_create  = ( width  & ~0x07 ) + ( (width  & 0x07)? 8 : 0 ) ;
1995            height_create = ( height & ~0x07 ) + ( (height & 0x07)? 8 : 0 ) ;
1996      } else {
1997            width_create  = width  ;
1998            height_create = height ;
1999      }
2000
2001   // don't prescale above max texture size
2002   while (texture->xprescale > 1 && width_create * texture->xprescale > m_texture_max_width)
2003      texture->xprescale--;
2004   while (texture->yprescale > 1 && height_create * texture->yprescale > m_texture_max_height)
2005      texture->yprescale--;
2006   if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != window().prescale() || texture->yprescale != window().prescale()))
2007      osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", window().prescale(), window().prescale(), texture->xprescale, texture->yprescale);
2008
2009   width  *= texture->xprescale;
2010   height *= texture->yprescale;
2011   width_create  *= texture->xprescale;
2012   height_create *= texture->yprescale;
2013
2014   // adjust the size for the border (must do this *after* the power of 2 clamp to satisfy
2015   // OpenGL semantics)
2016   if (texture->borderpix)
2017   {
2018      width += 2;
2019      height += 2;
2020      width_create += 2;
2021      height_create += 2;
2022   }
2023      *p_width=width;
2024      *p_height=height;
2025      *p_width_create=width_create;
2026      *p_height_create=height_create;
2027}
2028
2029void sdl_info_ogl::texture_compute_size_type(const render_texinfo *texsource, texture_info *texture, UINT32 flags)
2030{
2031   int finalheight, finalwidth;
2032   int finalheight_create, finalwidth_create;
2033
2034   // if we're not wrapping, add a 1 pixel border on all sides
2035   texture->borderpix = 0; //!(texture->flags & PRIMFLAG_TEXWRAP_MASK);
2036   if (PRIMFLAG_GET_SCREENTEX(flags))
2037   {
2038      texture->borderpix = 0; // don't border the screen right now, there's a bug
2039   }
2040
2041   texture_compute_type_subroutine(texsource, texture, flags);
2042
2043   texture_compute_size_subroutine(texture, flags, texsource->width, texsource->height,
2044                           &finalwidth, &finalheight, &finalwidth_create, &finalheight_create);
2045
2046   // if we added pixels for the border, and that just barely pushed us over, take it back
2047   if (texture->borderpix &&
2048      ((finalwidth > m_texture_max_width && finalwidth - 2 <= m_texture_max_width) ||
2049         (finalheight > m_texture_max_height && finalheight - 2 <= m_texture_max_height)))
2050   {
2051      texture->borderpix = FALSE;
2052
2053      texture_compute_type_subroutine(texsource, texture, flags);
2054
2055      texture_compute_size_subroutine(texture, flags, texsource->width, texsource->height,
2056                              &finalwidth, &finalheight, &finalwidth_create, &finalheight_create);
2057   }
2058
2059   // if we're above the max width/height, do what?
2060   if (finalwidth_create > m_texture_max_width || finalheight_create > m_texture_max_height)
2061   {
2062      static int printed = FALSE;
2063      if (!printed)
2064         osd_printf_warning("Texture too big! (wanted: %dx%d, max is %dx%d)\n", finalwidth_create, finalheight_create, m_texture_max_width, m_texture_max_height);
2065      printed = TRUE;
2066   }
2067
2068   if(!texture->nocopy || texture->type==TEXTURE_TYPE_DYNAMIC || texture->type==TEXTURE_TYPE_SHADER ||
2069      // any of the mame core's device generated bitmap types:
2070      texture->format==SDL_TEXFORMAT_RGB32  ||
2071      texture->format==SDL_TEXFORMAT_RGB32_PALETTED  ||
2072      texture->format==SDL_TEXFORMAT_RGB15  ||
2073      texture->format==SDL_TEXFORMAT_RGB15_PALETTED  ||
2074      texture->format==SDL_TEXFORMAT_PALETTE16  ||
2075      texture->format==SDL_TEXFORMAT_PALETTE16A
2076      )
2077   {
2078      osd_printf_verbose("GL texture: copy %d, shader %d, dynamic %d, %dx%d %dx%d [%s, Equal: %d, Palette: %d,\n"
2079               "            scale %dx%d, border %d, pitch %d,%d/%d], bytes/pix %d\n",
2080         !texture->nocopy, texture->type==TEXTURE_TYPE_SHADER, texture->type==TEXTURE_TYPE_DYNAMIC,
2081         finalwidth, finalheight, finalwidth_create, finalheight_create,
2082         texfmt_to_string[texture->format],
2083         (int)texture_copy_properties[texture->format][SDL_TEXFORMAT_SRC_EQUALS_DEST],
2084         (int)texture_copy_properties[texture->format][SDL_TEXFORMAT_SRC_HAS_PALETTE],
2085         texture->xprescale, texture->yprescale,
2086         texture->borderpix, texsource->rowpixels, finalwidth, m_texture_max_width,
2087         (int)sizeof(UINT32)
2088         );
2089   }
2090
2091   // set the final values
2092   texture->rawwidth = finalwidth;
2093   texture->rawheight = finalheight;
2094   texture->rawwidth_create = finalwidth_create;
2095   texture->rawheight_create = finalheight_create;
2096}
2097
2098//============================================================
2099//  texture_create
2100//============================================================
2101
2102static int gl_checkFramebufferStatus(void)
2103{
2104   GLenum status;
2105   status=(GLenum)pfn_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
2106   switch(status) {
2107      case GL_FRAMEBUFFER_COMPLETE_EXT:
2108         return 0;
2109      case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
2110         osd_printf_error("GL FBO: incomplete,incomplete attachment\n");
2111         return -1;
2112      case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
2113         osd_printf_error("GL FBO: Unsupported framebuffer format\n");
2114         return -1;
2115      case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
2116         osd_printf_error("GL FBO: incomplete,missing attachment\n");
2117         return -1;
2118      case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
2119         osd_printf_error("GL FBO: incomplete,attached images must have same dimensions\n");
2120         return -1;
2121      case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
2122            osd_printf_error("GL FBO: incomplete,attached images must have same format\n");
2123         return -1;
2124      case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
2125         osd_printf_error("GL FBO: incomplete,missing draw buffer\n");
2126         return -1;
2127      case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
2128         osd_printf_error("GL FBO: incomplete,missing read buffer\n");
2129         return -1;
2130#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
2131      case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
2132         osd_printf_error("GL FBO: incomplete, duplicate attachment\n");
2133         return -1;
2134#endif
2135      case 0:
2136         osd_printf_error("GL FBO: incomplete, implementation fault\n");
2137         return -1;
2138      default:
2139         osd_printf_error("GL FBO: incomplete, implementation ERROR\n");
2140         /* fall through */
2141   }
2142   return -1;
2143}
2144
2145static int texture_fbo_create(UINT32 text_unit, UINT32 text_name, UINT32 fbo_name, int width, int height)
2146{
2147   pfn_glActiveTexture(text_unit);
2148   pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_name);
2149   glBindTexture(GL_TEXTURE_2D, text_name);
2150   {
2151      GLint _width, _height;
2152      if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
2153                  0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &_width, &_height, 1) )
2154      {
2155         osd_printf_error("cannot create fbo texture, req: %dx%d, avail: %dx%d - bail out\n",
2156                  width, height, (int)_width, (int)_height);
2157         return -1;
2158      }
2159
2160      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
2161            0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL );
2162   }
2163   // non-screen textures will never be filtered
2164   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2165   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2166
2167   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
2168   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
2169
2170   pfn_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
2171               GL_TEXTURE_2D, text_name, 0);
2172
2173   if ( gl_checkFramebufferStatus() )
2174   {
2175      osd_printf_error("FBO error fbo texture - bail out\n");
2176      return -1;
2177   }
2178
2179   return 0;
2180}
2181
2182int sdl_info_ogl::texture_shader_create(const render_texinfo *texsource, texture_info *texture, UINT32 flags)
2183{
2184   int uniform_location;
2185   int i;
2186   int surf_w_pow2  = get_valid_pow2_value (m_blit_dim.width(), texture->texpow2);
2187   int surf_h_pow2  = get_valid_pow2_value (m_blit_dim.height(), texture->texpow2);
2188
2189   assert ( texture->type==TEXTURE_TYPE_SHADER );
2190
2191   GL_CHECK_ERROR_QUIET();
2192
2193   if( m_glsl_program_num > 1 )
2194   {
2195      // multipass mode
2196      assert(m_usefbo);
2197
2198      // GL_TEXTURE3 GLSL Uniforms
2199      texture->mpass_dest_idx = 0;
2200      texture->mpass_textureunit[0] = GL_TEXTURE3;
2201      texture->mpass_textureunit[1] = GL_TEXTURE2;
2202   }
2203
2204   for(i=0; i<m_glsl_program_num; i++)
2205   {
2206      if ( i<=m_glsl_program_mb2sc )
2207      {
2208         m_glsl_program[i] = glsl_shader_get_program_mamebm(glsl_shader_feature, i);
2209      } else {
2210         m_glsl_program[i] = glsl_shader_get_program_scrn(i-1-m_glsl_program_mb2sc);
2211      }
2212      pfn_glUseProgramObjectARB(m_glsl_program[i]);
2213
2214      if ( i<=m_glsl_program_mb2sc )
2215      {
2216         // GL_TEXTURE0 GLSL Uniforms
2217         uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture");
2218         pfn_glUniform1iARB(uniform_location, 0);
2219         GL_CHECK_ERROR_NORMAL();
2220      }
2221
2222      {
2223         GLfloat color_texture_sz[2] = { (GLfloat)texture->rawwidth, (GLfloat)texture->rawheight };
2224         uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_sz");
2225         pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_sz[0]));
2226         GL_CHECK_ERROR_NORMAL();
2227      }
2228
2229      GLfloat color_texture_pow2_sz[2] = { (GLfloat)texture->rawwidth_create, (GLfloat)texture->rawheight_create };
2230      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "color_texture_pow2_sz");
2231      pfn_glUniform2fvARB(uniform_location, 1, &(color_texture_pow2_sz[0]));
2232      GL_CHECK_ERROR_NORMAL();
2233
2234      GLfloat screen_texture_sz[2] = { (GLfloat) m_blit_dim.width(), (GLfloat) m_blit_dim.height() };
2235      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_sz");
2236      pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_sz[0]));
2237      GL_CHECK_ERROR_NORMAL();
2238
2239      GLfloat screen_texture_pow2_sz[2] = { (GLfloat)surf_w_pow2, (GLfloat)surf_h_pow2 };
2240      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[i], "screen_texture_pow2_sz");
2241      pfn_glUniform2fvARB(uniform_location, 1, &(screen_texture_pow2_sz[0]));
2242      GL_CHECK_ERROR_NORMAL();
2243   }
2244
2245   pfn_glUseProgramObjectARB(m_glsl_program[0]); // start with 1st shader
2246
2247   if( m_glsl_program_num > 1 )
2248   {
2249      // multipass mode
2250      // GL_TEXTURE2/GL_TEXTURE3
2251      pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
2252      glGenTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
2253
2254      for (i=0; i<2; i++)
2255      {
2256         if ( texture_fbo_create(texture->mpass_textureunit[i],
2257                           texture->mpass_texture_mamebm[i],
2258                  texture->mpass_fbo_mamebm[i],
2259                  texture->rawwidth_create, texture->rawheight_create) )
2260         {
2261            return -1;
2262         }
2263      }
2264
2265      pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
2266
2267      osd_printf_verbose("GL texture: mpass mame-bmp   2x %dx%d (pow2 %dx%d)\n",
2268         texture->rawwidth, texture->rawheight, texture->rawwidth_create, texture->rawheight_create);
2269   }
2270
2271   if( m_glsl_program_num > 1 && m_glsl_program_mb2sc < m_glsl_program_num - 1 )
2272   {
2273      // multipass mode
2274      // GL_TEXTURE2/GL_TEXTURE3
2275      pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
2276      glGenTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
2277
2278      for (i=0; i<2; i++)
2279      {
2280         if ( texture_fbo_create(texture->mpass_textureunit[i],
2281                           texture->mpass_texture_scrn[i],
2282                  texture->mpass_fbo_scrn[i],
2283                  surf_w_pow2, surf_h_pow2) )
2284         {
2285            return -1;
2286         }
2287      }
2288
2289      osd_printf_verbose("GL texture: mpass screen-bmp 2x %dx%d (pow2 %dx%d)\n",
2290         m_width, m_height, surf_w_pow2, surf_h_pow2);
2291   }
2292
2293   // GL_TEXTURE0
2294   // get a name for this texture
2295   glGenTextures(1, (GLuint *)&texture->texture);
2296   pfn_glActiveTexture(GL_TEXTURE0);
2297   glBindTexture(GL_TEXTURE_2D, texture->texture);
2298
2299   glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth_create);
2300
2301   UINT32 * dummy = NULL;
2302   GLint _width, _height;
2303   if ( gl_texture_check_size(GL_TEXTURE_2D, 0, GL_RGBA8,
2304               texture->rawwidth_create, texture->rawheight_create,
2305               0,
2306               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
2307               &_width, &_height, 1) )
2308   {
2309      osd_printf_error("cannot create bitmap texture, req: %dx%d, avail: %dx%d - bail out\n",
2310         texture->rawwidth_create, texture->rawheight_create, (int)_width, (int)_height);
2311      return -1;
2312   }
2313
2314   dummy = (UINT32 *) malloc(texture->rawwidth_create * texture->rawheight_create * sizeof(UINT32));
2315   memset(dummy, 0, texture->rawwidth_create * texture->rawheight_create * sizeof(UINT32));
2316   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
2317         texture->rawwidth_create, texture->rawheight_create,
2318         0,
2319         GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, dummy);
2320         glFinish(); // should not be necessary, .. but make sure we won't access the memory after free
2321   free(dummy);
2322
2323   if ((PRIMFLAG_GET_SCREENTEX(flags)) && video_config.filter)
2324   {
2325      assert( glsl_shader_feature == GLSL_SHADER_FEAT_PLAIN );
2326
2327      // screen textures get the user's choice of filtering
2328      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2329      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2330   }
2331   else
2332   {
2333      // non-screen textures will never be filtered
2334      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2335      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2336   }
2337
2338   // set wrapping mode appropriately
2339   if (texture->flags & PRIMFLAG_TEXWRAP_MASK)
2340   {
2341      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2342      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2343   }
2344   else
2345   {
2346      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
2347      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
2348   }
2349
2350   GL_CHECK_ERROR_NORMAL();
2351
2352   return 0;
2353}
2354
2355texture_info *sdl_info_ogl::texture_create(const render_texinfo *texsource, UINT32 flags)
2356{
2357   texture_info *texture;
2358
2359   // allocate a new texture
2360   texture = global_alloc(texture_info);
2361
2362   // fill in the core data
2363   texture->hash = texture_compute_hash(texsource, flags);
2364   texture->flags = flags;
2365   texture->texinfo = *texsource;
2366   texture->texinfo.seqid = -1; // force set data
2367   if (PRIMFLAG_GET_SCREENTEX(flags))
2368   {
2369      texture->xprescale = window().prescale();
2370      texture->yprescale = window().prescale();
2371   }
2372   else
2373   {
2374      texture->xprescale = 1;
2375      texture->yprescale = 1;
2376   }
2377
2378   // set the texture_format
2379      //
2380      // src/emu/validity.c:validate_display() states,
2381      // an emulated driver can only produce
2382      //      BITMAP_FORMAT_IND16 and BITMAP_FORMAT_RGB32
2383      // where only the first original paletted.
2384      //
2385      // other paletted formats, i.e.:
2386      //   SDL_TEXFORMAT_RGB32_PALETTED, SDL_TEXFORMAT_RGB15_PALETTED and SDL_TEXFORMAT_YUY16_PALETTED
2387      // add features like brightness etc by the mame core
2388      //
2389      // all palette lookup may be implemented using shaders later on ..
2390      // that's why we keep the EQUAL flag TRUE, for all original true color bitmaps.
2391      //
2392   switch (PRIMFLAG_GET_TEXFORMAT(flags))
2393   {
2394      case TEXFORMAT_ARGB32:
2395         texture->format = SDL_TEXFORMAT_ARGB32;
2396         break;
2397      case TEXFORMAT_RGB32:
2398         if (texsource->palette != NULL)
2399            texture->format = SDL_TEXFORMAT_RGB32_PALETTED;
2400         else
2401            texture->format = SDL_TEXFORMAT_RGB32;
2402         break;
2403      case TEXFORMAT_PALETTE16:
2404         texture->format = SDL_TEXFORMAT_PALETTE16;
2405         break;
2406      case TEXFORMAT_PALETTEA16:
2407         texture->format = SDL_TEXFORMAT_PALETTE16A;
2408         break;
2409      case TEXFORMAT_YUY16:
2410         if (texsource->palette != NULL)
2411            texture->format = SDL_TEXFORMAT_YUY16_PALETTED;
2412         else
2413            texture->format = SDL_TEXFORMAT_YUY16;
2414         break;
2415
2416      default:
2417         osd_printf_error("Unknown textureformat %d\n", PRIMFLAG_GET_TEXFORMAT(flags));
2418   }
2419
2420   // compute the size
2421   texture_compute_size_type(texsource, texture, flags);
2422
2423   texture->pbo=0;
2424
2425   if ( texture->type != TEXTURE_TYPE_SHADER && m_useglsl)
2426   {
2427      pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
2428   }
2429
2430   if ( texture->type==TEXTURE_TYPE_SHADER )
2431   {
2432      if ( texture_shader_create(texsource, texture, flags) )
2433      {
2434         global_free(texture);
2435         return NULL;
2436      }
2437   }
2438   else
2439   {
2440      // get a name for this texture
2441      glGenTextures(1, (GLuint *)&texture->texture);
2442
2443      glEnable(texture->texTarget);
2444
2445      // make sure we're operating on *this* texture
2446      glBindTexture(texture->texTarget, texture->texture);
2447
2448      // this doesn't actually upload, it just sets up the PBO's parameters
2449      glTexImage2D(texture->texTarget, 0, GL_RGBA8,
2450            texture->rawwidth_create, texture->rawheight_create,
2451            texture->borderpix ? 1 : 0,
2452            GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
2453
2454      if ((PRIMFLAG_GET_SCREENTEX(flags)) && video_config.filter)
2455      {
2456         // screen textures get the user's choice of filtering
2457         glTexParameteri(texture->texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2458         glTexParameteri(texture->texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2459      }
2460      else
2461      {
2462         // non-screen textures will never be filtered
2463         glTexParameteri(texture->texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2464         glTexParameteri(texture->texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2465      }
2466
2467      if( texture->texTarget==GL_TEXTURE_RECTANGLE_ARB )
2468      {
2469         // texture rectangles can't wrap
2470         glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
2471         glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
2472      } else {
2473         // set wrapping mode appropriately
2474         if (texture->flags & PRIMFLAG_TEXWRAP_MASK)
2475         {
2476            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2477            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2478         }
2479         else
2480         {
2481            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
2482            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
2483         }
2484      }
2485   }
2486
2487   if ( texture->type == TEXTURE_TYPE_DYNAMIC )
2488   {
2489      assert(m_usepbo);
2490
2491      // create the PBO
2492      pfn_glGenBuffers(1, (GLuint *)&texture->pbo);
2493
2494      pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
2495
2496      // set up the PBO dimension, ..
2497      pfn_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
2498                     texture->rawwidth * texture->rawheight * sizeof(UINT32),
2499               NULL, GL_STREAM_DRAW);
2500   }
2501
2502   if ( !texture->nocopy && texture->type!=TEXTURE_TYPE_DYNAMIC )
2503   {
2504      texture->data = (UINT32 *) malloc(texture->rawwidth* texture->rawheight * sizeof(UINT32));
2505      texture->data_own=TRUE;
2506   }
2507
2508   // add us to the texture list
2509   if (m_texhash[texture->hash] == NULL)
2510      m_texhash[texture->hash] = texture;
2511   else
2512   {
2513      int i;
2514      for (i = HASH_SIZE; i < HASH_SIZE + OVERFLOW_SIZE; i++)
2515         if (m_texhash[i] == NULL)
2516         {
2517            m_texhash[i] = texture;
2518            break;
2519         }
2520      assert_always(i < HASH_SIZE + OVERFLOW_SIZE, "texture hash exhausted ...");
2521   }
2522
2523   if(m_usevbo)
2524   {
2525      // Generate And Bind The Texture Coordinate Buffer
2526      pfn_glGenBuffers( 1, &(texture->texCoordBufferName) );
2527      pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
2528      // Load The Data
2529      pfn_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW );
2530      glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // we are using ARB VBO buffers
2531   }
2532   else
2533   {
2534      glTexCoordPointer(2, GL_FLOAT, 0, texture->texCoord);
2535   }
2536
2537   return texture;
2538}
2539
2540//============================================================
2541//  copyline_palette16
2542//============================================================
2543
2544INLINE void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2545{
2546   int x;
2547
2548   assert(xborderpix == 0 || xborderpix == 1);
2549   if (xborderpix)
2550      *dst++ = 0xff000000 | palette[*src];
2551   for (x = 0; x < width; x++)
2552   {
2553      int srcpix = *src++;
2554      for (int x2 = 0; x2 < xprescale; x2++)
2555         *dst++ = 0xff000000 | palette[srcpix];
2556   }
2557   if (xborderpix)
2558      *dst++ = 0xff000000 | palette[*--src];
2559}
2560
2561
2562
2563//============================================================
2564//  copyline_palettea16
2565//============================================================
2566
2567INLINE void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2568{
2569   int x;
2570
2571   assert(xborderpix == 0 || xborderpix == 1);
2572   if (xborderpix)
2573      *dst++ = palette[*src];
2574   for (x = 0; x < width; x++)
2575   {
2576      int srcpix = *src++;
2577      for (int x2 = 0; x2 < xprescale; x2++)
2578         *dst++ = palette[srcpix];
2579   }
2580   if (xborderpix)
2581      *dst++ = palette[*--src];
2582}
2583
2584
2585
2586//============================================================
2587//  copyline_rgb32
2588//============================================================
2589
2590INLINE void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2591{
2592   int x;
2593
2594   assert(xborderpix == 0 || xborderpix == 1);
2595
2596   // palette (really RGB map) case
2597   if (palette != NULL)
2598   {
2599      if (xborderpix)
2600      {
2601         rgb_t srcpix = *src;
2602         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2603      }
2604      for (x = 0; x < width; x++)
2605      {
2606         rgb_t srcpix = *src++;
2607         for (int x2 = 0; x2 < xprescale; x2++)
2608         {
2609            *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2610         }
2611      }
2612      if (xborderpix)
2613      {
2614         rgb_t srcpix = *--src;
2615         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2616      }
2617   }
2618
2619   // direct case
2620   else
2621   {
2622      if (xborderpix)
2623         *dst++ = 0xff000000 | *src;
2624      for (x = 0; x < width; x++)
2625      {
2626         rgb_t srcpix = *src++;
2627
2628         for (int x2 = 0; x2 < xprescale; x2++)
2629         {
2630            *dst++ = 0xff000000 | srcpix;
2631         }
2632      }
2633      if (xborderpix)
2634         *dst++ = 0xff000000 | *--src;
2635   }
2636}
2637
2638//============================================================
2639//  copyline_argb32
2640//============================================================
2641
2642INLINE void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2643{
2644   int x;
2645
2646   assert(xborderpix == 0 || xborderpix == 1);
2647
2648   // palette (really RGB map) case
2649   if (palette != NULL)
2650   {
2651      if (xborderpix)
2652      {
2653         rgb_t srcpix = *src;
2654         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2655      }
2656      for (x = 0; x < width; x++)
2657      {
2658         rgb_t srcpix = *src++;
2659         for (int x2 = 0; x2 < xprescale; x2++)
2660            *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2661      }
2662      if (xborderpix)
2663      {
2664         rgb_t srcpix = *--src;
2665         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2666      }
2667   }
2668
2669   // direct case
2670   else
2671   {
2672      if (xborderpix)
2673         *dst++ = *src;
2674      for (x = 0; x < width; x++)
2675      {
2676         rgb_t srcpix = *src++;
2677         for (int x2 = 0; x2 < xprescale; x2++)
2678            *dst++ = srcpix;
2679      }
2680      if (xborderpix)
2681         *dst++ = *--src;
2682   }
2683}
2684
2685INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr)
2686{
2687   /* original equations:
2688
2689       C = Y - 16
2690       D = Cb - 128
2691       E = Cr - 128
2692
2693       R = clip(( 298 * C           + 409 * E + 128) >> 8)
2694       G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
2695       B = clip(( 298 * C + 516 * D           + 128) >> 8)
2696
2697       R = clip(( 298 * (Y - 16)                    + 409 * (Cr - 128) + 128) >> 8)
2698       G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8)
2699       B = clip(( 298 * (Y - 16) + 516 * (Cb - 128)                    + 128) >> 8)
2700
2701       R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
2702       G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
2703       B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
2704
2705       R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
2706       G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
2707       B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
2708   */
2709   int r, g, b, common;
2710
2711   common = 298 * y - 298 * 16;
2712   r = (common +                        409 * cr - 409 * 128 + 128) >> 8;
2713   g = (common - 100 * cb + 100 * 128 - 208 * cr + 208 * 128 + 128) >> 8;
2714   b = (common + 516 * cb - 516 * 128                        + 128) >> 8;
2715
2716   if (r < 0) r = 0;
2717   else if (r > 255) r = 255;
2718   if (g < 0) g = 0;
2719   else if (g > 255) g = 255;
2720   if (b < 0) b = 0;
2721   else if (b > 255) b = 255;
2722
2723   return rgb_t(0xff, r, g, b);
2724}
2725
2726//============================================================
2727//  copyline_yuy16_to_argb
2728//============================================================
2729
2730INLINE void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix, int xprescale)
2731{
2732   int x;
2733
2734   assert(xborderpix == 0 || xborderpix == 2);
2735   assert(width % 2 == 0);
2736
2737   // palette (really RGB map) case
2738   if (palette != NULL)
2739   {
2740      if (xborderpix)
2741      {
2742         UINT16 srcpix0 = src[0];
2743         UINT16 srcpix1 = src[1];
2744         UINT8 cb = srcpix0 & 0xff;
2745         UINT8 cr = srcpix1 & 0xff;
2746         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2747         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2748      }
2749      for (x = 0; x < width / 2; x++)
2750      {
2751         UINT16 srcpix0 = *src++;
2752         UINT16 srcpix1 = *src++;
2753         UINT8 cb = srcpix0 & 0xff;
2754         UINT8 cr = srcpix1 & 0xff;
2755         for (int x2 = 0; x2 < xprescale/2; x2++)
2756         {
2757            *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2758            *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2759         }
2760      }
2761      if (xborderpix)
2762      {
2763         UINT16 srcpix1 = *--src;
2764         UINT16 srcpix0 = *--src;
2765         UINT8 cb = srcpix0 & 0xff;
2766         UINT8 cr = srcpix1 & 0xff;
2767         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2768         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2769      }
2770   }
2771
2772   // direct case
2773   else
2774   {
2775      if (xborderpix)
2776      {
2777         UINT16 srcpix0 = src[0];
2778         UINT16 srcpix1 = src[1];
2779         UINT8 cb = srcpix0 & 0xff;
2780         UINT8 cr = srcpix1 & 0xff;
2781         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2782         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2783      }
2784      for (x = 0; x < width; x += 2)
2785      {
2786         UINT16 srcpix0 = *src++;
2787         UINT16 srcpix1 = *src++;
2788         UINT8 cb = srcpix0 & 0xff;
2789         UINT8 cr = srcpix1 & 0xff;
2790         for (int x2 = 0; x2 < xprescale/2; x2++)
2791         {
2792            *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2793            *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2794         }
2795      }
2796      if (xborderpix)
2797      {
2798         UINT16 srcpix1 = *--src;
2799         UINT16 srcpix0 = *--src;
2800         UINT8 cb = srcpix0 & 0xff;
2801         UINT8 cr = srcpix1 & 0xff;
2802         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2803         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2804      }
2805   }
2806}
2807
2808//============================================================
2809//  texture_set_data
2810//============================================================
2811
2812static void texture_set_data(texture_info *texture, const render_texinfo *texsource, UINT32 flags)
2813{
2814   if ( texture->type == TEXTURE_TYPE_DYNAMIC )
2815   {
2816      assert(texture->pbo);
2817      assert(!texture->nocopy);
2818
2819      texture->data = (UINT32 *) pfn_glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
2820   }
2821
2822   // note that nocopy and borderpix are mutually exclusive, IOW
2823   // they cannot be both true, thus this cannot lead to the
2824   // borderpix code below writing to texsource->base .
2825   if (texture->nocopy)
2826   {
2827      texture->data = (UINT32 *) texsource->base;
2828   }
2829
2830   // always fill non-wrapping textures with an extra pixel on the top
2831   if (texture->borderpix)
2832   {
2833      memset(texture->data, 0,
2834            (texsource->width * texture->xprescale + 2) * sizeof(UINT32));
2835   }
2836
2837   // when nescesarry copy (and convert) the data
2838   if (!texture->nocopy)
2839   {
2840      int y, y2;
2841      UINT8 *dst;
2842
2843      for (y = 0; y < texsource->height; y++)
2844      {
2845         for (y2 = 0; y2 < texture->yprescale; y2++)
2846         {
2847            dst = (UINT8 *)(texture->data + (y * texture->yprescale + texture->borderpix + y2) * texture->rawwidth);
2848
2849            switch (PRIMFLAG_GET_TEXFORMAT(flags))
2850            {
2851               case TEXFORMAT_PALETTE16:
2852                  copyline_palette16((UINT32 *)dst, (UINT16 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2853                  break;
2854
2855               case TEXFORMAT_PALETTEA16:
2856                  copyline_palettea16((UINT32 *)dst, (UINT16 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2857                  break;
2858
2859               case TEXFORMAT_RGB32:
2860                  copyline_rgb32((UINT32 *)dst, (UINT32 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2861                  break;
2862
2863               case TEXFORMAT_ARGB32:
2864                  copyline_argb32((UINT32 *)dst, (UINT32 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2865                  break;
2866
2867               case TEXFORMAT_YUY16:
2868                  copyline_yuy16_to_argb((UINT32 *)dst, (UINT16 *)texsource->base + y * texsource->rowpixels, texsource->width, texsource->palette, texture->borderpix, texture->xprescale);
2869                  break;
2870
2871               default:
2872                  osd_printf_error("Unknown texture blendmode=%d format=%d\n", PRIMFLAG_GET_BLENDMODE(flags), PRIMFLAG_GET_TEXFORMAT(flags));
2873                  break;
2874            }
2875         }
2876      }
2877   }
2878
2879   // always fill non-wrapping textures with an extra pixel on the bottom
2880   if (texture->borderpix)
2881   {
2882      memset((UINT8 *)texture->data +
2883            (texsource->height + 1) * texture->rawwidth * sizeof(UINT32),
2884            0,
2885         (texsource->width * texture->xprescale + 2) * sizeof(UINT32));
2886   }
2887
2888   if ( texture->type == TEXTURE_TYPE_SHADER )
2889   {
2890      pfn_glActiveTexture(GL_TEXTURE0);
2891      glBindTexture(texture->texTarget, texture->texture);
2892
2893      if (texture->nocopy)
2894         glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->texinfo.rowpixels);
2895      else
2896         glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
2897
2898      // and upload the image
2899      glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
2900            GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texture->data);
2901   }
2902   else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
2903   {
2904      glBindTexture(texture->texTarget, texture->texture);
2905
2906      glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
2907
2908      // unmap the buffer from the CPU space so it can DMA
2909      pfn_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
2910
2911      // kick off the DMA
2912      glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
2913               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
2914   }
2915   else
2916   {
2917      glBindTexture(texture->texTarget, texture->texture);
2918
2919      // give the card a hint
2920      if (texture->nocopy)
2921         glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->texinfo.rowpixels);
2922      else
2923         glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
2924
2925      // and upload the image
2926      glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
2927                  GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, texture->data);
2928   }
2929}
2930
2931//============================================================
2932//  texture_find
2933//============================================================
2934
2935static int compare_texture_primitive(const texture_info *texture, const render_primitive *prim)
2936{
2937   if (texture->texinfo.base == prim->texture.base &&
2938      texture->texinfo.width == prim->texture.width &&
2939      texture->texinfo.height == prim->texture.height &&
2940      texture->texinfo.rowpixels == prim->texture.rowpixels &&
2941      /* texture->texinfo.palette == prim->texture.palette && */
2942      ((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0)
2943      return 1;
2944   else
2945      return 0;
2946}
2947
2948texture_info *sdl_info_ogl::texture_find(const render_primitive *prim)
2949{
2950   HashT texhash = texture_compute_hash(&prim->texture, prim->flags);
2951   texture_info *texture;
2952
2953   texture = m_texhash[texhash];
2954   if (texture != NULL)
2955   {
2956      int i;
2957      if (compare_texture_primitive(texture, prim))
2958         return texture;
2959      for (i=HASH_SIZE; i<HASH_SIZE + OVERFLOW_SIZE; i++)
2960      {
2961         texture = m_texhash[i];
2962         if (texture != NULL && compare_texture_primitive(texture, prim))
2963            return texture;
2964      }
2965   }
2966   return NULL;
2967}
2968
2969//============================================================
2970//  texture_update
2971//============================================================
2972
2973void sdl_info_ogl::texture_coord_update(texture_info *texture, const render_primitive *prim, int shaderIdx)
2974{
2975   float ustart = 0.0f, ustop = 0.0f;            // beginning/ending U coordinates
2976   float vstart = 0.0f, vstop = 0.0f;            // beginning/ending V coordinates
2977   float du, dv;
2978
2979   if ( texture->type != TEXTURE_TYPE_SHADER ||
2980         ( texture->type == TEXTURE_TYPE_SHADER && shaderIdx<=m_glsl_program_mb2sc ) )
2981   {
2982      // compute the U/V scale factors
2983      if (texture->borderpix)
2984      {
2985         int unscaledwidth = (texture->rawwidth_create-2) / texture->xprescale + 2;
2986         int unscaledheight = (texture->rawheight_create-2) / texture->yprescale + 2;
2987         ustart = 1.0f / (float)(unscaledwidth);
2988         ustop = (float)(prim->texture.width + 1) / (float)(unscaledwidth);
2989         vstart = 1.0f / (float)(unscaledheight);
2990         vstop = (float)(prim->texture.height + 1) / (float)(unscaledheight);
2991      }
2992      else
2993      {
2994         ustop  = (float)(prim->texture.width*texture->xprescale) / (float)texture->rawwidth_create;
2995         vstop  = (float)(prim->texture.height*texture->yprescale) / (float)texture->rawheight_create;
2996      }
2997   }
2998   else if ( texture->type == TEXTURE_TYPE_SHADER && shaderIdx>m_glsl_program_mb2sc )
2999   {
3000      int surf_w_pow2  = get_valid_pow2_value (m_width, texture->texpow2);
3001      int surf_h_pow2  = get_valid_pow2_value (m_height, texture->texpow2);
3002
3003      ustop  = (float)(m_width) / (float)surf_w_pow2;
3004      vstop  = (float)(m_height) / (float)surf_h_pow2;
3005
3006   }
3007   else
3008   {
3009      assert(0); // ??
3010   }
3011
3012   du = ustop - ustart;
3013   dv = vstop - vstart;
3014
3015   if ( texture->texTarget == GL_TEXTURE_RECTANGLE_ARB )
3016   {
3017      // texture coordinates for TEXTURE_RECTANGLE are 0,0 -> w,h
3018      // rather than 0,0 -> 1,1 as with normal OpenGL texturing
3019      du *= (float)texture->rawwidth;
3020      dv *= (float)texture->rawheight;
3021   }
3022
3023   if ( texture->type == TEXTURE_TYPE_SHADER && shaderIdx!=m_glsl_program_mb2sc )
3024   {
3025      // 1:1 tex coord CCW (0/0) (1/0) (1/1) (0/1)
3026      // we must go CW here due to the mame bitmap order
3027      texture->texCoord[0]=ustart + du * 0.0f;
3028      texture->texCoord[1]=vstart + dv * 1.0f;
3029      texture->texCoord[2]=ustart + du * 1.0f;
3030      texture->texCoord[3]=vstart + dv * 1.0f;
3031      texture->texCoord[4]=ustart + du * 1.0f;
3032      texture->texCoord[5]=vstart + dv * 0.0f;
3033      texture->texCoord[6]=ustart + du * 0.0f;
3034      texture->texCoord[7]=vstart + dv * 0.0f;
3035   }
3036   else
3037   {
3038      // transformation: mamebm -> scrn
3039      texture->texCoord[0]=ustart + du * prim->texcoords.tl.u;
3040      texture->texCoord[1]=vstart + dv * prim->texcoords.tl.v;
3041      texture->texCoord[2]=ustart + du * prim->texcoords.tr.u;
3042      texture->texCoord[3]=vstart + dv * prim->texcoords.tr.v;
3043      texture->texCoord[4]=ustart + du * prim->texcoords.br.u;
3044      texture->texCoord[5]=vstart + dv * prim->texcoords.br.v;
3045      texture->texCoord[6]=ustart + du * prim->texcoords.bl.u;
3046      texture->texCoord[7]=vstart + dv * prim->texcoords.bl.v;
3047   }
3048}
3049
3050void sdl_info_ogl::texture_mpass_flip(texture_info *texture, int shaderIdx)
3051{
3052   UINT32 mpass_src_idx = texture->mpass_dest_idx;
3053
3054   texture->mpass_dest_idx = (mpass_src_idx+1) % 2;
3055
3056   if ( shaderIdx>0 )
3057   {
3058      int uniform_location;
3059      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "mpass_texture");
3060      pfn_glUniform1iARB(uniform_location, texture->mpass_textureunit[mpass_src_idx]-GL_TEXTURE0);
3061      GL_CHECK_ERROR_NORMAL();
3062   }
3063
3064   pfn_glActiveTexture(texture->mpass_textureunit[mpass_src_idx]);
3065   if ( shaderIdx<=m_glsl_program_mb2sc )
3066   {
3067      glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[mpass_src_idx]);
3068   }
3069   else
3070   {
3071      glBindTexture(texture->texTarget, texture->mpass_texture_scrn[mpass_src_idx]);
3072   }
3073   pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
3074   glBindTexture(texture->texTarget, 0);
3075
3076   pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
3077
3078   if ( shaderIdx<m_glsl_program_num-1 )
3079   {
3080      if ( shaderIdx>=m_glsl_program_mb2sc )
3081      {
3082         glBindTexture(texture->texTarget, texture->mpass_texture_scrn[texture->mpass_dest_idx]);
3083         pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_scrn[texture->mpass_dest_idx]);
3084      }
3085      else
3086      {
3087         glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[texture->mpass_dest_idx]);
3088         pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_mamebm[texture->mpass_dest_idx]);
3089      }
3090
3091      if ( shaderIdx==0 )
3092      {
3093         glPushAttrib(GL_VIEWPORT_BIT);
3094         GL_CHECK_ERROR_NORMAL();
3095         glViewport(0.0, 0.0, (GLsizei)texture->rawwidth, (GLsizei)texture->rawheight);
3096      }
3097      else if ( shaderIdx==m_glsl_program_mb2sc )
3098      {
3099         assert ( m_glsl_program_mb2sc < m_glsl_program_num-1 );
3100         glPopAttrib(); // glViewport(0.0, 0.0, (GLsizei)window().width, (GLsizei)window().height)
3101         GL_CHECK_ERROR_NORMAL();
3102      }
3103      glClear(GL_COLOR_BUFFER_BIT); // make sure the whole texture is redrawn ..
3104   }
3105   else
3106   {
3107      glBindTexture(texture->texTarget, 0);
3108      pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3109
3110      if ( m_glsl_program_mb2sc == m_glsl_program_num-1 )
3111      {
3112         glPopAttrib(); // glViewport(0.0, 0.0, (GLsizei)window().width, (GLsizei)window().height)
3113         GL_CHECK_ERROR_NORMAL();
3114      }
3115
3116      pfn_glActiveTexture(GL_TEXTURE0);
3117      glBindTexture(texture->texTarget, 0);
3118   }
3119}
3120
3121void sdl_info_ogl::texture_shader_update(texture_info *texture, render_container *container, int shaderIdx)
3122{
3123   int uniform_location;
3124   GLfloat vid_attributes[4];
3125
3126   if (container!=NULL)
3127   {
3128      render_container::user_settings settings;
3129      container->get_user_settings(settings);
3130      /* FIXME: the code below is in just for illustration issue on
3131       * how to set shader variables. gamma, contrast and brightness are
3132       * handled already by the core
3133       */
3134      vid_attributes[0] = settings.m_gamma;
3135      vid_attributes[1] = settings.m_contrast;
3136      vid_attributes[2] = settings.m_brightness;
3137      vid_attributes[3] = 0.0f;
3138      uniform_location = pfn_glGetUniformLocationARB(m_glsl_program[shaderIdx], "vid_attributes");
3139      pfn_glUniform4fvARB(uniform_location, 1, &(vid_attributes[shaderIdx]));
3140      if ( GL_CHECK_ERROR_QUIET() ) {
3141         osd_printf_verbose("GLSL: could not set 'vid_attributes' for shader prog idx %d\n", shaderIdx);
3142      }
3143   }
3144}
3145
3146texture_info * sdl_info_ogl::texture_update(const render_primitive *prim, int shaderIdx)
3147{
3148   texture_info *texture = texture_find(prim);
3149   int texBound = 0;
3150
3151   // if we didn't find one, create a new texture
3152   if (texture == NULL && prim->texture.base != NULL)
3153   {
3154      texture = texture_create(&prim->texture, prim->flags);
3155   }
3156   else if (texture != NULL)
3157   {
3158      if ( texture->type == TEXTURE_TYPE_SHADER )
3159      {
3160         pfn_glUseProgramObjectARB(m_glsl_program[shaderIdx]); // back to our shader
3161      }
3162      else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
3163      {
3164         assert ( m_usepbo ) ;
3165         pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
3166         glEnable(texture->texTarget);
3167      }
3168      else
3169      {
3170         glEnable(texture->texTarget);
3171      }
3172   }
3173
3174   if (texture != NULL)
3175   {
3176      if ( texture->type == TEXTURE_TYPE_SHADER )
3177      {
3178         texture_shader_update(texture, prim->container, shaderIdx);
3179         if ( m_glsl_program_num>1 )
3180         {
3181            texture_mpass_flip(texture, shaderIdx);
3182         }
3183      }
3184
3185      if ( shaderIdx==0 ) // redundant for subsequent multipass shader
3186      {
3187         if (prim->texture.base != NULL && texture->texinfo.seqid != prim->texture.seqid)
3188         {
3189            texture->texinfo.seqid = prim->texture.seqid;
3190
3191            // if we found it, but with a different seqid, copy the data
3192            texture_set_data(texture, &prim->texture, prim->flags);
3193            texBound=1;
3194         }
3195      }
3196
3197      if (!texBound) {
3198         glBindTexture(texture->texTarget, texture->texture);
3199      }
3200      texture_coord_update(texture, prim, shaderIdx);
3201
3202      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3203      if(m_usevbo)
3204      {
3205         pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
3206         // Load The Data
3207         pfn_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord );
3208         glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // we are using ARB VBO buffers
3209      }
3210      else
3211      {
3212         glTexCoordPointer(2, GL_FLOAT, 0, texture->texCoord);
3213      }
3214   }
3215
3216      return texture;
3217}
3218
3219void sdl_info_ogl::texture_disable(texture_info * texture)
3220{
3221   if ( texture->type == TEXTURE_TYPE_SHADER )
3222   {
3223      assert ( m_useglsl );
3224      pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
3225   } else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
3226   {
3227      pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
3228      glDisable(texture->texTarget);
3229   } else {
3230      glDisable(texture->texTarget);
3231   }
3232}
3233
3234void sdl_info_ogl::texture_all_disable()
3235{
3236   if ( m_useglsl )
3237   {
3238      pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
3239
3240      pfn_glActiveTexture(GL_TEXTURE3);
3241      glBindTexture(GL_TEXTURE_2D, 0);
3242      if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3243      pfn_glActiveTexture(GL_TEXTURE2);
3244      glBindTexture(GL_TEXTURE_2D, 0);
3245      if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3246      pfn_glActiveTexture(GL_TEXTURE1);
3247      glBindTexture(GL_TEXTURE_2D, 0);
3248      if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3249      pfn_glActiveTexture(GL_TEXTURE0);
3250      glBindTexture(GL_TEXTURE_2D, 0);
3251      if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
3252   }
3253   glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
3254
3255   if(m_usetexturerect)
3256   {
3257      glDisable(GL_TEXTURE_RECTANGLE_ARB);
3258   }
3259   glDisable(GL_TEXTURE_2D);
3260
3261   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3262   if(m_usevbo)
3263   {
3264      pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); // unbind ..
3265   }
3266   if ( m_usepbo )
3267   {
3268      pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
3269   }
3270}
trunk/src/osd/sdl/drawsdl.c
r244651r244652
1//============================================================
2//
3//  drawsdl.c - SDL software and OpenGL implementation
4//
5//  Copyright (c) 1996-2011, Nicola Salmoria and the MAME Team.
6//  Visit http://mamedev.org for licensing and usage restrictions.
7//
8//  SDLMAME by Olivier Galibert and R. Belmont
9//
10//============================================================
11
12// standard C headers
13#include <math.h>
14#include <stdio.h>
15
16// MAME headers
17#include "emu.h"
18#include "ui/ui.h"
19#include "rendersw.inc"
20
21// standard SDL headers
22#include "sdlinc.h"
23
24// OSD headers
25#include "osdsdl.h"
26#include "window.h"
27
28//============================================================
29//  DEBUGGING
30//============================================================
31
32//============================================================
33//  CONSTANTS
34//============================================================
35
36//============================================================
37//  TYPES
38//============================================================
39
40struct sdl_scale_mode;
41
42#if (SDLMAME_SDL2)
43#define DRAW2_SCALEMODE_NEAREST "0"
44#define DRAW2_SCALEMODE_LINEAR  "1"
45#define DRAW2_SCALEMODE_BEST    "2"
46#endif
47
48/* sdl_info is the information about SDL for the current screen */
49class sdl_info : public osd_renderer
50{
51public:
52
53   sdl_info(osd_window *w, int extra_flags)
54   : osd_renderer(w, extra_flags),
55   #if (SDLMAME_SDL2)
56   m_sdl_renderer(NULL),
57   m_texture_id(NULL),
58   #else
59   m_yuvsurf(NULL),
60   #endif
61   m_yuv_lookup(NULL),
62   m_yuv_bitmap(NULL),
63   //m_hw_scale_width(0),
64   //m_hw_scale_height(0),
65   m_last_hofs(0),
66   m_last_vofs(0),
67   m_blit_dim(0, 0),
68   m_last_dim(0, 0)
69   { }
70
71   /* virtual */ int create();
72   /* virtual */ int draw(const int update);
73   /* virtual */ int xy_to_render_target(const int x, const int y, int *xt, int *yt);
74   /* virtual */ void destroy();
75   /* virtual */ render_primitive_list *get_primitives()
76   {
77      osd_dim nd = window().blit_surface_size();
78      if (nd != m_blit_dim)
79      {
80         m_blit_dim = nd;
81         notify_changed();
82      }
83      window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().aspect());
84      return &window().target()->get_primitives();
85   }
86
87private:
88   void destroy_all_textures();
89   void yuv_init();
90#if (SDLMAME_SDL2)
91   void setup_texture(const osd_dim &size);
92#endif
93   void yuv_lookup_set(unsigned int pen, unsigned char red,
94            unsigned char green, unsigned char blue);
95
96#if (!SDLMAME_SDL2)
97   void yuv_overlay_init();
98#endif
99
100   INT32               m_blittimer;
101
102#if (SDLMAME_SDL2)
103   SDL_Renderer        *m_sdl_renderer;
104   SDL_Texture         *m_texture_id;
105#else
106   SDL_Overlay         *m_yuvsurf;
107#endif
108
109   // YUV overlay
110   UINT32              *m_yuv_lookup;
111   UINT16              *m_yuv_bitmap;
112
113   // if we leave scaling to SDL and the underlying driver, this
114   // is the render_target_width/height to use
115
116   int                 m_last_hofs;
117   int                 m_last_vofs;
118   osd_dim             m_blit_dim;
119   osd_dim             m_last_dim;
120};
121
122struct sdl_scale_mode
123{
124   const char      *name;
125   int             is_scale;           /* Scale mode?           */
126   int             is_yuv;             /* Yuv mode?             */
127   int             mult_w;             /* Width multiplier      */
128   int             mult_h;             /* Height multiplier     */
129#if (!SDLMAME_SDL2)
130   int             m_extra_flags;        /* Texture/surface flags */
131#else
132   const char      *sdl_scale_mode;        /* what to use as a hint ? */
133#endif
134   int             pixel_format;       /* Pixel/Overlay format  */
135   void            (*yuv_blit)(const UINT16 *bitmap, UINT8 *ptr, const int pitch, const UINT32 *lookup, const int width, const int height);
136};
137
138//============================================================
139//  INLINES
140//============================================================
141
142//============================================================
143//  PROTOTYPES
144//============================================================
145
146// core functions
147static void drawsdl_exit(void);
148
149// YUV overlays
150
151static void yuv_RGB_to_YV12(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
152      const UINT32 *lookup, const int width, const int height);
153static void yuv_RGB_to_YV12X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
154      const UINT32 *lookup, const int width, const int height);
155static void yuv_RGB_to_YUY2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
156      const UINT32 *lookup, const int width, const int height);
157static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
158      const UINT32 *lookup, const int width, const int height);
159
160// Static declarations
161
162#if (!SDLMAME_SDL2)
163static int shown_video_info = 0;
164
165static const sdl_scale_mode scale_modes[] =
166{
167      { "none",    0, 0, 1, 1, osd_renderer::FLAG_NEEDS_DOUBLEBUF, 0, 0 },
168      { "async",   0, 0, 1, 1, osd_renderer::FLAG_NEEDS_DOUBLEBUF | osd_renderer::FLAG_NEEDS_ASYNCBLIT, 0, 0 },
169      { "yv12",    1, 1, 1, 1, 0,              SDL_YV12_OVERLAY, yuv_RGB_to_YV12 },
170      { "yv12x2",  1, 1, 2, 2, 0,              SDL_YV12_OVERLAY, yuv_RGB_to_YV12X2 },
171      { "yuy2",    1, 1, 1, 1, 0,              SDL_YUY2_OVERLAY, yuv_RGB_to_YUY2 },
172      { "yuy2x2",  1, 1, 2, 1, 0,              SDL_YUY2_OVERLAY, yuv_RGB_to_YUY2X2 },
173      { NULL }
174};
175#else
176static const sdl_scale_mode scale_modes[] =
177{
178      { "none",    0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, 0 },
179      { "hwblit",  1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, 0 },
180      { "hwbest",  1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, 0 },
181      /* SDL1.2 uses interpolation as well */
182      { "yv12",    1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
183      { "yv12x2",  1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
184      { "yuy2",    1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
185      { "yuy2x2",  1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
186      { NULL }
187};
188#endif
189
190//============================================================
191//  drawsdl_scale_mode
192//============================================================
193
194const char *drawsdl_scale_mode_str(int index)
195{
196   const sdl_scale_mode *sm = scale_modes;
197
198   while (index>0)
199   {
200      if (sm->name == NULL)
201         return NULL;
202      index--;
203      sm++;
204   }
205   return sm->name;
206};
207
208int drawsdl_scale_mode(const char *s)
209{
210   const sdl_scale_mode *sm = scale_modes;
211   int index;
212
213   index = 0;
214   while (sm->name != NULL)
215   {
216      if (strcmp(sm->name, s) == 0)
217         return index;
218      index++;
219      sm++;
220   }
221   return -1;
222}
223
224
225static osd_renderer *drawsdl_create(osd_window *window)
226{
227   // FIXME: QUALITY HINTS
228#if (SDLMAME_SDL2)
229   return global_alloc(sdl_info(window, osd_renderer::FLAG_NONE));
230#else
231   const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
232   return global_alloc(sdl_info(window, sm->m_extra_flags));
233#endif
234}
235
236//============================================================
237//  drawsdl_init
238//============================================================
239
240int drawsdl_init(osd_draw_callbacks *callbacks)
241{
242   // fill in the callbacks
243   callbacks->create = drawsdl_create;
244   callbacks->exit = drawsdl_exit;
245
246   if (SDLMAME_SDL2)
247      osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
248   else
249      osd_printf_verbose("Using SDL single-window soft driver (SDL 1.2)\n");
250
251   return 0;
252}
253
254//============================================================
255//  drawsdl_exit
256//============================================================
257
258static void drawsdl_exit(void)
259{
260}
261
262//============================================================
263//  setup_texture for window
264//============================================================
265
266#if (SDLMAME_SDL2)
267void sdl_info::setup_texture(const osd_dim &size)
268{
269   const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
270   SDL_DisplayMode mode;
271   UINT32 fmt;
272
273   // Determine preferred pixelformat and set up yuv if necessary
274   SDL_GetCurrentDisplayMode(window().monitor()->handle(), &mode);
275
276   if (m_yuv_bitmap)
277   {
278      global_free_array(m_yuv_bitmap);
279      m_yuv_bitmap = NULL;
280   }
281
282   fmt = (sdl_sm->pixel_format ? sdl_sm->pixel_format : mode.format);
283
284   if (sdl_sm->is_scale)
285   {
286      int m_hw_scale_width = 0;
287      int m_hw_scale_height = 0;
288
289      window().target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
290      if (window().prescale())
291      {
292         m_hw_scale_width *= window().prescale();
293         m_hw_scale_height *= window().prescale();
294
295         /* This must be a multiple of 2 */
296         m_hw_scale_width = (m_hw_scale_width + 1) & ~1;
297      }
298      if (sdl_sm->is_yuv)
299         m_yuv_bitmap = global_alloc_array(UINT16, m_hw_scale_width * m_hw_scale_height);
300
301      int w = m_hw_scale_width * sdl_sm->mult_w;
302      int h = m_hw_scale_height * sdl_sm->mult_h;
303
304      m_texture_id = SDL_CreateTexture(m_sdl_renderer, fmt, SDL_TEXTUREACCESS_STREAMING, w, h);
305
306   }
307   else
308   {
309      m_texture_id = SDL_CreateTexture(m_sdl_renderer,fmt, SDL_TEXTUREACCESS_STREAMING,
310            size.width(), size.height());
311   }
312}
313#endif
314
315//============================================================
316//  yuv_overlay_init
317//============================================================
318
319#if (!SDLMAME_SDL2)
320void sdl_info::yuv_overlay_init()
321{
322   const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
323   int minimum_width, minimum_height;
324
325   window().target()->compute_minimum_size(minimum_width, minimum_height);
326
327   if (window().prescale())
328   {
329      minimum_width *= window().prescale();
330      minimum_height *= window().prescale();
331   }
332
333   if (m_yuvsurf != NULL)
334   {
335      SDL_FreeYUVOverlay(m_yuvsurf);
336      m_yuvsurf = NULL;
337   }
338
339   if (m_yuv_bitmap != NULL)
340   {
341      global_free_array(m_yuv_bitmap);
342   }
343
344   osd_printf_verbose("SDL: Creating %d x %d YUV-Overlay ...\n", minimum_width, minimum_height);
345
346   m_yuv_bitmap = global_alloc_array(UINT16, minimum_width*minimum_height);
347
348   m_yuvsurf = SDL_CreateYUVOverlay(minimum_width * sdl_sm->mult_w, minimum_height * sdl_sm->mult_h,
349         sdl_sm->pixel_format, window().sdl_surface());
350
351   if ( m_yuvsurf == NULL ) {
352      osd_printf_error("SDL: Couldn't create SDL_yuv_overlay: %s\n", SDL_GetError());
353      //return 1;
354   }
355
356   if (!shown_video_info)
357   {
358      osd_printf_verbose("YUV Mode         : %s\n", sdl_sm->name);
359      osd_printf_verbose("YUV Overlay Size : %d x %d\n", minimum_width, minimum_height);
360      osd_printf_verbose("YUV Acceleration : %s\n", m_yuvsurf->hw_overlay ? "Hardware" : "Software");
361      shown_video_info = 1;
362   }
363}
364#endif
365
366//============================================================
367//  drawsdl_show_info
368//============================================================
369
370#if (SDLMAME_SDL2)
371static void drawsdl_show_info(struct SDL_RendererInfo *render_info)
372{
373#define RF_ENTRY(x) {x, #x }
374   static struct {
375      int flag;
376      const char *name;
377   } rflist[] =
378      {
379#if 0
380         RF_ENTRY(SDL_RENDERER_SINGLEBUFFER),
381         RF_ENTRY(SDL_RENDERER_PRESENTCOPY),
382         RF_ENTRY(SDL_RENDERER_PRESENTFLIP2),
383         RF_ENTRY(SDL_RENDERER_PRESENTFLIP3),
384         RF_ENTRY(SDL_RENDERER_PRESENTDISCARD),
385#endif
386         RF_ENTRY(SDL_RENDERER_PRESENTVSYNC),
387         RF_ENTRY(SDL_RENDERER_ACCELERATED),
388         {-1, NULL}
389      };
390   int i;
391
392   osd_printf_verbose("window: using renderer %s\n", render_info->name ? render_info->name : "<unknown>");
393   for (i = 0; rflist[i].name != NULL; i++)
394      if (render_info->flags & rflist[i].flag)
395         osd_printf_verbose("renderer: flag %s\n", rflist[i].name);
396}
397#endif
398
399//============================================================
400//  sdl_info::create
401// a
402// a
403// a
404// a
405// a
406// a
407// a
408// a
409// a
410// a
411// a
412// a
413// a
414// a
415// a
416// a
417// a
418// a
419// a
420// a
421// a
422// a
423// a
424// a
425// a
426// a
427//============================================================
428
429
430int sdl_info::create()
431{
432#if (SDLMAME_SDL2)
433   const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
434
435   // create renderer
436
437   /* set hints ... */
438   SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, sm->sdl_scale_mode);
439
440
441   if (video_config.waitvsync)
442      m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
443   else
444      m_sdl_renderer = SDL_CreateRenderer(window().sdl_window(), -1, SDL_RENDERER_ACCELERATED);
445
446   if (!m_sdl_renderer)
447   {
448      fatalerror("Error on creating renderer: %s\n", SDL_GetError());
449   }
450
451   {
452      struct SDL_RendererInfo render_info;
453
454      SDL_GetRendererInfo(m_sdl_renderer, &render_info);
455      drawsdl_show_info(&render_info);
456
457      // Check scale mode
458
459      if (sm->pixel_format)
460      {
461         int i;
462         int found = 0;
463
464         for (i=0; i < render_info.num_texture_formats; i++)
465            if (sm->pixel_format == render_info.texture_formats[i])
466               found = 1;
467
468         if (!found)
469         {
470            fatalerror("window: Scale mode %s not supported!", sm->name);
471         }
472      }
473   }
474
475#if 0
476   int w = 0, h = 0;
477   window().get_size(w, h);
478   setup_texture(w, h);
479#endif
480#else
481#endif
482
483   m_yuv_lookup = NULL;
484   m_blittimer = 0;
485
486   yuv_init();
487   osd_printf_verbose("Leave sdl_info::create\n");
488   return 0;
489}
490
491//============================================================
492//  sdl_info::destroy
493//============================================================
494
495void sdl_info::destroy()
496{
497   // free the memory in the window
498
499   destroy_all_textures();
500
501   if (m_yuv_lookup != NULL)
502   {
503      global_free_array(m_yuv_lookup);
504      m_yuv_lookup = NULL;
505   }
506   if (m_yuv_bitmap != NULL)
507   {
508      global_free_array(m_yuv_bitmap);
509      m_yuv_bitmap = NULL;
510   }
511}
512
513//============================================================
514//  drawsdl_xy_to_render_target
515//============================================================
516
517int sdl_info::xy_to_render_target(int x, int y, int *xt, int *yt)
518{
519   *xt = x - m_last_hofs;
520   *yt = y - m_last_vofs;
521   if (*xt<0 || *xt >= m_blit_dim.width())
522      return 0;
523   if (*yt<0 || *yt >= m_blit_dim.height())
524      return 0;
525   return 1;
526}
527
528//============================================================
529//  drawsdl_destroy_all_textures
530//============================================================
531
532void sdl_info::destroy_all_textures()
533{
534#if (SDLMAME_SDL2)
535   SDL_DestroyTexture(m_texture_id);
536   m_texture_id = NULL;
537#else
538   if (m_yuvsurf != NULL)
539   {
540      SDL_FreeYUVOverlay(m_yuvsurf);
541      m_yuvsurf = NULL;
542   }
543#endif
544}
545
546
547//============================================================
548//  sdl_info::draw
549//============================================================
550
551int sdl_info::draw(int update)
552{
553   const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
554   UINT8 *surfptr;
555   INT32 pitch;
556   Uint32 rmask, gmask, bmask;
557#if (SDLMAME_SDL2)
558   Uint32 amask;
559#endif
560   INT32 vofs, hofs, blitwidth, blitheight, ch, cw;
561   int bpp;
562
563   if (video_config.novideo)
564   {
565      return 0;
566   }
567
568   osd_dim wdim = window().get_size();
569   if (has_flags(FI_CHANGED) || (wdim != m_last_dim))
570   {
571      destroy_all_textures();
572      clear_flags(FI_CHANGED);
573      m_blittimer = 3;
574      m_last_dim = wdim;
575#if (SDLMAME_SDL2)
576      SDL_RenderSetViewport(m_sdl_renderer, NULL);
577      if (m_texture_id != NULL)
578         SDL_DestroyTexture(m_texture_id);
579      setup_texture(m_blit_dim);
580      m_blittimer = 3;
581#else
582      const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
583      if (sdl_sm->is_yuv)
584      {
585         yuv_overlay_init();
586      }
587#endif
588   }
589
590   // lock it if we need it
591#if (!SDLMAME_SDL2)
592
593   pitch = window().sdl_surface()->pitch;
594   bpp = window().sdl_surface()->format->BytesPerPixel;
595   rmask = window().sdl_surface()->format->Rmask;
596   gmask = window().sdl_surface()->format->Gmask;
597   bmask = window().sdl_surface()->format->Bmask;
598//  amask = sdlsurf->format->Amask;
599#if 0
600   if (window().blitwidth() != m_old_blitwidth || window().blitheight() != m_old_blitheight)
601   {
602      if (sm->is_yuv)
603         yuv_overlay_init();
604      m_old_blitwidth = window().blitwidth();
605      m_old_blitheight = window().blitheight();
606      m_blittimer = 3;
607   }
608#endif
609   if (SDL_MUSTLOCK(window().sdl_surface()))
610      SDL_LockSurface(window().sdl_surface());
611
612   // Clear if necessary
613   if (m_blittimer > 0)
614   {
615      memset(window().sdl_surface()->pixels, 0, wdim.height() * window().sdl_surface()->pitch);
616      m_blittimer--;
617   }
618
619
620   if (sm->is_yuv)
621   {
622      SDL_LockYUVOverlay(m_yuvsurf);
623      surfptr = m_yuvsurf->pixels[0]; // (UINT8 *) m_yuv_bitmap;
624      pitch = m_yuvsurf->pitches[0]; // (UINT8 *) m_yuv_bitmap;
625#if 0
626      printf("abcd %d\n", m_yuvsurf->h);
627      printf("abcd %d %d %d\n", m_yuvsurf->pitches[0], m_yuvsurf->pitches[1], m_yuvsurf->pitches[2]);
628      printf("abcd %p %p %p\n", m_yuvsurf->pixels[0], m_yuvsurf->pixels[1], m_yuvsurf->pixels[2]);
629      printf("abcd %ld %ld\n", m_yuvsurf->pixels[1] - m_yuvsurf->pixels[0], m_yuvsurf->pixels[2] - m_yuvsurf->pixels[1]);
630#endif
631   }
632   else
633      surfptr = (UINT8 *)window().sdl_surface()->pixels;
634#else
635   //SDL_SelectRenderer(window().sdl_window);
636
637
638   {
639      Uint32 format;
640      int access, w, h;
641
642      SDL_QueryTexture(m_texture_id, &format, &access, &w, &h);
643      SDL_PixelFormatEnumToMasks(format, &bpp, &rmask, &gmask, &bmask, &amask);
644      bpp = bpp / 8; /* convert to bytes per pixels */
645   }
646
647   // Clear if necessary
648   if (m_blittimer > 0)
649   {
650      /* SDL Underlays need alpha = 0 ! */
651      SDL_SetRenderDrawColor(m_sdl_renderer,0,0,0,0);
652      SDL_RenderFillRect(m_sdl_renderer,NULL);
653      //SDL_RenderFill(0,0,0,0 /*255*/,NULL);
654      m_blittimer--;
655   }
656
657   SDL_LockTexture(m_texture_id, NULL, (void **) &surfptr, &pitch);
658
659#endif
660   // get ready to center the image
661   vofs = hofs = 0;
662   blitwidth = m_blit_dim.width();
663   blitheight = m_blit_dim.height();
664
665   ch = wdim.height();
666   cw = wdim.width();
667
668   // do not crash if the window's smaller than the blit area
669   if (blitheight > ch)
670   {
671         blitheight = ch;
672   }
673   else if (video_config.centerv)
674   {
675      vofs = (ch - m_blit_dim.height()) / 2;
676   }
677
678   if (blitwidth > cw)
679   {
680         blitwidth = cw;
681   }
682   else if (video_config.centerh)
683   {
684      hofs = (cw - m_blit_dim.width()) / 2;
685   }
686
687   m_last_hofs = hofs;
688   m_last_vofs = vofs;
689
690   window().m_primlist->acquire_lock();
691
692   int mamewidth, mameheight;
693
694#if !SDLMAME_SDL2
695      if (!sm->is_yuv)
696      {
697         surfptr += ((vofs * pitch) + (hofs * bpp));
698         mamewidth = blitwidth; //sdl_surface()->w;
699         mameheight = blitheight; //sdl_surface()->h;
700      }
701      else
702      {
703         mamewidth = m_yuvsurf->w / sm->mult_w;
704         mameheight = m_yuvsurf->h / sm->mult_h;
705      }
706#else
707      Uint32 fmt = 0;
708      int access = 0;
709      SDL_QueryTexture(m_texture_id, &fmt, &access, &mamewidth, &mameheight);
710      mamewidth /= sm->mult_w;
711      mameheight /= sm->mult_h;
712#endif
713   //printf("w h %d %d %d %d\n", mamewidth, mameheight, blitwidth, blitheight);
714
715   // rescale bounds
716   float fw = (float) mamewidth / (float) blitwidth;
717   float fh = (float) mameheight / (float) blitheight;
718
719   // FIXME: this could be a lot easier if we get the primlist here!
720   //          Bounds would be set fit for purpose and done!
721
722   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
723   {
724      prim->bounds.x0 = floor(fw * prim->bounds.x0 + 0.5f);
725      prim->bounds.x1 = floor(fw * prim->bounds.x1 + 0.5f);
726      prim->bounds.y0 = floor(fh * prim->bounds.y0 + 0.5f);
727      prim->bounds.y1 = floor(fh * prim->bounds.y1 + 0.5f);
728   }
729
730   // render to it
731   if (!sm->is_yuv)
732   {
733      switch (rmask)
734      {
735         case 0x0000ff00:
736            software_renderer<UINT32, 0,0,0, 8,16,24>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
737            break;
738
739         case 0x00ff0000:
740            software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
741            break;
742
743         case 0x000000ff:
744            software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
745            break;
746
747         case 0xf800:
748            software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
749            break;
750
751         case 0x7c00:
752            software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
753            break;
754
755         default:
756            osd_printf_error("SDL: ERROR! Unknown video mode: R=%08X G=%08X B=%08X\n", rmask, gmask, bmask);
757            break;
758      }
759   }
760   else
761   {
762      assert (m_yuv_bitmap != NULL);
763      assert (surfptr != NULL);
764      software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, m_yuv_bitmap, mamewidth, mameheight, mamewidth);
765      sm->yuv_blit((UINT16 *)m_yuv_bitmap, surfptr, pitch, m_yuv_lookup, mamewidth, mameheight);
766   }
767
768   window().m_primlist->release_lock();
769
770   // unlock and flip
771#if (!SDLMAME_SDL2)
772   if (SDL_MUSTLOCK(window().sdl_surface())) SDL_UnlockSurface(window().sdl_surface());
773   if (!sm->is_yuv)
774   {
775      SDL_Flip(window().sdl_surface());
776   }
777   else
778   {
779      SDL_Rect r;
780
781      SDL_UnlockYUVOverlay(m_yuvsurf);
782      r.x = hofs;
783      r.y = vofs;
784      r.w = blitwidth;
785      r.h = blitheight;
786      SDL_DisplayYUVOverlay(m_yuvsurf, &r);
787   }
788#else
789   SDL_UnlockTexture(m_texture_id);
790   {
791      SDL_Rect r;
792
793      r.x=hofs;
794      r.y=vofs;
795      r.w=blitwidth;
796      r.h=blitheight;
797      //printf("blitwidth %d %d - %d %d\n", blitwidth, blitheight, window().width, window().height);
798      //SDL_UpdateTexture(sdltex, NULL, sdlsurf->pixels, pitch);
799      SDL_RenderCopy(m_sdl_renderer,m_texture_id, NULL, &r);
800      SDL_RenderPresent(m_sdl_renderer);
801   }
802#endif
803   return 0;
804}
805//============================================================
806// YUV Blitting
807//============================================================
808
809#define CU_CLAMP(v, a, b)   ((v < a)? a: ((v > b)? b: v))
810#define RGB2YUV_F(r,g,b,y,u,v) \
811      (y) = (0.299*(r) + 0.587*(g) + 0.114*(b) ); \
812      (u) = (-0.169*(r) - 0.331*(g) + 0.5*(b) + 128); \
813      (v) = (0.5*(r) - 0.419*(g) - 0.081*(b) + 128); \
814   (y) = CU_CLAMP(y,0,255); \
815   (u) = CU_CLAMP(u,0,255); \
816   (v) = CU_CLAMP(v,0,255)
817
818#define RGB2YUV(r,g,b,y,u,v) \
819      (y) = ((  8453*(r) + 16594*(g) +  3223*(b) +  524288) >> 15); \
820      (u) = (( -4878*(r) -  9578*(g) + 14456*(b) + 4210688) >> 15); \
821      (v) = (( 14456*(r) - 12105*(g) -  2351*(b) + 4210688) >> 15)
822
823#ifdef LSB_FIRST
824#define Y1MASK  0x000000FF
825#define  UMASK  0x0000FF00
826#define Y2MASK  0x00FF0000
827#define  VMASK  0xFF000000
828#define Y1SHIFT  0
829#define  USHIFT  8
830#define Y2SHIFT 16
831#define  VSHIFT 24
832#else
833#define Y1MASK  0xFF000000
834#define  UMASK  0x00FF0000
835#define Y2MASK  0x0000FF00
836#define  VMASK  0x000000FF
837#define Y1SHIFT 24
838#define  USHIFT 16
839#define Y2SHIFT  8
840#define  VSHIFT  0
841#endif
842
843#define YMASK  (Y1MASK|Y2MASK)
844#define UVMASK (UMASK|VMASK)
845
846void sdl_info::yuv_lookup_set(unsigned int pen, unsigned char red,
847         unsigned char green, unsigned char blue)
848{
849   UINT32 y,u,v;
850
851   RGB2YUV(red,green,blue,y,u,v);
852
853   /* Storing this data in YUYV order simplifies using the data for
854      YUY2, both with and without smoothing... */
855   m_yuv_lookup[pen]=(y<<Y1SHIFT)|(u<<USHIFT)|(y<<Y2SHIFT)|(v<<VSHIFT);
856}
857
858void sdl_info::yuv_init()
859{
860   unsigned char r,g,b;
861   if (m_yuv_lookup == NULL)
862      m_yuv_lookup = global_alloc_array(UINT32, 65536);
863   for (r = 0; r < 32; r++)
864      for (g = 0; g < 32; g++)
865         for (b = 0; b < 32; b++)
866         {
867            int idx = (r << 10) | (g << 5) | b;
868            yuv_lookup_set(idx,
869               (r << 3) | (r >> 2),
870               (g << 3) | (g >> 2),
871               (b << 3) | (b >> 2));
872         }
873}
874
875//UINT32 *lookup = sdl->m_yuv_lookup;
876
877static void yuv_RGB_to_YV12(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
878      const UINT32 *lookup, const int width, const int height)
879{
880   int x, y;
881   UINT8 *pixels[3];
882   int u1,v1,y1,u2,v2,y2,u3,v3,y3,u4,v4,y4;      /* 12 */
883
884   pixels[0] = ptr;
885   pixels[1] = ptr + pitch * height;
886   pixels[2] = pixels[1] + pitch * height / 4;
887
888   for(y=0;y<height;y+=2)
889   {
890      const UINT16 *src=bitmap + (y * width) ;
891      const UINT16 *src2=src + width;
892
893      UINT8 *dest_y = pixels[0] + y * pitch;
894      UINT8 *dest_v = pixels[1] + (y>>1) * pitch / 2;
895      UINT8 *dest_u = pixels[2] + (y>>1) * pitch / 2;
896
897      for(x=0;x<width;x+=2)
898      {
899         v1 = lookup[src[x]];
900         y1 = (v1>>Y1SHIFT) & 0xff;
901         u1 = (v1>>USHIFT)  & 0xff;
902         v1 = (v1>>VSHIFT)  & 0xff;
903
904         v2 = lookup[src[x+1]];
905         y2 = (v2>>Y1SHIFT) & 0xff;
906         u2 = (v2>>USHIFT)  & 0xff;
907         v2 = (v2>>VSHIFT)  & 0xff;
908
909         v3 = lookup[src2[x]];
910         y3 = (v3>>Y1SHIFT) & 0xff;
911         u3 = (v3>>USHIFT)  & 0xff;
912         v3 = (v3>>VSHIFT)  & 0xff;
913
914         v4 = lookup[src2[x+1]];
915         y4 = (v4>>Y1SHIFT) & 0xff;
916         u4 = (v4>>USHIFT)  & 0xff;
917         v4 = (v4>>VSHIFT)  & 0xff;
918
919         dest_y[x] = y1;
920         dest_y[x+pitch] = y3;
921         dest_y[x+1] = y2;
922         dest_y[x+pitch+1] = y4;
923
924         dest_u[x>>1] = (u1+u2+u3+u4)/4;
925         dest_v[x>>1] = (v1+v2+v3+v4)/4;
926
927      }
928   }
929}
930
931static void yuv_RGB_to_YV12X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
932      const UINT32 *lookup, const int width, const int height)
933{
934   /* this one is used when scale==2 */
935   unsigned int x,y;
936   int u1,v1,y1;
937   UINT8 *pixels[3];
938
939   pixels[0] = ptr;
940   pixels[1] = ptr + pitch * height * 2;
941#if (SDLMAME_SDL2)
942   int p2 = (pitch >> 1);
943#else
944   int p2 = (pitch + 7) & ~ 7;;
945   p2 = (p2 >> 1);
946#endif
947   pixels[2] = pixels[1] + p2 * height;
948
949   for(y=0;y<height;y++)
950   {
951      const UINT16 *src = bitmap + (y * width) ;
952
953      UINT16 *dest_y = (UINT16 *)(pixels[0] + 2 * y * pitch);
954      UINT8 *dest_v = pixels[1] + y * p2;
955      UINT8 *dest_u = pixels[2] + y * p2;
956      for(x=0;x<width;x++)
957      {
958         v1 = lookup[src[x]];
959         y1 = (v1 >> Y1SHIFT) & 0xff;
960         u1 = (v1 >> USHIFT)  & 0xff;
961         v1 = (v1 >> VSHIFT)  & 0xff;
962
963         dest_y[x + pitch/2] = y1 << 8 | y1;
964         dest_y[x] = y1 << 8 | y1;
965         dest_u[x] = u1;
966         dest_v[x] = v1;
967      }
968   }
969}
970
971static void yuv_RGB_to_YUY2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
972      const UINT32 *lookup, const int width, const int height)
973{
974   /* this one is used when scale==2 */
975   unsigned int y;
976   UINT32 p1,p2,uv;
977   const int yuv_pitch = pitch/4;
978
979   for(y=0;y<height;y++)
980   {
981      const UINT16 *src=bitmap + (y * width) ;
982      const UINT16 *end=src+width;
983
984      UINT32 *dest = (UINT32 *) ptr;
985      dest += y * yuv_pitch;
986      for(; src<end; src+=2)
987      {
988         p1  = lookup[src[0]];
989         p2  = lookup[src[1]];
990         uv = (p1&UVMASK)>>1;
991         uv += (p2&UVMASK)>>1;
992         *dest++ = (p1&Y1MASK)|(p2&Y2MASK)|(uv&UVMASK);
993      }
994   }
995}
996
997static void yuv_RGB_to_YUY2X2(const UINT16 *bitmap, UINT8 *ptr, const int pitch, \
998      const UINT32 *lookup, const int width, const int height)
999{
1000   /* this one is used when scale==2 */
1001   unsigned int y;
1002   int yuv_pitch = pitch / 4;
1003
1004   for(y=0;y<height;y++)
1005   {
1006      const UINT16 *src=bitmap + (y * width) ;
1007      const UINT16 *end=src+width;
1008
1009      UINT32 *dest = (UINT32 *) ptr;
1010      dest += (y * yuv_pitch);
1011      for(; src<end; src++)
1012      {
1013         dest[0] = lookup[src[0]];
1014         dest++;
1015      }
1016   }
1017}
trunk/src/osd/sdl/sdl.mak
r244651r244652
428428   $(OSDOBJ)/modules/font \
429429   $(OSDOBJ)/modules/netdev \
430430   $(OSDOBJ)/modules/opengl \
431
431   $(OSDOBJ)/modules/render
432   
432433#-------------------------------------------------
433434# OSD core library
434435#-------------------------------------------------
r244651r244652
461462   $(OSDOBJ)/modules/sound/sdl_sound.o  \
462463   $(OSDOBJ)/modules/sound/none.o  \
463464   $(SDLOBJ)/video.o \
464   $(SDLOBJ)/drawsdl.o \
465465   $(SDLOBJ)/window.o \
466466   $(SDLOBJ)/output.o \
467467   $(SDLOBJ)/watchdog.o \
r244651r244652
475475   $(OSDOBJ)/modules/netdev/none.o \
476476   $(OSDOBJ)/modules/midi/portmidi.o \
477477   $(OSDOBJ)/modules/midi/none.o \
478   $(OSDOBJ)/modules/render/drawsdl.o \
478479
479480ifdef NO_USE_MIDI
480481   DEFS += -DNO_USE_MIDI
r244651r244652
484485# Add SDL2.0 support
485486
486487ifeq ($(SDL_LIBVER),sdl2)
487OSDOBJS += $(SDLOBJ)/draw13.o
488OSDOBJS += $(OSDOBJ)/modules/render/draw13.o
488489endif
489490
490491# add an ARCH define
r244651r244652
809810
810811ifdef USE_BGFX
811812DEFS += -DUSE_BGFX
812OSDOBJS += $(SDLOBJ)/drawbgfx.o
813OSDOBJS += $(OSDOBJ)/modules/render/drawbgfx.o
813814INCPATH += -I$(3RDPARTY)/bgfx/include -I$(3RDPARTY)/bx/include
814815USE_DISPATCH_GL = 0
815816BGFX_LIB = $(OBJ)/libbgfx.a
r244651r244652
823824DEFS += -DUSE_OPENGL=0
824825else
825826OSDOBJS += \
826   $(SDLOBJ)/drawogl.o \
827   $(OSDOBJ)/modules/render/drawogl.o \
827828   $(OSDOBJ)/modules/opengl/gl_shader_tool.o \
828829   $(OSDOBJ)/modules/opengl/gl_shader_mgr.o
829830   
r244651r244652
930931endif # solaris
931932
932933# drawSDL depends on the core software renderer, so make sure it exists
933$(SDLOBJ)/drawsdl.o : $(SRC)/emu/rendersw.inc $(SDLSRC)/drawogl.c
934$(OSDOBJ)/modules/render/drawsdl.o : $(SRC)/emu/rendersw.inc $(OSDSRC)/modules/render/drawogl.c
934935
935936# draw13 depends on blit13.h
936$(SDLOBJ)/draw13.o : $(SDLSRC)/blit13.h
937$(OSDOBJ)/modules/render/draw13.o : $(OSDSRC)/modules/render/blit13.h
937938
938939#$(OSDCOREOBJS): $(SDLSRC)/sdl.mak
939940
trunk/src/osd/windows/d3d9intf.c
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  d3d9intf.c - Direct3D 9 abstraction layer
6//
7//============================================================
8
9// standard windows headers
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12#include <d3d9.h>
13#include <d3dx9.h>
14#undef interface
15
16// MAME headers
17#include "emu.h"
18
19// MAMEOS headers
20#include "d3dintf.h"
21#include "winmain.h"
22
23
24
25//============================================================
26//  TYPE DEFINITIONS
27//============================================================
28
29typedef IDirect3D9 *(WINAPI *direct3dcreate9_ptr)(UINT SDKVersion);
30
31namespace d3d
32{
33//============================================================
34//  PROTOTYPES
35//============================================================
36
37static void set_interfaces(base *d3dptr);
38
39//============================================================
40//  INLINES
41//============================================================
42
43INLINE void convert_present_params(const present_parameters *params, D3DPRESENT_PARAMETERS *d3d9params)
44{
45   memset(d3d9params, 0, sizeof(*d3d9params));
46   d3d9params->BackBufferWidth = params->BackBufferWidth;
47   d3d9params->BackBufferHeight = params->BackBufferHeight;
48   d3d9params->BackBufferFormat = params->BackBufferFormat;
49   d3d9params->BackBufferCount = params->BackBufferCount;
50   d3d9params->MultiSampleType = params->MultiSampleType;
51   d3d9params->MultiSampleQuality = params->MultiSampleQuality;
52   d3d9params->SwapEffect = params->SwapEffect;
53   d3d9params->hDeviceWindow = params->hDeviceWindow;
54   d3d9params->Windowed = params->Windowed;
55   d3d9params->EnableAutoDepthStencil = params->EnableAutoDepthStencil;
56   d3d9params->AutoDepthStencilFormat = params->AutoDepthStencilFormat;
57   d3d9params->Flags = params->Flags;
58   d3d9params->FullScreen_RefreshRateInHz = params->FullScreen_RefreshRateInHz;
59   d3d9params->PresentationInterval = params->PresentationInterval;
60}
61
62
63
64//============================================================
65//  drawd3d9_init
66//============================================================
67
68base *drawd3d9_init(void)
69{
70   bool post_available = true;
71
72   // dynamically grab the create function from d3d9.dll
73   HINSTANCE dllhandle = LoadLibrary(TEXT("d3d9.dll"));
74   if (dllhandle == NULL)
75   {
76      osd_printf_verbose("Direct3D: Unable to access d3d9.dll\n");
77      return NULL;
78   }
79
80   // import the create function
81   direct3dcreate9_ptr direct3dcreate9 = (direct3dcreate9_ptr)GetProcAddress(dllhandle, "Direct3DCreate9");
82   if (direct3dcreate9 == NULL)
83   {
84      osd_printf_verbose("Direct3D: Unable to find Direct3DCreate9\n");
85      FreeLibrary(dllhandle);
86      dllhandle = NULL;
87      return NULL;
88   }
89
90   // create our core direct 3d object
91   IDirect3D9 *d3d9 = (*direct3dcreate9)(D3D_SDK_VERSION);
92   if (d3d9 == NULL)
93   {
94      osd_printf_verbose("Direct3D: Error attempting to initialize Direct3D9\n");
95      FreeLibrary(dllhandle);
96      dllhandle = NULL;
97      return NULL;
98   }
99
100   // dynamically grab the shader load function from d3dx9.dll
101   HINSTANCE fxhandle = NULL;
102   for (int idx = 99; idx >= 0; idx--) // a shameful moogle
103   {
104      wchar_t dllbuf[13];
105      wsprintf(dllbuf, TEXT("d3dx9_%d.dll"), idx);
106      fxhandle = LoadLibrary(dllbuf);
107      if (fxhandle != NULL)
108      {
109         break;
110      }
111   }
112   if (fxhandle == NULL)
113   {
114      osd_printf_verbose("Direct3D: Warning - Unable find any D3D9 DLLs; disabling post-effect rendering\n");
115      post_available = false;
116   }
117
118   // allocate an object to hold our data
119   base *d3dptr = global_alloc(base);
120   d3dptr->version = 9;
121   d3dptr->d3dobj = d3d9;
122   d3dptr->dllhandle = dllhandle;
123   d3dptr->post_fx_available = post_available;
124   d3dptr->libhandle = fxhandle;
125   set_interfaces(d3dptr);
126
127   osd_printf_verbose("Direct3D: Using Direct3D 9\n");
128   return d3dptr;
129}
130
131
132
133//============================================================
134//  Direct3D interfaces
135//============================================================
136
137static HRESULT check_device_format(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format)
138{
139   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
140   return IDirect3D9_CheckDeviceFormat(d3d9, adapter, devtype, adapterformat, usage, restype, format);
141}
142
143
144static HRESULT check_device_type(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed)
145{
146   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
147   return IDirect3D9_CheckDeviceType(d3d9, adapter, devtype, format, backformat, windowed);
148}
149
150static HRESULT create_device(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev)
151{
152   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
153   D3DPRESENT_PARAMETERS d3d9params;
154   convert_present_params(params, &d3d9params);
155   return IDirect3D9_CreateDevice(d3d9, adapter, devtype, focus, behavior, &d3d9params, (IDirect3DDevice9 **)dev);
156}
157
158static HRESULT enum_adapter_modes(base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode)
159{
160   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
161   return IDirect3D9_EnumAdapterModes(d3d9, adapter, format, index, mode);
162}
163
164
165static UINT get_adapter_count(base *d3dptr)
166{
167   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
168   return IDirect3D9_GetAdapterCount(d3d9);
169}
170
171
172static HRESULT get_adapter_display_mode(base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode)
173{
174   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
175   return IDirect3D9_GetAdapterDisplayMode(d3d9, adapter, mode);
176}
177
178
179static HRESULT get_adapter_identifier(base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier)
180{
181   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
182   D3DADAPTER_IDENTIFIER9 id;
183   HRESULT result = IDirect3D9_GetAdapterIdentifier(d3d9, adapter, flags, &id);
184   memcpy(identifier->Driver, id.Driver, sizeof(identifier->Driver));
185   memcpy(identifier->Description, id.Description, sizeof(identifier->Description));
186   identifier->DriverVersion = id.DriverVersion;
187   identifier->VendorId = id.VendorId;
188   identifier->DeviceId = id.DeviceId;
189   identifier->SubSysId = id.SubSysId;
190   identifier->Revision = id.Revision;
191   identifier->DeviceIdentifier = id.DeviceIdentifier;
192   identifier->WHQLLevel = id.WHQLLevel;
193   return result;
194}
195
196
197static UINT get_adapter_mode_count(base *d3dptr, UINT adapter, D3DFORMAT format)
198{
199   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
200   return IDirect3D9_GetAdapterModeCount(d3d9, adapter, format);
201}
202
203
204static HMONITOR get_adapter_monitor(base *d3dptr, UINT adapter)
205{
206   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
207   return IDirect3D9_GetAdapterMonitor(d3d9, adapter);
208}
209
210
211static HRESULT get_caps_dword(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value)
212{
213   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
214   D3DCAPS9 caps;
215   HRESULT result = IDirect3D9_GetDeviceCaps(d3d9, adapter, devtype, &caps);
216   switch (which)
217   {
218      case CAPS_PRESENTATION_INTERVALS:   *value = caps.PresentationIntervals;    break;
219      case CAPS_CAPS2:                    *value = caps.Caps2;                    break;
220      case CAPS_DEV_CAPS:                 *value = caps.DevCaps;                  break;
221      case CAPS_SRCBLEND_CAPS:            *value = caps.SrcBlendCaps;             break;
222      case CAPS_DSTBLEND_CAPS:            *value = caps.DestBlendCaps;            break;
223      case CAPS_TEXTURE_CAPS:             *value = caps.TextureCaps;              break;
224      case CAPS_TEXTURE_FILTER_CAPS:      *value = caps.TextureFilterCaps;        break;
225      case CAPS_TEXTURE_ADDRESS_CAPS:     *value = caps.TextureAddressCaps;       break;
226      case CAPS_TEXTURE_OP_CAPS:          *value = caps.TextureOpCaps;            break;
227      case CAPS_MAX_TEXTURE_ASPECT:       *value = caps.MaxTextureAspectRatio;    break;
228      case CAPS_MAX_TEXTURE_WIDTH:        *value = caps.MaxTextureWidth;          break;
229      case CAPS_MAX_TEXTURE_HEIGHT:       *value = caps.MaxTextureHeight;         break;
230      case CAPS_STRETCH_RECT_FILTER:      *value = caps.StretchRectFilterCaps;    break;
231      case CAPS_MAX_PS30_INSN_SLOTS:      *value = caps.MaxPixelShader30InstructionSlots; break;
232   }
233   return result;
234}
235
236
237static ULONG release(base *d3dptr)
238{
239   IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj;
240   ULONG result = IDirect3D9_Release(d3d9);
241   FreeLibrary(d3dptr->dllhandle);
242   global_free(d3dptr);
243   return result;
244}
245
246
247static const interface d3d9_interface =
248{
249   check_device_format,
250   check_device_type,
251   create_device,
252   enum_adapter_modes,
253   get_adapter_count,
254   get_adapter_display_mode,
255   get_adapter_identifier,
256   get_adapter_mode_count,
257   get_adapter_monitor,
258   get_caps_dword,
259   release
260};
261
262
263
264//============================================================
265//  Direct3DDevice interfaces
266//============================================================
267
268static HRESULT device_begin_scene(device *dev)
269{
270   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
271   return IDirect3DDevice9_BeginScene(device);
272}
273
274static HRESULT device_clear(device *dev, DWORD count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
275{
276   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
277   return IDirect3DDevice9_Clear(device, count, rects, flags, color, z, stencil);
278}
279
280
281static HRESULT device_create_offscreen_plain_surface(device *dev, UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, surface **surface)
282{
283   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
284   return IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, pool, (IDirect3DSurface9 **)surface, NULL);
285}
286
287static HRESULT device_create_texture(device *dev, UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, texture **texture)
288{
289   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
290   return IDirect3DDevice9_CreateTexture(device, width, height, levels, usage, format, pool, (IDirect3DTexture9 **)texture, NULL);
291}
292
293
294static HRESULT device_create_vertex_buffer(device *dev, UINT length, DWORD usage, DWORD fvf, D3DPOOL pool, vertex_buffer **buf)
295{
296   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
297   return IDirect3DDevice9_CreateVertexBuffer(device, length, usage, fvf, pool, (IDirect3DVertexBuffer9 **)buf, NULL);
298}
299
300
301static HRESULT device_draw_primitive(device *dev, D3DPRIMITIVETYPE type, UINT start, UINT count)
302{
303   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
304   return IDirect3DDevice9_DrawPrimitive(device, type, start, count);
305}
306
307
308static HRESULT device_end_scene(device *dev)
309{
310   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
311   return IDirect3DDevice9_EndScene(device);
312}
313
314
315static HRESULT device_get_raster_status(device *dev, D3DRASTER_STATUS *status)
316{
317   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
318   return IDirect3DDevice9_GetRasterStatus(device, 0, status);
319}
320
321
322static HRESULT device_get_render_target(device *dev, DWORD index, surface **surface)
323{
324   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
325   return IDirect3DDevice9_GetRenderTarget(device, index, (IDirect3DSurface9 **)surface);
326}
327
328
329static HRESULT device_get_render_target_data(device *dev, surface *rendertarget, surface *destsurface)
330{
331   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
332   return IDirect3DDevice9_GetRenderTargetData(device, (IDirect3DSurface9 *)rendertarget, (IDirect3DSurface9 *)destsurface);
333}
334
335
336static HRESULT device_present(device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags)
337{
338   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
339   if (flags != 0)
340   {
341      IDirect3DSwapChain9 *chain;
342      HRESULT result = IDirect3DDevice9_GetSwapChain(device, 0, &chain);
343      if (result == D3D_OK)
344      {
345         result = IDirect3DSwapChain9_Present(chain, source, dest, override, dirty, flags);
346         IDirect3DSwapChain9_Release(chain);
347         return result;
348      }
349   }
350   return IDirect3DDevice9_Present(device, source, dest, override, dirty);
351}
352
353
354static ULONG device_release(device *dev)
355{
356   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
357   return IDirect3DDevice9_Release(device);
358}
359
360
361static HRESULT device_reset(device *dev, present_parameters *params)
362{
363   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
364   D3DPRESENT_PARAMETERS d3d9params;
365   convert_present_params(params, &d3d9params);
366   return IDirect3DDevice9_Reset(device, &d3d9params);
367}
368
369
370static void device_set_gamma_ramp(device *dev, DWORD flags, const D3DGAMMARAMP *ramp)
371{
372   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
373   IDirect3DDevice9_SetGammaRamp(device, 0, flags, ramp);
374}
375
376
377static HRESULT device_set_render_state(device *dev, D3DRENDERSTATETYPE state, DWORD value)
378{
379   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
380   return IDirect3DDevice9_SetRenderState(device, state, value);
381}
382
383
384static HRESULT device_set_render_target(device *dev, DWORD index, surface *surf)
385{
386   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
387   IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf;
388   return IDirect3DDevice9_SetRenderTarget(device, index, surface);
389}
390
391
392static HRESULT device_create_render_target(device *dev, UINT width, UINT height, D3DFORMAT format, surface **surface)
393{
394   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
395   return IDirect3DDevice9_CreateRenderTarget(device, width, height, format, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)surface, NULL);
396}
397
398
399static HRESULT device_set_stream_source(device *dev, UINT number, vertex_buffer *vbuf, UINT stride)
400{
401   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
402   IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf;
403   return IDirect3DDevice9_SetStreamSource(device, number, vertexbuf, 0, stride);
404}
405
406
407static HRESULT device_set_texture(device *dev, DWORD stage, texture *tex)
408{
409   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
410   IDirect3DBaseTexture9 *texture = (IDirect3DBaseTexture9 *)tex;
411   return IDirect3DDevice9_SetTexture(device, stage, texture);
412}
413
414
415static HRESULT device_set_texture_stage_state(device *dev, DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value)
416{
417   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
418
419   // some state which was here got pushed into sampler state in D3D9
420   switch ((DWORD)state)
421   {
422      case D3DTSS_ADDRESSU:
423         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_ADDRESSU, value);
424      case D3DTSS_ADDRESSV:
425         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_ADDRESSV, value);
426      case D3DTSS_BORDERCOLOR:
427         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_BORDERCOLOR, value);
428      case D3DTSS_MAGFILTER:
429         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAGFILTER, value);
430      case D3DTSS_MINFILTER:
431         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MINFILTER, value);
432      case D3DTSS_MIPFILTER:
433         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MIPFILTER, value);
434      case D3DTSS_MIPMAPLODBIAS:
435         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MIPMAPLODBIAS, value);
436      case D3DTSS_MAXMIPLEVEL:
437         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAXMIPLEVEL, value);
438      case D3DTSS_MAXANISOTROPY:
439         return IDirect3DDevice9_SetSamplerState(device, stage, D3DSAMP_MAXANISOTROPY, value);
440      default:
441         return IDirect3DDevice9_SetTextureStageState(device, stage, state, value);
442   }
443}
444
445
446static HRESULT device_set_vertex_format(device *dev, D3DFORMAT format)
447{
448   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
449   return IDirect3DDevice9_SetFVF(device, format);
450}
451
452
453static HRESULT device_stretch_rect(device *dev, surface *source, const RECT *srcrect, surface *dest, const RECT *dstrect, D3DTEXTUREFILTERTYPE filter)
454{
455   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
456   IDirect3DSurface9 *ssurface = (IDirect3DSurface9 *)source;
457   IDirect3DSurface9 *dsurface = (IDirect3DSurface9 *)dest;
458   return IDirect3DDevice9_StretchRect(device, ssurface, srcrect, dsurface, dstrect, filter);
459}
460
461
462static HRESULT device_test_cooperative_level(device *dev)
463{
464   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
465   return IDirect3DDevice9_TestCooperativeLevel(device);
466}
467
468
469static const device_interface d3d9_device_interface =
470{
471   device_begin_scene,
472   device_clear,
473   device_create_offscreen_plain_surface,
474   device_create_texture,
475   device_create_vertex_buffer,
476   device_create_render_target,
477   device_draw_primitive,
478   device_end_scene,
479   device_get_raster_status,
480   device_get_render_target,
481   device_get_render_target_data,
482   device_present,
483   device_release,
484   device_reset,
485   device_set_gamma_ramp,
486   device_set_render_state,
487   device_set_render_target,
488   device_set_stream_source,
489   device_set_texture,
490   device_set_texture_stage_state,
491   device_set_vertex_format,
492   device_stretch_rect,
493   device_test_cooperative_level
494};
495
496
497
498//============================================================
499//  Direct3DSurface interfaces
500//============================================================
501
502static HRESULT surface_lock_rect(surface *surf, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags)
503{
504   IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf;
505   return IDirect3DSurface9_LockRect(surface, locked, rect, flags);
506}
507
508
509static ULONG surface_release(surface *surf)
510{
511   IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf;
512   return IDirect3DSurface9_Release(surface);
513}
514
515
516static HRESULT surface_unlock_rect(surface *surf)
517{
518   IDirect3DSurface9 *surface = (IDirect3DSurface9 *)surf;
519   return IDirect3DSurface9_UnlockRect(surface);
520}
521
522
523static const surface_interface d3d9_surface_interface =
524{
525   surface_lock_rect,
526   surface_release,
527   surface_unlock_rect
528};
529
530
531
532//============================================================
533//  Direct3DTexture interfaces
534//============================================================
535
536static HRESULT texture_get_surface_level(texture *tex, UINT level, surface **surface)
537{
538   IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex;
539   return IDirect3DTexture9_GetSurfaceLevel(texture, level, (IDirect3DSurface9 **)surface);
540}
541
542
543static HRESULT texture_lock_rect(texture *tex, UINT level, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags)
544{
545   IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex;
546   return IDirect3DTexture9_LockRect(texture, level, locked, rect, flags);
547}
548
549
550static ULONG texture_release(texture *tex)
551{
552   IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex;
553   return IDirect3DTexture9_Release(texture);
554}
555
556
557static HRESULT texture_unlock_rect(texture *tex, UINT level)
558{
559   IDirect3DTexture9 *texture = (IDirect3DTexture9 *)tex;
560   return IDirect3DTexture9_UnlockRect(texture, level);
561}
562
563
564static const texture_interface d3d9_texture_interface =
565{
566   texture_get_surface_level,
567   texture_lock_rect,
568   texture_release,
569   texture_unlock_rect
570};
571
572
573
574//============================================================
575//  Direct3DVertexBuffer interfaces
576//============================================================
577
578static HRESULT vertex_buffer_lock(vertex_buffer *vbuf, UINT offset, UINT size, VOID **data, DWORD flags)
579{
580   IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf;
581   return IDirect3DVertexBuffer9_Lock(vertexbuf, offset, size, data, flags);
582}
583
584
585static ULONG vertex_buffer_release(vertex_buffer *vbuf)
586{
587   IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf;
588   return IDirect3DVertexBuffer9_Release(vertexbuf);
589}
590
591
592static HRESULT vertex_buffer_unlock(vertex_buffer *vbuf)
593{
594   IDirect3DVertexBuffer9 *vertexbuf = (IDirect3DVertexBuffer9 *)vbuf;
595   return IDirect3DVertexBuffer9_Unlock(vertexbuf);
596}
597
598
599static const vertex_buffer_interface d3d9_vertex_buffer_interface =
600{
601   vertex_buffer_lock,
602   vertex_buffer_release,
603   vertex_buffer_unlock
604};
605
606
607//============================================================
608//  set_interfaces
609//============================================================
610
611static void set_interfaces(base *d3dptr)
612{
613   d3dptr->d3d = d3d9_interface;
614   d3dptr->device = d3d9_device_interface;
615   d3dptr->surface = d3d9_surface_interface;
616   d3dptr->texture = d3d9_texture_interface;
617   d3dptr->vertexbuf = d3d9_vertex_buffer_interface;
618}
619
620};
trunk/src/osd/windows/d3dcomm.h
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  d3dcomm.h - Common Win32 Direct3D structures
6//
7//============================================================
8
9#ifndef __WIN_D3DCOMM__
10#define __WIN_D3DCOMM__
11
12//============================================================
13//  FORWARD DECLARATIONS
14//============================================================
15
16namespace d3d
17{
18class texture_info;
19class renderer;
20
21//============================================================
22//  TYPE DEFINITIONS
23//============================================================
24
25class vec2f
26{
27public:
28   vec2f()
29   {
30      memset(&c, 0, sizeof(float) * 2);
31   }
32   vec2f(float x, float y)
33   {
34      c.x = x;
35      c.y = y;
36   }
37
38   vec2f operator+(const vec2f& a)
39   {
40      return vec2f(c.x + a.c.x, c.y + a.c.y);
41   }
42
43   vec2f operator-(const vec2f& a)
44   {
45      return vec2f(c.x - a.c.x, c.y - a.c.y);
46   }
47
48   struct
49   {
50      float x, y;
51   } c;
52};
53
54class texture_manager
55{
56public:
57   texture_manager() { }
58   texture_manager(renderer *d3d);
59   ~texture_manager();
60
61   void                    update_textures();
62
63   void                    create_resources();
64   void                    delete_resources();
65
66   texture_info *          find_texinfo(const render_texinfo *texture, UINT32 flags);
67   UINT32                  texture_compute_hash(const render_texinfo *texture, UINT32 flags);
68
69   texture_info *          get_texlist() { return m_texlist; }
70   void                    set_texlist(texture_info *texlist) { m_texlist = texlist; }
71   bool                    is_dynamic_supported() { return (bool)m_dynamic_supported; }
72   void                    set_dynamic_supported(bool dynamic_supported) { m_dynamic_supported = dynamic_supported; }
73   bool                    is_stretch_supported() { return (bool)m_stretch_supported; }
74   D3DFORMAT               get_yuv_format() { return m_yuv_format; }
75
76   DWORD                   get_texture_caps() { return m_texture_caps; }
77   DWORD                   get_max_texture_aspect() { return m_texture_max_aspect; }
78   DWORD                   get_max_texture_width() { return m_texture_max_width; }
79   DWORD                   get_max_texture_height() { return m_texture_max_height; }
80
81   texture_info *          get_default_texture() { return m_default_texture; }
82   texture_info *          get_vector_texture() { return m_vector_texture; }
83
84   renderer *              get_d3d() { return m_renderer; }
85
86private:
87   renderer *              m_renderer;
88
89   texture_info *          m_texlist;                  // list of active textures
90   int                     m_dynamic_supported;        // are dynamic textures supported?
91   int                     m_stretch_supported;        // is StretchRect with point filtering supported?
92   D3DFORMAT               m_yuv_format;               // format to use for YUV textures
93
94   DWORD                   m_texture_caps;             // textureCaps field
95   DWORD                   m_texture_max_aspect;       // texture maximum aspect ratio
96   DWORD                   m_texture_max_width;        // texture maximum width
97   DWORD                   m_texture_max_height;       // texture maximum height
98
99   bitmap_argb32           m_vector_bitmap;            // experimental: bitmap for vectors
100   texture_info *          m_vector_texture;           // experimental: texture for vectors
101
102   bitmap_rgb32            m_default_bitmap;           // experimental: default bitmap
103   texture_info *          m_default_texture;          // experimental: default texture
104};
105
106
107/* texture_info holds information about a texture */
108class texture_info
109{
110public:
111   texture_info(texture_manager *manager, const render_texinfo *texsource, int prescale, UINT32 flags);
112   ~texture_info();
113
114   render_texinfo &        get_texinfo() { return m_texinfo; }
115
116   int                     get_width() { return m_rawdims.c.x; }
117   int                     get_height() { return m_rawdims.c.y; }
118   int                     get_xscale() { return m_xprescale; }
119   int                     get_yscale() { return m_yprescale; }
120
121   UINT32                  get_flags() { return m_flags; }
122
123   void                    set_data(const render_texinfo *texsource, UINT32 flags);
124
125   texture_info *          get_next() { return m_next; }
126   texture_info *          get_prev() { return m_prev; }
127
128   UINT32                  get_hash() { return m_hash; }
129
130   void                    set_next(texture_info *next) { m_next = next; }
131   void                    set_prev(texture_info *prev) { m_prev = prev; }
132
133   bool                    paused() { return m_cur_frame == m_prev_frame; }
134   void                    advance_frame() { m_prev_frame = m_cur_frame; }
135   void                    increment_frame_count() { m_cur_frame++; }
136   void                    mask_frame_count(int mask) { m_cur_frame %= mask; }
137
138   int                     get_cur_frame() { return m_cur_frame; }
139   int                     get_prev_frame() { return m_prev_frame; }
140
141   texture *               get_tex() { return m_d3dtex; }
142   surface *               get_surface() { return m_d3dsurface; }
143   texture *               get_finaltex() { return m_d3dfinaltex; }
144
145   vec2f &                 get_uvstart() { return m_start; }
146   vec2f &                 get_uvstop() { return m_stop; }
147   vec2f &                 get_rawdims() { return m_rawdims; }
148
149private:
150   void prescale();
151   void compute_size(int texwidth, int texheight);
152
153   texture_manager *       m_texture_manager;          // texture manager pointer
154
155   renderer *              m_renderer;                 // renderer pointer
156
157   texture_info *          m_next;                     // next texture in the list
158   texture_info *          m_prev;                     // prev texture in the list
159
160   UINT32                  m_hash;                     // hash value for the texture
161   UINT32                  m_flags;                    // rendering flags
162   render_texinfo          m_texinfo;                  // copy of the texture info
163   vec2f                   m_start;                    // beggining UV coordinates
164   vec2f                   m_stop;                     // ending UV coordinates
165   vec2f                   m_rawdims;                  // raw dims of the texture
166   int                     m_type;                     // what type of texture are we?
167   int                     m_xborderpix, m_yborderpix; // number of border pixels on X/Y
168   int                     m_xprescale, m_yprescale;   // X/Y prescale factor
169   int                     m_cur_frame;                // what is our current frame?
170   int                     m_prev_frame;               // what was our last frame? (used to determine pause state)
171   texture *               m_d3dtex;                   // Direct3D texture pointer
172   surface *               m_d3dsurface;               // Direct3D offscreen plain surface pointer
173   texture *               m_d3dfinaltex;              // Direct3D final (post-scaled) texture
174};
175
176/* d3d::poly_info holds information about a single polygon/d3d primitive */
177class poly_info
178{
179public:
180   poly_info() { }
181
182   void init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
183         UINT32 flags, d3d::texture_info *texture, UINT32 modmode,
184         float prim_width, float prim_height);
185   void init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
186         UINT32 flags, d3d::texture_info *texture, UINT32 modmode,
187         float line_time, float line_length,
188         float prim_width, float prim_height);
189
190   D3DPRIMITIVETYPE        get_type() { return m_type; }
191   UINT32                  get_count() { return m_count; }
192   UINT32                  get_vertcount() { return m_numverts; }
193   UINT32                  get_flags() { return m_flags; }
194
195   d3d::texture_info *     get_texture() { return m_texture; }
196   DWORD                   get_modmode() { return m_modmode; }
197
198   float                   get_line_time() { return m_line_time; }
199   float                   get_line_length() { return m_line_length; }
200
201   float                   get_prim_width() { return m_prim_width; }
202   float                   get_prim_height() { return m_prim_height; }
203
204private:
205
206   D3DPRIMITIVETYPE        m_type;                       // type of primitive
207   UINT32                  m_count;                      // total number of primitives
208   UINT32                  m_numverts;                   // total number of vertices
209   UINT32                  m_flags;                      // rendering flags
210
211   texture_info *          m_texture;                    // pointer to texture info
212   DWORD                   m_modmode;                    // texture modulation mode
213
214   float                   m_line_time;                  // used by vectors
215   float                   m_line_length;                // used by vectors
216
217   float                   m_prim_width;                 // used by quads
218   float                   m_prim_height;                // used by quads
219};
220
221}; // d3d
222
223/* vertex describes a single vertex */
224struct vertex
225{
226   float                   x, y, z;                    // X,Y,Z coordinates
227   float                   rhw;                        // RHW when no HLSL, padding when HLSL
228   D3DCOLOR                color;                      // diffuse color
229   float                   u0, v0;                     // texture stage 0 coordinates
230   float                   u1, v1;                     // additional info for vector data
231};
232
233
234/* line_aa_step is used for drawing antialiased lines */
235struct line_aa_step
236{
237   float                   xoffs, yoffs;               // X/Y deltas
238   float                   weight;                     // weight contribution
239};
240
241
242#endif
trunk/src/osd/windows/d3dhlsl.c
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  d3dhlsl.c - Win32 Direct3D HLSL implementation
6//
7//============================================================
8
9// Useful info:
10//  Windows XP/2003 shipped with DirectX 8.1
11//  Windows 2000 shipped with DirectX 7a
12//  Windows 98SE shipped with DirectX 6.1a
13//  Windows 98 shipped with DirectX 5
14//  Windows NT shipped with DirectX 3.0a
15//  Windows 95 shipped with DirectX 2
16
17// standard windows headers
18#define WIN32_LEAN_AND_MEAN
19#include <windows.h>
20#include <tchar.h>
21#include <mmsystem.h>
22#include <d3d9.h>
23#include <d3dx9.h>
24#include <math.h>
25#undef interface
26
27// MAME headers
28#include "emu.h"
29#include "render.h"
30#include "ui/ui.h"
31#include "rendutil.h"
32#include "options.h"
33#include "emuopts.h"
34#include "aviio.h"
35#include "png.h"
36#include "screen.h"
37
38// MAMEOS headers
39#include "d3dintf.h"
40#include "winmain.h"
41#include "window.h"
42#include "config.h"
43#include "d3dcomm.h"
44#include "drawd3d.h"
45#include "strconv.h"
46
47
48
49//============================================================
50//  GLOBALS
51//============================================================
52
53static slider_state *g_slider_list;
54static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *templ, const char *extension, int idx);
55
56namespace d3d
57{
58hlsl_options shaders::s_hlsl_presets[4] =
59{
60   {   // 25% Shadow mask, 50% Scanlines, 3% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
61      true,
62      0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
63      0.03f, 0.03f,
64      0.5f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
65      { 0.0f, 0.0f },
66      { 0.0f, 0.0f, 0.0f },
67      { 0.0f, 0.0f, 0.0f },
68      { 0.0f, 0.0f, 0.0f },
69      { 0.0f, 0.0f, 0.0f },
70      { 1.0f, 0.0f, 0.0f },
71      { 0.0f, 1.0f, 0.0f },
72      { 0.0f, 0.0f, 1.0f },
73      { 0.0f, 0.0f, 0.0f },
74      { 1.0f, 1.0f, 1.0f },
75      { 0.9f, 0.9f, 0.9f },
76      { 0.05f,0.05f,0.05f},
77      { 0.25f,0.25f,0.25f},
78      1.2f,
79      false, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0,
80      0.9f, 4.0f,
81      1.0f, 0.21f, 0.19f, 0.17f, 0.15f, 0.14f, 0.13f, 0.12f, 0.11f, 0.10f, 0.09f
82   },
83   {   // 25% Shadow mask, 0% Scanlines, 3% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
84      true,
85      0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
86      0.03f, 0.03f,
87      0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
88      { 0.0f, 0.0f },
89      { 0.0f, 0.0f, 0.0f },
90      { 0.0f, 0.0f, 0.0f },
91      { 0.0f, 0.0f, 0.0f },
92      { 0.0f, 0.0f, 0.0f },
93      { 1.0f, 0.0f, 0.0f },
94      { 0.0f, 1.0f, 0.0f },
95      { 0.0f, 0.0f, 1.0f },
96      { 0.0f, 0.0f, 0.0f },
97      { 1.0f, 1.0f, 1.0f },
98      { 0.9f, 0.9f, 0.9f },
99      { 0.05f,0.05f,0.05f},
100      { 0.25f,0.25f,0.25f},
101      1.2f,
102      false, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0,
103      0.9f, 4.0f,
104      1.0f, 0.21f, 0.19f, 0.17f, 0.15f, 0.14f, 0.13f, 0.12f, 0.11f, 0.10f, 0.09f
105   },
106   {   // 25% Shadow mask, 0% Scanlines, 0% Pincushion, 0 defocus, No Tint, 0.9 Exponent, 5% Floor, 25% Phosphor Return, 120% Saturation
107      true,
108      0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
109      0.0f, 0.0f,
110      0.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.0f,
111      { 0.0f, 0.0f },
112      { 0.0f, 0.0f, 0.0f },
113      { 0.0f, 0.0f, 0.0f },
114      { 0.0f, 0.0f, 0.0f },
115      { 0.0f, 0.0f, 0.0f },
116      { 1.0f, 0.0f, 0.0f },
117      { 0.0f, 1.0f, 0.0f },
118      { 0.0f, 0.0f, 1.0f },
119      { 0.0f, 0.0f, 0.0f },
120      { 1.0f, 1.0f, 1.0f },
121      { 0.9f, 0.9f, 0.9f },
122      { 0.05f,0.05f,0.05f},
123      { 0.25f,0.25f,0.25f},
124      1.2f,
125      false, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0,
126      0.9f, 4.0f,
127      1.0f, 0.21f, 0.19f, 0.17f, 0.15f, 0.14f, 0.13f, 0.12f, 0.11f, 0.10f, 0.09f
128   },
129   {   // 25% Shadow mask, 100% Scanlines, 15% Pincushion, 3 defocus, 24-degree Tint Out, 1.5 Exponent, 5% Floor, 70% Phosphor Return, 80% Saturation, Bad Convergence
130      true,
131      0.25f, { "aperture.png" }, 320, 240, 0.09375f, 0.109375f,
132      0.15f, 0.15f,
133      1.0f, 1.0f, 0.5f, 1.0f, 0.0f, 0.5f,
134      { 3.0f, 3.0f },
135      { 0.5f,-0.33f,0.7f },
136      { 0.0f,-1.0f, 0.5f },
137      { 0.0f, 0.2f, 0.3f },
138      { 0.0f, 0.2f, 0.0f },
139      { 0.8f, 0.2f, 0.0f },
140      { 0.0f, 0.8f, 0.2f},
141      { 0.2f, 0.0f, 0.8f},
142      { 0.0f, 0.0f, 0.0f },
143      { 1.0f, 1.0f, 1.0f },
144      { 1.5f, 1.5f, 1.5f },
145      { 0.05f,0.05f,0.05f},
146      { 0.7f, 0.7f, 0.7f},
147      0.8f,
148      false, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0,
149      0.9f, 4.0f,
150      1.0f, 0.21f, 0.19f, 0.17f, 0.15f, 0.14f, 0.13f, 0.12f, 0.11f, 0.10f, 0.09f
151   },
152};
153
154//============================================================
155//  PROTOTYPES
156//============================================================
157
158static void get_vector(const char *data, int count, float *out, int report_error);
159
160
161//============================================================
162//  TYPE DEFINITIONS
163//============================================================
164
165typedef HRESULT (WINAPI *direct3dx9_loadeffect_ptr)(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, const D3DXMACRO *pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT *ppEffect, LPD3DXBUFFER *ppCompilationErrors);
166static direct3dx9_loadeffect_ptr g_load_effect = NULL;
167
168//============================================================
169//  shader manager constructor
170//============================================================
171
172shaders::shaders()
173{
174   master_enable = false;
175   vector_enable = true;
176   prescale_size_x = 1;
177   prescale_size_y = 1;
178   prescale_force_x = 0;
179   prescale_force_y = 0;
180   preset = -1;
181   shadow_texture = NULL;
182   options = NULL;
183   paused = true;
184   lastidx = -1;
185   targethead = NULL;
186   cachehead = NULL;
187   initialized = false;
188}
189
190
191
192//============================================================
193//  shaders destructor
194//============================================================
195
196shaders::~shaders()
197{
198   global_free(options);
199   cache_target *currcache = cachehead;
200   while(cachehead != NULL)
201   {
202      cachehead = currcache->next;
203      global_free(currcache);
204      currcache = cachehead;
205   }
206
207   render_target *currtarget = targethead;
208   while(targethead != NULL)
209   {
210      targethead = currtarget->next;
211      global_free(currtarget);
212      currtarget = targethead;
213   }
214}
215
216
217
218//============================================================
219//  shaders::window_save
220//============================================================
221
222void shaders::window_save()
223{
224   if (!master_enable || !d3dintf->post_fx_available)
225      return;
226
227   HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &snap_copy_texture);
228   if (result != D3D_OK)
229   {
230      osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL snapshot (%08x), bailing\n", (UINT32)result);
231      return;
232   }
233   (*d3dintf->texture.get_surface_level)(snap_copy_texture, 0, &snap_copy_target);
234
235   result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &snap_texture);
236   if (result != D3D_OK)
237   {
238      osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL snapshot (%08x), bailing\n", (UINT32)result);
239      return;
240   }
241   (*d3dintf->texture.get_surface_level)(snap_texture, 0, &snap_target);
242
243   render_snap = true;
244   snap_rendered = false;
245}
246
247
248
249//============================================================
250//  shaders::window_record
251//============================================================
252
253void shaders::window_record()
254{
255   if (!master_enable || !d3dintf->post_fx_available)
256      return;
257
258   windows_options &options = downcast<windows_options &>(machine->options());
259   const char *filename = options.d3d_hlsl_write();
260
261   if (avi_output_file != NULL)
262      end_avi_recording();
263   else if (filename[0] != 0)
264      begin_avi_recording(filename);
265}
266
267
268//============================================================
269//  shaders::avi_update_snap
270//============================================================
271
272void shaders::avi_update_snap(surface *surface)
273{
274   if (!master_enable || !d3dintf->post_fx_available)
275      return;
276
277   D3DLOCKED_RECT rect;
278
279   // if we don't have a bitmap, or if it's not the right size, allocate a new one
280   if (!avi_snap.valid() || (int)snap_width != avi_snap.width() || (int)snap_height != avi_snap.height())
281   {
282      avi_snap.allocate((int)snap_width, (int)snap_height);
283   }
284
285   // copy the texture
286   HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->get_device(), surface, avi_copy_surface);
287   if (result != D3D_OK)
288   {
289      return;
290   }
291
292   // lock the texture
293   result = (*d3dintf->surface.lock_rect)(avi_copy_surface, &rect, NULL, D3DLOCK_DISCARD);
294   if (result != D3D_OK)
295   {
296      return;
297   }
298
299   // loop over Y
300   for (int srcy = 0; srcy < (int)snap_height; srcy++)
301   {
302      DWORD *src = (DWORD *)((BYTE *)rect.pBits + srcy * rect.Pitch);
303      UINT32 *dst = &avi_snap.pix32(srcy);
304
305      for(int x = 0; x < snap_width; x++)
306         *dst++ = *src++;
307   }
308
309   // unlock
310   result = (*d3dintf->surface.unlock_rect)(avi_copy_surface);
311   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
312}
313
314
315
316//============================================================
317//  hlsl_render_snapshot
318//============================================================
319
320void shaders::render_snapshot(surface *surface)
321{
322   if (!master_enable || !d3dintf->post_fx_available)
323      return;
324
325   D3DLOCKED_RECT rect;
326
327   render_snap = false;
328
329   // if we don't have a bitmap, or if it's not the right size, allocate a new one
330   if (!avi_snap.valid() || snap_width != (avi_snap.width() / 2) || snap_height != (avi_snap.height() / 2))
331   {
332      avi_snap.allocate(snap_width / 2, snap_height / 2);
333   }
334
335   // copy the texture
336   HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->get_device(), surface, snap_copy_target);
337   if (result != D3D_OK)
338   {
339      return;
340   }
341
342   // lock the texture
343   result = (*d3dintf->surface.lock_rect)(snap_copy_target, &rect, NULL, D3DLOCK_DISCARD);
344   if (result != D3D_OK)
345   {
346      return;
347   }
348
349   for(int cy = 0; cy < 2; cy++)
350   {
351      for(int cx = 0; cx < 2; cx++)
352      {
353         // loop over Y
354         for (int srcy = 0; srcy < snap_height / 2; srcy++)
355         {
356            int toty = (srcy + cy * (snap_height / 2));
357            int totx = cx * (snap_width / 2);
358            DWORD *src = (DWORD *)((BYTE *)rect.pBits + toty * rect.Pitch + totx * 4);
359            UINT32 *dst = &avi_snap.pix32(srcy);
360
361            for(int x = 0; x < snap_width / 2; x++)
362               *dst++ = *src++;
363         }
364
365         int idx = cy * 2 + cx;
366
367         emu_file file(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
368         file_error filerr = open_next(d3d, file, NULL, "png", idx);
369         if (filerr != FILERR_NONE)
370            return;
371
372         // add two text entries describing the image
373         astring text1(emulator_info::get_appname(), " ", build_version);
374         astring text2(machine->system().manufacturer, " ", machine->system().description);
375         png_info pnginfo = { 0 };
376         png_add_text(&pnginfo, "Software", text1);
377         png_add_text(&pnginfo, "System", text2);
378
379         // now do the actual work
380         png_error error = png_write_bitmap(file, &pnginfo, avi_snap, 1 << 24, NULL);
381         if (error != PNGERR_NONE)
382            osd_printf_error("Error generating PNG for HLSL snapshot: png_error = %d\n", error);
383
384         // free any data allocated
385         png_free(&pnginfo);
386      }
387   }
388
389   // unlock
390   result = (*d3dintf->surface.unlock_rect)(snap_copy_target);
391   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
392
393   if(snap_texture != NULL)
394   {
395      (*d3dintf->texture.release)(snap_texture);
396      snap_texture = NULL;
397   }
398
399   if(snap_target != NULL)
400   {
401      (*d3dintf->surface.release)(snap_target);
402      snap_target = NULL;
403   }
404
405   if(snap_copy_texture != NULL)
406   {
407      (*d3dintf->texture.release)(snap_copy_texture);
408      snap_copy_texture = NULL;
409   }
410
411   if(snap_copy_target != NULL)
412   {
413      (*d3dintf->surface.release)(snap_copy_target);
414      snap_copy_target = NULL;
415   }
416}
417
418
419//============================================================
420//  shaders::record_texture
421//============================================================
422
423void shaders::record_texture()
424{
425   if (!master_enable || !d3dintf->post_fx_available)
426      return;
427
428   surface *surface = avi_final_target;
429
430   // ignore if nothing to do
431   if (avi_output_file == NULL || surface == NULL)
432      return;
433
434   // get the current time
435   attotime curtime = machine->time();
436
437   avi_update_snap(surface);
438
439   // loop until we hit the right time
440   while (avi_next_frame_time <= curtime)
441   {
442      // handle an AVI recording
443      // write the next frame
444      avi_error avierr = avi_append_video_frame(avi_output_file, avi_snap);
445      if (avierr != AVIERR_NONE)
446      {
447         end_avi_recording();
448         return;
449      }
450
451      // advance time
452      avi_next_frame_time += avi_frame_period;
453      avi_frame++;
454   }
455}
456
457
458//============================================================
459//  shaders::end_hlsl_avi_recording
460//============================================================
461
462void shaders::end_avi_recording()
463{
464   if (!master_enable || !d3dintf->post_fx_available)
465      return;
466
467   if (avi_output_file != NULL)
468      avi_close(avi_output_file);
469
470   avi_output_file = NULL;
471   avi_frame = 0;
472}
473
474
475//============================================================
476//  shaders::toggle
477//============================================================
478
479void shaders::toggle()
480{
481   if (master_enable)
482   {
483      if (initialized)
484      {
485         delete_resources(false);
486      }
487      master_enable = !master_enable;
488   }
489   else
490   {
491      if (!initialized)
492      {
493         master_enable = !master_enable;
494         bool failed = create_resources(false);
495         if (failed)
496         {
497            master_enable = false;
498         }
499      }
500      else
501      {
502         master_enable = !master_enable;
503      }
504   }
505}
506
507//============================================================
508//  shaders::begin_avi_recording
509//============================================================
510
511void shaders::begin_avi_recording(const char *name)
512{
513   if (!master_enable || !d3dintf->post_fx_available)
514      return;
515
516   // stop any existing recording
517   end_avi_recording();
518
519   // reset the state
520   avi_frame = 0;
521   avi_next_frame_time = machine->time();
522
523   // build up information about this new movie
524   avi_movie_info info;
525   info.video_format = 0;
526   info.video_timescale = 1000 * ((machine->first_screen() != NULL) ? ATTOSECONDS_TO_HZ(machine->first_screen()->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE);
527   info.video_sampletime = 1000;
528   info.video_numsamples = 0;
529   info.video_width = snap_width;
530   info.video_height = snap_height;
531   info.video_depth = 24;
532
533   info.audio_format = 0;
534   info.audio_timescale = machine->sample_rate();
535   info.audio_sampletime = 1;
536   info.audio_numsamples = 0;
537   info.audio_channels = 2;
538   info.audio_samplebits = 16;
539   info.audio_samplerate = machine->sample_rate();
540
541   // create a new temporary movie file
542   file_error filerr;
543   astring fullpath;
544   {
545      emu_file tempfile(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
546      if (name != NULL)
547      {
548         filerr = tempfile.open(name);
549      }
550      else
551      {
552         filerr = open_next(d3d, tempfile, NULL, "avi", 0);
553      }
554
555      // compute the frame time
556      {
557         avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
558      }
559
560      // if we succeeded, make a copy of the name and create the real file over top
561      if (filerr == FILERR_NONE)
562      {
563         fullpath = tempfile.fullpath();
564      }
565   }
566
567   if (filerr == FILERR_NONE)
568   {
569      // create the file and free the string
570      avi_error avierr = avi_create(fullpath, &info, &avi_output_file);
571      if (avierr != AVIERR_NONE)
572      {
573         osd_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
574      }
575   }
576}
577
578
579//============================================================
580//  remove_cache_target - remove an active cache target when
581//  refcount hits zero
582//============================================================
583
584void shaders::remove_cache_target(cache_target *cache)
585{
586   if (cache != NULL)
587   {
588      if (cache == cachehead)
589      {
590         cachehead = cachehead->next;
591      }
592
593      if (cache->prev != NULL)
594      {
595         cache->prev->next = cache->next;
596      }
597
598      if (cache->next != NULL)
599      {
600         cache->next->prev = cache->prev;
601      }
602
603      global_free(cache);
604   }
605}
606
607
608//============================================================
609//  remove_render_target - remove an active target
610//============================================================
611
612void shaders::remove_render_target(texture_info *texture)
613{
614   remove_render_target(find_render_target(texture));
615}
616
617void shaders::remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index)
618{
619   render_target *target = find_render_target(width, height, screen_index, page_index);
620   if (target != NULL)
621   {
622      remove_render_target(target);
623   }
624}
625
626void shaders::remove_render_target(render_target *rt)
627{
628   if (rt != NULL)
629   {
630      if (rt == targethead)
631      {
632         targethead = targethead->next;
633      }
634
635      if (rt->prev != NULL)
636      {
637         rt->prev->next = rt->next;
638      }
639
640      if (rt->next != NULL)
641      {
642         rt->next->prev = rt->prev;
643      }
644
645      cache_target *cache = find_cache_target(rt->screen_index, rt->width, rt->height);
646      if (cache != NULL)
647      {
648         remove_cache_target(cache);
649      }
650
651      int screen_index = rt->screen_index;
652      int other_page = 1 - rt->page_index;
653      int width = rt->width;
654      int height = rt->height;
655
656      global_free(rt);
657
658      // Remove other double-buffered page (if it exists)
659      remove_render_target(width, height, screen_index, other_page);
660   }
661}
662
663
664//============================================================
665//  shaders::set_texture
666//============================================================
667
668void shaders::set_texture(texture_info *texture)
669{
670   if (!master_enable || !d3dintf->post_fx_available)
671      return;
672
673   if(texture != NULL)
674   {
675      paused = texture->paused();
676      texture->advance_frame();
677   }
678
679   texture_info *default_texture = d3d->get_default_texture();
680   default_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
681   if (options->yiq_enable)
682      yiq_encode_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
683   else
684      color_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex());
685}
686
687
688//============================================================
689//  shaders::init
690//============================================================
691
692void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *renderer)
693{
694   if (!d3dintf->post_fx_available)
695      return;
696
697   g_load_effect = (direct3dx9_loadeffect_ptr)GetProcAddress(d3dintf->libhandle, "D3DXCreateEffectFromFileW");
698   if (g_load_effect == NULL)
699   {
700      printf("Direct3D: Unable to find D3DXCreateEffectFromFileW\n");
701      d3dintf->post_fx_available = false;
702      return;
703   }
704
705   this->d3dintf = d3dintf;
706   this->machine = machine;
707   this->d3d = renderer;
708
709   master_enable = downcast<windows_options &>(machine->options()).d3d_hlsl_enable();
710   prescale_size_x = 1;
711   prescale_size_y = 1;
712   preset = downcast<windows_options &>(machine->options()).d3d_hlsl_preset();
713   if (preset < -1 || preset > 3)
714   {
715      preset = -1;
716   }
717
718   snap_width = downcast<windows_options &>(machine->options()).d3d_snap_width();
719   snap_height = downcast<windows_options &>(machine->options()).d3d_snap_height();
720   prescale_force_x = 0;
721   prescale_force_y = 0;
722
723   windows_options &winoptions = downcast<windows_options &>(machine->options());
724
725   options = (hlsl_options*)global_alloc_clear(hlsl_options);
726
727   options->params_dirty = true;
728   strcpy(options->shadow_mask_texture, downcast<windows_options &>(machine->options()).screen_shadow_mask_texture()); // unsafe
729
730   prescale_force_x = winoptions.d3d_hlsl_prescale_x();
731   prescale_force_y = winoptions.d3d_hlsl_prescale_y();
732   if(preset == -1)
733   {
734      options->shadow_mask_alpha = winoptions.screen_shadow_mask_alpha();
735      options->shadow_mask_count_x = winoptions.screen_shadow_mask_count_x();
736      options->shadow_mask_count_y = winoptions.screen_shadow_mask_count_y();
737      options->shadow_mask_u_size = winoptions.screen_shadow_mask_u_size();
738      options->shadow_mask_v_size = winoptions.screen_shadow_mask_v_size();
739      options->curvature = winoptions.screen_curvature();
740      options->pincushion = winoptions.screen_pincushion();
741      options->scanline_alpha = winoptions.screen_scanline_amount();
742      options->scanline_scale = winoptions.screen_scanline_scale();
743      options->scanline_height = winoptions.screen_scanline_height();
744      options->scanline_bright_scale = winoptions.screen_scanline_bright_scale();
745      options->scanline_bright_offset = winoptions.screen_scanline_bright_offset();
746      options->scanline_offset = winoptions.screen_scanline_offset();
747      get_vector(winoptions.screen_defocus(), 2, options->defocus, TRUE);
748      get_vector(winoptions.screen_converge_x(), 3, options->converge_x, TRUE);
749      get_vector(winoptions.screen_converge_y(), 3, options->converge_y, TRUE);
750      get_vector(winoptions.screen_radial_converge_x(), 3, options->radial_converge_x, TRUE);
751      get_vector(winoptions.screen_radial_converge_y(), 3, options->radial_converge_y, TRUE);
752      get_vector(winoptions.screen_red_ratio(), 3, options->red_ratio, TRUE);
753      get_vector(winoptions.screen_grn_ratio(), 3, options->grn_ratio, TRUE);
754      get_vector(winoptions.screen_blu_ratio(), 3, options->blu_ratio, TRUE);
755      get_vector(winoptions.screen_offset(), 3, options->offset, TRUE);
756      get_vector(winoptions.screen_scale(), 3, options->scale, TRUE);
757      get_vector(winoptions.screen_power(), 3, options->power, TRUE);
758      get_vector(winoptions.screen_floor(), 3, options->floor, TRUE);
759      get_vector(winoptions.screen_phosphor(), 3, options->phosphor, TRUE);
760      options->saturation = winoptions.screen_saturation();
761   }
762   else
763   {
764      options = &s_hlsl_presets[preset];
765   }
766
767   options->yiq_enable = winoptions.screen_yiq_enable();
768   options->yiq_cc = winoptions.screen_yiq_cc();
769   options->yiq_a = winoptions.screen_yiq_a();
770   options->yiq_b = winoptions.screen_yiq_b();
771   options->yiq_o = winoptions.screen_yiq_o();
772   options->yiq_p = winoptions.screen_yiq_p();
773   options->yiq_n = winoptions.screen_yiq_n();
774   options->yiq_y = winoptions.screen_yiq_y();
775   options->yiq_i = winoptions.screen_yiq_i();
776   options->yiq_q = winoptions.screen_yiq_q();
777   options->yiq_scan_time = winoptions.screen_yiq_scan_time();
778   options->yiq_phase_count = winoptions.screen_yiq_phase_count();
779   options->vector_length_scale = winoptions.screen_vector_length_scale();
780   options->vector_length_ratio = winoptions.screen_vector_length_ratio();
781   options->vector_bloom_scale = winoptions.screen_vector_bloom_scale();
782   options->raster_bloom_scale = winoptions.screen_raster_bloom_scale();
783   options->bloom_level0_weight = winoptions.screen_bloom_lvl0_weight();
784   options->bloom_level1_weight = winoptions.screen_bloom_lvl1_weight();
785   options->bloom_level2_weight = winoptions.screen_bloom_lvl2_weight();
786   options->bloom_level3_weight = winoptions.screen_bloom_lvl3_weight();
787   options->bloom_level4_weight = winoptions.screen_bloom_lvl4_weight();
788   options->bloom_level5_weight = winoptions.screen_bloom_lvl5_weight();
789   options->bloom_level6_weight = winoptions.screen_bloom_lvl6_weight();
790   options->bloom_level7_weight = winoptions.screen_bloom_lvl7_weight();
791   options->bloom_level8_weight = winoptions.screen_bloom_lvl8_weight();
792   options->bloom_level9_weight = winoptions.screen_bloom_lvl9_weight();
793   options->bloom_level10_weight = winoptions.screen_bloom_lvl10_weight();
794
795   options->params_dirty = true;
796
797   g_slider_list = init_slider_list();
798}
799
800
801
802//============================================================
803//  shaders::init_fsfx_quad
804//============================================================
805
806void shaders::init_fsfx_quad(void *vertbuf)
807{
808   // Called at the start of each frame by the D3D code in order to reserve two triangles
809   // that are guaranteed to be at a fixed position so as to simply use D3DPT_TRIANGLELIST, 0, 2
810   // instead of having to do bookkeeping about a specific screen quad
811   if (!master_enable || !d3dintf->post_fx_available)
812      return;
813
814   // get a pointer to the vertex buffer
815   fsfx_vertices = (vertex *)vertbuf;
816   if (fsfx_vertices == NULL)
817      return;
818
819   // fill in the vertexes clockwise
820   fsfx_vertices[0].x = 0.0f;
821   fsfx_vertices[0].y = 0.0f;
822   fsfx_vertices[1].x = d3d->get_width();
823   fsfx_vertices[1].y = 0.0f;
824   fsfx_vertices[2].x = 0.0f;
825   fsfx_vertices[2].y = d3d->get_height();
826   fsfx_vertices[3].x = d3d->get_width();
827   fsfx_vertices[3].y = 0.0f;
828   fsfx_vertices[4].x = 0.0f;
829   fsfx_vertices[4].y = d3d->get_height();
830   fsfx_vertices[5].x = d3d->get_width();
831   fsfx_vertices[5].y = d3d->get_height();
832
833   fsfx_vertices[0].u0 = 0.0f;
834   fsfx_vertices[0].v0 = 0.0f;
835
836   fsfx_vertices[1].u0 = 1.0f;
837   fsfx_vertices[1].v0 = 0.0f;
838
839   fsfx_vertices[2].u0 = 0.0f;
840   fsfx_vertices[2].v0 = 1.0f;
841
842   fsfx_vertices[3].u0 = 1.0f;
843   fsfx_vertices[3].v0 = 0.0f;
844
845   fsfx_vertices[4].u0 = 0.0f;
846   fsfx_vertices[4].v0 = 1.0f;
847
848   fsfx_vertices[5].u0 = 1.0f;
849   fsfx_vertices[5].v0 = 1.0f;
850
851   fsfx_vertices[0].u1 = 0.0f;
852   fsfx_vertices[0].v1 = 0.0f;
853   fsfx_vertices[1].u1 = 0.0f;
854   fsfx_vertices[1].v1 = 0.0f;
855   fsfx_vertices[2].u1 = 0.0f;
856   fsfx_vertices[2].v1 = 0.0f;
857   fsfx_vertices[3].u1 = 0.0f;
858   fsfx_vertices[3].v1 = 0.0f;
859   fsfx_vertices[4].u1 = 0.0f;
860   fsfx_vertices[4].v1 = 0.0f;
861   fsfx_vertices[5].u1 = 0.0f;
862   fsfx_vertices[5].v1 = 0.0f;
863
864   // set the color, Z parameters to standard values
865   for (int i = 0; i < 6; i++)
866   {
867      fsfx_vertices[i].z = 0.0f;
868      fsfx_vertices[i].rhw = 1.0f;
869      fsfx_vertices[i].color = D3DCOLOR_ARGB(255, 255, 255, 255);
870   }
871}
872
873
874
875//============================================================
876//  shaders::create_resources
877//============================================================
878
879int shaders::create_resources(bool reset)
880{
881   if (!master_enable || !d3dintf->post_fx_available)
882      return 0;
883
884   HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
885   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
886
887   result = (*d3dintf->device.create_texture)(d3d->get_device(), 4, 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &black_texture);
888   if (result != D3D_OK)
889   {
890      osd_printf_verbose("Direct3D: Unable to init video-memory target for black texture (%08x)\n", (UINT32)result);
891      return 1;
892   }
893   (*d3dintf->texture.get_surface_level)(black_texture, 0, &black_surface);
894   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, black_surface);
895   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
896   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
897   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
898   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
899   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
900
901   result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)snap_width, (int)snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &avi_copy_texture);
902   if (result != D3D_OK)
903   {
904      osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
905      return 1;
906   }
907   (*d3dintf->texture.get_surface_level)(avi_copy_texture, 0, &avi_copy_surface);
908
909   result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)snap_width, (int)snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &avi_final_texture);
910   if (result != D3D_OK)
911   {
912      osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL AVI dumping (%08x)\n", (UINT32)result);
913      return 1;
914   }
915   (*d3dintf->texture.get_surface_level)(avi_final_texture, 0, &avi_final_target);
916
917   emu_file file(machine->options().art_path(), OPEN_FLAG_READ);
918   render_load_png(shadow_bitmap, file, NULL, options->shadow_mask_texture);
919
920   // experimental: if we have a shadow bitmap, create a texture for it
921   if (shadow_bitmap.valid())
922   {
923      render_texinfo texture;
924
925      // fake in the basic data so it looks like it came from render.c
926      texture.base = shadow_bitmap.raw_pixptr(0);
927      texture.rowpixels = shadow_bitmap.rowpixels();
928      texture.width = shadow_bitmap.width();
929      texture.height = shadow_bitmap.height();
930      texture.palette = NULL;
931      texture.seqid = 0;
932
933      // FIXME: should shadow bitmap really use prescale?
934      // now create it
935      shadow_texture = new texture_info(d3d->get_texture_manager(), &texture, video_config.prescale, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
936   }
937
938   const char *fx_dir = downcast<windows_options &>(machine->options()).screen_post_fx_dir();
939
940   default_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir);
941   post_effect = new effect(this, d3d->get_device(), "post.fx", fx_dir);
942   prescale_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir);
943   phosphor_effect = new effect(this, d3d->get_device(), "phosphor.fx", fx_dir);
944   focus_effect = new effect(this, d3d->get_device(), "focus.fx", fx_dir);
945   deconverge_effect = new effect(this, d3d->get_device(), "deconverge.fx", fx_dir);
946   color_effect = new effect(this, d3d->get_device(), "color.fx", fx_dir);
947   yiq_encode_effect = new effect(this, d3d->get_device(), "yiq_encode.fx", fx_dir);
948   yiq_decode_effect = new effect(this, d3d->get_device(), "yiq_decode.fx", fx_dir);
949   bloom_effect = new effect(this, d3d->get_device(), "bloom.fx", fx_dir);
950   downsample_effect = new effect(this, d3d->get_device(), "downsample.fx", fx_dir);
951   vector_effect = new effect(this, d3d->get_device(), "vector.fx", fx_dir);
952
953   if (!default_effect->is_valid()) return 1;
954   if (!post_effect->is_valid()) return 1;
955   if (!prescale_effect->is_valid()) return 1;
956   if (!phosphor_effect->is_valid()) return 1;
957   if (!focus_effect->is_valid()) return 1;
958   if (!deconverge_effect->is_valid()) return 1;
959   if (!color_effect->is_valid()) return 1;
960   if (!yiq_encode_effect->is_valid()) return 1;
961   if (!yiq_decode_effect->is_valid()) return 1;
962   if (!bloom_effect->is_valid()) return 1;
963   if (!downsample_effect->is_valid()) return 1;
964   if (!vector_effect->is_valid()) return 1;
965
966   yiq_encode_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
967   yiq_encode_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
968   yiq_encode_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
969   yiq_encode_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
970   yiq_encode_effect->add_uniform("AValue", uniform::UT_FLOAT, uniform::CU_NTSC_A);
971   yiq_encode_effect->add_uniform("BValue", uniform::UT_FLOAT, uniform::CU_NTSC_B);
972   yiq_encode_effect->add_uniform("PValue", uniform::UT_FLOAT, uniform::CU_NTSC_P);
973   yiq_encode_effect->add_uniform("NotchHalfWidth", uniform::UT_FLOAT, uniform::CU_NTSC_NOTCH);
974   yiq_encode_effect->add_uniform("YFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_YFREQ);
975   yiq_encode_effect->add_uniform("IFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_IFREQ);
976   yiq_encode_effect->add_uniform("QFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_QFREQ);
977   yiq_encode_effect->add_uniform("ScanTime", uniform::UT_FLOAT, uniform::CU_NTSC_HTIME);
978
979   yiq_decode_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
980   yiq_decode_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
981   yiq_decode_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
982   yiq_decode_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
983   yiq_decode_effect->add_uniform("AValue", uniform::UT_FLOAT, uniform::CU_NTSC_A);
984   yiq_decode_effect->add_uniform("BValue", uniform::UT_FLOAT, uniform::CU_NTSC_B);
985   yiq_decode_effect->add_uniform("OValue", uniform::UT_FLOAT, uniform::CU_NTSC_O);
986   yiq_decode_effect->add_uniform("PValue", uniform::UT_FLOAT, uniform::CU_NTSC_P);
987   yiq_decode_effect->add_uniform("NotchHalfWidth", uniform::UT_FLOAT, uniform::CU_NTSC_NOTCH);
988   yiq_decode_effect->add_uniform("YFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_YFREQ);
989   yiq_decode_effect->add_uniform("IFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_IFREQ);
990   yiq_decode_effect->add_uniform("QFreqResponse", uniform::UT_FLOAT, uniform::CU_NTSC_QFREQ);
991   yiq_decode_effect->add_uniform("ScanTime", uniform::UT_FLOAT, uniform::CU_NTSC_HTIME);
992
993   color_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
994   color_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
995
996   color_effect->add_uniform("YIQEnable", uniform::UT_FLOAT, uniform::CU_NTSC_ENABLE);
997   color_effect->add_uniform("RedRatios", uniform::UT_VEC3, uniform::CU_COLOR_RED_RATIOS);
998   color_effect->add_uniform("GrnRatios", uniform::UT_VEC3, uniform::CU_COLOR_GRN_RATIOS);
999   color_effect->add_uniform("BluRatios", uniform::UT_VEC3, uniform::CU_COLOR_BLU_RATIOS);
1000   color_effect->add_uniform("Offset", uniform::UT_VEC3, uniform::CU_COLOR_OFFSET);
1001   color_effect->add_uniform("Scale", uniform::UT_VEC3, uniform::CU_COLOR_SCALE);
1002   color_effect->add_uniform("Saturation", uniform::UT_FLOAT, uniform::CU_COLOR_SATURATION);
1003
1004   prescale_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1005   prescale_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
1006
1007   deconverge_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1008   deconverge_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
1009   deconverge_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
1010   deconverge_effect->add_uniform("ConvergeX", uniform::UT_VEC3, uniform::CU_CONVERGE_LINEAR_X);
1011   deconverge_effect->add_uniform("ConvergeY", uniform::UT_VEC3, uniform::CU_CONVERGE_LINEAR_Y);
1012   deconverge_effect->add_uniform("RadialConvergeX", uniform::UT_VEC3, uniform::CU_CONVERGE_RADIAL_X);
1013   deconverge_effect->add_uniform("RadialConvergeY", uniform::UT_VEC3, uniform::CU_CONVERGE_RADIAL_Y);
1014
1015   focus_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1016   focus_effect->add_uniform("Defocus", uniform::UT_VEC2, uniform::CU_FOCUS_SIZE);
1017
1018   phosphor_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1019   phosphor_effect->add_uniform("Phosphor", uniform::UT_VEC3, uniform::CU_PHOSPHOR_LIFE);
1020   phosphor_effect->add_uniform("Passthrough", uniform::UT_FLOAT, uniform::CU_PHOSPHOR_IGNORE);
1021
1022   post_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS);
1023   post_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT);
1024   post_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
1025
1026   post_effect->add_uniform("PincushionAmount", uniform::UT_FLOAT, uniform::CU_POST_PINCUSHION);
1027   post_effect->add_uniform("CurvatureAmount", uniform::UT_FLOAT, uniform::CU_POST_CURVATURE);
1028
1029   post_effect->add_uniform("ShadowAlpha", uniform::UT_FLOAT, uniform::CU_POST_SHADOW_ALPHA);
1030   post_effect->add_uniform("ShadowCount", uniform::UT_VEC2, uniform::CU_POST_SHADOW_COUNT);
1031   post_effect->add_uniform("ShadowUV", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV);
1032   post_effect->add_uniform("ShadowDims", uniform::UT_VEC2, uniform::CU_POST_SHADOW_DIMS);
1033
1034   post_effect->add_uniform("ScanlineAlpha", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_ALPHA);
1035   post_effect->add_uniform("ScanlineScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_SCALE);
1036   post_effect->add_uniform("ScanlineHeight", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_HEIGHT);
1037   post_effect->add_uniform("ScanlineBrightScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_SCALE);
1038   post_effect->add_uniform("ScanlineBrightOffset", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_OFFSET);
1039   post_effect->add_uniform("Power", uniform::UT_VEC3, uniform::CU_POST_POWER);
1040   post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR);
1041
1042   initialized = true;
1043
1044   return 0;
1045}
1046
1047
1048//============================================================
1049//  shaders::begin_draw
1050//============================================================
1051
1052void shaders::begin_draw()
1053{
1054   if (!master_enable || !d3dintf->post_fx_available)
1055      return;
1056
1057   curr_effect = default_effect;
1058
1059   default_effect->set_technique("TestTechnique");
1060   post_effect->set_technique("ScanMaskTechnique");
1061   phosphor_effect->set_technique("TestTechnique");
1062   focus_effect->set_technique("TestTechnique");
1063   deconverge_effect->set_technique("DeconvergeTechnique");
1064   color_effect->set_technique("ColorTechnique");
1065   yiq_encode_effect->set_technique("EncodeTechnique");
1066   yiq_decode_effect->set_technique("DecodeTechnique");
1067
1068   HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer);
1069   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
1070}
1071
1072
1073//============================================================
1074//  shaders::begin_frame
1075//============================================================
1076
1077void shaders::begin_frame()
1078{
1079   record_texture();
1080}
1081
1082
1083//============================================================
1084//  shaders::blit
1085//============================================================
1086
1087void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type,
1088                  UINT32 prim_index, UINT32 prim_count, int dstw, int dsth)
1089{
1090   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
1091   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1092
1093   curr_effect = default_effect;
1094
1095   curr_effect->set_texture("Diffuse", src);
1096
1097   float dst_dims[2] = { (float)dstw, (float)dsth };
1098   curr_effect->set_vector("ScreenDims", 2, dst_dims);
1099   curr_effect->set_float("PostPass", 1.0f);
1100   curr_effect->set_float("PincushionAmount", options->pincushion);
1101   curr_effect->set_float("Brighten", 0.0f);
1102
1103   unsigned int num_passes = 0;
1104   curr_effect->begin(&num_passes, 0);
1105
1106   for (UINT pass = 0; pass < num_passes; pass++)
1107   {
1108      curr_effect->begin_pass(pass);
1109      // add the primitives
1110      HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count);
1111      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1112      curr_effect->end_pass();
1113   }
1114
1115   curr_effect->end();
1116
1117   if (new_dst)
1118   {
1119      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, new_dst);
1120      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1121   }
1122}
1123
1124
1125
1126//============================================================
1127//  shaders::blit
1128//============================================================
1129
1130void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type,
1131                  UINT32 prim_index, UINT32 prim_count)
1132{
1133   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst);
1134   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1135   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
1136   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1137
1138   curr_effect = default_effect;
1139
1140   curr_effect->set_texture("Diffuse", src);
1141
1142   vec2f screendims = d3d->get_dims();
1143   curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
1144   curr_effect->set_float("PostPass", 1.0f);
1145   curr_effect->set_float("PincushionAmount", options->pincushion);
1146   curr_effect->set_float("Brighten", 1.0f);
1147
1148   unsigned int num_passes = 0;
1149   curr_effect->begin(&num_passes, 0);
1150
1151   for (UINT pass = 0; pass < num_passes; pass++)
1152   {
1153      curr_effect->begin_pass(pass);
1154      // add the primitives
1155      HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count);
1156      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1157      curr_effect->end_pass();
1158   }
1159
1160   curr_effect->end();
1161
1162   curr_effect->set_float("Brighten", 0.0f);
1163
1164   if (new_dst)
1165   {
1166      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, new_dst);
1167      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1168   }
1169}
1170
1171//============================================================
1172//  shaders::end_frame
1173//============================================================
1174
1175void shaders::end_frame()
1176{
1177   if (!master_enable || !d3dintf->post_fx_available)
1178      return;
1179
1180   if(render_snap && snap_rendered)
1181   {
1182      render_snapshot(snap_target);
1183   }
1184
1185   if (!lines_pending)
1186      return;
1187
1188   lines_pending = false;
1189
1190   /*render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
1191   if (rt == NULL)
1192   {
1193       return;
1194   }
1195
1196   blit(backbuffer, rt->render_texture[1], NULL, vecbuf_type, vecbuf_index, vecbuf_count);
1197
1198   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]);
1199   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1200   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1201   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1202   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
1203   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);*/
1204}
1205
1206
1207//============================================================
1208//  shaders::init_effect_info
1209//============================================================
1210
1211void shaders::init_effect_info(poly_info *poly)
1212{
1213   if (!master_enable || !d3dintf->post_fx_available)
1214      return;
1215
1216   texture_info *texture = poly->get_texture();
1217
1218   if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && texture != NULL)
1219   {
1220      // Plug in all of the shader settings we're going to need
1221      // This is extremely slow, but we're not rendering models here,
1222      // just post-processing.
1223      curr_effect = post_effect;
1224
1225      curr_effect->set_float("ScanlineOffset", (texture->get_cur_frame() == 0) ? 0.0f : options->scanline_offset);
1226   }
1227   else
1228   {
1229      curr_effect = default_effect;
1230
1231      curr_effect->set_float("FixedAlpha", 1.0f);
1232   }
1233}
1234
1235
1236//============================================================
1237//  shaders::find_render_target
1238//============================================================
1239
1240render_target* shaders::find_render_target(texture_info *info)
1241{
1242   render_target *curr = targethead;
1243   UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata;
1244   UINT32 screen_index = screen_index_data >> 1;
1245   UINT32 page_index = screen_index_data & 1;
1246
1247   while (curr != NULL && (curr->screen_index != screen_index || curr->page_index != page_index ||
1248      curr->width != info->get_texinfo().width || curr->height != info->get_texinfo().height))
1249   {
1250      curr = curr->next;
1251   }
1252
1253   return curr;
1254}
1255
1256
1257//============================================================
1258//  shaders::find_render_target
1259//============================================================
1260
1261render_target* shaders::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index)
1262{
1263   render_target *curr = targethead;
1264
1265   while (curr != NULL && (curr->width != width || curr->height != height || curr->screen_index != screen_index || curr->page_index != page_index))
1266   {
1267      curr = curr->next;
1268   }
1269
1270   return curr;
1271}
1272
1273
1274//============================================================
1275//  shaders::find_cache_target
1276//============================================================
1277
1278cache_target* shaders::find_cache_target(UINT32 screen_index, int width, int height)
1279{
1280   cache_target *curr = cachehead;
1281
1282   while (curr != NULL && (curr->screen_index != screen_index || curr->width != width || curr->height != height))
1283   {
1284      curr = curr->next;
1285   }
1286
1287   return curr;
1288}
1289
1290void shaders::ntsc_pass(render_target *rt, vec2f &sourcedims, vec2f &delta)
1291{
1292   UINT num_passes = 0;
1293
1294   if(options->yiq_enable)
1295   {
1296      // Convert our signal into YIQ
1297      curr_effect = yiq_encode_effect;
1298      curr_effect->update_uniforms();
1299
1300      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[4]);
1301
1302      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1303      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1304      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1305
1306      curr_effect->begin(&num_passes, 0);
1307
1308      for (UINT pass = 0; pass < num_passes; pass++)
1309      {
1310         curr_effect->begin_pass(pass);
1311         // add the primitives
1312         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1313         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1314         curr_effect->end_pass();
1315      }
1316
1317      curr_effect->end();
1318
1319      // Convert our signal from YIQ
1320      curr_effect = yiq_decode_effect;
1321
1322      curr_effect->set_texture("Composite", rt->render_texture[4]);
1323      curr_effect->set_texture("Diffuse", curr_texture->get_finaltex());
1324      curr_effect->update_uniforms();
1325
1326      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[3]);
1327
1328      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1329      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1330      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1331
1332      curr_effect->begin(&num_passes, 0);
1333
1334      for (UINT pass = 0; pass < num_passes; pass++)
1335      {
1336         curr_effect->begin_pass(pass);
1337         // add the primitives
1338         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1339         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1340         curr_effect->end_pass();
1341      }
1342
1343      curr_effect->end();
1344
1345      curr_effect = color_effect;
1346
1347      curr_effect->set_texture("Diffuse", rt->render_texture[3]);
1348   }
1349}
1350
1351void shaders::color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims)
1352{
1353   UINT num_passes = 0;
1354
1355   curr_effect = color_effect;
1356   curr_effect->update_uniforms();
1357
1358   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->smalltarget);
1359
1360   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1361   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1362   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1363
1364   curr_effect->begin(&num_passes, 0);
1365
1366   for (UINT pass = 0; pass < num_passes; pass++)
1367   {
1368      curr_effect->begin_pass(pass);
1369      // add the primitives
1370      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1371      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1372      curr_effect->end_pass();
1373   }
1374
1375   curr_effect->end();
1376}
1377
1378void shaders::prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims)
1379{
1380   UINT num_passes = 0;
1381
1382   curr_effect = prescale_effect;
1383   curr_effect->update_uniforms();
1384   curr_effect->set_texture("Diffuse", rt->smalltexture);
1385
1386   curr_effect->begin(&num_passes, 0);
1387
1388   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->prescaletarget);
1389   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1390   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1391   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1392
1393   for (UINT pass = 0; pass < num_passes; pass++)
1394   {
1395      curr_effect->begin_pass(pass);
1396      // add the primitives
1397      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1398      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1399      curr_effect->end_pass();
1400   }
1401
1402   curr_effect->end();
1403}
1404
1405void shaders::deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims)
1406{
1407   UINT num_passes = 0;
1408
1409   curr_effect = deconverge_effect;
1410   curr_effect->update_uniforms();
1411   curr_effect->set_texture("Diffuse", rt->prescaletexture);
1412
1413   curr_effect->begin(&num_passes, 0);
1414
1415   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[2]);
1416   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1417   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1418   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1419
1420   for (UINT pass = 0; pass < num_passes; pass++)
1421   {
1422      curr_effect->begin_pass(pass);
1423      // add the primitives
1424      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1425      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1426      curr_effect->end_pass();
1427   }
1428
1429   curr_effect->end();
1430}
1431
1432void shaders::defocus_pass(render_target *rt, vec2f &texsize)
1433{
1434   UINT num_passes = 0;
1435
1436   // Defocus pass 1
1437   curr_effect = focus_effect;
1438   curr_effect->update_uniforms();
1439   curr_effect->set_texture("Diffuse", rt->render_texture[2]);
1440
1441   curr_effect->begin(&num_passes, 0);
1442
1443   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]);
1444   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1445   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1446   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1447
1448   for (UINT pass = 0; pass < num_passes; pass++)
1449   {
1450      curr_effect->begin_pass(pass);
1451      // add the primitives
1452      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1453      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1454      curr_effect->end_pass();
1455   }
1456
1457   curr_effect->end();
1458
1459   // Defocus pass 2
1460
1461   curr_effect->set_texture("Diffuse", rt->render_texture[0]);
1462
1463   curr_effect->begin(&num_passes, 0);
1464
1465   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]);
1466   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 7\n", (int)result);
1467
1468   for (UINT pass = 0; pass < num_passes; pass++)
1469   {
1470      curr_effect->begin_pass(pass);
1471      // add the primitives
1472      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1473      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1474      curr_effect->end_pass();
1475   }
1476
1477   curr_effect->end();
1478}
1479
1480void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable)
1481{
1482   UINT num_passes = 0;
1483
1484   curr_effect = phosphor_effect;
1485   phosphor_passthrough = false;
1486   curr_effect->update_uniforms();
1487
1488   float rtsize[2] = { rt->target_width, rt->target_height };
1489   curr_effect->set_vector("TargetDims", 2, rtsize);
1490
1491   curr_effect->set_texture("Diffuse", focus_enable ? rt->render_texture[1] : rt->render_texture[2]);
1492   curr_effect->set_texture("LastPass", ct->last_texture);
1493
1494   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]);
1495   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result);
1496   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1497   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1498
1499   curr_effect->begin(&num_passes, 0);
1500
1501   for (UINT pass = 0; pass < num_passes; pass++)
1502   {
1503      curr_effect->begin_pass(pass);
1504      // add the primitives
1505      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1506      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1507      curr_effect->end_pass();
1508   }
1509
1510   curr_effect->end();
1511
1512   // Pass along our phosphor'd screen
1513   phosphor_passthrough = true;
1514   curr_effect->update_uniforms();
1515   curr_effect->set_texture("Diffuse", rt->render_texture[0]);
1516   curr_effect->set_texture("LastPass", rt->render_texture[0]);
1517
1518   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, ct->last_target); // Avoid changing targets due to page flipping
1519   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result);
1520   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1521   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1522
1523   curr_effect->begin(&num_passes, 0);
1524
1525   for (UINT pass = 0; pass < num_passes; pass++)
1526   {
1527      curr_effect->begin_pass(pass);
1528      // add the primitives
1529      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1530      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1531      curr_effect->end_pass();
1532   }
1533
1534   curr_effect->end();
1535}
1536
1537void shaders::avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum)
1538{
1539   UINT num_passes = 0;
1540
1541   curr_effect = post_effect;
1542   curr_effect->update_uniforms();
1543   curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex());
1544
1545   // Scanlines and shadow mask, at high res for AVI logging
1546   if(avi_output_file != NULL)
1547   {
1548      curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
1549
1550      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, avi_final_target);
1551      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1552
1553      curr_effect->begin(&num_passes, 0);
1554
1555      for (UINT pass = 0; pass < num_passes; pass++)
1556      {
1557         curr_effect->begin_pass(pass);
1558         // add the primitives
1559         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1560         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1561         curr_effect->end_pass();
1562      }
1563
1564      curr_effect->end();
1565   }
1566
1567   if(render_snap)
1568   {
1569      curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
1570
1571      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, snap_target);
1572      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1573
1574      curr_effect->begin(&num_passes, 0);
1575
1576      for (UINT pass = 0; pass < num_passes; pass++)
1577      {
1578         curr_effect->begin_pass(pass);
1579         // add the primitives
1580         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1581         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1582         curr_effect->end_pass();
1583      }
1584
1585      curr_effect->end();
1586
1587      snap_rendered = true;
1588   }
1589}
1590
1591void shaders::screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum)
1592{
1593   UINT num_passes = 0;
1594
1595   curr_effect = post_effect;
1596   curr_effect->update_uniforms();
1597   curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex());
1598
1599   curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]);
1600
1601   d3d->set_wrap(D3DTADDRESS_MIRROR);
1602
1603   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[2]);
1604
1605   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0);
1606   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1607
1608   curr_effect->begin(&num_passes, 0);
1609
1610   for (UINT pass = 0; pass < num_passes; pass++)
1611   {
1612      curr_effect->begin_pass(pass);
1613      // add the primitives
1614      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1615      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1616      curr_effect->end_pass();
1617   }
1618
1619   curr_effect->end();
1620
1621   d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(poly->get_texture()->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
1622}
1623
1624void shaders::raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum)
1625{
1626   UINT num_passes = 0;
1627
1628   curr_effect = downsample_effect;
1629
1630   curr_effect->set_texture("Diffuse", rt->render_texture[2]);
1631   curr_effect->set_float("BloomRescale", options->raster_bloom_scale);
1632
1633   float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
1634   int bloom_index = 0;
1635   float bloom_width = rt->target_width;
1636   float bloom_height = rt->target_height;
1637   vec2f screendims = d3d->get_dims();
1638   curr_effect->set_vector("ScreenSize", 2, &screendims.c.x);
1639   float bloom_dims[11][2];
1640   for(; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
1641   {
1642      bloom_dims[bloom_index][0] = bloom_width;
1643      bloom_dims[bloom_index][1] = bloom_height;
1644      curr_effect->set_vector("TargetSize", 2, bloom_dims[bloom_index]);
1645
1646      curr_effect->begin(&num_passes, 0);
1647
1648      curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->render_texture[2] : rt->bloom_texture[bloom_index - 1]);
1649
1650      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->bloom_target[bloom_index]);
1651      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1652      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1653      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1654
1655      for (UINT pass = 0; pass < num_passes; pass++)
1656      {
1657         curr_effect->begin_pass(pass);
1658         // add the primitives
1659         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1660         //result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1661         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1662         curr_effect->end_pass();
1663      }
1664
1665      curr_effect->end();
1666
1667      bloom_index++;
1668      bloom_width *= 0.5f;
1669      bloom_height *= 0.5f;
1670   }
1671
1672   curr_effect = bloom_effect;
1673
1674   float target_size[2] = { d3d->get_width(), d3d->get_height() };
1675   curr_effect->set_vector("TargetSize", 2, target_size);
1676   float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight, options->bloom_level2_weight, options->bloom_level3_weight };
1677   float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight, options->bloom_level6_weight, options->bloom_level7_weight };
1678   float weight89A[3]  = { options->bloom_level8_weight, options->bloom_level9_weight, options->bloom_level10_weight };
1679   curr_effect->set_vector("Level0123Weight", 4, weight0123);
1680   curr_effect->set_vector("Level4567Weight", 4, weight4567);
1681   curr_effect->set_vector("Level89AWeight", 3, weight89A);
1682   curr_effect->set_vector("Level01Size", 4, bloom_dims[0]);
1683   curr_effect->set_vector("Level23Size", 4, bloom_dims[2]);
1684   curr_effect->set_vector("Level45Size", 4, bloom_dims[4]);
1685   curr_effect->set_vector("Level67Size", 4, bloom_dims[6]);
1686   curr_effect->set_vector("Level89Size", 4, bloom_dims[8]);
1687   curr_effect->set_vector("LevelASize", 2, bloom_dims[10]);
1688
1689   curr_effect->set_texture("DiffuseA", rt->render_texture[2]);
1690
1691   char name[9] = "Diffuse*";
1692   for(int index = 1; index < bloom_index; index++)
1693   {
1694      name[7] = 'A' + index;
1695      curr_effect->set_texture(name, rt->bloom_texture[index - 1]);
1696   }
1697   for(int index = bloom_index; index < 11; index++)
1698   {
1699      name[7] = 'A' + index;
1700      curr_effect->set_texture(name, black_texture);
1701   }
1702
1703   curr_effect->begin(&num_passes, 0);
1704
1705   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
1706   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1707
1708   for (UINT pass = 0; pass < num_passes; pass++)
1709   {
1710      curr_effect->begin_pass(pass);
1711      // add the primitives
1712      result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1713      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1714      curr_effect->end_pass();
1715   }
1716
1717   curr_effect->end();
1718}
1719
1720//============================================================
1721//  shaders::render_quad
1722//============================================================
1723
1724void shaders::render_quad(poly_info *poly, int vertnum)
1725{
1726   if (!master_enable || !d3dintf->post_fx_available)
1727      return;
1728
1729   UINT num_passes = 0;
1730   curr_texture = poly->get_texture();
1731
1732   if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && curr_texture != NULL)
1733   {
1734      render_target *rt = find_render_target(curr_texture);
1735      if (rt == NULL)
1736      {
1737         return;
1738      }
1739      cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_texinfo().width, curr_texture->get_texinfo().height);
1740
1741      vec2f& sourcedims = curr_texture->get_rawdims();
1742      vec2f delta = curr_texture->get_uvstop() - curr_texture->get_uvstart();
1743      vec2f texsize(rt->width, rt->height);
1744      float defocus_x = options->defocus[0];
1745      float defocus_y = options->defocus[1];
1746      bool focus_enable = defocus_x != 0.0f || defocus_y != 0.0f;
1747
1748      ntsc_pass(rt, sourcedims, delta);
1749      color_convolution_pass(rt, texsize, sourcedims);
1750      prescale_pass(rt, texsize, sourcedims);
1751      deconverge_pass(rt, texsize, delta, sourcedims);
1752      if (focus_enable)
1753      {
1754         defocus_pass(rt, texsize);
1755      }
1756      phosphor_pass(rt, ct, texsize, focus_enable);
1757      avi_post_pass(rt, texsize, delta, sourcedims, poly, vertnum);
1758      screen_post_pass(rt, texsize, delta, sourcedims, poly, vertnum);
1759      raster_bloom_pass(rt, texsize, delta, poly, vertnum);
1760
1761      curr_texture->increment_frame_count();
1762      curr_texture->mask_frame_count(options->yiq_phase_count);
1763
1764      options->params_dirty = false;
1765
1766   }
1767   else if(PRIMFLAG_GET_VECTOR(poly->get_flags()) && vector_enable)
1768   {
1769      render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
1770      if (rt == NULL)
1771      {
1772         return;
1773      }
1774
1775      lines_pending = true;
1776
1777      curr_effect = vector_effect;
1778
1779      if(options->params_dirty)
1780      {
1781         vec2f screendims = d3d->get_dims();
1782         curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
1783      }
1784
1785      float time_params[2] = { 0.0f, 0.0f };
1786      float length_params[3] = { poly->get_line_length(), options->vector_length_scale, options->vector_length_ratio };
1787      curr_effect->set_vector("TimeParams", 2, time_params);
1788      curr_effect->set_vector("LengthParams", 3, length_params);
1789
1790      curr_effect->begin(&num_passes, 0);
1791
1792      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]);
1793      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1794
1795      for (UINT pass = 0; pass < num_passes; pass++)
1796      {
1797         curr_effect->begin_pass(pass);
1798         // add the primitives
1799         HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1800         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1801         curr_effect->end_pass();
1802      }
1803
1804      curr_effect->end();
1805      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
1806      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1807
1808      curr_effect = default_effect;
1809
1810      curr_effect->set_float("FixedAlpha", 1.0f);
1811   }
1812   else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable)
1813   {
1814      render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
1815
1816      /* Bloom */
1817      curr_effect = downsample_effect;
1818
1819      curr_effect->set_texture("Diffuse", rt->render_texture[0]);
1820      curr_effect->set_float("BloomRescale", options->vector_bloom_scale);
1821
1822      float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
1823      int bloom_index = 0;
1824      float bloom_width = rt->target_width;
1825      float bloom_height = rt->target_height;
1826      float screen_size[2] = { d3d->get_width(), d3d->get_height() };
1827      curr_effect->set_vector("ScreenSize", 2, screen_size);
1828      float bloom_dims[11][2];
1829      for(; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
1830      {
1831         bloom_dims[bloom_index][0] = bloom_width;
1832         bloom_dims[bloom_index][1] = bloom_height;
1833         curr_effect->set_vector("TargetSize", 2, bloom_dims[bloom_index]);
1834
1835         curr_effect->begin(&num_passes, 0);
1836
1837         curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->render_texture[0] : rt->bloom_texture[bloom_index - 1]);
1838
1839         HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->bloom_target[bloom_index]);
1840         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1841         result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1842         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1843
1844         for (UINT pass = 0; pass < num_passes; pass++)
1845         {
1846            curr_effect->begin_pass(pass);
1847            // add the primitives
1848            result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1849            if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1850            curr_effect->end_pass();
1851         }
1852
1853         curr_effect->end();
1854
1855         bloom_index++;
1856         bloom_width *= 0.5f;
1857         bloom_height *= 0.5f;
1858      }
1859
1860      // Bloom composite pass
1861      curr_effect = bloom_effect;
1862
1863      float target_size[2] = { d3d->get_width(), d3d->get_height() };
1864      curr_effect->set_vector("TargetSize", 2, target_size);
1865      float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight,
1866                        options->bloom_level2_weight, options->bloom_level3_weight };
1867      float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight,
1868                        options->bloom_level6_weight, options->bloom_level7_weight };
1869      float weight89A[3] = { options->bloom_level8_weight, options->bloom_level9_weight,
1870                        options->bloom_level10_weight };
1871      curr_effect->set_vector("Level0123Weight", 4, weight0123);
1872      curr_effect->set_vector("Level4567Weight", 4, weight4567);
1873      curr_effect->set_vector("Level89AWeight", 3, weight89A);
1874      curr_effect->set_vector("Level01Size", 4, bloom_dims[0]);
1875      curr_effect->set_vector("Level23Size", 4, bloom_dims[2]);
1876      curr_effect->set_vector("Level45Size", 4, bloom_dims[4]);
1877      curr_effect->set_vector("Level67Size", 4, bloom_dims[6]);
1878      curr_effect->set_vector("Level89Size", 4, bloom_dims[8]);
1879      curr_effect->set_vector("LevelASize", 2, bloom_dims[10]);
1880
1881      curr_effect->set_texture("DiffuseA", rt->render_texture[0]);
1882
1883      char name[9] = "Diffuse*";
1884      for(int index = 1; index < bloom_index; index++)
1885      {
1886         name[7] = 'A' + index;
1887         curr_effect->set_texture(name, rt->bloom_texture[index - 1]);
1888      }
1889      for(int index = bloom_index; index < 11; index++)
1890      {
1891         name[7] = 'A' + index;
1892         curr_effect->set_texture(name, black_texture);
1893      }
1894
1895      curr_effect->begin(&num_passes, 0);
1896
1897      HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]);
1898      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
1899      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1900      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1901
1902      for (UINT pass = 0; pass < num_passes; pass++)
1903      {
1904         curr_effect->begin_pass(pass);
1905         // add the primitives
1906         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1907         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1908         curr_effect->end_pass();
1909      }
1910
1911      curr_effect->end();
1912
1913      /* Phosphor */
1914      curr_effect = phosphor_effect;
1915
1916      if(options->params_dirty)
1917      {
1918         vec2f screendims = d3d->get_dims();
1919         curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
1920         curr_effect->set_vector("Phosphor", 3, options->phosphor);
1921      }
1922      float target_dims[2] = { d3d->get_width(), d3d->get_height() };
1923      curr_effect->set_vector("TargetDims", 2, target_dims);
1924      curr_effect->set_float("Passthrough", 0.0f);
1925
1926      curr_effect->set_texture("Diffuse", rt->render_texture[1]);
1927      curr_effect->set_texture("LastPass", rt->render_texture[2]);
1928
1929      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[3]);
1930      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result);
1931      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1932      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1933
1934      curr_effect->begin(&num_passes, 0);
1935
1936      for (UINT pass = 0; pass < num_passes; pass++)
1937      {
1938         curr_effect->begin_pass(pass);
1939         // add the primitives
1940         result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2);
1941         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1942         curr_effect->end_pass();
1943      }
1944
1945      curr_effect->end();
1946
1947      blit(rt->target[2], rt->render_texture[3], NULL, poly->get_type(), vertnum, poly->get_count());
1948      blit(backbuffer, rt->render_texture[3], backbuffer, poly->get_type(), vertnum, poly->get_count());
1949
1950      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]);
1951      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1952      result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
1953      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
1954      result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
1955      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
1956
1957      lines_pending = false;
1958   }
1959   else
1960   {
1961      curr_effect = default_effect;
1962
1963      vec2f screendims = d3d->get_dims();
1964      curr_effect->set_vector("ScreenDims", 2, &screendims.c.x);
1965      curr_effect->set_float("PostPass", 0.0f);
1966
1967      curr_effect->begin(&num_passes, 0);
1968
1969      for (UINT pass = 0; pass < num_passes; pass++)
1970      {
1971         curr_effect->begin_pass(pass);
1972         // add the primitives
1973         HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count());
1974         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1975         curr_effect->end_pass();
1976      }
1977
1978      curr_effect->end();
1979   }
1980
1981   curr_texture = NULL;
1982}
1983
1984
1985
1986//============================================================
1987//  shaders::end_draw
1988//============================================================
1989
1990void shaders::end_draw()
1991{
1992   if (!master_enable || !d3dintf->post_fx_available)
1993      return;
1994
1995   (*d3dintf->surface.release)(backbuffer);
1996}
1997
1998
1999//============================================================
2000//  shaders::register_prescaled_texture
2001//============================================================
2002
2003bool shaders::register_prescaled_texture(texture_info *texture)
2004{
2005   return register_texture(texture);
2006}
2007
2008
2009//============================================================
2010//  shaders::add_cache_target - register a cache target
2011//============================================================
2012bool shaders::add_cache_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index)
2013{
2014   cache_target* target = (cache_target*)global_alloc_clear(cache_target);
2015
2016   if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale))
2017   {
2018      global_free(target);
2019      return false;
2020   }
2021
2022   if (info != NULL)
2023   {
2024      target->width = info->get_texinfo().width;
2025      target->height = info->get_texinfo().height;
2026   }
2027   else
2028   {
2029      target->width = d3d->get_width();
2030      target->height = d3d->get_height();
2031   }
2032
2033   target->next = cachehead;
2034   target->prev = NULL;
2035
2036   target->screen_index = screen_index;
2037
2038   if (cachehead != NULL)
2039   {
2040      cachehead->prev = target;
2041   }
2042   cachehead = target;
2043
2044   return true;
2045}
2046
2047render_target* shaders::get_vector_target()
2048{
2049   if (!vector_enable)
2050   {
2051      return NULL;
2052   }
2053
2054   return find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
2055}
2056
2057void shaders::create_vector_target(render_primitive *prim)
2058{
2059   if (!add_render_target(d3d, NULL, d3d->get_width(), d3d->get_height(), 1, 1))
2060   {
2061      vector_enable = false;
2062   }
2063}
2064
2065//============================================================
2066//  shaders::add_render_target - register a render target
2067//============================================================
2068
2069bool shaders::add_render_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale)
2070{
2071   UINT32 screen_index = 0;
2072   UINT32 page_index = 0;
2073   if (info != NULL)
2074   {
2075      render_target *existing_target = find_render_target(info);
2076      if (existing_target != NULL)
2077      {
2078         remove_render_target(existing_target);
2079      }
2080
2081      UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata;
2082      screen_index = screen_index_data >> 1;
2083      page_index = screen_index_data & 1;
2084   }
2085   else
2086   {
2087      render_target *existing_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
2088      if (existing_target != NULL)
2089      {
2090         remove_render_target(existing_target);
2091      }
2092   }
2093
2094   render_target* target = (render_target*)global_alloc_clear(render_target);
2095
2096   if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale))
2097   {
2098      global_free(target);
2099      return false;
2100   }
2101
2102   if (info != NULL)
2103   {
2104      target->width = info->get_texinfo().width;
2105      target->height = info->get_texinfo().height;
2106   }
2107   else
2108   {
2109      target->width = d3d->get_width();
2110      target->height = d3d->get_height();
2111   }
2112
2113   HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->target[0]);
2114   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
2115   result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
2116   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
2117   result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
2118   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
2119
2120   target->screen_index = screen_index;
2121   target->page_index = page_index;
2122
2123   cache_target* cache = find_cache_target(target->screen_index, target->width, target->height);
2124   if (cache == NULL)
2125   {
2126      if (!add_cache_target(d3d, info, width, height, xprescale, yprescale, target->screen_index))
2127      {
2128         global_free(target);
2129         return false;
2130      }
2131   }
2132
2133   target->next = targethead;
2134   target->prev = NULL;
2135
2136   if (targethead != NULL)
2137   {
2138      targethead->prev = target;
2139   }
2140   targethead = target;
2141
2142   return true;
2143}
2144
2145//============================================================
2146//  shaders::enumerate_screens
2147//============================================================
2148void shaders::enumerate_screens()
2149{
2150   screen_device_iterator iter(machine->root_device());
2151   num_screens = iter.count();
2152}
2153
2154
2155//============================================================
2156//  shaders::register_texture(texture::info)
2157//============================================================
2158
2159bool shaders::register_texture(texture_info *texture)
2160{
2161   int width = texture->get_width();
2162   int height = texture->get_height();
2163   int xscale = texture->get_xscale();
2164   int yscale = texture->get_yscale();
2165
2166   if (!master_enable || !d3dintf->post_fx_available)
2167   {
2168      return false;
2169   }
2170
2171   enumerate_screens();
2172
2173   int hlsl_prescale_x = prescale_force_x;
2174   int hlsl_prescale_y = prescale_force_y;
2175
2176   // Find the nearest prescale factor that is over our screen size
2177   if (hlsl_prescale_x == 0)
2178   {
2179      hlsl_prescale_x = 1;
2180      while (width * xscale * hlsl_prescale_x <= d3d->get_width())
2181      {
2182         hlsl_prescale_x++;
2183      }
2184      hlsl_prescale_x--;
2185   }
2186
2187   if (hlsl_prescale_y == 0)
2188   {
2189      hlsl_prescale_y = 1;
2190      while (height * yscale * hlsl_prescale_y <= d3d->get_height())
2191      {
2192         hlsl_prescale_y++;
2193      }
2194      hlsl_prescale_y--;
2195   }
2196
2197   hlsl_prescale_x = ((hlsl_prescale_x == 0) ? 1 : hlsl_prescale_x);
2198   hlsl_prescale_y = ((hlsl_prescale_y == 0) ? 1 : hlsl_prescale_y);
2199
2200   if (!add_render_target(d3d, texture, width, height, xscale * hlsl_prescale_x, yscale * hlsl_prescale_y))
2201      return false;
2202
2203   options->params_dirty = true;
2204
2205   return true;
2206}
2207
2208//============================================================
2209//  shaders::delete_resources
2210//============================================================
2211
2212void shaders::delete_resources(bool reset)
2213{
2214   if (!master_enable || !d3dintf->post_fx_available)
2215      return;
2216
2217   initialized = false;
2218
2219   cache_target *currcache = cachehead;
2220   while(cachehead != NULL)
2221   {
2222      cachehead = currcache->next;
2223      global_free(currcache);
2224      currcache = cachehead;
2225   }
2226
2227   render_target *currtarget = targethead;
2228   while(targethead != NULL)
2229   {
2230      targethead = currtarget->next;
2231      global_free(currtarget);
2232      currtarget = targethead;
2233   }
2234
2235   if (downsample_effect != NULL)
2236   {
2237      delete downsample_effect;
2238      downsample_effect = NULL;
2239   }
2240   if (bloom_effect != NULL)
2241   {
2242      delete bloom_effect;
2243      bloom_effect = NULL;
2244   }
2245   if (vector_effect != NULL)
2246   {
2247      delete vector_effect;
2248      vector_effect = NULL;
2249   }
2250   if (default_effect != NULL)
2251   {
2252      delete default_effect;
2253      default_effect = NULL;
2254   }
2255   if (post_effect != NULL)
2256   {
2257      delete post_effect;
2258      post_effect = NULL;
2259   }
2260   if (prescale_effect != NULL)
2261   {
2262      delete prescale_effect;
2263      prescale_effect = NULL;
2264   }
2265   if (phosphor_effect != NULL)
2266   {
2267      delete phosphor_effect;
2268      phosphor_effect = NULL;
2269   }
2270   if (focus_effect != NULL)
2271   {
2272      delete focus_effect;
2273      focus_effect = NULL;
2274   }
2275   if (deconverge_effect != NULL)
2276   {
2277      delete deconverge_effect;
2278      deconverge_effect = NULL;
2279   }
2280   if (color_effect != NULL)
2281   {
2282      delete color_effect;
2283      color_effect = NULL;
2284   }
2285   if (yiq_encode_effect != NULL)
2286   {
2287      delete yiq_encode_effect;
2288      yiq_encode_effect = NULL;
2289   }
2290   if (yiq_decode_effect != NULL)
2291   {
2292      delete yiq_decode_effect;
2293      yiq_decode_effect = NULL;
2294   }
2295
2296   if (backbuffer != NULL)
2297   {
2298      (*d3dintf->surface.release)(backbuffer);
2299      backbuffer = NULL;
2300   }
2301
2302   if (black_surface != NULL)
2303   {
2304      (*d3dintf->surface.release)(black_surface);
2305      black_surface = NULL;
2306   }
2307   if (black_texture != NULL)
2308   {
2309      (*d3dintf->texture.release)(black_texture);
2310      black_texture = NULL;
2311   }
2312
2313   if (avi_copy_texture != NULL)
2314   {
2315      (*d3dintf->texture.release)(avi_copy_texture);
2316      avi_copy_texture = NULL;
2317   }
2318
2319   if (avi_copy_surface != NULL)
2320   {
2321      (*d3dintf->surface.release)(avi_copy_surface);
2322      avi_copy_surface = NULL;
2323   }
2324
2325   if (avi_final_texture != NULL)
2326   {
2327      (*d3dintf->texture.release)(avi_final_texture);
2328      avi_final_texture = NULL;
2329   }
2330
2331   if (avi_final_target != NULL)
2332   {
2333      (*d3dintf->surface.release)(avi_final_target);
2334      avi_final_target = NULL;
2335   }
2336
2337   shadow_bitmap.reset();
2338}
2339
2340
2341//============================================================
2342//  get_vector
2343//============================================================
2344
2345static void get_vector(const char *data, int count, float *out, int report_error)
2346{
2347   if (count > 3)
2348   {
2349      if (sscanf(data, "%f,%f,%f,%f", &out[0], &out[1], &out[2], &out[3]) < 4 && report_error)
2350         osd_printf_error("Illegal quad vector value = %s\n", data);
2351   }
2352   else if(count > 2)
2353   {
2354      if (sscanf(data, "%f,%f,%f", &out[0], &out[1], &out[2]) < 3 && report_error)
2355         osd_printf_error("Illegal triple vector value = %s\n", data);
2356   }
2357   else if(count > 1)
2358   {
2359      if (sscanf(data, "%f,%f", &out[0], &out[1]) < 2 && report_error)
2360         osd_printf_error("Illegal double vector value = %s\n", data);
2361   }
2362   else if(count > 0)
2363   {
2364      if (sscanf(data, "%f", &out[0]) < 1 && report_error)
2365         osd_printf_error("Illegal single vector value = %s\n", data);
2366   }
2367}
2368
2369
2370/*-------------------------------------------------
2371    slider_alloc - allocate a new slider entry
2372    currently duplicated from ui.c, this could
2373    be done in a more ideal way.
2374-------------------------------------------------*/
2375
2376static slider_state *slider_alloc(running_machine &machine, const char *title, INT32 minval, INT32 defval, INT32 maxval, INT32 incval, slider_update update, void *arg)
2377{
2378   int size = sizeof(slider_state) + strlen(title);
2379   slider_state *state = (slider_state *)auto_alloc_array_clear(machine, UINT8, size);
2380
2381   state->minval = minval;
2382   state->defval = defval;
2383   state->maxval = maxval;
2384   state->incval = incval;
2385   state->update = update;
2386   state->arg = arg;
2387   strcpy(state->description, title);
2388
2389   return state;
2390}
2391
2392
2393//============================================================
2394//  assorted global slider accessors
2395//============================================================
2396
2397static INT32 slider_set(float *option, float scale, const char *fmt, astring *string, INT32 newval)
2398{
2399   if (option != NULL && newval != SLIDER_NOCHANGE) *option = (float)newval * scale;
2400   if (string != NULL) string->printf(fmt, *option);
2401   return floor(*option / scale + 0.5f);
2402}
2403
2404static INT32 slider_shadow_mask_alpha(running_machine &machine, void *arg, astring *string, INT32 newval)
2405{
2406   return slider_set(&(((hlsl_options*)arg)->shadow_mask_alpha), 0.01f, "%2.2f", string, newval);
2407}
2408
2409static INT32 slider_shadow_mask_x_count(running_machine &machine, void *arg, astring *string, INT32 newval)
2410{
2411   hlsl_options *options = (hlsl_options*)arg;
2412   if (newval != SLIDER_NOCHANGE) options->shadow_mask_count_x = newval;
2413   if (string != NULL) string->printf("%d", options->shadow_mask_count_x);
2414   options->params_dirty = true;
2415   return options->shadow_mask_count_x;
2416}
2417
2418static INT32 slider_shadow_mask_y_count(running_machine &machine, void *arg, astring *string, INT32 newval)
2419{
2420   hlsl_options *options = (hlsl_options*)arg;
2421   if (newval != SLIDER_NOCHANGE) options->shadow_mask_count_y = newval;
2422   if (string != NULL) string->printf("%d", options->shadow_mask_count_y);
2423   options->params_dirty = true;
2424   return options->shadow_mask_count_y;
2425}
2426
2427static INT32 slider_shadow_mask_usize(running_machine &machine, void *arg, astring *string, INT32 newval)
2428{
2429   ((hlsl_options*)arg)->params_dirty = true;
2430   return slider_set(&(((hlsl_options*)arg)->shadow_mask_u_size), 1.0f / 32.0f, "%2.5f", string, newval);
2431}
2432
2433static INT32 slider_shadow_mask_vsize(running_machine &machine, void *arg, astring *string, INT32 newval)
2434{
2435   ((hlsl_options*)arg)->params_dirty = true;
2436   return slider_set(&(((hlsl_options*)arg)->shadow_mask_v_size), 1.0f / 32.0f, "%2.5f", string, newval);
2437}
2438
2439static INT32 slider_curvature(running_machine &machine, void *arg, astring *string, INT32 newval)
2440{
2441   ((hlsl_options*)arg)->params_dirty = true;
2442   return slider_set(&(((hlsl_options*)arg)->curvature), 0.01f, "%2.2f", string, newval);
2443}
2444
2445static INT32 slider_pincushion(running_machine &machine, void *arg, astring *string, INT32 newval)
2446{
2447   ((hlsl_options*)arg)->params_dirty = true;
2448   return slider_set(&(((hlsl_options*)arg)->pincushion), 0.01f, "%2.2f", string, newval);
2449}
2450
2451static INT32 slider_scanline_alpha(running_machine &machine, void *arg, astring *string, INT32 newval)
2452{
2453   ((hlsl_options*)arg)->params_dirty = true;
2454   return slider_set(&(((hlsl_options*)arg)->scanline_alpha), 0.01f, "%2.2f", string, newval);
2455}
2456
2457static INT32 slider_scanline_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2458{
2459   ((hlsl_options*)arg)->params_dirty = true;
2460   return slider_set(&(((hlsl_options*)arg)->scanline_scale), 0.05f, "%2.2f", string, newval);
2461}
2462
2463static INT32 slider_scanline_height(running_machine &machine, void *arg, astring *string, INT32 newval)
2464{
2465   ((hlsl_options*)arg)->params_dirty = true;
2466   return slider_set(&(((hlsl_options*)arg)->scanline_height), 0.05f, "%2.2f", string, newval);
2467}
2468
2469static INT32 slider_scanline_bright_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2470{
2471   ((hlsl_options*)arg)->params_dirty = true;
2472   return slider_set(&(((hlsl_options*)arg)->scanline_bright_scale), 0.05f, "%2.2f", string, newval);
2473}
2474
2475static INT32 slider_scanline_bright_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2476{
2477   ((hlsl_options*)arg)->params_dirty = true;
2478   return slider_set(&(((hlsl_options*)arg)->scanline_bright_offset), 0.05f, "%2.2f", string, newval);
2479}
2480
2481static INT32 slider_scanline_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2482{
2483   ((hlsl_options*)arg)->params_dirty = true;
2484   return slider_set(&(((hlsl_options*)arg)->scanline_offset), 0.05f, "%2.2f", string, newval);
2485}
2486
2487static INT32 slider_defocus_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2488{
2489   ((hlsl_options*)arg)->params_dirty = true;
2490   return slider_set(&(((hlsl_options*)arg)->defocus[0]), 0.5f, "%2.1f", string, newval);
2491}
2492
2493static INT32 slider_defocus_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2494{
2495   ((hlsl_options*)arg)->params_dirty = true;
2496   return slider_set(&(((hlsl_options*)arg)->defocus[1]), 0.5f, "%2.1f", string, newval);
2497}
2498
2499static INT32 slider_red_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2500{
2501   ((hlsl_options*)arg)->params_dirty = true;
2502   return slider_set(&(((hlsl_options*)arg)->converge_x[0]), 0.1f, "%3.1f", string, newval);
2503}
2504
2505static INT32 slider_red_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2506{
2507   ((hlsl_options*)arg)->params_dirty = true;
2508   return slider_set(&(((hlsl_options*)arg)->converge_y[0]), 0.1f, "%3.1f", string, newval);
2509}
2510
2511static INT32 slider_green_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2512{
2513   ((hlsl_options*)arg)->params_dirty = true;
2514   return slider_set(&(((hlsl_options*)arg)->converge_x[1]), 0.1f, "%3.1f", string, newval);
2515}
2516
2517static INT32 slider_green_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2518{
2519   ((hlsl_options*)arg)->params_dirty = true;
2520   return slider_set(&(((hlsl_options*)arg)->converge_y[1]), 0.1f, "%3.1f", string, newval);
2521}
2522
2523static INT32 slider_blue_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2524{
2525   ((hlsl_options*)arg)->params_dirty = true;
2526   return slider_set(&(((hlsl_options*)arg)->converge_x[2]), 0.1f, "%3.1f", string, newval);
2527}
2528
2529static INT32 slider_blue_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2530{
2531   ((hlsl_options*)arg)->params_dirty = true;
2532   return slider_set(&(((hlsl_options*)arg)->converge_y[2]), 0.1f, "%3.1f", string, newval);
2533}
2534
2535static INT32 slider_red_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2536{
2537   ((hlsl_options*)arg)->params_dirty = true;
2538   return slider_set(&(((hlsl_options*)arg)->radial_converge_x[0]), 0.1f, "%3.1f", string, newval);
2539}
2540
2541static INT32 slider_red_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2542{
2543   ((hlsl_options*)arg)->params_dirty = true;
2544   return slider_set(&(((hlsl_options*)arg)->radial_converge_y[0]), 0.1f, "%3.1f", string, newval);
2545}
2546
2547static INT32 slider_green_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2548{
2549   ((hlsl_options*)arg)->params_dirty = true;
2550   return slider_set(&(((hlsl_options*)arg)->radial_converge_x[1]), 0.1f, "%3.1f", string, newval);
2551}
2552
2553static INT32 slider_green_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2554{
2555   ((hlsl_options*)arg)->params_dirty = true;
2556   return slider_set(&(((hlsl_options*)arg)->radial_converge_y[1]), 0.1f, "%3.1f", string, newval);
2557}
2558
2559static INT32 slider_blue_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
2560{
2561   ((hlsl_options*)arg)->params_dirty = true;
2562   return slider_set(&(((hlsl_options*)arg)->radial_converge_x[2]), 0.1f, "%3.1f", string, newval);
2563}
2564
2565static INT32 slider_blue_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
2566{
2567   ((hlsl_options*)arg)->params_dirty = true;
2568   return slider_set(&(((hlsl_options*)arg)->radial_converge_y[2]), 0.1f, "%3.1f", string, newval);
2569}
2570
2571static INT32 slider_red_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
2572{
2573   ((hlsl_options*)arg)->params_dirty = true;
2574   return slider_set(&(((hlsl_options*)arg)->red_ratio[0]), 0.005f, "%2.3f", string, newval);
2575}
2576
2577static INT32 slider_red_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
2578{
2579   ((hlsl_options*)arg)->params_dirty = true;
2580   return slider_set(&(((hlsl_options*)arg)->red_ratio[1]), 0.005f, "%2.3f", string, newval);
2581}
2582
2583static INT32 slider_red_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
2584{
2585   ((hlsl_options*)arg)->params_dirty = true;
2586   return slider_set(&(((hlsl_options*)arg)->red_ratio[2]), 0.005f, "%2.3f", string, newval);
2587}
2588
2589static INT32 slider_green_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
2590{
2591   ((hlsl_options*)arg)->params_dirty = true;
2592   return slider_set(&(((hlsl_options*)arg)->grn_ratio[0]), 0.005f, "%2.3f", string, newval);
2593}
2594
2595static INT32 slider_green_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
2596{
2597   ((hlsl_options*)arg)->params_dirty = true;
2598   return slider_set(&(((hlsl_options*)arg)->grn_ratio[1]), 0.005f, "%2.3f", string, newval);
2599}
2600
2601static INT32 slider_green_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
2602{
2603   ((hlsl_options*)arg)->params_dirty = true;
2604   return slider_set(&(((hlsl_options*)arg)->grn_ratio[2]), 0.005f, "%2.3f", string, newval);
2605}
2606
2607static INT32 slider_blue_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
2608{
2609   ((hlsl_options*)arg)->params_dirty = true;
2610   return slider_set(&(((hlsl_options*)arg)->blu_ratio[0]), 0.005f, "%2.3f", string, newval);
2611}
2612
2613static INT32 slider_blue_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
2614{
2615   ((hlsl_options*)arg)->params_dirty = true;
2616   return slider_set(&(((hlsl_options*)arg)->blu_ratio[1]), 0.005f, "%2.3f", string, newval);
2617}
2618
2619static INT32 slider_blue_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
2620{
2621   ((hlsl_options*)arg)->params_dirty = true;
2622   return slider_set(&(((hlsl_options*)arg)->blu_ratio[2]), 0.005f, "%2.3f", string, newval);
2623}
2624
2625static INT32 slider_red_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2626{
2627   ((hlsl_options*)arg)->params_dirty = true;
2628   return slider_set(&(((hlsl_options*)arg)->offset[0]), 0.01f, "%2.2f", string, newval);
2629}
2630
2631static INT32 slider_green_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2632{
2633   ((hlsl_options*)arg)->params_dirty = true;
2634   return slider_set(&(((hlsl_options*)arg)->offset[1]), 0.01f, "%2.2f", string, newval);
2635}
2636
2637static INT32 slider_blue_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
2638{
2639   ((hlsl_options*)arg)->params_dirty = true;
2640   return slider_set(&(((hlsl_options*)arg)->offset[2]), 0.01f, "%2.2f", string, newval);
2641}
2642
2643static INT32 slider_red_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2644{
2645   ((hlsl_options*)arg)->params_dirty = true;
2646   return slider_set(&(((hlsl_options*)arg)->scale[0]), 0.01f, "%2.2f", string, newval);
2647}
2648
2649static INT32 slider_green_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2650{
2651   ((hlsl_options*)arg)->params_dirty = true;
2652   return slider_set(&(((hlsl_options*)arg)->scale[1]), 0.01f, "%2.2f", string, newval);
2653}
2654
2655static INT32 slider_blue_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2656{
2657   ((hlsl_options*)arg)->params_dirty = true;
2658   return slider_set(&(((hlsl_options*)arg)->scale[2]), 0.01f, "%2.2f", string, newval);
2659}
2660
2661static INT32 slider_red_power(running_machine &machine, void *arg, astring *string, INT32 newval)
2662{
2663   ((hlsl_options*)arg)->params_dirty = true;
2664   return slider_set(&(((hlsl_options*)arg)->power[0]), 0.05f, "%2.2f", string, newval);
2665}
2666
2667static INT32 slider_green_power(running_machine &machine, void *arg, astring *string, INT32 newval)
2668{
2669   ((hlsl_options*)arg)->params_dirty = true;
2670   return slider_set(&(((hlsl_options*)arg)->power[1]), 0.05f, "%2.2f", string, newval);
2671}
2672
2673static INT32 slider_blue_power(running_machine &machine, void *arg, astring *string, INT32 newval)
2674{
2675   ((hlsl_options*)arg)->params_dirty = true;
2676   return slider_set(&(((hlsl_options*)arg)->power[2]), 0.05f, "%2.2f", string, newval);
2677}
2678
2679static INT32 slider_red_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
2680{
2681   ((hlsl_options*)arg)->params_dirty = true;
2682   return slider_set(&(((hlsl_options*)arg)->floor[0]), 0.01f, "%2.2f", string, newval);
2683}
2684
2685static INT32 slider_green_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
2686{
2687   ((hlsl_options*)arg)->params_dirty = true;
2688   return slider_set(&(((hlsl_options*)arg)->floor[1]), 0.01f, "%2.2f", string, newval);
2689}
2690
2691static INT32 slider_blue_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
2692{
2693   ((hlsl_options*)arg)->params_dirty = true;
2694   return slider_set(&(((hlsl_options*)arg)->floor[2]), 0.01f, "%2.2f", string, newval);
2695}
2696
2697static INT32 slider_red_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
2698{
2699   ((hlsl_options*)arg)->params_dirty = true;
2700   return slider_set(&(((hlsl_options*)arg)->phosphor[0]), 0.01f, "%2.2f", string, newval);
2701}
2702
2703static INT32 slider_green_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
2704{
2705   ((hlsl_options*)arg)->params_dirty = true;
2706   return slider_set(&(((hlsl_options*)arg)->phosphor[1]), 0.01f, "%2.2f", string, newval);
2707}
2708
2709static INT32 slider_blue_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
2710{
2711   ((hlsl_options*)arg)->params_dirty = true;
2712   return slider_set(&(((hlsl_options*)arg)->phosphor[2]), 0.01f, "%2.2f", string, newval);
2713}
2714
2715static INT32 slider_saturation(running_machine &machine, void *arg, astring *string, INT32 newval)
2716{
2717   ((hlsl_options*)arg)->params_dirty = true;
2718   return slider_set(&(((hlsl_options*)arg)->saturation), 0.01f, "%2.2f", string, newval);
2719}
2720
2721static INT32 slider_vector_attenuation(running_machine &machine, void *arg, astring *string, INT32 newval)
2722{
2723   ((hlsl_options*)arg)->params_dirty = true;
2724   return slider_set(&(((hlsl_options*)arg)->vector_length_scale), 0.01f, "%1.2f", string, newval);
2725}
2726
2727static INT32 slider_vector_length_max(running_machine &machine, void *arg, astring *string, INT32 newval)
2728{
2729   ((hlsl_options*)arg)->params_dirty = true;
2730   return slider_set(&(((hlsl_options*)arg)->vector_length_ratio), 1.0f, "%4f", string, newval);
2731}
2732
2733static INT32 slider_vector_bloom_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2734{
2735   ((hlsl_options*)arg)->params_dirty = true;
2736   return slider_set(&(((hlsl_options*)arg)->vector_bloom_scale), 0.001f, "%1.3f", string, newval);
2737}
2738
2739static INT32 slider_raster_bloom_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2740{
2741   ((hlsl_options*)arg)->params_dirty = true;
2742   return slider_set(&(((hlsl_options*)arg)->raster_bloom_scale), 0.001f, "%1.3f", string, newval);
2743}
2744
2745static INT32 slider_bloom_lvl0_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2746{
2747   ((hlsl_options*)arg)->params_dirty = true;
2748   return slider_set(&(((hlsl_options*)arg)->bloom_level0_weight), 0.01f, "%1.2f", string, newval);
2749}
2750
2751static INT32 slider_bloom_lvl1_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2752{
2753   ((hlsl_options*)arg)->params_dirty = true;
2754   return slider_set(&(((hlsl_options*)arg)->bloom_level1_weight), 0.01f, "%1.2f", string, newval);
2755}
2756
2757static INT32 slider_bloom_lvl2_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2758{
2759   ((hlsl_options*)arg)->params_dirty = true;
2760   return slider_set(&(((hlsl_options*)arg)->bloom_level2_weight), 0.01f, "%1.2f", string, newval);
2761}
2762
2763static INT32 slider_bloom_lvl3_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2764{
2765   ((hlsl_options*)arg)->params_dirty = true;
2766   return slider_set(&(((hlsl_options*)arg)->bloom_level3_weight), 0.01f, "%1.2f", string, newval);
2767}
2768
2769static INT32 slider_bloom_lvl4_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2770{
2771   ((hlsl_options*)arg)->params_dirty = true;
2772   return slider_set(&(((hlsl_options*)arg)->bloom_level4_weight), 0.01f, "%1.2f", string, newval);
2773}
2774
2775static INT32 slider_bloom_lvl5_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2776{
2777   ((hlsl_options*)arg)->params_dirty = true;
2778   return slider_set(&(((hlsl_options*)arg)->bloom_level5_weight), 0.01f, "%1.2f", string, newval);
2779}
2780
2781static INT32 slider_bloom_lvl6_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2782{
2783   ((hlsl_options*)arg)->params_dirty = true;
2784   return slider_set(&(((hlsl_options*)arg)->bloom_level6_weight), 0.01f, "%1.2f", string, newval);
2785}
2786
2787static INT32 slider_bloom_lvl7_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2788{
2789   ((hlsl_options*)arg)->params_dirty = true;
2790   return slider_set(&(((hlsl_options*)arg)->bloom_level7_weight), 0.01f, "%1.2f", string, newval);
2791}
2792
2793static INT32 slider_bloom_lvl8_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2794{
2795   ((hlsl_options*)arg)->params_dirty = true;
2796   return slider_set(&(((hlsl_options*)arg)->bloom_level8_weight), 0.01f, "%1.2f", string, newval);
2797}
2798
2799static INT32 slider_bloom_lvl9_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2800{
2801   ((hlsl_options*)arg)->params_dirty = true;
2802   return slider_set(&(((hlsl_options*)arg)->bloom_level9_weight), 0.01f, "%1.2f", string, newval);
2803}
2804
2805static INT32 slider_bloom_lvl10_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
2806{
2807   ((hlsl_options*)arg)->params_dirty = true;
2808   return slider_set(&(((hlsl_options*)arg)->bloom_level10_weight), 0.01f, "%1.2f", string, newval);
2809}
2810
2811//============================================================
2812//  init_slider_list
2813//============================================================
2814
2815shaders::slider_desc shaders::s_sliders[] =
2816{
2817   { "Shadow Mask Darkness",                0,     0,   100, 1, slider_shadow_mask_alpha },
2818   { "Shadow Mask X Count",                 1,   320,  1024, 1, slider_shadow_mask_x_count },
2819   { "Shadow Mask Y Count",                 1,   240,  1024, 1, slider_shadow_mask_y_count },
2820   { "Shadow Mask Pixel Count X",           1,     6,    64, 1, slider_shadow_mask_usize },
2821   { "Shadow Mask Pixel Count Y",           1,     7,    64, 1, slider_shadow_mask_vsize },
2822   { "Shadow Mask Pixel Count Y",           1,     7,    64, 1, slider_shadow_mask_vsize },
2823   { "Shadow Mask Pixel Count Y",           1,     7,    64, 1, slider_shadow_mask_vsize },
2824   { "Shadow Mask Pixel Count Y",           1,     7,    64, 1, slider_shadow_mask_vsize },
2825   { "Screen Curvature",                    0,     3,   100, 1, slider_curvature },
2826   { "Image Pincushion",                    0,     3,   100, 1, slider_pincushion },
2827   { "Scanline Darkness",                   0,   100,   100, 1, slider_scanline_alpha },
2828   { "Scanline Screen Height",              1,    20,    80, 1, slider_scanline_scale },
2829   { "Scanline Indiv. Height",              1,    20,    80, 1, slider_scanline_height },
2830   { "Scanline Brightness",                 0,    20,    40, 1, slider_scanline_bright_scale },
2831   { "Scanline Brightness Overdrive",       0,     0,    20, 1, slider_scanline_bright_offset },
2832   { "Scanline Jitter",                     0,     0,    40, 1, slider_scanline_offset },
2833   { "Defocus X",                           0,     0,    64, 1, slider_defocus_x },
2834   { "Defocus Y",                           0,     0,    64, 1, slider_defocus_y },
2835   { "Red Position Offset X",           -1500,     3,  1500, 1, slider_red_converge_x },
2836   { "Red Position Offset Y",           -1500,     0,  1500, 1, slider_red_converge_y },
2837   { "Green Position Offset X",         -1500,     0,  1500, 1, slider_green_converge_x },
2838   { "Green Position Offset Y",         -1500,     3,  1500, 1, slider_green_converge_y },
2839   { "Blue Position Offset X",          -1500,     3,  1500, 1, slider_blue_converge_x },
2840   { "Blue Position Offset Y",          -1500,     3,  1500, 1, slider_blue_converge_y },
2841   { "Red Convergence X",               -1500,     0,  1500, 1, slider_red_radial_converge_x },
2842   { "Red Convergence Y",               -1500,     0,  1500, 1, slider_red_radial_converge_y },
2843   { "Green Convergence X",             -1500,     0,  1500, 1, slider_green_radial_converge_x },
2844   { "Green Convergence Y",             -1500,     0,  1500, 1, slider_green_radial_converge_y },
2845   { "Blue Convergence X",              -1500,     0,  1500, 1, slider_blue_radial_converge_x },
2846   { "Blue Convergence Y",              -1500,     0,  1500, 1, slider_blue_radial_converge_y },
2847   { "Red Output from Red Input",        -400,     0,   400, 5, slider_red_from_r },
2848   { "Red Output from Green Input",      -400,     0,   400, 5, slider_red_from_g },
2849   { "Red Output from Blue Input",       -400,     0,   400, 5, slider_red_from_b },
2850   { "Green Output from Red Input",      -400,     0,   400, 5, slider_green_from_r },
2851   { "Green Output from Green Input",    -400,     0,   400, 5, slider_green_from_g },
2852   { "Green Output from Blue Input",     -400,     0,   400, 5, slider_green_from_b },
2853   { "Blue Output from Red Input",       -400,     0,   400, 5, slider_blue_from_r },
2854   { "Blue Output from Green Input",     -400,     0,   400, 5, slider_blue_from_g },
2855   { "Blue Output from Blue Input",      -400,     0,   400, 5, slider_blue_from_b },
2856   { "Saturation",                          0,   140,   400, 1, slider_saturation },
2857   { "Red DC Offset",                    -100,     0,   100, 1, slider_red_offset },
2858   { "Green DC Offset",                  -100,     0,   100, 1, slider_green_offset },
2859   { "Blue DC Offset",                   -100,     0,   100, 1, slider_blue_offset },
2860   { "Red Scale",                        -200,    95,   200, 1, slider_red_scale },
2861   { "Green Scale",                      -200,    95,   200, 1, slider_green_scale },
2862   { "Blue Scale",                       -200,    95,   200, 1, slider_blue_scale },
2863   { "Red Gamma",                         -80,    16,    80, 1, slider_red_power },
2864   { "Green Gamma",                       -80,    16,    80, 1, slider_green_power },
2865   { "Blue Gamma",                        -80,    16,    80, 1, slider_blue_power },
2866   { "Red Floor",                           0,     5,   100, 1, slider_red_floor },
2867   { "Green Floor",                         0,     5,   100, 1, slider_green_floor },
2868   { "Blue Floor",                          0,     5,   100, 1, slider_blue_floor },
2869   { "Red Phosphor Life",                   0,    40,   100, 1, slider_red_phosphor_life },
2870   { "Green Phosphor Life",                 0,    40,   100, 1, slider_green_phosphor_life },
2871   { "Blue Phosphor Life",                  0,    40,   100, 1, slider_blue_phosphor_life },
2872   { "Vector Length Attenuation",           0,    80,   100, 1, slider_vector_attenuation },
2873   { "Vector Attenuation Length Limit",     1,   500,  1000, 1, slider_vector_length_max },
2874   { "Vector Bloom Scale",                  0,   300,  1000, 5, slider_vector_bloom_scale },
2875   { "Raster Bloom Scale",                  0,   225,  1000, 5, slider_raster_bloom_scale },
2876   { "Bloom Level 0 Scale",                 0,   100,   100, 1, slider_bloom_lvl0_scale },
2877   { "Bloom Level 1 Scale",                 0,    21,   100, 1, slider_bloom_lvl1_scale },
2878   { "Bloom Level 2 Scale",                 0,    19,   100, 1, slider_bloom_lvl2_scale },
2879   { "Bloom Level 3 Scale",                 0,    17,   100, 1, slider_bloom_lvl3_scale },
2880   { "Bloom Level 4 Scale",                 0,    15,   100, 1, slider_bloom_lvl4_scale },
2881   { "Bloom Level 5 Scale",                 0,    14,   100, 1, slider_bloom_lvl5_scale },
2882   { "Bloom Level 6 Scale",                 0,    13,   100, 1, slider_bloom_lvl6_scale },
2883   { "Bloom Level 7 Scale",                 0,    12,   100, 1, slider_bloom_lvl7_scale },
2884   { "Bloom Level 8 Scale",                 0,    11,   100, 1, slider_bloom_lvl8_scale },
2885   { "Bloom Level 9 Scale",                 0,    10,   100, 1, slider_bloom_lvl9_scale },
2886   { "Bloom Level 10 Scale",                0,     9,   100, 1, slider_bloom_lvl10_scale },
2887   { NULL, 0, 0, 0, 0, NULL },
2888};
2889
2890slider_state *shaders::init_slider_list()
2891{
2892   if (!master_enable || !d3dintf->post_fx_available)
2893   {
2894      g_slider_list = NULL;
2895      return NULL;
2896   }
2897
2898   slider_state *listhead = NULL;
2899   slider_state **tailptr = &listhead;
2900
2901   for (int index = 0; s_sliders[index].name != NULL; index++)
2902   {
2903      slider_desc *slider = &s_sliders[index];
2904      *tailptr = slider_alloc(*machine, slider->name, slider->minval, slider->defval, slider->maxval, slider->step, slider->adjustor, (void*)options);
2905      tailptr = &(*tailptr)->next;
2906   }
2907
2908   return listhead;
2909}
2910
2911//============================================================
2912//  uniform functions
2913//============================================================
2914
2915uniform::uniform(effect *shader, const char *name, uniform_type type, int id)
2916{
2917   m_shader = shader;
2918   m_type = type;
2919   m_next = NULL;
2920   m_handle = m_shader->get_parameter(NULL, name);
2921   m_ival = 0;
2922   memset(m_vec, 0, sizeof(float) * 4);
2923   m_mval = NULL;
2924   m_texture = NULL;
2925   m_id = id;
2926
2927   switch (type)
2928   {
2929   case UT_INT:
2930   case UT_FLOAT:
2931   case UT_MATRIX:
2932   case UT_SAMPLER:
2933      m_count = 1;
2934      break;
2935   case UT_VEC2:
2936      m_count = 2;
2937      break;
2938   case UT_VEC3:
2939      m_count = 3;
2940      break;
2941   case UT_VEC4:
2942      m_count = 4;
2943      break;
2944   default:
2945      m_count = 1;
2946      break;
2947   }
2948}
2949
2950void uniform::set_next(uniform *next)
2951{
2952   m_next = next;
2953}
2954
2955void uniform::update()
2956{
2957   if (m_id >= CU_COUNT)
2958   {
2959      return;
2960   }
2961
2962   shaders *shadersys = m_shader->m_shaders;
2963   hlsl_options *options = shadersys->options;
2964   renderer *d3d = shadersys->d3d;
2965
2966
2967   switch(m_id)
2968   {
2969      case CU_SCREEN_DIMS:
2970      {
2971         vec2f screendims = d3d->get_dims();
2972         m_shader->set_vector("ScreenDims", 2, &screendims.c.x);
2973         break;
2974      }
2975      case CU_SOURCE_DIMS:
2976      {
2977         vec2f& sourcedims = shadersys->curr_texture->get_rawdims();
2978         m_shader->set_vector("SourceDims", 2, &sourcedims.c.x);
2979         break;
2980      }
2981      case CU_SOURCE_RECT:
2982      {
2983         vec2f delta = shadersys->curr_texture->get_uvstop() - shadersys->curr_texture->get_uvstart();
2984         m_shader->set_vector("SourceRect", 2, &delta.c.x);
2985         break;
2986      }
2987
2988      case CU_NTSC_CCFREQ:
2989         m_shader->set_float("CCValue", options->yiq_cc);
2990         break;
2991      case CU_NTSC_A:
2992         m_shader->set_float("AValue", options->yiq_a);
2993         break;
2994      case CU_NTSC_B:
2995         m_shader->set_float("BValue", options->yiq_b);
2996         break;
2997      case CU_NTSC_O:
2998         m_shader->set_float("OValue", options->yiq_o);
2999         break;
3000      case CU_NTSC_P:
3001         m_shader->set_float("PValue", options->yiq_p);
3002         break;
3003      case CU_NTSC_NOTCH:
3004         m_shader->set_float("NotchHalfWidth", options->yiq_n);
3005         break;
3006      case CU_NTSC_YFREQ:
3007         m_shader->set_float("YFreqResponse", options->yiq_y);
3008         break;
3009      case CU_NTSC_IFREQ:
3010         m_shader->set_float("IFreqResponse", options->yiq_i);
3011         break;
3012      case CU_NTSC_QFREQ:
3013         m_shader->set_float("QFreqResponse", options->yiq_q);
3014         break;
3015      case CU_NTSC_HTIME:
3016         m_shader->set_float("ScanTime", options->yiq_scan_time);
3017         break;
3018      case CU_NTSC_ENABLE:
3019         m_shader->set_float("YIQEnable", options->yiq_enable ? 1.0f : 0.0f);
3020         break;
3021
3022      case CU_COLOR_RED_RATIOS:
3023         m_shader->set_vector("RedRatios", 3, options->red_ratio);
3024         break;
3025      case CU_COLOR_GRN_RATIOS:
3026         m_shader->set_vector("GrnRatios", 3, options->grn_ratio);
3027         break;
3028      case CU_COLOR_BLU_RATIOS:
3029         m_shader->set_vector("BluRatios", 3, options->blu_ratio);
3030         break;
3031      case CU_COLOR_OFFSET:
3032         m_shader->set_vector("Offset", 3, options->offset);
3033         break;
3034      case CU_COLOR_SCALE:
3035         m_shader->set_vector("Scale", 3, options->scale);
3036         break;
3037      case CU_COLOR_SATURATION:
3038         m_shader->set_float("Saturation", options->saturation);
3039         break;
3040
3041      case CU_CONVERGE_LINEAR_X:
3042         m_shader->set_vector("ConvergeX", 3, options->converge_x);
3043         break;
3044      case CU_CONVERGE_LINEAR_Y:
3045         m_shader->set_vector("ConvergeY", 3, options->converge_y);
3046         break;
3047      case CU_CONVERGE_RADIAL_X:
3048         m_shader->set_vector("RadialConvergeX", 3, options->radial_converge_x);
3049         break;
3050      case CU_CONVERGE_RADIAL_Y:
3051         m_shader->set_vector("RadialConvergeY", 3, options->radial_converge_y);
3052         break;
3053
3054      case CU_FOCUS_SIZE:
3055         m_shader->set_vector("Defocus", 2, &options->defocus[0]);
3056         break;
3057
3058      case CU_PHOSPHOR_LIFE:
3059         m_shader->set_vector("Phosphor", 3, options->phosphor);
3060         break;
3061      case CU_PHOSPHOR_IGNORE:
3062         m_shader->set_float("Passthrough", shadersys->phosphor_passthrough ? 1.0f : 0.0f);
3063         break;
3064
3065      case CU_POST_PINCUSHION:
3066         m_shader->set_float("PincushionAmount", options->pincushion);
3067         break;
3068      case CU_POST_CURVATURE:
3069         m_shader->set_float("CurvatureAmount", options->curvature);
3070         break;
3071      case CU_POST_SHADOW_ALPHA:
3072         m_shader->set_float("ShadowAlpha", shadersys->shadow_texture == NULL ? 0.0f : options->shadow_mask_alpha);
3073         break;
3074      case CU_POST_SHADOW_COUNT:
3075      {
3076         float shadowcount[2] = { options->shadow_mask_count_x, options->shadow_mask_count_y };
3077         m_shader->set_vector("ShadowCount", 2, shadowcount);
3078         break;
3079      }
3080      case CU_POST_SHADOW_UV:
3081      {
3082         float shadowuv[2] = { options->shadow_mask_u_size, options->shadow_mask_v_size };
3083         m_shader->set_vector("ShadowUV", 2, shadowuv);
3084         break;
3085      }
3086      case CU_POST_SHADOW_DIMS:
3087      {
3088         vec2f shadow_dims;
3089
3090         if (shadersys->shadow_texture)
3091         {
3092            shadow_dims = shadersys->shadow_texture->get_rawdims();
3093         }
3094         else
3095         {
3096            shadow_dims.c.x = 1.0f;
3097            shadow_dims.c.y = 1.0f;
3098         }
3099
3100         m_shader->set_vector("ShadowDims", 2, &shadow_dims.c.x);
3101         break;
3102      }
3103      case CU_POST_SCANLINE_ALPHA:
3104         m_shader->set_float("ScanlineAlpha", options->scanline_alpha);
3105         break;
3106      case CU_POST_SCANLINE_SCALE:
3107         m_shader->set_float("ScanlineScale", options->scanline_scale);
3108         break;
3109      case CU_POST_SCANLINE_HEIGHT:
3110         m_shader->set_float("ScanlineHeight", options->scanline_height);
3111         break;
3112      case CU_POST_SCANLINE_BRIGHT_SCALE:
3113         m_shader->set_float("ScanlineBrightScale", options->scanline_bright_scale);
3114         break;
3115      case CU_POST_SCANLINE_BRIGHT_OFFSET:
3116         m_shader->set_float("ScanlineBrightOffset", options->scanline_bright_offset);
3117         break;
3118      case CU_POST_POWER:
3119         m_shader->set_vector("Power", 3, options->power);
3120         break;
3121      case CU_POST_FLOOR:
3122         m_shader->set_vector("Floor", 3, options->floor);
3123         break;
3124
3125      case CU_BLOOM_RESCALE:
3126         m_shader->set_float("BloomRescale", options->raster_bloom_scale);
3127         break;
3128      case CU_BLOOM_LVL0123_WEIGHTS:
3129      {
3130         float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight, options->bloom_level2_weight, options->bloom_level3_weight };
3131         m_shader->set_vector("Level0123Weight", 4, weight0123);
3132         break;
3133      }
3134      case CU_BLOOM_LVL4567_WEIGHTS:
3135      {
3136         float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight, options->bloom_level6_weight, options->bloom_level7_weight };
3137         m_shader->set_vector("Level4567Weight", 4, weight4567);
3138         break;
3139      }
3140      case CU_BLOOM_LVL89A_WEIGHTS:
3141      {
3142         float weight89A[3]  = { options->bloom_level8_weight, options->bloom_level9_weight, options->bloom_level10_weight };
3143         m_shader->set_vector("Level89AWeight", 3, weight89A);
3144         break;
3145      }
3146   }
3147}
3148
3149void uniform::set(float x, float y, float z, float w)
3150{
3151   m_vec[0] = x;
3152   m_vec[1] = y;
3153   m_vec[2] = z;
3154   m_vec[3] = w;
3155}
3156
3157void uniform::set(float x, float y, float z)
3158{
3159   m_vec[0] = x;
3160   m_vec[1] = y;
3161   m_vec[2] = z;
3162}
3163
3164void uniform::set(float x, float y)
3165{
3166   m_vec[0] = x;
3167   m_vec[1] = y;
3168}
3169
3170void uniform::set(float x)
3171{
3172   m_vec[0] = x;
3173}
3174
3175void uniform::set(int x)
3176{
3177   m_ival = x;
3178}
3179
3180void uniform::set(matrix *mat)
3181{
3182   m_mval = mat;
3183}
3184
3185void uniform::set(texture *tex)
3186{
3187   m_texture = tex;
3188}
3189
3190void uniform::upload()
3191{
3192   switch(m_type)
3193   {
3194      case UT_INT:
3195         m_shader->set_int(m_handle, m_ival);
3196         break;
3197      case UT_FLOAT:
3198         m_shader->set_float(m_handle, m_vec[0]);
3199         break;
3200      case UT_VEC2:
3201      case UT_VEC3:
3202      case UT_VEC4:
3203         m_shader->set_vector(m_handle, m_count, m_vec);
3204         break;
3205      case UT_MATRIX:
3206         m_shader->set_matrix(m_handle, m_mval);
3207         break;
3208      case UT_SAMPLER:
3209         m_shader->set_texture(m_handle, m_texture);
3210         break;
3211   }
3212}
3213
3214//============================================================
3215//  effect functions
3216//============================================================
3217
3218effect::effect(shaders *shadersys, device *dev, const char *name, const char *path)
3219{
3220   IDirect3DDevice9 *device = (IDirect3DDevice9 *)dev;
3221   LPD3DXBUFFER buffer_errors = NULL;
3222
3223   m_shaders = shadersys;
3224   m_uniform_head = NULL;
3225   m_uniform_tail = NULL;
3226   m_effect = NULL;
3227   m_valid = false;
3228
3229   char name_cstr[1024];
3230   sprintf(name_cstr, "%s\\%s", path, name);
3231   TCHAR *effect_name = tstring_from_utf8(name_cstr);
3232
3233   HRESULT hr = (*g_load_effect)(device, effect_name, NULL, NULL, 0, NULL, &m_effect, &buffer_errors);
3234   if(FAILED(hr))
3235   {
3236      if(buffer_errors != NULL)
3237      {
3238         LPVOID compile_errors = buffer_errors->GetBufferPointer();
3239         printf("Unable to compile shader: %s\n", (const char*)compile_errors); fflush(stdout);
3240      }
3241      else
3242      {
3243         printf("Shader %s is missing, corrupt or cannot be compiled.\n", (const char*)name); fflush(stdout);
3244      }
3245   }
3246   else
3247   {
3248      m_valid = true;
3249   }
3250
3251   osd_free(effect_name);
3252}
3253
3254effect::~effect()
3255{
3256   m_effect->Release();
3257   m_effect = NULL;
3258   uniform *curr = m_uniform_head;
3259   while (curr != NULL)
3260   {
3261      uniform *next = curr->get_next();
3262      delete curr;
3263      curr = next;
3264   }
3265   m_uniform_head = NULL;
3266   m_uniform_tail = NULL;
3267}
3268
3269void effect::add_uniform(const char *name, uniform::uniform_type type, int id)
3270{
3271   uniform *newuniform = new uniform(this, name, type, id);
3272   if (newuniform == NULL)
3273   {
3274      return;
3275   }
3276
3277   if (m_uniform_head == NULL)
3278   {
3279      m_uniform_head = newuniform;
3280   }
3281   if (m_uniform_tail != NULL)
3282   {
3283      m_uniform_tail->set_next(newuniform);
3284   }
3285   m_uniform_tail = newuniform;
3286}
3287
3288void effect::update_uniforms()
3289{
3290   uniform *curr = m_uniform_head;
3291   while(curr != NULL)
3292   {
3293      curr->update();
3294      curr = curr->get_next();
3295   }
3296}
3297
3298void effect::begin(UINT *passes, DWORD flags)
3299{
3300   m_effect->Begin(passes, flags);
3301}
3302
3303void effect::end()
3304{
3305   m_effect->End();
3306}
3307
3308void effect::begin_pass(UINT pass)
3309{
3310   m_effect->BeginPass(pass);
3311}
3312
3313void effect::end_pass()
3314{
3315   m_effect->EndPass();
3316}
3317
3318void effect::set_technique(const char *name)
3319{
3320   m_effect->SetTechnique(name);
3321}
3322
3323void effect::set_vector(D3DXHANDLE param, int count, float *vector)
3324{
3325   static D3DXVECTOR4 out_vector;
3326   if (count > 0)
3327      out_vector.x = vector[0];
3328   if (count > 1)
3329      out_vector.y = vector[1];
3330   if (count > 2)
3331      out_vector.z = vector[2];
3332   if (count > 3)
3333      out_vector.w = vector[3];
3334   m_effect->SetVector(param, &out_vector);
3335}
3336
3337void effect::set_float(D3DXHANDLE param, float value)
3338{
3339   m_effect->SetFloat(param, value);
3340}
3341
3342void effect::set_int(D3DXHANDLE param, int value)
3343{
3344   m_effect->SetInt(param, value);
3345}
3346
3347void effect::set_matrix(D3DXHANDLE param, matrix *matrix)
3348{
3349   m_effect->SetMatrix(param, (D3DXMATRIX*)matrix);
3350}
3351
3352void effect::set_texture(D3DXHANDLE param, texture *tex)
3353{
3354   m_effect->SetTexture(param, (IDirect3DTexture9*)tex);
3355}
3356
3357D3DXHANDLE effect::get_parameter(D3DXHANDLE param, const char *name)
3358{
3359   return m_effect->GetParameterByName(param, name);
3360}
3361
3362ULONG effect::release()
3363{
3364   return m_effect->Release();
3365}
3366
3367};
3368
3369//============================================================
3370//  get_slider_list
3371//============================================================
3372
3373void *windows_osd_interface::get_slider_list()
3374{
3375   return (void*)g_slider_list;
3376}
3377
3378
3379
3380// NOTE: The function below is taken directly from src/emu/video.c and should likely be moved into a global helper function.
3381//-------------------------------------------------
3382//  open_next - open the next non-existing file of
3383//  type filetype according to our numbering
3384//  scheme
3385//-------------------------------------------------
3386
3387static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *templ, const char *extension, int idx)
3388{
3389   UINT32 origflags = file.openflags();
3390
3391   // handle defaults
3392   const char *snapname = templ ? templ : d3d->window().machine().options().snap_name();
3393
3394   if (snapname == NULL || snapname[0] == 0)
3395      snapname = "%g/%i";
3396   astring snapstr(snapname);
3397
3398   // strip any extension in the provided name
3399   int index = snapstr.rchr(0, '.');
3400   if (index != -1)
3401      snapstr.substr(0, index);
3402
3403   // handle %d in the template (for image devices)
3404   astring snapdev("%d_");
3405   int pos = snapstr.find(0, snapdev);
3406
3407   if (pos != -1)
3408   {
3409      // if more %d are found, revert to default and ignore them all
3410      if (snapstr.find(pos + 3, snapdev) != -1)
3411         snapstr.cpy("%g/%i");
3412      // else if there is a single %d, try to create the correct snapname
3413      else
3414      {
3415         int name_found = 0;
3416
3417         // find length of the device name
3418         int end1 = snapstr.find(pos + 3, "/");
3419         int end2 = snapstr.find(pos + 3, "%");
3420         int end = -1;
3421
3422         if ((end1 != -1) && (end2 != -1))
3423            end = MIN(end1, end2);
3424         else if (end1 != -1)
3425            end = end1;
3426         else if (end2 != -1)
3427            end = end2;
3428         else
3429            end = snapstr.len();
3430
3431         if (end - pos < 3)
3432            fatalerror("Something very wrong is going on!!!\n");
3433
3434         // copy the device name to an astring
3435         astring snapdevname;
3436         snapdevname.cpysubstr(snapstr, pos + 3, end - pos - 3);
3437
3438         // verify that there is such a device for this system
3439         image_interface_iterator iter(d3d->window().machine().root_device());
3440         for (device_image_interface *image = iter.first(); image != NULL; iter.next())
3441         {
3442            // get the device name
3443            astring tempdevname(image->brief_instance_name());
3444
3445            if (snapdevname.cmp(tempdevname) == 0)
3446            {
3447               // verify that such a device has an image mounted
3448               if (image->basename() != NULL)
3449               {
3450                  astring filename(image->basename());
3451
3452                  // strip extension
3453                  filename.substr(0, filename.rchr(0, '.'));
3454
3455                  // setup snapname and remove the %d_
3456                  snapstr.replace(0, snapdevname, filename);
3457                  snapstr.del(pos, 3);
3458
3459                  name_found = 1;
3460               }
3461            }
3462         }
3463
3464         // or fallback to default
3465         if (name_found == 0)
3466            snapstr.cpy("%g/%i");
3467      }
3468   }
3469
3470   // add our own index
3471   // add our own extension
3472   snapstr.cat(".").cat(extension);
3473
3474   // substitute path and gamename up front
3475   snapstr.replace(0, "/", PATH_SEPARATOR);
3476   snapstr.replace(0, "%g", d3d->window().machine().basename());
3477
3478   // determine if the template has an index; if not, we always use the same name
3479   astring fname;
3480   if (snapstr.find(0, "%i") == -1)
3481      fname.cpy(snapstr);
3482
3483   // otherwise, we scan for the next available filename
3484   else
3485   {
3486      // try until we succeed
3487      astring seqtext;
3488      file.set_openflags(OPEN_FLAG_READ);
3489      for (int seq = 0; ; seq++)
3490      {
3491         // build up the filename
3492         fname.cpy(snapstr).replace(0, "%i", seqtext.format("%04d_%d", seq, idx).cstr());
3493
3494         // try to open the file; stop when we fail
3495         file_error filerr = file.open(fname);
3496         if (filerr != FILERR_NONE)
3497            break;
3498      }
3499   }
3500
3501   // create the final file
3502   file.set_openflags(origflags);
3503   return file.open(fname);
3504}
trunk/src/osd/windows/d3dhlsl.h
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawd3d.c - Win32 Direct3D HLSL-specific header
6//
7//============================================================
8
9#ifndef __WIN_D3DHLSL__
10#define __WIN_D3DHLSL__
11
12#include "aviio.h"
13
14//============================================================
15//  CONSTANTS
16//============================================================
17
18
19//============================================================
20//  TYPE DEFINITIONS
21//============================================================
22
23namespace d3d
24{
25class effect;
26class shaders;
27
28class uniform
29{
30public:
31   typedef enum
32   {
33      UT_VEC4,
34      UT_VEC3,
35      UT_VEC2,
36      UT_FLOAT,
37      UT_INT,
38      UT_MATRIX,
39      UT_SAMPLER,
40   } uniform_type;
41
42   enum
43   {
44      CU_SCREEN_DIMS = 0,
45      CU_SOURCE_DIMS,
46      CU_SOURCE_RECT,
47
48      CU_NTSC_CCFREQ,
49      CU_NTSC_A,
50      CU_NTSC_B,
51      CU_NTSC_O,
52      CU_NTSC_P,
53      CU_NTSC_NOTCH,
54      CU_NTSC_YFREQ,
55      CU_NTSC_IFREQ,
56      CU_NTSC_QFREQ,
57      CU_NTSC_HTIME,
58      CU_NTSC_ENABLE,
59
60      CU_COLOR_RED_RATIOS,
61      CU_COLOR_GRN_RATIOS,
62      CU_COLOR_BLU_RATIOS,
63      CU_COLOR_OFFSET,
64      CU_COLOR_SCALE,
65      CU_COLOR_SATURATION,
66
67      CU_CONVERGE_LINEAR_X,
68      CU_CONVERGE_LINEAR_Y,
69      CU_CONVERGE_RADIAL_X,
70      CU_CONVERGE_RADIAL_Y,
71
72      CU_FOCUS_SIZE,
73
74      CU_PHOSPHOR_LIFE,
75      CU_PHOSPHOR_IGNORE,
76
77      CU_POST_PINCUSHION,
78      CU_POST_CURVATURE,
79      CU_POST_SHADOW_ALPHA,
80      CU_POST_SHADOW_COUNT,
81      CU_POST_SHADOW_UV,
82      CU_POST_SHADOW_DIMS,
83      CU_POST_SCANLINE_ALPHA,
84      CU_POST_SCANLINE_SCALE,
85      CU_POST_SCANLINE_HEIGHT,
86      CU_POST_SCANLINE_BRIGHT_SCALE,
87      CU_POST_SCANLINE_BRIGHT_OFFSET,
88      CU_POST_POWER,
89      CU_POST_FLOOR,
90
91      CU_BLOOM_RESCALE,
92      CU_BLOOM_LVL0123_WEIGHTS,
93      CU_BLOOM_LVL4567_WEIGHTS,
94      CU_BLOOM_LVL89A_WEIGHTS,
95
96      CU_COUNT,
97   };
98
99   uniform(effect *shader, const char *name, uniform_type type, int id);
100
101   void        set_next(uniform *next);
102   uniform *   get_next() { return m_next; }
103
104   void        set(float x, float y, float z, float w);
105   void        set(float x, float y, float z);
106   void        set(float x, float y);
107   void        set(float x);
108   void        set(int x);
109   void        set(matrix *mat);
110   void        set(texture *tex);
111
112   void        upload();
113   void        update();
114
115protected:
116   uniform     *m_next;
117
118   float       m_vec[4];
119   int         m_ival;
120   matrix      *m_mval;
121   texture     *m_texture;
122   int         m_count;
123   uniform_type    m_type;
124   int         m_id;
125
126   effect      *m_shader;
127   D3DXHANDLE  m_handle;
128};
129
130class effect
131{
132   friend class uniform;
133
134public:
135   effect(shaders *shadersys, device *dev, const char *name, const char *path);
136   ~effect();
137
138   void        begin(UINT *passes, DWORD flags);
139   void        begin_pass(UINT pass);
140
141   void        end();
142   void        end_pass();
143
144   void        set_technique(const char *name);
145
146   void        set_vector(D3DXHANDLE param, int count, float *vector);
147   void        set_float(D3DXHANDLE param, float value);
148   void        set_int(D3DXHANDLE param, int value);
149   void        set_matrix(D3DXHANDLE param, matrix *matrix);
150   void        set_texture(D3DXHANDLE param, texture *tex);
151
152   void        add_uniform(const char *name, uniform::uniform_type type, int id);
153   void        update_uniforms();
154
155   D3DXHANDLE  get_parameter(D3DXHANDLE param, const char *name);
156
157   ULONG       release();
158
159   shaders*    get_shaders() { return m_shaders; }
160
161   bool        is_valid() { return m_valid; }
162
163private:
164   uniform     *m_uniform_head;
165   uniform     *m_uniform_tail;
166   ID3DXEffect *m_effect;
167   shaders     *m_shaders;
168
169   bool        m_valid;
170};
171
172class render_target;
173class cache_target;
174class renderer;
175
176/* hlsl_options is the information about runtime-mutable Direct3D HLSL options */
177/* in the future this will be moved into an OSD/emu shared buffer */
178struct hlsl_options
179{
180   bool                    params_dirty;
181   float                   shadow_mask_alpha;
182   char                    shadow_mask_texture[1024];
183   int                     shadow_mask_count_x;
184   int                     shadow_mask_count_y;
185   float                   shadow_mask_u_size;
186   float                   shadow_mask_v_size;
187   float                   curvature;
188   float                   pincushion;
189   float                   scanline_alpha;
190   float                   scanline_scale;
191   float                   scanline_height;
192   float                   scanline_bright_scale;
193   float                   scanline_bright_offset;
194   float                   scanline_offset;
195   float                   defocus[2];
196   float                   converge_x[3];
197   float                   converge_y[3];
198   float                   radial_converge_x[3];
199   float                   radial_converge_y[3];
200   float                   red_ratio[3];
201   float                   grn_ratio[3];
202   float                   blu_ratio[3];
203   float                   offset[3];
204   float                   scale[3];
205   float                   power[3];
206   float                   floor[3];
207   float                   phosphor[3];
208   float                   saturation;
209
210   // NTSC
211   bool                    yiq_enable;
212   float                   yiq_cc;
213   float                   yiq_a;
214   float                   yiq_b;
215   float                   yiq_o;
216   float                   yiq_p;
217   float                   yiq_n;
218   float                   yiq_y;
219   float                   yiq_i;
220   float                   yiq_q;
221   float                   yiq_scan_time;
222   int                     yiq_phase_count;
223
224   // Vectors
225   float                   vector_length_scale;
226   float                   vector_length_ratio;
227
228   // Bloom
229   float                   vector_bloom_scale;
230   float                   raster_bloom_scale;
231   float                   bloom_level0_weight;
232   float                   bloom_level1_weight;
233   float                   bloom_level2_weight;
234   float                   bloom_level3_weight;
235   float                   bloom_level4_weight;
236   float                   bloom_level5_weight;
237   float                   bloom_level6_weight;
238   float                   bloom_level7_weight;
239   float                   bloom_level8_weight;
240   float                   bloom_level9_weight;
241   float                   bloom_level10_weight;
242};
243
244class shaders
245{
246   friend class effect;
247   friend class uniform;
248
249public:
250   // construction/destruction
251   shaders();
252   ~shaders();
253
254   void init(base *d3dintf, running_machine *machine, d3d::renderer *renderer);
255
256   bool enabled() { return master_enable; }
257   void toggle();
258
259   bool vector_enabled() { return master_enable && vector_enable; }
260   render_target* get_vector_target();
261   void create_vector_target(render_primitive *prim);
262
263   void begin_frame();
264   void end_frame();
265
266   void begin_draw();
267   void end_draw();
268
269   void init_effect_info(poly_info *poly);
270   void render_quad(poly_info *poly, int vertnum);
271
272   bool register_texture(texture_info *texture);
273   bool register_prescaled_texture(texture_info *texture);
274   bool add_render_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale);
275   bool add_cache_target(renderer* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index);
276
277   void window_save();
278   void window_record();
279   bool recording() { return avi_output_file != NULL; }
280
281   void avi_update_snap(surface *surface);
282   void render_snapshot(surface *surface);
283   void record_texture();
284   void init_fsfx_quad(void *vertbuf);
285
286   void                    set_texture(texture_info *texture);
287   render_target *         find_render_target(texture_info *info);
288   void                    remove_render_target(texture_info *texture);
289   void                    remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
290   void                    remove_render_target(render_target *rt);
291
292   int create_resources(bool reset);
293   void delete_resources(bool reset);
294
295   // slider-related functions
296   slider_state *init_slider_list();
297
298   struct slider_desc
299   {
300      const char *        name;
301      int                 minval;
302      int                 defval;
303      int                 maxval;
304      int                 step;
305      INT32 (*adjustor)(running_machine &, void *, astring *, INT32);
306   };
307
308private:
309   void                    blit(surface *dst, texture *src, surface *new_dst,
310                           D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count,
311                           int dstw, int dsth);
312   void                    blit(surface *dst, texture *src, surface *new_dst,
313                           D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count);
314   void                    enumerate_screens();
315
316   void                    end_avi_recording();
317   void                    begin_avi_recording(const char *name);
318
319   bool                    register_texture(texture_info *texture, int width, int height, int xscale, int yscale);
320
321   render_target*          find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
322   cache_target *          find_cache_target(UINT32 screen_index, int width, int height);
323   void                    remove_cache_target(cache_target *cache);
324
325   // Shader passes
326   void                    ntsc_pass(render_target *rt, vec2f &texsize, vec2f &delta);
327   void                    color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims);
328   void                    prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims);
329   void                    deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims);
330   void                    defocus_pass(render_target *rt, vec2f &texsize);
331   void                    phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable);
332   void                    screen_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum);
333   void                    avi_post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum);
334   void                    raster_bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum);
335
336   base *                  d3dintf;                    // D3D interface
337
338   running_machine *       machine;
339   d3d::renderer *         d3d;                        // D3D renderer
340
341   bool                    master_enable;              // overall enable flag
342   bool                    vector_enable;              // vector post-processing enable flag
343   bool                    paused;                     // whether or not rendering is currently paused
344   int                     num_screens;                // number of emulated physical screens
345   int                     curr_screen;                // current screen for render target operations
346   int                     curr_frame;                 // current frame (0/1) of a screen for render target operations
347   int                     lastidx;                    // index of the last-encountered target
348   bool                    write_ini;                  // enable external ini saving
349   bool                    read_ini;                   // enable external ini loading
350   int                     prescale_force_x;           // prescale force x
351   int                     prescale_force_y;           // prescale force y
352   int                     prescale_size_x;            // prescale size x
353   int                     prescale_size_y;            // prescale size y
354   int                     preset;                     // preset, if relevant
355   bitmap_argb32           shadow_bitmap;              // shadow mask bitmap for post-processing shader
356   texture_info *          shadow_texture;             // shadow mask texture for post-processing shader
357   hlsl_options *          options;                    // current uniform state
358   D3DPRIMITIVETYPE        vecbuf_type;
359   UINT32                  vecbuf_index;
360   UINT32                  vecbuf_count;
361
362   avi_file *              avi_output_file;            // AVI file
363   bitmap_rgb32            avi_snap;                   // AVI snapshot
364   int                     avi_frame;                  // AVI frame
365   attotime                avi_frame_period;           // AVI frame period
366   attotime                avi_next_frame_time;        // AVI next frame time
367   surface *               avi_copy_surface;           // AVI destination surface in system memory
368   texture *               avi_copy_texture;           // AVI destination texture in system memory
369   surface *               avi_final_target;           // AVI upscaled surface
370   texture *               avi_final_texture;          // AVI upscaled texture
371
372   surface *               black_surface;              // black dummy surface
373   texture *               black_texture;              // black dummy texture
374
375   bool                    render_snap;                // whether or not to take HLSL post-render snapshot
376   bool                    snap_rendered;              // whether we just rendered our HLSL post-render shot or not
377   surface *               snap_copy_target;           // snapshot destination surface in system memory
378   texture *               snap_copy_texture;          // snapshot destination surface in system memory
379   surface *               snap_target;                // snapshot upscaled surface
380   texture *               snap_texture;               // snapshot upscaled texture
381   int                     snap_width;                 // snapshot width
382   int                     snap_height;                // snapshot height
383   bool                    lines_pending;              // whether or not we have lines to flush on the next quad
384
385   bool                    initialized;                // whether or not we're initialize
386
387   // HLSL effects
388   surface *               backbuffer;                 // pointer to our device's backbuffer
389   effect *                curr_effect;                // pointer to the currently active effect object
390   effect *                default_effect;             // pointer to the primary-effect object
391   effect *                prescale_effect;            // pointer to the prescale-effect object
392   effect *                post_effect;                // pointer to the post-effect object
393   effect *                focus_effect;               // pointer to the focus-effect object
394   effect *                phosphor_effect;            // pointer to the phosphor-effect object
395   effect *                deconverge_effect;          // pointer to the deconvergence-effect object
396   effect *                color_effect;               // pointer to the color-effect object
397   effect *                yiq_encode_effect;          // pointer to the YIQ encoder effect object
398   effect *                yiq_decode_effect;          // pointer to the YIQ decoder effect object
399   effect *                bloom_effect;               // pointer to the bloom composite effect
400   effect *                downsample_effect;          // pointer to the bloom downsample effect
401   effect *                vector_effect;              // pointer to the vector-effect object
402   vertex *                fsfx_vertices;              // pointer to our full-screen-quad object
403
404   texture_info *          curr_texture;
405   bool                    phosphor_passthrough;
406
407public:
408   render_target *         targethead;
409   cache_target *          cachehead;
410
411   static slider_desc      s_sliders[];
412   static hlsl_options     s_hlsl_presets[4];
413};
414
415};
416
417#endif
trunk/src/osd/windows/d3dintf.h
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  d3dintf.h - Direct3D 8/9 interface abstractions
6//
7//============================================================
8
9#ifndef __WIN_D3DINTF__
10#define __WIN_D3DINTF__
11
12
13//============================================================
14//  CONSTANTS
15//============================================================
16
17#ifndef D3DCAPS2_DYNAMICTEXTURES
18#define D3DCAPS2_DYNAMICTEXTURES 0x20000000L
19#endif
20
21#ifndef D3DPRESENT_DONOTWAIT
22#define D3DPRESENT_DONOTWAIT 0x00000001L
23#endif
24
25
26#define D3DTSS_ADDRESSU       13
27#define D3DTSS_ADDRESSV       14
28#define D3DTSS_BORDERCOLOR    15
29#define D3DTSS_MAGFILTER      16
30#define D3DTSS_MINFILTER      17
31#define D3DTSS_MIPFILTER      18
32#define D3DTSS_MIPMAPLODBIAS  19
33#define D3DTSS_MAXMIPLEVEL    20
34#define D3DTSS_MAXANISOTROPY  21
35
36namespace d3d
37{
38//============================================================
39//  TYPE DEFINITIONS
40//============================================================
41
42struct base;
43struct device;
44struct surface;
45struct texture;
46struct vertex_buffer;
47class effect;
48typedef D3DXVECTOR4 vector;
49typedef D3DMATRIX matrix;
50
51//============================================================
52//  Abstracted presentation parameters
53//============================================================
54
55struct present_parameters
56{
57   UINT BackBufferWidth;
58   UINT BackBufferHeight;
59   D3DFORMAT BackBufferFormat;
60   UINT BackBufferCount;
61   D3DMULTISAMPLE_TYPE MultiSampleType;
62   DWORD MultiSampleQuality;
63   D3DSWAPEFFECT SwapEffect;
64   HWND hDeviceWindow;
65   BOOL Windowed;
66   BOOL EnableAutoDepthStencil;
67   D3DFORMAT AutoDepthStencilFormat;
68   DWORD Flags;
69   UINT FullScreen_RefreshRateInHz;
70   UINT PresentationInterval;
71};
72
73
74//============================================================
75//  Abstracted device identifier
76//============================================================
77
78struct adapter_identifier
79{
80   char            Driver[512];
81   char            Description[512];
82   LARGE_INTEGER   DriverVersion;
83   DWORD           VendorId;
84   DWORD           DeviceId;
85   DWORD           SubSysId;
86   DWORD           Revision;
87   GUID            DeviceIdentifier;
88   DWORD           WHQLLevel;
89};
90
91
92//============================================================
93//  Caps enumeration
94//============================================================
95
96enum caps_index
97{
98   CAPS_PRESENTATION_INTERVALS,
99   CAPS_CAPS2,
100   CAPS_DEV_CAPS,
101   CAPS_SRCBLEND_CAPS,
102   CAPS_DSTBLEND_CAPS,
103   CAPS_TEXTURE_CAPS,
104   CAPS_TEXTURE_FILTER_CAPS,
105   CAPS_TEXTURE_ADDRESS_CAPS,
106   CAPS_TEXTURE_OP_CAPS,
107   CAPS_MAX_TEXTURE_ASPECT,
108   CAPS_MAX_TEXTURE_WIDTH,
109   CAPS_MAX_TEXTURE_HEIGHT,
110   CAPS_STRETCH_RECT_FILTER,
111   CAPS_MAX_PS30_INSN_SLOTS
112};
113
114
115//============================================================
116//  Direct3D interfaces
117//============================================================
118
119struct interface
120{
121   HRESULT  (*check_device_format)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT adapterformat, DWORD usage, D3DRESOURCETYPE restype, D3DFORMAT format);
122   HRESULT  (*check_device_type)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, D3DFORMAT format, D3DFORMAT backformat, BOOL windowed);
123   HRESULT  (*create_device)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, HWND focus, DWORD behavior, present_parameters *params, device **dev);
124   HRESULT  (*enum_adapter_modes)(base *d3dptr, UINT adapter, D3DFORMAT format, UINT index, D3DDISPLAYMODE *mode);
125   UINT     (*get_adapter_count)(base *d3dptr);
126   HRESULT  (*get_adapter_display_mode)(base *d3dptr, UINT adapter, D3DDISPLAYMODE *mode);
127   HRESULT  (*get_adapter_identifier)(base *d3dptr, UINT adapter, DWORD flags, adapter_identifier *identifier);
128   UINT     (*get_adapter_mode_count)(base *d3dptr, UINT adapter, D3DFORMAT format);
129   HMONITOR (*get_adapter_monitor)(base *d3dptr, UINT adapter);
130   HRESULT  (*get_caps_dword)(base *d3dptr, UINT adapter, D3DDEVTYPE devtype, caps_index which, DWORD *value);
131   ULONG    (*release)(base *d3dptr);
132};
133
134
135//============================================================
136//  Direct3DDevice interfaces
137//============================================================
138
139struct device_interface
140{
141   HRESULT (*begin_scene)(device *dev);
142   HRESULT (*clear)(device *dev, DWORD count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil);
143   HRESULT (*create_offscreen_plain_surface)(device *dev, UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, surface **surface);
144   HRESULT (*create_texture)(device *dev, UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool, texture **texture);
145   HRESULT (*create_vertex_buffer)(device *dev, UINT length, DWORD usage, DWORD fvf, D3DPOOL pool, vertex_buffer **buf);
146   HRESULT (*create_render_target)(device *dev, UINT width, UINT height, D3DFORMAT format, surface **surface);
147   HRESULT (*draw_primitive)(device *dev, D3DPRIMITIVETYPE type, UINT start, UINT count);
148   HRESULT (*end_scene)(device *dev);
149   HRESULT (*get_raster_status)(device *dev, D3DRASTER_STATUS *status);
150   HRESULT (*get_render_target)(device *dev, DWORD index, surface **surface);
151   HRESULT (*get_render_target_data)(device *dev, surface *rendertarget, surface *destsurface);
152   HRESULT (*present)(device *dev, const RECT *source, const RECT *dest, HWND override, RGNDATA *dirty, DWORD flags);
153   ULONG   (*release)(device *dev);
154   HRESULT (*reset)(device *dev, present_parameters *params);
155   void    (*set_gamma_ramp)(device *dev, DWORD flags, const D3DGAMMARAMP *ramp);
156   HRESULT (*set_render_state)(device *dev, D3DRENDERSTATETYPE state, DWORD value);
157   HRESULT (*set_render_target)(device *dev, DWORD index, surface *surf);
158   HRESULT (*set_stream_source)(device *dev, UINT number, vertex_buffer *vbuf, UINT stride);
159   HRESULT (*set_texture)(device *dev, DWORD stage, texture *tex);
160   HRESULT (*set_texture_stage_state)(device *dev, DWORD stage, D3DTEXTURESTAGESTATETYPE state, DWORD value);
161   HRESULT (*set_vertex_format)(device *dev, D3DFORMAT format);
162   HRESULT (*stretch_rect)(device *dev, surface *source, const RECT *srcrect, surface *dest, const RECT *dstrect, D3DTEXTUREFILTERTYPE filter);
163   HRESULT (*test_cooperative_level)(device *dev);
164};
165
166
167//============================================================
168//  Direct3DSurface interfaces
169//============================================================
170
171struct surface_interface
172{
173   HRESULT (*lock_rect)(surface *surf, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags);
174   ULONG   (*release)(surface *tex);
175   HRESULT (*unlock_rect)(surface *surf);
176};
177
178
179//============================================================
180//  Direct3DTexture interfaces
181//============================================================
182
183struct texture_interface
184{
185   HRESULT (*get_surface_level)(texture *tex, UINT level, surface **surface);
186   HRESULT (*lock_rect)(texture *tex, UINT level, D3DLOCKED_RECT *locked, const RECT *rect, DWORD flags);
187   ULONG   (*release)(texture *tex);
188   HRESULT (*unlock_rect)(texture *tex, UINT level);
189};
190
191
192//============================================================
193//  Direct3DVertexBuffer interfaces
194//============================================================
195
196struct vertex_buffer_interface
197{
198   HRESULT (*lock)(vertex_buffer *vbuf, UINT offset, UINT size, VOID **data, DWORD flags);
199   ULONG   (*release)(vertex_buffer *vbuf);
200   HRESULT (*unlock)(vertex_buffer *vbuf);
201};
202
203
204//============================================================
205//  Core D3D object
206//============================================================
207
208struct base
209{
210   // internal objects
211   int                         version;
212   void *                      d3dobj;
213   HINSTANCE                   dllhandle;
214   bool                        post_fx_available;
215   HINSTANCE                   libhandle;
216
217   // interface pointers
218   interface               d3d;
219   device_interface        device;
220   surface_interface       surface;
221   texture_interface       texture;
222   vertex_buffer_interface vertexbuf;
223};
224
225
226//============================================================
227//  PROTOTYPES
228//============================================================
229
230base *drawd3d9_init(void);
231
232};
233
234#endif
trunk/src/osd/windows/drawbgfx.c
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Miodrag Milanovic
3//============================================================
4//
5//  drawbgfx.c - BGFX drawer
6//
7//============================================================
8
9// standard windows headers
10#define __STDC_LIMIT_MACROS
11#define __STDC_FORMAT_MACROS
12#define __STDC_CONSTANT_MACROS
13#define WIN32_LEAN_AND_MEAN
14#include <windows.h>
15
16// MAME headers
17#include "emu.h"
18
19// MAMEOS headers
20#include "window.h"
21
22#include <bgfxplatform.h>
23#include <bgfx.h>
24
25class renderer_bgfx : public osd_renderer
26{
27public:
28   renderer_bgfx(osd_window *window)
29   : osd_renderer(window, FLAG_NONE) { }
30
31   virtual ~renderer_bgfx() { }
32
33   virtual int create();
34   virtual render_primitive_list *get_primitives();
35   virtual int draw(const int update);
36   virtual void save() {};
37   virtual void record() {};
38   virtual void toggle_fsfx() {};
39   virtual void destroy();
40
41private:
42};
43
44
45//============================================================
46//  PROTOTYPES
47//============================================================
48
49// core functions
50static void drawbgfx_exit(void);
51
52//============================================================
53//  drawnone_create
54//============================================================
55
56osd_renderer *drawbgfx_create(osd_window *window)
57{
58   return global_alloc(renderer_bgfx(window));
59}
60
61//============================================================
62//  drawbgfx_init
63//============================================================
64
65int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks)
66{
67   // fill in the callbacks
68   memset(callbacks, 0, sizeof(*callbacks));
69   callbacks->exit = drawbgfx_exit;
70   callbacks->create = drawbgfx_create;
71   return 0;
72}
73
74
75
76//============================================================
77//  drawbgfx_exit
78//============================================================
79
80static void drawbgfx_exit(void)
81{
82}
83
84
85
86//============================================================
87//  drawbgfx_window_init
88//============================================================
89
90int renderer_bgfx::create()
91{
92   RECT client;
93   GetClientRect(window().m_hwnd, &client);
94
95   bgfx::winSetHwnd(window().m_hwnd);
96   bgfx::init();
97   bgfx::reset(rect_width(&client), rect_height(&client), BGFX_RESET_VSYNC);
98
99   // Enable debug text.
100   bgfx::setDebug(BGFX_DEBUG_STATS);// BGFX_DEBUG_TEXT);
101
102   return 0;
103}
104
105
106
107//============================================================
108//  drawbgfx_window_destroy
109//============================================================
110
111void renderer_bgfx::destroy()
112{
113   // Shutdown bgfx.
114   bgfx::shutdown();
115}
116
117
118
119//============================================================
120//  drawbgfx_window_get_primitives
121//============================================================
122
123render_primitive_list *renderer_bgfx::get_primitives()
124{
125   RECT client;
126   GetClientRect(window().m_hwnd, &client);
127   window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
128   return &window().target()->get_primitives();
129}
130
131
132
133//============================================================
134//  drawbgfx_window_draw
135//============================================================
136
137int renderer_bgfx::draw(int update)
138{
139   RECT client;
140   GetClientRect(window().m_hwnd, &client);
141
142   bgfx::setViewClear(0
143      , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
144      , 0x000000ff
145      , 1.0f
146      , 0
147      );
148   // Set view 0 default viewport.
149   bgfx::setViewRect(0, 0, 0, rect_width(&client), rect_height(&client));
150
151   // This dummy draw call is here to make sure that view 0 is cleared
152   // if no other draw calls are submitted to view 0.
153   bgfx::submit(0);
154
155   window().m_primlist->acquire_lock();
156
157   // now draw
158   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
159   {
160      switch (prim->type)
161      {
162         /**
163          * Try to stay in one Begin/End block as long as possible,
164          * since entering and leaving one is most expensive..
165          */
166         case render_primitive::LINE:
167            // check if it's really a point
168/*
169                if (((prim->bounds.x1 - prim->bounds.x0) == 0) && ((prim->bounds.y1 - prim->bounds.y0) == 0))
170                {
171                    curPrimitive=GL_POINTS;
172                } else {
173                    curPrimitive=GL_LINES;
174                }
175
176                if(pendingPrimitive!=GL_NO_PRIMITIVE && pendingPrimitive!=curPrimitive)
177                {
178                    glEnd();
179                    pendingPrimitive=GL_NO_PRIMITIVE;
180                }
181
182                if ( pendingPrimitive==GL_NO_PRIMITIVE )
183                {
184                            set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags));
185                }
186
187                glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
188
189                if(pendingPrimitive!=curPrimitive)
190                {
191                    glBegin(curPrimitive);
192                    pendingPrimitive=curPrimitive;
193                }
194
195                // check if it's really a point
196                if (curPrimitive==GL_POINTS)
197                {
198                    glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
199                }
200                else
201                {
202                    glVertex2f(prim->bounds.x0+hofs, prim->bounds.y0+vofs);
203                    glVertex2f(prim->bounds.x1+hofs, prim->bounds.y1+vofs);
204                }*/
205            break;
206
207         case render_primitive::QUAD:
208/*
209                if(pendingPrimitive!=GL_NO_PRIMITIVE)
210                {
211                    glEnd();
212                    pendingPrimitive=GL_NO_PRIMITIVE;
213                }
214
215                glColor4f(prim->color.r, prim->color.g, prim->color.b, prim->color.a);
216
217                set_blendmode(sdl, PRIMFLAG_GET_BLENDMODE(prim->flags));
218
219                texture = texture_update(window, prim, 0);
220
221
222                sdl->texVerticex[0]=prim->bounds.x0 + hofs;
223                sdl->texVerticex[1]=prim->bounds.y0 + vofs;
224                sdl->texVerticex[2]=prim->bounds.x1 + hofs;
225                sdl->texVerticex[3]=prim->bounds.y0 + vofs;
226                sdl->texVerticex[4]=prim->bounds.x1 + hofs;
227                sdl->texVerticex[5]=prim->bounds.y1 + vofs;
228                sdl->texVerticex[6]=prim->bounds.x0 + hofs;
229                sdl->texVerticex[7]=prim->bounds.y1 + vofs;
230
231                glDrawArrays(GL_QUADS, 0, 4);
232*/
233            break;
234
235         default:
236            throw emu_fatalerror("Unexpected render_primitive type");
237      }
238   }
239
240   window().m_primlist->release_lock();
241   // Advance to next frame. Rendering thread will be kicked to
242   // process submitted rendering primitives.
243   bgfx::frame();
244
245   return 0;
246}
trunk/src/osd/windows/drawd3d.c
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawd3d.c - Win32 Direct3D implementation
6//
7//============================================================
8
9// Useful info:
10//  Windows XP/2003 shipped with DirectX 8.1
11//  Windows 2000 shipped with DirectX 7a
12//  Windows 98SE shipped with DirectX 6.1a
13//  Windows 98 shipped with DirectX 5
14//  Windows NT shipped with DirectX 3.0a
15//  Windows 95 shipped with DirectX 2
16
17// standard windows headers
18#define WIN32_LEAN_AND_MEAN
19#include <windows.h>
20#include <tchar.h>
21#include <mmsystem.h>
22#include <d3d9.h>
23#include <d3dx9.h>
24#include <math.h>
25#undef interface
26
27// MAME headers
28#include "emu.h"
29#include "render.h"
30#include "ui/ui.h"
31#include "rendutil.h"
32#include "options.h"
33#include "emuopts.h"
34#include "aviio.h"
35#include "png.h"
36
37// MAMEOS headers
38#include "d3dintf.h"
39#include "winmain.h"
40#include "window.h"
41#include "config.h"
42#include "strconv.h"
43#include "d3dcomm.h"
44#include "drawd3d.h"
45
46
47
48//============================================================
49//  DEBUGGING
50//============================================================
51
52extern void mtlog_add(const char *event);
53
54
55
56//============================================================
57//  CONSTANTS
58//============================================================
59
60#define ENABLE_BORDER_PIX   (1)
61
62enum
63{
64   TEXTURE_TYPE_PLAIN,
65   TEXTURE_TYPE_DYNAMIC,
66   TEXTURE_TYPE_SURFACE
67};
68
69
70
71//============================================================
72//  MACROS
73//============================================================
74
75#define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0)
76
77
78
79//============================================================
80//  GLOBALS
81//============================================================
82
83static const line_aa_step line_aa_1step[] =
84{
85   {  0.00f,  0.00f,  1.00f  },
86   { 0 }
87};
88
89static const line_aa_step line_aa_4step[] =
90{
91   { -0.25f,  0.00f,  0.25f  },
92   {  0.25f,  0.00f,  0.25f  },
93   {  0.00f, -0.25f,  0.25f  },
94   {  0.00f,  0.25f,  0.25f  },
95   { 0 }
96};
97
98//============================================================
99//  INLINES
100//============================================================
101
102INLINE BOOL GetClientRectExceptMenu(HWND hWnd, PRECT pRect, BOOL fullscreen)
103{
104   static HMENU last_menu;
105   static RECT last_rect;
106   static RECT cached_rect;
107   HMENU menu = GetMenu(hWnd);
108   BOOL result = GetClientRect(hWnd, pRect);
109
110   if (!fullscreen || !menu)
111      return result;
112
113   // to avoid flicker use cache if we can use
114   if (last_menu != menu || memcmp(&last_rect, pRect, sizeof *pRect) != 0)
115   {
116      last_menu = menu;
117      last_rect = *pRect;
118
119      SetMenu(hWnd, NULL);
120      result = GetClientRect(hWnd, &cached_rect);
121      SetMenu(hWnd, menu);
122   }
123
124   *pRect = cached_rect;
125   return result;
126}
127
128
129INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr)
130{
131   /* original equations:
132
133       C = Y - 16
134       D = Cb - 128
135       E = Cr - 128
136
137       R = clip(( 298 * C           + 409 * E + 128) >> 8)
138       G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
139       B = clip(( 298 * C + 516 * D           + 128) >> 8)
140
141       R = clip(( 298 * (Y - 16)                    + 409 * (Cr - 128) + 128) >> 8)
142       G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8)
143       B = clip(( 298 * (Y - 16) + 516 * (Cb - 128)                    + 128) >> 8)
144
145       R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
146       G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
147       B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
148
149       R = clip(( 298 * Y - 298 * 16                        + 409 * Cr - 409 * 128 + 128) >> 8)
150       G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
151       B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128                        + 128) >> 8)
152   */
153   int r, g, b, common;
154
155   common = 298 * y - 298 * 16;
156   r = (common +                        409 * cr - 409 * 128 + 128) >> 8;
157   g = (common - 100 * cb + 100 * 128 - 208 * cr + 208 * 128 + 128) >> 8;
158   b = (common + 516 * cb - 516 * 128                        + 128) >> 8;
159
160   if (r < 0) r = 0;
161   else if (r > 255) r = 255;
162   if (g < 0) g = 0;
163   else if (g > 255) g = 255;
164   if (b < 0) b = 0;
165   else if (b > 255) b = 255;
166
167   return rgb_t(0xff, r, g, b);
168}
169
170//============================================================
171//  drawd3d_init
172//============================================================
173
174static d3d::base *               d3dintf; // FIX ME
175
176//============================================================
177//  PROTOTYPES
178//============================================================
179
180// core functions
181static void drawd3d_exit(void);
182
183//============================================================
184//  drawd3d_window_init
185//============================================================
186
187int d3d::renderer::create()
188{
189   if (!initialize())
190   {
191      destroy();
192      osd_printf_error("Unable to initialize Direct3D.\n");
193      return 1;
194   }
195
196   return 0;
197}
198
199//============================================================
200//  drawd3d_exit
201//============================================================
202
203static void drawd3d_exit(void)
204{
205   if (d3dintf != NULL)
206      (*d3dintf->d3d.release)(d3dintf);
207}
208
209void d3d::renderer::toggle_fsfx()
210{
211   set_restarting(true);
212}
213
214void d3d::renderer::record()
215{
216   get_shaders()->window_record();
217}
218
219void d3d::renderer::save()
220{
221   get_shaders()->window_save();
222}
223
224
225
226//============================================================
227//  drawd3d_window_destroy
228//============================================================
229
230void d3d::renderer::destroy()
231{
232   if (get_shaders() != NULL && get_shaders()->recording())
233      get_shaders()->window_record();
234
235}
236
237
238
239//============================================================
240//  drawd3d_window_get_primitives
241//============================================================
242
243render_primitive_list *d3d::renderer::get_primitives()
244{
245   RECT client;
246
247   GetClientRectExceptMenu(window().m_hwnd, &client, window().fullscreen());
248   if (rect_width(&client) > 0 && rect_height(&client) > 0)
249   {
250      window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
251      window().target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh());
252   }
253   return &window().target()->get_primitives();
254}
255
256//============================================================
257//  drawnone_create
258//============================================================
259
260static osd_renderer *drawd3d_create(osd_window *window)
261{
262   return global_alloc(d3d::renderer(window));
263}
264
265int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks)
266{
267   d3dintf = NULL;
268
269   // Use Direct3D9
270   d3dintf = d3d::drawd3d9_init();
271
272   // if we failed, note the error
273   if (d3dintf == NULL)
274   {
275      osd_printf_error("Unable to initialize Direct3D.\n");
276      return 1;
277   }
278
279   // fill in the callbacks
280   memset(callbacks, 0, sizeof(*callbacks));
281   callbacks->exit = drawd3d_exit;
282   callbacks->create = drawd3d_create;
283   return 0;
284}
285
286//============================================================
287//  drawd3d_window_draw
288//============================================================
289
290int d3d::renderer::draw(const int update)
291{
292   int check = pre_window_draw_check();
293   if (check >= 0)
294      return check;
295
296   begin_frame();
297   process_primitives();
298   end_frame();
299
300   return 0;
301}
302
303namespace d3d
304{
305void renderer::set_texture(texture_info *texture)
306{
307   if (texture != m_last_texture)
308   {
309      m_last_texture = texture;
310      m_last_texture_flags = (texture == NULL ? 0 : texture->get_flags());
311      HRESULT result = (*d3dintf->device.set_texture)(m_device, 0, (texture == NULL) ? get_default_texture()->get_finaltex() : texture->get_finaltex());
312      m_shaders->set_texture(texture);
313      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result);
314   }
315}
316
317
318void renderer::set_filter(int filter)
319{
320   if (filter != m_last_filter)
321   {
322      m_last_filter = filter;
323      HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
324      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
325      result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
326      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
327      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
328      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
329      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
330      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
331   }
332}
333
334
335void renderer::set_wrap(D3DTEXTUREADDRESS wrap)
336{
337   if (wrap != m_last_wrap)
338   {
339      m_last_wrap = wrap;
340      HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, wrap);
341      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
342      result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, wrap);
343      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
344      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, wrap);
345      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
346      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, wrap);
347      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
348   }
349}
350
351
352void renderer::set_modmode(DWORD modmode)
353{
354   if (modmode != m_last_modmode)
355   {
356      m_last_modmode = modmode;
357      HRESULT result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_COLOROP, modmode);
358      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
359      result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_COLOROP, modmode);
360      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
361   }
362}
363
364
365void renderer::set_blendmode(int blendmode)
366{
367   int blendenable;
368   int blendop;
369   int blendsrc;
370   int blenddst;
371
372   // choose the parameters
373   switch (blendmode)
374   {
375      default:
376      case BLENDMODE_NONE:            blendenable = FALSE;    blendop = D3DBLENDOP_ADD;   blendsrc = D3DBLEND_SRCALPHA;   blenddst = D3DBLEND_INVSRCALPHA;    break;
377      case BLENDMODE_ALPHA:           blendenable = TRUE;     blendop = D3DBLENDOP_ADD;   blendsrc = D3DBLEND_SRCALPHA;   blenddst = D3DBLEND_INVSRCALPHA;    break;
378      case BLENDMODE_RGB_MULTIPLY:    blendenable = TRUE;     blendop = D3DBLENDOP_ADD;   blendsrc = D3DBLEND_DESTCOLOR;  blenddst = D3DBLEND_ZERO;           break;
379      case BLENDMODE_ADD:             blendenable = TRUE;     blendop = D3DBLENDOP_ADD;   blendsrc = D3DBLEND_SRCALPHA;   blenddst = D3DBLEND_ONE;            break;
380   }
381
382   // adjust the bits that changed
383   if (blendenable != m_last_blendenable)
384   {
385      m_last_blendenable = blendenable;
386      HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHABLENDENABLE, blendenable);
387      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
388   }
389
390   if (blendop != m_last_blendop)
391   {
392      m_last_blendop = blendop;
393      HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_BLENDOP, blendop);
394      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
395   }
396
397   if (blendsrc != m_last_blendsrc)
398   {
399      m_last_blendsrc = blendsrc;
400      HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SRCBLEND, blendsrc);
401      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
402   }
403
404   if (blenddst != m_last_blenddst)
405   {
406      m_last_blenddst = blenddst;
407      HRESULT result = (*d3dintf->device.set_render_state)(m_device, D3DRS_DESTBLEND, blenddst);
408      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
409   }
410}
411
412
413void renderer::reset_render_states()
414{
415   // this ensures subsequent calls to the above setters will force-update the data
416   m_last_texture = (texture_info *)~0;
417   m_last_filter = -1;
418   m_last_blendenable = -1;
419   m_last_blendop = -1;
420   m_last_blendsrc = -1;
421   m_last_blenddst = -1;
422   m_last_wrap = (D3DTEXTUREADDRESS)-1;
423}
424
425
426
427texture_manager::texture_manager(renderer *d3d)
428{
429   m_renderer = d3d;
430
431   m_texlist = NULL;
432   m_vector_texture = NULL;
433   m_default_texture = NULL;
434
435   // check for dynamic texture support
436   DWORD tempcaps;
437   HRESULT result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_CAPS2, &tempcaps);
438   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
439   m_dynamic_supported = ((tempcaps & D3DCAPS2_DYNAMICTEXTURES) != 0);
440   if (m_dynamic_supported) osd_printf_verbose("Direct3D: Using dynamic textures\n");
441
442   // check for stretchrect support
443   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_STRETCH_RECT_FILTER, &tempcaps);
444   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
445   m_stretch_supported = ((tempcaps & D3DPTFILTERCAPS_MAGFPOINT) != 0);
446   if (m_stretch_supported && video_config.prescale > 1) osd_printf_verbose("Direct3D: Using StretchRect for prescaling\n");
447
448   // get texture caps
449   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_TEXTURE_CAPS, &m_texture_caps);
450   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
451   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_ASPECT, &m_texture_max_aspect);
452   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
453   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_WIDTH, &m_texture_max_width);
454   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
455   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_HEIGHT, &m_texture_max_height);
456   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
457
458   // pick a YUV texture format
459   m_yuv_format = D3DFMT_UYVY;
460   result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
461   if (result != D3D_OK)
462   {
463      m_yuv_format = D3DFMT_YUY2;
464      result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
465      if (result != D3D_OK)
466         m_yuv_format = D3DFMT_A8R8G8B8;
467   }
468   osd_printf_verbose("Direct3D: YUV format = %s\n", (m_yuv_format == D3DFMT_YUY2) ? "YUY2" : (m_yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB");
469
470   // set the max texture size
471   d3d->window().target()->set_max_texture_size(m_texture_max_width, m_texture_max_height);
472   osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height);
473}
474
475texture_manager::~texture_manager()
476{
477}
478
479void texture_manager::create_resources()
480{
481   // experimental: load a PNG to use for vector rendering; it is treated
482   // as a brightness map
483   emu_file file(m_renderer->window().machine().options().art_path(), OPEN_FLAG_READ);
484   render_load_png(m_vector_bitmap, file, NULL, "vector.png");
485   if (m_vector_bitmap.valid())
486   {
487      m_vector_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
488      render_load_png(m_vector_bitmap, file, NULL, "vector.png", true);
489   }
490
491   m_default_bitmap.allocate(8, 8);
492   m_default_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
493
494   if (m_default_bitmap.valid())
495   {
496      render_texinfo texture;
497
498      // fake in the basic data so it looks like it came from render.c
499      texture.base = m_default_bitmap.raw_pixptr(0);
500      texture.rowpixels = m_default_bitmap.rowpixels();
501      texture.width = m_default_bitmap.width();
502      texture.height = m_default_bitmap.height();
503      texture.palette = NULL;
504      texture.seqid = 0;
505
506      // now create it
507      m_default_texture = global_alloc(texture_info(this, &texture, m_renderer->window().prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32)));
508   }
509
510   // experimental: if we have a vector bitmap, create a texture for it
511   if (m_vector_bitmap.valid())
512   {
513      render_texinfo texture;
514
515      // fake in the basic data so it looks like it came from render.c
516      texture.base = &m_vector_bitmap.pix32(0);
517      texture.rowpixels = m_vector_bitmap.rowpixels();
518      texture.width = m_vector_bitmap.width();
519      texture.height = m_vector_bitmap.height();
520      texture.palette = NULL;
521      texture.seqid = 0;
522
523      // now create it
524      m_vector_texture = global_alloc(texture_info(this, &texture, m_renderer->window().prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32)));
525   }
526}
527
528void texture_manager::delete_resources()
529{
530   // is part of m_texlist and will be free'd there
531   //global_free(m_default_texture);
532   m_default_texture = NULL;
533
534   //global_free(m_vector_texture);
535   m_vector_texture = NULL;
536
537   // free all textures
538   while (m_texlist != NULL)
539   {
540      texture_info *tex = m_texlist;
541      m_texlist = tex->get_next();
542      global_free(tex);
543   }
544}
545
546UINT32 texture_manager::texture_compute_hash(const render_texinfo *texture, UINT32 flags)
547{
548   return (FPTR)texture->base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK));
549}
550
551texture_info *texture_manager::find_texinfo(const render_texinfo *texinfo, UINT32 flags)
552{
553   UINT32 hash = texture_compute_hash(texinfo, flags);
554   texture_info *texture;
555
556   // find a match
557   for (texture = m_renderer->get_texture_manager()->get_texlist(); texture != NULL; texture = texture->get_next())
558   {
559      UINT32 test_screen = (UINT32)texture->get_texinfo().osddata >> 1;
560      UINT32 test_page = (UINT32)texture->get_texinfo().osddata & 1;
561      UINT32 prim_screen = (UINT32)texinfo->osddata >> 1;
562      UINT32 prim_page = (UINT32)texinfo->osddata & 1;
563      if (test_screen != prim_screen || test_page != prim_page)
564      {
565         continue;
566      }
567
568      if (texture->get_hash() == hash &&
569         texture->get_texinfo().base == texinfo->base &&
570         texture->get_texinfo().width == texinfo->width &&
571         texture->get_texinfo().height == texinfo->height &&
572         ((texture->get_flags() ^ flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0)
573      {
574         // Reject a texture if it belongs to an out-of-date render target, so as to cause the HLSL system to re-cache
575         if (m_renderer->get_shaders()->enabled() && texinfo->width != 0 && texinfo->height != 0 && (flags & PRIMFLAG_SCREENTEX_MASK) != 0)
576         {
577            if (m_renderer->get_shaders()->find_render_target(texture) != NULL)
578            {
579               return texture;
580            }
581         }
582         else
583         {
584            return texture;
585         }
586      }
587   }
588
589   // Nothing found, check if we need to unregister something with HLSL
590   if (m_renderer->get_shaders()->enabled())
591   {
592      if (texinfo->width == 0 || texinfo->height == 0)
593      {
594         return NULL;
595      }
596
597      UINT32 prim_screen = texinfo->osddata >> 1;
598      UINT32 prim_page = texinfo->osddata & 1;
599
600      for (texture = m_renderer->get_texture_manager()->get_texlist(); texture != NULL; texture = texture->get_next())
601      {
602         UINT32 test_screen = texture->get_texinfo().osddata >> 1;
603         UINT32 test_page = texture->get_texinfo().osddata & 1;
604         if (test_screen != prim_screen || test_page != prim_page)
605         {
606            continue;
607         }
608
609         // Clear out our old texture reference
610         if (texture->get_hash() == hash &&
611            texture->get_texinfo().base == texinfo->base &&
612            ((texture->get_flags() ^ flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0 &&
613            (texture->get_texinfo().width != texinfo->width ||
614               texture->get_texinfo().height != texinfo->height))
615         {
616            m_renderer->get_shaders()->remove_render_target(texture);
617         }
618      }
619   }
620
621   return NULL;
622}
623
624renderer::renderer(osd_window *window)
625   : osd_renderer(window, FLAG_NONE)
626{
627   m_device = NULL;
628   m_restarting = false;
629   m_shaders = NULL;
630   m_numverts = 0;
631   m_numpolys = 0;
632   m_vertexbuf = NULL;
633   m_lockedbuf = NULL;
634   m_vectorbatch = NULL;
635   m_last_texture = NULL;
636   m_hlsl_buf = NULL;
637   m_texture_manager = NULL;
638}
639
640int renderer::initialize()
641{
642   // configure the adapter for the mode we want
643   if (config_adapter_mode())
644      return false;
645
646   // create the device immediately for the full screen case (defer for window mode)
647   if (window().fullscreen() && device_create(window().m_focus_hwnd))
648      return false;
649
650   return true;
651}
652
653int renderer::pre_window_draw_check()
654{
655   // if we're in the middle of resizing, leave things alone
656   if (window().m_resize_state == RESIZE_STATE_RESIZING)
657      return 0;
658
659   // if we're restarting the renderer, leave things alone
660   if (m_restarting)
661   {
662      m_shaders->toggle();
663
664      // free all existing resources and re-create
665      device_delete_resources();
666      device_create_resources();
667
668      m_restarting = false;
669   }
670
671   // if we have a device, check the cooperative level
672   if (m_device != NULL)
673   {
674      if (device_test_cooperative())
675      {
676         return 1;
677      }
678   }
679
680   // in window mode, we need to track the window size
681   if (!window().fullscreen() || m_device == NULL)
682   {
683      // if the size changes, skip this update since the render target will be out of date
684      if (update_window_size())
685         return 0;
686
687      // if we have no device, after updating the size, return an error so GDI can try
688      if (m_device == NULL)
689         return 1;
690   }
691
692   return -1;
693}
694
695void texture_manager::update_textures()
696{
697   for (render_primitive *prim = m_renderer->window().m_primlist->first(); prim != NULL; prim = prim->next())
698   {
699      if (prim->texture.base != NULL)
700      {
701         texture_info *texture = find_texinfo(&prim->texture, prim->flags);
702         if (texture == NULL)
703         {
704            // if there isn't one, create a new texture
705            global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags));
706         }
707         else
708         {
709            // if there is one, but with a different seqid, copy the data
710            if (texture->get_texinfo().seqid != prim->texture.seqid)
711            {
712               texture->set_data(&prim->texture, prim->flags);
713               texture->get_texinfo().seqid = prim->texture.seqid;
714            }
715         }
716      }
717      else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim->flags))
718      {
719         if (!m_renderer->get_shaders()->get_vector_target())
720         {
721            m_renderer->get_shaders()->create_vector_target(prim);
722         }
723      }
724   }
725}
726
727void renderer::begin_frame()
728{
729   HRESULT result = (*d3dintf->device.clear)(m_device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
730   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
731
732   m_shaders->begin_frame();
733
734   window().m_primlist->acquire_lock();
735
736   // first update any textures
737   m_texture_manager->update_textures();
738
739   // begin the scene
740mtlog_add("drawd3d_window_draw: begin_scene");
741   result = (*d3dintf->device.begin_scene)(m_device);
742   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
743
744   m_lockedbuf = NULL;
745
746   if(m_shaders->enabled())
747   {
748      m_hlsl_buf = (void*)mesh_alloc(6);
749      m_shaders->init_fsfx_quad(m_hlsl_buf);
750   }
751
752   m_line_count = 0;
753
754   // loop over primitives
755   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
756      if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags))
757         m_line_count++;
758}
759
760void renderer::process_primitives()
761{
762   // Rotating index for vector time offsets
763   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
764   {
765      switch (prim->type)
766      {
767         case render_primitive::LINE:
768            if (PRIMFLAG_GET_VECTOR(prim->flags))
769            {
770               if (m_line_count > 0)
771                  batch_vectors();
772               else
773                  continue;
774            }
775            else
776            {
777               draw_line(prim);
778            }
779            break;
780
781         case render_primitive::QUAD:
782            draw_quad(prim);
783            break;
784
785         default:
786            throw emu_fatalerror("Unexpected render_primitive type");
787      }
788   }
789}
790
791void renderer::end_frame()
792{
793   window().m_primlist->release_lock();
794
795   // flush any pending polygons
796   primitive_flush_pending();
797
798   m_shaders->end_frame();
799
800   // finish the scene
801   HRESULT result = (*d3dintf->device.end_scene)(m_device);
802   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result);
803
804   // present the current buffers
805   result = (*d3dintf->device.present)(m_device, NULL, NULL, NULL, NULL, 0);
806   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device present call\n", (int)result);
807}
808
809//============================================================
810//  device_create
811//============================================================
812
813int renderer::device_create(HWND device_hwnd)
814{
815   // if a device exists, free it
816   if (m_device != NULL)
817      device_delete();
818
819   // verify the caps
820   int verify = device_verify_caps();
821   if (verify == 2)
822   {
823      osd_printf_error("Error: Device does not meet minimum requirements for Direct3D rendering\n");
824      return 1;
825   }
826   if (verify == 1)
827      osd_printf_warning("Warning: Device may not perform well for Direct3D rendering\n");
828
829   // verify texture formats
830   HRESULT result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
831   if (result != D3D_OK)
832   {
833      osd_printf_error("Error: A8R8G8B8 format textures not supported\n");
834      return 1;
835   }
836
837   m_texture_manager = global_alloc(texture_manager(this));
838
839try_again:
840   // try for XRGB first
841   m_screen_format = D3DFMT_X8R8G8B8;
842   result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, m_screen_format);
843   if (result != D3D_OK)
844   {
845      // if not, try for ARGB
846      m_screen_format = D3DFMT_A8R8G8B8;
847      result = (*d3dintf->d3d.check_device_format)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, m_screen_format);
848      if (result != D3D_OK && m_texture_manager->is_dynamic_supported())
849      {
850         m_texture_manager->set_dynamic_supported(FALSE);
851         goto try_again;
852      }
853      if (result != D3D_OK)
854      {
855         osd_printf_error("Error: unable to configure a screen texture format\n");
856         return 1;
857      }
858   }
859
860   // initialize the D3D presentation parameters
861   memset(&m_presentation, 0, sizeof(m_presentation));
862   m_presentation.BackBufferWidth               = m_width;
863   m_presentation.BackBufferHeight              = m_height;
864   m_presentation.BackBufferFormat              = m_pixformat;
865   m_presentation.BackBufferCount               = video_config.triplebuf ? 2 : 1;
866   m_presentation.MultiSampleType               = D3DMULTISAMPLE_NONE;
867   m_presentation.SwapEffect                    = D3DSWAPEFFECT_DISCARD;
868   m_presentation.hDeviceWindow                 = window().m_hwnd;
869   m_presentation.Windowed                      = !window().fullscreen() || window().win_has_menu();
870   m_presentation.EnableAutoDepthStencil        = FALSE;
871   m_presentation.AutoDepthStencilFormat        = D3DFMT_D16;
872   m_presentation.Flags                         = 0;
873   m_presentation.FullScreen_RefreshRateInHz    = m_refresh;
874   m_presentation.PresentationInterval          = ((video_config.triplebuf && window().fullscreen()) ||
875                                       video_config.waitvsync || video_config.syncrefresh) ?
876                                       D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
877
878   // create the D3D device
879   result = (*d3dintf->d3d.create_device)(d3dintf, m_adapter, D3DDEVTYPE_HAL, device_hwnd,
880               D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &m_presentation, &m_device);
881   if (result != D3D_OK)
882   {
883      // if we got a "DEVICELOST" error, it may be transitory; count it and only fail if
884      // we exceed a threshold
885      if (result == D3DERR_DEVICELOST)
886      {
887         m_create_error_count++;
888         if (m_create_error_count < 10)
889         {
890            return 0;
891         }
892      }
893
894      //  fatal error if we just can't do it
895      osd_printf_error("Unable to create the Direct3D device (%08X)\n", (UINT32)result);
896      return 1;
897   }
898   m_create_error_count = 0;
899   osd_printf_verbose("Direct3D: Device created at %dx%d\n", m_width, m_height);
900
901   // set the gamma if we need to
902   if (window().fullscreen())
903   {
904      // only set the gamma if it's not 1.0f
905      windows_options &options = downcast<windows_options &>(window().machine().options());
906      float brightness = options.full_screen_brightness();
907      float contrast = options.full_screen_contrast();
908      float gamma = options.full_screen_gamma();
909      if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f)
910      {
911         // warn if we can't do it
912         if (!m_gamma_supported)
913         {
914            osd_printf_warning("Direct3D: Warning - device does not support full screen gamma correction.\n");
915         }
916         else
917         {
918            // create a standard ramp and set it
919            D3DGAMMARAMP ramp;
920            for (int i = 0; i < 256; i++)
921            {
922               ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, gamma) << 8;
923            }
924            (*d3dintf->device.set_gamma_ramp)(m_device, 0, &ramp);
925         }
926      }
927   }
928
929   int ret = m_shaders->create_resources(false);
930   if (ret != 0)
931      return ret;
932
933   return device_create_resources();
934}
935
936
937
938//============================================================
939//  device_create_resources
940//============================================================
941
942int renderer::device_create_resources()
943{
944   // allocate a vertex buffer to use
945   HRESULT result = (*d3dintf->device.create_vertex_buffer)(m_device,
946            sizeof(vertex) * VERTEX_BUFFER_SIZE,
947            D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
948            VERTEX_BASE_FORMAT | ((m_shaders->enabled() && d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW),
949            D3DPOOL_DEFAULT, &m_vertexbuf);
950   if (result != D3D_OK)
951   {
952      osd_printf_error("Error creating vertex buffer (%08X)\n", (UINT32)result);
953      return 1;
954   }
955
956   // set the vertex format
957   result = (*d3dintf->device.set_vertex_format)(m_device, (D3DFORMAT)(VERTEX_BASE_FORMAT | ((m_shaders->enabled() &&
958      d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW)));
959   if (result != D3D_OK)
960   {
961      osd_printf_error("Error setting vertex format (%08X)\n", (UINT32)result);
962      return 1;
963   }
964
965   // set the fixed render state
966   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZENABLE, D3DZB_FALSE);
967   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_FILLMODE, D3DFILL_SOLID);
968   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SHADEMODE, D3DSHADE_FLAT);
969   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZWRITEENABLE, FALSE);
970   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHATESTENABLE, TRUE);
971   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_LASTPIXEL, TRUE);
972   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_CULLMODE, D3DCULL_NONE);
973   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ZFUNC, D3DCMP_LESS);
974   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHAREF, 0);
975   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_ALPHAFUNC, D3DCMP_GREATER);
976   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_DITHERENABLE, FALSE);
977   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_FOGENABLE, FALSE);
978   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_SPECULARENABLE, FALSE);
979   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_STENCILENABLE, FALSE);
980   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_WRAP0, FALSE);
981   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_CLIPPING, TRUE);
982   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_LIGHTING, FALSE);
983   result = (*d3dintf->device.set_render_state)(m_device, D3DRS_COLORVERTEX, TRUE);
984
985   result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
986   result = (*d3dintf->device.set_texture_stage_state)(m_device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
987   result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
988   result = (*d3dintf->device.set_texture_stage_state)(m_device, 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
989
990   // reset the local states to force updates
991   reset_render_states();
992
993   // clear the buffer
994   result = (*d3dintf->device.clear)(m_device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
995   result = (*d3dintf->device.present)(m_device, NULL, NULL, NULL, NULL, 0);
996
997   m_texture_manager->create_resources();
998
999   return 0;
1000}
1001
1002
1003
1004//============================================================
1005//  device_delete
1006//============================================================
1007
1008renderer::~renderer()
1009{
1010   device_delete();
1011}
1012
1013void renderer::device_delete()
1014{
1015   if (m_shaders != NULL)
1016   {
1017      // free our effects
1018      m_shaders->delete_resources(false);
1019
1020      // delete the HLSL interface
1021      global_free(m_shaders);
1022   }
1023
1024   // free our base resources
1025   device_delete_resources();
1026
1027   if (m_texture_manager != NULL)
1028   {
1029      global_free(m_texture_manager);
1030   }
1031   m_texture_manager = NULL;
1032
1033   // free the device itself
1034   if (m_device != NULL)
1035   {
1036      (*d3dintf->device.reset)(m_device, &m_presentation);
1037      (*d3dintf->device.release)(m_device);
1038   }
1039   m_device = NULL;
1040}
1041
1042//============================================================
1043//  device_delete_resources
1044//============================================================
1045
1046void renderer::device_delete_resources()
1047{
1048   if (m_texture_manager != NULL)
1049      m_texture_manager->delete_resources();
1050   // free the vertex buffer
1051   if (m_vertexbuf != NULL)
1052      (*d3dintf->vertexbuf.release)(m_vertexbuf);
1053   m_vertexbuf = NULL;
1054}
1055
1056
1057
1058//============================================================
1059//  device_verify_caps
1060//============================================================
1061
1062int renderer::device_verify_caps()
1063{
1064   int retval = 0;
1065
1066   m_shaders = global_alloc_clear(shaders);
1067   // FIXME: Dynamic cast
1068   m_shaders->init(d3dintf, &window().machine(), this);
1069
1070   DWORD tempcaps;
1071   HRESULT result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_MAX_PS30_INSN_SLOTS, &tempcaps);
1072   if (result != D3D_OK) osd_printf_verbose("Direct3D Error %08X during get_caps_dword call\n", (int)result);
1073   if (tempcaps < 512)
1074   {
1075      osd_printf_verbose("Direct3D: Warning - Device does not support Pixel Shader 3.0, falling back to non-PS rendering\n");
1076      d3dintf->post_fx_available = false;
1077   }
1078
1079   // verify presentation capabilities
1080   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_PRESENTATION_INTERVALS, &tempcaps);
1081   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
1082   if (!(tempcaps & D3DPRESENT_INTERVAL_IMMEDIATE))
1083   {
1084      osd_printf_verbose("Direct3D: Error - Device does not support immediate presentations\n");
1085      retval = 2;
1086   }
1087   if (!(tempcaps & D3DPRESENT_INTERVAL_ONE))
1088   {
1089      osd_printf_verbose("Direct3D: Error - Device does not support per-refresh presentations\n");
1090      retval = 2;
1091   }
1092
1093   // verify device capabilities
1094   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_DEV_CAPS, &tempcaps);
1095   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
1096   if (!(tempcaps & D3DDEVCAPS_CANRENDERAFTERFLIP))
1097   {
1098      osd_printf_verbose("Direct3D: Warning - Device does not support queued rendering after a page flip\n");
1099      retval = 1;
1100   }
1101   if (!(tempcaps & D3DDEVCAPS_HWRASTERIZATION))
1102   {
1103      osd_printf_verbose("Direct3D: Warning - Device does not support hardware rasterization\n");
1104      retval = 1;
1105   }
1106
1107   // verify texture operation capabilities
1108   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_TEXTURE_OP_CAPS, &tempcaps);
1109   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
1110   if (!(tempcaps & D3DTEXOPCAPS_MODULATE))
1111   {
1112      osd_printf_verbose("Direct3D: Warning - Device does not support texture modulation\n");
1113      retval = 1;
1114   }
1115
1116   // set a simpler flag to indicate mod2x and mod4x texture modes
1117   m_mod2x_supported = ((tempcaps & D3DTEXOPCAPS_MODULATE2X) != 0);
1118   m_mod4x_supported = ((tempcaps & D3DTEXOPCAPS_MODULATE4X) != 0);
1119
1120   result = (*d3dintf->d3d.get_caps_dword)(d3dintf, m_adapter, D3DDEVTYPE_HAL, CAPS_CAPS2, &tempcaps);
1121   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
1122   m_gamma_supported = ((tempcaps & D3DCAPS2_FULLSCREENGAMMA) != 0);
1123
1124   return retval;
1125}
1126
1127
1128
1129//============================================================
1130//  device_test_cooperative
1131//============================================================
1132
1133int renderer::device_test_cooperative()
1134{
1135   // check our current status; if we lost the device, punt to GDI
1136   HRESULT result = (*d3dintf->device.test_cooperative_level)(m_device);
1137   if (result == D3DERR_DEVICELOST)
1138      return 1;
1139
1140   // if we're able to reset ourselves, try it
1141   if (result == D3DERR_DEVICENOTRESET)
1142   {
1143      osd_printf_verbose("Direct3D: resetting device\n");
1144
1145      // free all existing resources and call reset on the device
1146      //device_delete();
1147      device_delete_resources();
1148      m_shaders->delete_resources(true);
1149      result = (*d3dintf->device.reset)(m_device, &m_presentation);
1150
1151      // if it didn't work, punt to GDI
1152      if (result != D3D_OK)
1153      {
1154         osd_printf_error("Unable to reset, result %08x\n", (UINT32)result);
1155         return 1;
1156      }
1157
1158      // try to create the resources again; if that didn't work, delete the whole thing
1159      if (device_create_resources())
1160      {
1161         osd_printf_verbose("Direct3D: failed to recreate resources for device; failing permanently\n");
1162         device_delete();
1163         return 1;
1164      }
1165
1166      if (m_shaders->create_resources(true))
1167      {
1168         osd_printf_verbose("Direct3D: failed to recreate HLSL resources for device; failing permanently\n");
1169         device_delete();
1170         return 1;
1171      }
1172   }
1173   return 0;
1174}
1175
1176
1177
1178//============================================================
1179//  config_adapter_mode
1180//============================================================
1181
1182int renderer::config_adapter_mode()
1183{
1184   adapter_identifier identifier;
1185
1186   // choose the monitor number
1187   m_adapter = get_adapter_for_monitor();
1188
1189   // get the identifier
1190   HRESULT result = (*d3dintf->d3d.get_adapter_identifier)(d3dintf, m_adapter, 0, &identifier);
1191   if (result != D3D_OK)
1192   {
1193      osd_printf_error("Error getting identifier for adapter #%d\n", m_adapter);
1194      return 1;
1195   }
1196   osd_printf_verbose("Direct3D: Configuring adapter #%d = %s\n", m_adapter, identifier.Description);
1197
1198   // get the current display mode
1199   result = (*d3dintf->d3d.get_adapter_display_mode)(d3dintf, m_adapter, &m_origmode);
1200   if (result != D3D_OK)
1201   {
1202      osd_printf_error("Error getting mode for adapter #%d\n", m_adapter);
1203      return 1;
1204   }
1205
1206   // choose a resolution: window mode case
1207   if (!window().fullscreen() || !video_config.switchres || window().win_has_menu())
1208   {
1209      RECT client;
1210
1211      // bounds are from the window client rect
1212      GetClientRectExceptMenu(window().m_hwnd, &client, window().fullscreen());
1213      m_width = client.right - client.left;
1214      m_height = client.bottom - client.top;
1215
1216      // pix format is from the current mode
1217      m_pixformat = m_origmode.Format;
1218      m_refresh = 0;
1219
1220      // make sure it's a pixel format we can get behind
1221      if (m_pixformat != D3DFMT_X1R5G5B5 && m_pixformat != D3DFMT_R5G6B5 && m_pixformat != D3DFMT_X8R8G8B8)
1222      {
1223         osd_printf_error("Device %s currently in an unsupported mode\n", window().monitor()->devicename());
1224         return 1;
1225      }
1226   }
1227
1228   // choose a resolution: full screen mode case
1229   else
1230   {
1231      // default to the current mode exactly
1232      m_width = m_origmode.Width;
1233      m_height = m_origmode.Height;
1234      m_pixformat = m_origmode.Format;
1235      m_refresh = m_origmode.RefreshRate;
1236
1237      // if we're allowed to switch resolutions, override with something better
1238      if (video_config.switchres)
1239         pick_best_mode();
1240   }
1241
1242   // see if we can handle the device type
1243   result = (*d3dintf->d3d.check_device_type)(d3dintf, m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !window().fullscreen());
1244   if (result != D3D_OK)
1245   {
1246      osd_printf_error("Proposed video mode not supported on device %s\n", window().monitor()->devicename());
1247      return 1;
1248   }
1249   return 0;
1250}
1251
1252
1253
1254//============================================================
1255//  get_adapter_for_monitor
1256//============================================================
1257
1258int renderer::get_adapter_for_monitor()
1259{
1260   int maxadapter = (*d3dintf->d3d.get_adapter_count)(d3dintf);
1261
1262   // iterate over adapters until we error or find a match
1263   for (int adapternum = 0; adapternum < maxadapter; adapternum++)
1264   {
1265      // get the monitor for this adapter
1266      HMONITOR curmonitor = (*d3dintf->d3d.get_adapter_monitor)(d3dintf, adapternum);
1267
1268      // if we match the proposed monitor, this is it
1269      if (curmonitor == window().monitor()->handle())
1270      {
1271         return adapternum;
1272      }
1273   }
1274
1275   // default to the default
1276   return D3DADAPTER_DEFAULT;
1277}
1278
1279
1280
1281//============================================================
1282//  pick_best_mode
1283//============================================================
1284
1285void renderer::pick_best_mode()
1286{
1287   double target_refresh = 60.0;
1288   INT32 minwidth, minheight;
1289   float best_score = 0.0f;
1290
1291   // determine the refresh rate of the primary screen
1292   const screen_device *primary_screen = window().machine().config().first_screen();
1293   if (primary_screen != NULL)
1294   {
1295      target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
1296   }
1297
1298   // determine the minimum width/height for the selected target
1299   // note: technically we should not be calling this from an alternate window
1300   // thread; however, it is only done during init time, and the init code on
1301   // the main thread is waiting for us to finish, so it is safe to do so here
1302   window().target()->compute_minimum_size(minwidth, minheight);
1303
1304   // use those as the target for now
1305   INT32 target_width = minwidth;
1306   INT32 target_height = minheight;
1307
1308   // determine the maximum number of modes
1309   int maxmodes = (*d3dintf->d3d.get_adapter_mode_count)(d3dintf, m_adapter, D3DFMT_X8R8G8B8);
1310
1311   // enumerate all the video modes and find the best match
1312   osd_printf_verbose("Direct3D: Selecting video mode...\n");
1313   for (int modenum = 0; modenum < maxmodes; modenum++)
1314   {
1315      // check this mode
1316      D3DDISPLAYMODE mode;
1317      HRESULT result = (*d3dintf->d3d.enum_adapter_modes)(d3dintf, m_adapter, D3DFMT_X8R8G8B8, modenum, &mode);
1318      if (result != D3D_OK)
1319         break;
1320
1321      // skip non-32 bit modes
1322      if (mode.Format != D3DFMT_X8R8G8B8)
1323         continue;
1324
1325      // compute initial score based on difference between target and current
1326      float size_score = 1.0f / (1.0f + fabs((float)(mode.Width - target_width)) + fabs((float)(mode.Height - target_height)));
1327
1328      // if the mode is too small, give a big penalty
1329      if (mode.Width < minwidth || mode.Height < minheight)
1330         size_score *= 0.01f;
1331
1332      // if mode is smaller than we'd like, it only scores up to 0.1
1333      if (mode.Width < target_width || mode.Height < target_height)
1334         size_score *= 0.1f;
1335
1336      // if we're looking for a particular mode, that's a winner
1337      if (mode.Width == window().m_win_config.width && mode.Height == window().m_win_config.height)
1338         size_score = 2.0f;
1339
1340      // compute refresh score
1341      float refresh_score = 1.0f / (1.0f + fabs((double)mode.RefreshRate - target_refresh));
1342
1343      // if refresh is smaller than we'd like, it only scores up to 0.1
1344      if ((double)mode.RefreshRate < target_refresh)
1345         refresh_score *= 0.1f;
1346
1347      // if we're looking for a particular refresh, make sure it matches
1348      if (mode.RefreshRate == window().m_win_config.refresh)
1349         refresh_score = 2.0f;
1350
1351      // weight size and refresh equally
1352      float final_score = size_score + refresh_score;
1353
1354      // best so far?
1355      osd_printf_verbose("  %4dx%4d@%3dHz -> %f\n", mode.Width, mode.Height, mode.RefreshRate, final_score * 1000.0f);
1356      if (final_score > best_score)
1357      {
1358         best_score = final_score;
1359         m_width = mode.Width;
1360         m_height = mode.Height;
1361         m_pixformat = mode.Format;
1362         m_refresh = mode.RefreshRate;
1363      }
1364   }
1365   osd_printf_verbose("Direct3D: Mode selected = %4dx%4d@%3dHz\n", m_width, m_height, m_refresh);
1366}
1367
1368
1369
1370//============================================================
1371//  update_window_size
1372//============================================================
1373
1374int renderer::update_window_size()
1375{
1376   // get the current window bounds
1377   RECT client;
1378   GetClientRectExceptMenu(window().m_hwnd, &client, window().fullscreen());
1379
1380   // if we have a device and matching width/height, nothing to do
1381   if (m_device != NULL && rect_width(&client) == m_width && rect_height(&client) == m_height)
1382   {
1383      // clear out any pending resizing if the area didn't change
1384      if (window().m_resize_state == RESIZE_STATE_PENDING)
1385         window().m_resize_state = RESIZE_STATE_NORMAL;
1386      return FALSE;
1387   }
1388
1389   // if we're in the middle of resizing, leave it alone as well
1390   if (window().m_resize_state == RESIZE_STATE_RESIZING)
1391      return FALSE;
1392
1393   // set the new bounds and create the device again
1394   m_width = rect_width(&client);
1395   m_height = rect_height(&client);
1396   if (device_create(window().m_focus_hwnd))
1397      return FALSE;
1398
1399   // reset the resize state to normal, and indicate we made a change
1400   window().m_resize_state = RESIZE_STATE_NORMAL;
1401   return TRUE;
1402}
1403
1404//============================================================
1405//  batch_vectors
1406//============================================================
1407
1408void renderer::batch_vectors()
1409{
1410   windows_options &options = downcast<windows_options &>(window().machine().options());
1411
1412   int vector_size = (options.antialias() ? 24 : 6);
1413   m_vectorbatch = mesh_alloc(m_line_count * vector_size);
1414   m_batchindex = 0;
1415
1416   static int start_index = 0;
1417   int line_index = 0;
1418   float period = options.screen_vector_time_period();
1419   UINT32 cached_flags = 0;
1420   for (render_primitive *prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
1421   {
1422      switch (prim->type)
1423      {
1424         case render_primitive::LINE:
1425            if (PRIMFLAG_GET_VECTOR(prim->flags))
1426            {
1427               if (period == 0.0f || m_line_count == 0)
1428               {
1429                  batch_vector(prim, 1.0f);
1430               }
1431               else
1432               {
1433                  batch_vector(prim, (float)(start_index + line_index) / ((float)m_line_count * period));
1434                  line_index++;
1435               }
1436               cached_flags = prim->flags;
1437            }
1438            break;
1439
1440         default:
1441            // Skip
1442            break;
1443      }
1444   }
1445
1446   // now add a polygon entry
1447   m_poly[m_numpolys].init(D3DPT_TRIANGLELIST, m_line_count * (options.antialias() ? 8 : 2), vector_size * m_line_count, cached_flags,
1448      m_texture_manager->get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f);
1449   m_numpolys++;
1450
1451   start_index += (int)((float)line_index * period);
1452   if (m_line_count > 0)
1453   {
1454      start_index %= m_line_count;
1455   }
1456
1457   m_line_count = 0;
1458}
1459
1460void renderer::batch_vector(const render_primitive *prim, float line_time)
1461{
1462   // compute the effective width based on the direction of the line
1463   float effwidth = prim->width;
1464   if (effwidth < 0.5f)
1465   {
1466      effwidth = 0.5f;
1467   }
1468
1469   // determine the bounds of a quad to draw this line
1470   render_bounds b0, b1;
1471   render_line_to_quad(&prim->bounds, effwidth, &b0, &b1);
1472
1473   // iterate over AA steps
1474   for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step;
1475      step->weight != 0; step++)
1476   {
1477      // get a pointer to the vertex buffer
1478      if (m_vectorbatch == NULL)
1479         return;
1480
1481      m_vectorbatch[m_batchindex + 0].x = b0.x0 + step->xoffs;
1482      m_vectorbatch[m_batchindex + 0].y = b0.y0 + step->yoffs;
1483      m_vectorbatch[m_batchindex + 1].x = b0.x1 + step->xoffs;
1484      m_vectorbatch[m_batchindex + 1].y = b0.y1 + step->yoffs;
1485      m_vectorbatch[m_batchindex + 2].x = b1.x0 + step->xoffs;
1486      m_vectorbatch[m_batchindex + 2].y = b1.y0 + step->yoffs;
1487
1488      m_vectorbatch[m_batchindex + 3].x = b0.x1 + step->xoffs;
1489      m_vectorbatch[m_batchindex + 3].y = b0.y1 + step->yoffs;
1490      m_vectorbatch[m_batchindex + 4].x = b1.x0 + step->xoffs;
1491      m_vectorbatch[m_batchindex + 4].y = b1.y0 + step->yoffs;
1492      m_vectorbatch[m_batchindex + 5].x = b1.x1 + step->xoffs;
1493      m_vectorbatch[m_batchindex + 5].y = b1.y1 + step->yoffs;
1494
1495      float dx = b1.x1 - b0.x1;
1496      float dy = b1.y1 - b0.y1;
1497      float line_length = sqrtf(dx * dx + dy * dy);
1498
1499      // determine the color of the line
1500      INT32 r = (INT32)(prim->color.r * step->weight * 255.0f);
1501      INT32 g = (INT32)(prim->color.g * step->weight * 255.0f);
1502      INT32 b = (INT32)(prim->color.b * step->weight * 255.0f);
1503      INT32 a = (INT32)(prim->color.a * 255.0f);
1504      if (r > 255 || g > 255 || b > 255)
1505      {
1506         if (r > 2*255 || g > 2*255 || b > 2*255)
1507         {
1508            r >>= 2; g >>= 2; b >>= 2;
1509         }
1510         else
1511         {
1512            r >>= 1; g >>= 1; b >>= 1;
1513         }
1514      }
1515      if (r > 255) r = 255;
1516      if (g > 255) g = 255;
1517      if (b > 255) b = 255;
1518      if (a > 255) a = 255;
1519      DWORD color = D3DCOLOR_ARGB(a, r, g, b);
1520
1521      vec2f& start = (get_vector_texture() ? get_vector_texture()->get_uvstart() : get_default_texture()->get_uvstart());
1522      vec2f& stop = (get_vector_texture() ? get_vector_texture()->get_uvstop() : get_default_texture()->get_uvstop());
1523
1524      m_vectorbatch[m_batchindex + 0].u0 = start.c.x;
1525      m_vectorbatch[m_batchindex + 0].v0 = start.c.y;
1526      m_vectorbatch[m_batchindex + 1].u0 = start.c.x;
1527      m_vectorbatch[m_batchindex + 1].v0 = stop.c.y;
1528      m_vectorbatch[m_batchindex + 2].u0 = stop.c.x;
1529      m_vectorbatch[m_batchindex + 2].v0 = start.c.y;
1530
1531      m_vectorbatch[m_batchindex + 3].u0 = start.c.x;
1532      m_vectorbatch[m_batchindex + 3].v0 = stop.c.y;
1533      m_vectorbatch[m_batchindex + 4].u0 = stop.c.x;
1534      m_vectorbatch[m_batchindex + 4].v0 = start.c.y;
1535      m_vectorbatch[m_batchindex + 5].u0 = stop.c.x;
1536      m_vectorbatch[m_batchindex + 5].v0 = stop.c.y;
1537
1538      m_vectorbatch[m_batchindex + 0].u1 = line_length;
1539      m_vectorbatch[m_batchindex + 1].u1 = line_length;
1540      m_vectorbatch[m_batchindex + 2].u1 = line_length;
1541      m_vectorbatch[m_batchindex + 3].u1 = line_length;
1542      m_vectorbatch[m_batchindex + 4].u1 = line_length;
1543      m_vectorbatch[m_batchindex + 5].u1 = line_length;
1544
1545      // set the color, Z parameters to standard values
1546      for (int i = 0; i < 6; i++)
1547      {
1548         m_vectorbatch[m_batchindex + i].z = 0.0f;
1549         m_vectorbatch[m_batchindex + i].rhw = 1.0f;
1550         m_vectorbatch[m_batchindex + i].color = color;
1551      }
1552
1553      m_batchindex += 6;
1554   }
1555}
1556
1557//============================================================
1558//  draw_line
1559//============================================================
1560
1561void renderer::draw_line(const render_primitive *prim)
1562{
1563   // compute the effective width based on the direction of the line
1564   float effwidth = prim->width;
1565   if (effwidth < 0.5f)
1566   {
1567      effwidth = 0.5f;
1568   }
1569
1570   // determine the bounds of a quad to draw this line
1571   render_bounds b0, b1;
1572   render_line_to_quad(&prim->bounds, effwidth, &b0, &b1);
1573
1574   // iterate over AA steps
1575   for (const line_aa_step *step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step;
1576      step->weight != 0; step++)
1577   {
1578      // get a pointer to the vertex buffer
1579      vertex *vertex = mesh_alloc(4);
1580      if (vertex == NULL)
1581         return;
1582
1583      // rotate the unit vector by 135 degrees and add to point 0
1584      vertex[0].x = b0.x0 + step->xoffs;
1585      vertex[0].y = b0.y0 + step->yoffs;
1586
1587      // rotate the unit vector by -135 degrees and add to point 0
1588      vertex[1].x = b0.x1 + step->xoffs;
1589      vertex[1].y = b0.y1 + step->yoffs;
1590
1591      // rotate the unit vector by 45 degrees and add to point 1
1592      vertex[2].x = b1.x0 + step->xoffs;
1593      vertex[2].y = b1.y0 + step->yoffs;
1594
1595      // rotate the unit vector by -45 degrees and add to point 1
1596      vertex[3].x = b1.x1 + step->xoffs;
1597      vertex[3].y = b1.y1 + step->yoffs;
1598
1599      // determine the color of the line
1600      INT32 r = (INT32)(prim->color.r * step->weight * 255.0f);
1601      INT32 g = (INT32)(prim->color.g * step->weight * 255.0f);
1602      INT32 b = (INT32)(prim->color.b * step->weight * 255.0f);
1603      INT32 a = (INT32)(prim->color.a * 255.0f);
1604      if (r > 255) r = 255;
1605      if (g > 255) g = 255;
1606      if (b > 255) b = 255;
1607      if (a > 255) a = 255;
1608      DWORD color = D3DCOLOR_ARGB(a, r, g, b);
1609
1610      vec2f& start = (get_vector_texture() ? get_vector_texture()->get_uvstart() : get_default_texture()->get_uvstart());
1611      vec2f& stop = (get_vector_texture() ? get_vector_texture()->get_uvstop() : get_default_texture()->get_uvstop());
1612
1613      vertex[0].u0 = start.c.x;
1614      vertex[0].v0 = start.c.y;
1615
1616      vertex[2].u0 = stop.c.x;
1617      vertex[2].v0 = start.c.y;
1618
1619      vertex[1].u0 = start.c.x;
1620      vertex[1].v0 = stop.c.y;
1621
1622      vertex[3].u0 = stop.c.x;
1623      vertex[3].v0 = stop.c.y;
1624
1625      // set the color, Z parameters to standard values
1626      for (int i = 0; i < 4; i++)
1627      {
1628         vertex[i].z = 0.0f;
1629         vertex[i].rhw = 1.0f;
1630         vertex[i].color = color;
1631      }
1632
1633      // now add a polygon entry
1634      m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim->flags, get_vector_texture(),
1635                        D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f);
1636      m_numpolys++;
1637   }
1638}
1639
1640
1641
1642//============================================================
1643//  draw_quad
1644//============================================================
1645
1646void renderer::draw_quad(const render_primitive *prim)
1647{
1648   texture_info *texture = m_texture_manager->find_texinfo(&prim->texture, prim->flags);
1649
1650   if (texture == NULL)
1651   {
1652      texture = get_default_texture();
1653   }
1654
1655   // get a pointer to the vertex buffer
1656   vertex *vertex = mesh_alloc(4);
1657   if (vertex == NULL)
1658      return;
1659
1660   // fill in the vertexes clockwise
1661   vertex[0].x = prim->bounds.x0 - 0.5f;
1662   vertex[0].y = prim->bounds.y0 - 0.5f;
1663   vertex[1].x = prim->bounds.x1 - 0.5f;
1664   vertex[1].y = prim->bounds.y0 - 0.5f;
1665   vertex[2].x = prim->bounds.x0 - 0.5f;
1666   vertex[2].y = prim->bounds.y1 - 0.5f;
1667   vertex[3].x = prim->bounds.x1 - 0.5f;
1668   vertex[3].y = prim->bounds.y1 - 0.5f;
1669   float width = prim->bounds.x1 - prim->bounds.x0;
1670   float height = prim->bounds.y1 - prim->bounds.y0;
1671
1672   // set the texture coordinates
1673   if(texture != NULL)
1674   {
1675      vec2f& start = texture->get_uvstart();
1676      vec2f& stop = texture->get_uvstop();
1677      vec2f delta = stop - start;
1678      vertex[0].u0 = start.c.x + delta.c.x * prim->texcoords.tl.u;
1679      vertex[0].v0 = start.c.y + delta.c.y * prim->texcoords.tl.v;
1680      vertex[1].u0 = start.c.x + delta.c.x * prim->texcoords.tr.u;
1681      vertex[1].v0 = start.c.y + delta.c.y * prim->texcoords.tr.v;
1682      vertex[2].u0 = start.c.x + delta.c.x * prim->texcoords.bl.u;
1683      vertex[2].v0 = start.c.y + delta.c.y * prim->texcoords.bl.v;
1684      vertex[3].u0 = start.c.x + delta.c.x * prim->texcoords.br.u;
1685      vertex[3].v0 = start.c.y + delta.c.y * prim->texcoords.br.v;
1686   }
1687
1688   // determine the color, allowing for over modulation
1689   INT32 r = (INT32)(prim->color.r * 255.0f);
1690   INT32 g = (INT32)(prim->color.g * 255.0f);
1691   INT32 b = (INT32)(prim->color.b * 255.0f);
1692   INT32 a = (INT32)(prim->color.a * 255.0f);
1693   DWORD modmode = D3DTOP_MODULATE;
1694   if (texture != NULL)
1695   {
1696      if (m_mod2x_supported && (r > 255 || g > 255 || b > 255))
1697      {
1698         if (m_mod4x_supported && (r > 2*255 || g > 2*255 || b > 2*255))
1699         {
1700            r >>= 2; g >>= 2; b >>= 2;
1701            modmode = D3DTOP_MODULATE4X;
1702         }
1703         else
1704         {
1705            r >>= 1; g >>= 1; b >>= 1;
1706            modmode = D3DTOP_MODULATE2X;
1707         }
1708      }
1709   }
1710   if (r > 255) r = 255;
1711   if (g > 255) g = 255;
1712   if (b > 255) b = 255;
1713   if (a > 255) a = 255;
1714   DWORD color = D3DCOLOR_ARGB(a, r, g, b);
1715
1716   // set the color, Z parameters to standard values
1717   for (int i = 0; i < 4; i++)
1718   {
1719      vertex[i].z = 0.0f;
1720      vertex[i].rhw = 1.0f;
1721      vertex[i].color = color;
1722   }
1723
1724   // now add a polygon entry
1725   m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim->flags, texture, modmode, width, height);
1726   m_numpolys++;
1727}
1728
1729void poly_info::init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
1730                     UINT32 flags, texture_info *texture, UINT32 modmode,
1731                     float line_time, float line_length,
1732                     float prim_width, float prim_height)
1733{
1734   init(type, count, numverts, flags, texture, modmode, prim_width, prim_height);
1735   m_line_time = line_time;
1736   m_line_length = line_length;
1737}
1738
1739void poly_info::init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts,
1740                     UINT32 flags, texture_info *texture, UINT32 modmode,
1741                     float prim_width, float prim_height)
1742{
1743   m_type = type;
1744   m_count = count;
1745   m_numverts = numverts;
1746   m_flags = flags;
1747   m_texture = texture;
1748   m_modmode = modmode;
1749   m_prim_width = prim_width;
1750   m_prim_height = prim_height;
1751}
1752
1753//============================================================
1754//  primitive_alloc
1755//============================================================
1756
1757vertex *renderer::mesh_alloc(int numverts)
1758{
1759   HRESULT result;
1760
1761   // if we're going to overflow, flush
1762   if (m_lockedbuf != NULL && m_numverts + numverts >= VERTEX_BUFFER_SIZE)
1763   {
1764      primitive_flush_pending();
1765
1766      if(m_shaders->enabled())
1767      {
1768         m_hlsl_buf = (void*)mesh_alloc(6);
1769         m_shaders->init_fsfx_quad(m_hlsl_buf);
1770      }
1771   }
1772
1773   // if we don't have a lock, grab it now
1774   if (m_lockedbuf == NULL)
1775   {
1776      result = (*d3dintf->vertexbuf.lock)(m_vertexbuf, 0, 0, (VOID **)&m_lockedbuf, D3DLOCK_DISCARD);
1777      if (result != D3D_OK)
1778         return NULL;
1779   }
1780
1781   // if we already have the lock and enough room, just return a pointer
1782   if (m_lockedbuf != NULL && m_numverts + numverts < VERTEX_BUFFER_SIZE)
1783   {
1784      int oldverts = m_numverts;
1785      m_numverts += numverts;
1786      return &m_lockedbuf[oldverts];
1787   }
1788   return NULL;
1789}
1790
1791
1792
1793//============================================================
1794//  primitive_flush_pending
1795//============================================================
1796
1797void renderer::primitive_flush_pending()
1798{
1799   // ignore if we're not locked
1800   if (m_lockedbuf == NULL)
1801   {
1802      return;
1803   }
1804
1805   // unlock the buffer
1806   HRESULT result = (*d3dintf->vertexbuf.unlock)(m_vertexbuf);
1807   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result);
1808   m_lockedbuf = NULL;
1809
1810   // set the stream
1811   result = (*d3dintf->device.set_stream_source)(m_device, 0, m_vertexbuf, sizeof(vertex));
1812   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_stream_source call\n", (int)result);
1813
1814   m_shaders->begin_draw();
1815
1816   int vertnum = 0;
1817   if (m_shaders->enabled())
1818   {
1819      vertnum = 6;
1820   }
1821
1822   // now do the polys
1823   for (int polynum = 0; polynum < m_numpolys; polynum++)
1824   {
1825      UINT32 flags = m_poly[polynum].get_flags();
1826      texture_info *texture = m_poly[polynum].get_texture();
1827      int newfilter;
1828
1829      // set the texture if different
1830      set_texture(texture);
1831
1832      // set filtering if different
1833      if (texture != NULL)
1834      {
1835         newfilter = FALSE;
1836         if (PRIMFLAG_GET_SCREENTEX(flags))
1837            newfilter = video_config.filter;
1838         set_filter(newfilter);
1839         set_wrap(PRIMFLAG_GET_TEXWRAP(flags) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
1840         set_modmode(m_poly[polynum].get_modmode());
1841
1842         m_shaders->init_effect_info(&m_poly[polynum]);
1843      }
1844
1845      // set the blendmode if different
1846      set_blendmode(PRIMFLAG_GET_BLENDMODE(flags));
1847
1848      if (vertnum + m_poly[polynum].get_vertcount() > m_numverts)
1849      {
1850         osd_printf_error("Error: vertnum (%d) plus poly vertex count (%d) > %d\n", vertnum, m_poly[polynum].get_vertcount(), m_numverts);
1851         fflush(stdout);
1852      }
1853
1854      assert(vertnum + m_poly[polynum].get_vertcount() <= m_numverts);
1855
1856      if(m_shaders->enabled() && d3dintf->post_fx_available)
1857      {
1858         m_shaders->render_quad(&m_poly[polynum], vertnum);
1859      }
1860      else
1861      {
1862         // add the primitives
1863         result = (*d3dintf->device.draw_primitive)(m_device, m_poly[polynum].get_type(), vertnum,
1864                                          m_poly[polynum].get_count());
1865         if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
1866      }
1867
1868      vertnum += m_poly[polynum].get_vertcount();
1869   }
1870
1871   m_shaders->end_draw();
1872
1873   // reset the vertex count
1874   m_numverts = 0;
1875   m_numpolys = 0;
1876}
1877
1878//============================================================
1879//  texture_info destructor
1880//============================================================
1881
1882texture_info::~texture_info()
1883{
1884   if (m_d3dfinaltex != NULL)
1885   {
1886      if (m_d3dtex == m_d3dfinaltex)
1887      {
1888         m_d3dtex = NULL;
1889      }
1890      (*d3dintf->texture.release)(m_d3dfinaltex);
1891      m_d3dfinaltex = NULL;
1892   }
1893   if (m_d3dtex != NULL)
1894   {
1895      (*d3dintf->texture.release)(m_d3dtex);
1896      m_d3dtex = NULL;
1897   }
1898   if (m_d3dsurface != NULL)
1899   {
1900      (*d3dintf->surface.release)(m_d3dsurface);
1901      m_d3dsurface = NULL;
1902   }
1903}
1904
1905//============================================================
1906//  texture_info constructor
1907//============================================================
1908
1909texture_info::texture_info(texture_manager *manager, const render_texinfo* texsource, int prescale, UINT32 flags)
1910{
1911   HRESULT result;
1912
1913   // fill in the core data
1914   m_texture_manager = manager;
1915   m_renderer = m_texture_manager->get_d3d();
1916   m_hash = m_texture_manager->texture_compute_hash(texsource, flags);
1917   m_flags = flags;
1918   m_texinfo = *texsource;
1919   m_xprescale = prescale;
1920   m_yprescale = prescale;
1921
1922   m_d3dtex = NULL;
1923   m_d3dsurface = NULL;
1924   m_d3dfinaltex = NULL;
1925
1926   // compute the size
1927   compute_size(texsource->width, texsource->height);
1928
1929   // non-screen textures are easy
1930   if (!PRIMFLAG_GET_SCREENTEX(flags))
1931   {
1932      assert(PRIMFLAG_TEXFORMAT(flags) != TEXFORMAT_YUY16);
1933      result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex);
1934      if (result != D3D_OK)
1935         goto error;
1936      m_d3dfinaltex = m_d3dtex;
1937      m_type = TEXTURE_TYPE_PLAIN;
1938   }
1939
1940   // screen textures are allocated differently
1941   else
1942   {
1943      D3DFORMAT format;
1944      DWORD usage = m_texture_manager->is_dynamic_supported() ? D3DUSAGE_DYNAMIC : 0;
1945      D3DPOOL pool = m_texture_manager->is_dynamic_supported() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
1946      int maxdim = MAX(m_renderer->get_presentation()->BackBufferWidth, m_renderer->get_presentation()->BackBufferHeight);
1947
1948      // pick the format
1949      if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_YUY16)
1950      {
1951         format = m_texture_manager->get_yuv_format();
1952      }
1953      else if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_PALETTEA16)
1954      {
1955         format = D3DFMT_A8R8G8B8;
1956      }
1957      else
1958      {
1959         format = m_renderer->get_screen_format();
1960      }
1961
1962      // don't prescale above screen size
1963      while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale >= 2 * maxdim)
1964      {
1965         m_xprescale--;
1966      }
1967      while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale > manager->get_max_texture_width())
1968      {
1969         m_xprescale--;
1970      }
1971      while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale >= 2 * maxdim)
1972      {
1973         m_yprescale--;
1974      }
1975      while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale > manager->get_max_texture_height())
1976      {
1977         m_yprescale--;
1978      }
1979
1980      int prescale = m_renderer->window().prescale();
1981      if (m_xprescale != prescale || m_yprescale != prescale)
1982      {
1983         osd_printf_verbose("Direct3D: adjusting prescale from %dx%d to %dx%d\n", prescale, prescale, m_xprescale, m_yprescale);
1984      }
1985
1986      // loop until we allocate something or error
1987      for (int attempt = 0; attempt < 2; attempt++)
1988      {
1989         // second attempt is always 1:1
1990         if (attempt == 1)
1991         {
1992            m_xprescale = m_yprescale = 1;
1993         }
1994
1995         // screen textures with no prescaling are pretty easy
1996         if (m_xprescale == 1 && m_yprescale == 1)
1997         {
1998            result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex);
1999            if (result == D3D_OK)
2000            {
2001               m_d3dfinaltex = m_d3dtex;
2002               m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
2003               if (m_renderer->get_shaders()->enabled() && !m_renderer->get_shaders()->register_texture(this))
2004               {
2005                  goto error;
2006               }
2007
2008               break;
2009            }
2010         }
2011
2012         // screen textures with prescaling require two allocations
2013         else
2014         {
2015            // use an offscreen plain surface for stretching if supported
2016            // (won't work for YUY textures)
2017            if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16)
2018            {
2019               result = (*d3dintf->device.create_offscreen_plain_surface)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, format, D3DPOOL_DEFAULT, &m_d3dsurface);
2020               if (result != D3D_OK)
2021               {
2022                  continue;
2023               }
2024               m_type = TEXTURE_TYPE_SURFACE;
2025            }
2026
2027            // otherwise, we allocate a dynamic texture for the source
2028            else
2029            {
2030               result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex);
2031               if (result != D3D_OK)
2032               {
2033                  continue;
2034               }
2035               m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
2036            }
2037
2038            // for the target surface, we allocate a render target texture
2039            int scwidth = m_rawdims.c.x * m_xprescale;
2040            int scheight = m_rawdims.c.y * m_yprescale;
2041
2042            // target surfaces typically cannot be YCbCr, so we always pick RGB in that case
2043            D3DFORMAT finalfmt = (format != m_texture_manager->get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
2044            result = (*d3dintf->device.create_texture)(m_renderer->get_device(), scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex);
2045            if (result == D3D_OK)
2046            {
2047               if (m_renderer->get_shaders()->enabled() && !m_renderer->get_shaders()->register_prescaled_texture(this))
2048               {
2049                  goto error;
2050               }
2051               break;
2052            }
2053            (*d3dintf->texture.release)(m_d3dtex);
2054            m_d3dtex = NULL;
2055         }
2056      }
2057   }
2058
2059   // copy the data to the texture
2060   set_data(texsource, flags);
2061
2062   //texsource->osdhandle = (void*)this;
2063   // add us to the texture list
2064   if(m_texture_manager->get_texlist() != NULL)
2065      m_texture_manager->get_texlist()->m_prev = this;
2066   m_prev = NULL;
2067   m_next = m_texture_manager->get_texlist();
2068   m_texture_manager->set_texlist(this);
2069   return;
2070
2071error:
2072   d3dintf->post_fx_available = false;
2073   osd_printf_error("Direct3D: Critical warning: A texture failed to allocate. Expect things to get bad quickly.\n");
2074   if (m_d3dsurface != NULL)
2075      (*d3dintf->surface.release)(m_d3dsurface);
2076   if (m_d3dtex != NULL)
2077      (*d3dintf->texture.release)(m_d3dtex);
2078}
2079
2080
2081
2082//============================================================
2083//  texture_info::compute_size
2084//============================================================
2085
2086void texture_info::compute_size(int texwidth, int texheight)
2087{
2088   int finalheight = texheight;
2089   int finalwidth = texwidth;
2090
2091   // if we're not wrapping, add a 1-2 pixel border on all sides
2092   m_xborderpix = 0;
2093   m_yborderpix = 0;
2094   if (ENABLE_BORDER_PIX && !(m_flags & PRIMFLAG_TEXWRAP_MASK))
2095   {
2096      // note we need 2 pixels in X for YUY textures
2097      m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
2098      m_yborderpix = 1;
2099   }
2100
2101   // compute final texture size
2102   finalwidth += 2 * m_xborderpix;
2103   finalheight += 2 * m_yborderpix;
2104
2105   // round width/height up to nearest power of 2 if we need to
2106   if (!(m_texture_manager->get_texture_caps() & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
2107   {
2108      // first the width
2109      if (finalwidth & (finalwidth - 1))
2110      {
2111         finalwidth |= finalwidth >> 1;
2112         finalwidth |= finalwidth >> 2;
2113         finalwidth |= finalwidth >> 4;
2114         finalwidth |= finalwidth >> 8;
2115         finalwidth++;
2116      }
2117
2118      // then the height
2119      if (finalheight & (finalheight - 1))
2120      {
2121         finalheight |= finalheight >> 1;
2122         finalheight |= finalheight >> 2;
2123         finalheight |= finalheight >> 4;
2124         finalheight |= finalheight >> 8;
2125         finalheight++;
2126      }
2127   }
2128
2129   // round up to square if we need to
2130   if (m_texture_manager->get_texture_caps() & D3DPTEXTURECAPS_SQUAREONLY)
2131   {
2132      if (finalwidth < finalheight)
2133         finalwidth = finalheight;
2134      else
2135         finalheight = finalwidth;
2136   }
2137
2138   // adjust the aspect ratio if we need to
2139   while (finalwidth < finalheight && finalheight / finalwidth > m_texture_manager->get_max_texture_aspect())
2140   {
2141      finalwidth *= 2;
2142   }
2143   while (finalheight < finalwidth && finalwidth / finalheight > m_texture_manager->get_max_texture_aspect())
2144   {
2145      finalheight *= 2;
2146   }
2147
2148   // if we added pixels for the border, and that just barely pushed us over, take it back
2149   if ((finalwidth > m_texture_manager->get_max_texture_width() && finalwidth - 2 * m_xborderpix <= m_texture_manager->get_max_texture_width()) ||
2150      (finalheight > m_texture_manager->get_max_texture_height() && finalheight - 2 * m_yborderpix <= m_texture_manager->get_max_texture_height()))
2151   {
2152      finalwidth -= 2 * m_xborderpix;
2153      finalheight -= 2 * m_yborderpix;
2154      m_xborderpix = 0;
2155      m_yborderpix = 0;
2156   }
2157
2158   // if we're above the max width/height, do what?
2159   if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
2160   {
2161      static int printed = FALSE;
2162      if (!printed) osd_printf_warning("Texture too big! (wanted: %dx%d, max is %dx%d)\n", finalwidth, finalheight, (int)m_texture_manager->get_max_texture_width(), (int)m_texture_manager->get_max_texture_height());
2163      printed = TRUE;
2164   }
2165
2166   // compute the U/V scale factors
2167   m_start.c.x = (float)m_xborderpix / (float)finalwidth;
2168   m_start.c.y = (float)m_yborderpix / (float)finalheight;
2169   m_stop.c.x = (float)(texwidth + m_xborderpix) / (float)finalwidth;
2170   m_stop.c.y = (float)(texheight + m_yborderpix) / (float)finalheight;
2171
2172   // set the final values
2173   m_rawdims.c.x = finalwidth;
2174   m_rawdims.c.y = finalheight;
2175}
2176
2177
2178
2179//============================================================
2180//  copyline_palette16
2181//============================================================
2182
2183INLINE void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2184{
2185   int x;
2186
2187   assert(xborderpix == 0 || xborderpix == 1);
2188   if (xborderpix)
2189      *dst++ = 0xff000000 | palette[*src];
2190   for (x = 0; x < width; x++)
2191      *dst++ = 0xff000000 | palette[*src++];
2192   if (xborderpix)
2193      *dst++ = 0xff000000 | palette[*--src];
2194}
2195
2196
2197
2198//============================================================
2199//  copyline_palettea16
2200//============================================================
2201
2202INLINE void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2203{
2204   int x;
2205
2206   assert(xborderpix == 0 || xborderpix == 1);
2207   if (xborderpix)
2208      *dst++ = palette[*src];
2209   for (x = 0; x < width; x++)
2210      *dst++ = palette[*src++];
2211   if (xborderpix)
2212      *dst++ = palette[*--src];
2213}
2214
2215
2216
2217//============================================================
2218//  copyline_rgb32
2219//============================================================
2220
2221INLINE void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix)
2222{
2223   int x;
2224
2225   assert(xborderpix == 0 || xborderpix == 1);
2226
2227   // palette (really RGB map) case
2228   if (palette != NULL)
2229   {
2230      if (xborderpix)
2231      {
2232         rgb_t srcpix = *src;
2233         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2234      }
2235      for (x = 0; x < width; x++)
2236      {
2237         rgb_t srcpix = *src++;
2238         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2239      }
2240      if (xborderpix)
2241      {
2242         rgb_t srcpix = *--src;
2243         *dst++ = 0xff000000 | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2244      }
2245   }
2246
2247   // direct case
2248   else
2249   {
2250      if (xborderpix)
2251         *dst++ = 0xff000000 | *src;
2252      for (x = 0; x < width; x++)
2253         *dst++ = 0xff000000 | *src++;
2254      if (xborderpix)
2255         *dst++ = 0xff000000 | *--src;
2256   }
2257}
2258
2259
2260
2261//============================================================
2262//  copyline_argb32
2263//============================================================
2264
2265INLINE void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix)
2266{
2267   int x;
2268
2269   assert(xborderpix == 0 || xborderpix == 1);
2270
2271   // palette (really RGB map) case
2272   if (palette != NULL)
2273   {
2274      if (xborderpix)
2275      {
2276         rgb_t srcpix = *src;
2277         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2278      }
2279      for (x = 0; x < width; x++)
2280      {
2281         rgb_t srcpix = *src++;
2282         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2283      }
2284      if (xborderpix)
2285      {
2286         rgb_t srcpix = *--src;
2287         *dst++ = (srcpix & 0xff000000) | palette[0x200 + srcpix.r()] | palette[0x100 + srcpix.g()] | palette[srcpix.b()];
2288      }
2289   }
2290
2291   // direct case
2292   else
2293   {
2294      if (xborderpix)
2295         *dst++ = *src;
2296      for (x = 0; x < width; x++)
2297         *dst++ = *src++;
2298      if (xborderpix)
2299         *dst++ = *--src;
2300   }
2301}
2302
2303
2304
2305//============================================================
2306//  copyline_yuy16_to_yuy2
2307//============================================================
2308
2309INLINE void copyline_yuy16_to_yuy2(UINT16 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2310{
2311   int x;
2312
2313   assert(xborderpix == 0 || xborderpix == 2);
2314   assert(width % 2 == 0);
2315
2316   // palette (really RGB map) case
2317   if (palette != NULL)
2318   {
2319      if (xborderpix)
2320      {
2321         UINT16 srcpix0 = *src++;
2322         UINT16 srcpix1 = *src--;
2323         *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix0 << 8);
2324         *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix1 << 8);
2325      }
2326      for (x = 0; x < width; x += 2)
2327      {
2328         UINT16 srcpix0 = *src++;
2329         UINT16 srcpix1 = *src++;
2330         *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix0 << 8);
2331         *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix1 << 8);
2332      }
2333      if (xborderpix)
2334      {
2335         UINT16 srcpix1 = *--src;
2336         UINT16 srcpix0 = *--src;
2337         *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix0 << 8);
2338         *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix1 << 8);
2339      }
2340   }
2341
2342   // direct case
2343   else
2344   {
2345      if (xborderpix)
2346      {
2347         UINT16 srcpix0 = *src++;
2348         UINT16 srcpix1 = *src--;
2349         *dst++ = (srcpix0 >> 8) | (srcpix0 << 8);
2350         *dst++ = (srcpix0 >> 8) | (srcpix1 << 8);
2351      }
2352      for (x = 0; x < width; x += 2)
2353      {
2354         UINT16 srcpix0 = *src++;
2355         UINT16 srcpix1 = *src++;
2356         *dst++ = (srcpix0 >> 8) | (srcpix0 << 8);
2357         *dst++ = (srcpix1 >> 8) | (srcpix1 << 8);
2358      }
2359      if (xborderpix)
2360      {
2361         UINT16 srcpix1 = *--src;
2362         UINT16 srcpix0 = *--src;
2363         *dst++ = (srcpix1 >> 8) | (srcpix0 << 8);
2364         *dst++ = (srcpix1 >> 8) | (srcpix1 << 8);
2365      }
2366   }
2367}
2368
2369
2370
2371//============================================================
2372//  copyline_yuy16_to_uyvy
2373//============================================================
2374
2375INLINE void copyline_yuy16_to_uyvy(UINT16 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2376{
2377   int x;
2378
2379   assert(xborderpix == 0 || xborderpix == 2);
2380   assert(width % 2 == 0);
2381
2382   // palette (really RGB map) case
2383   if (palette != NULL)
2384   {
2385      if (xborderpix)
2386      {
2387         UINT16 srcpix0 = *src++;
2388         UINT16 srcpix1 = *src--;
2389         *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix0 & 0xff);
2390         *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix1 & 0xff);
2391      }
2392      for (x = 0; x < width; x += 2)
2393      {
2394         UINT16 srcpix0 = *src++;
2395         UINT16 srcpix1 = *src++;
2396         *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix0 & 0xff);
2397         *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix1 & 0xff);
2398      }
2399      if (xborderpix)
2400      {
2401         UINT16 srcpix1 = *--src;
2402         UINT16 srcpix0 = *--src;
2403         *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix0 & 0xff);
2404         *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix1 & 0xff);
2405      }
2406   }
2407
2408   // direct case
2409   else
2410   {
2411      if (xborderpix)
2412      {
2413         UINT16 srcpix0 = src[0];
2414         UINT16 srcpix1 = src[1];
2415         *dst++ = srcpix0;
2416         *dst++ = (srcpix0 & 0xff00) | (srcpix1 & 0x00ff);
2417      }
2418      for (x = 0; x < width; x += 2)
2419      {
2420         *dst++ = *src++;
2421         *dst++ = *src++;
2422      }
2423      if (xborderpix)
2424      {
2425         UINT16 srcpix1 = *--src;
2426         UINT16 srcpix0 = *--src;
2427         *dst++ = (srcpix1 & 0xff00) | (srcpix0 & 0x00ff);
2428         *dst++ = srcpix1;
2429      }
2430   }
2431}
2432
2433
2434
2435//============================================================
2436//  copyline_yuy16_to_argb
2437//============================================================
2438
2439INLINE void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
2440{
2441   int x;
2442
2443   assert(xborderpix == 0 || xborderpix == 2);
2444   assert(width % 2 == 0);
2445
2446   // palette (really RGB map) case
2447   if (palette != NULL)
2448   {
2449      if (xborderpix)
2450      {
2451         UINT16 srcpix0 = src[0];
2452         UINT16 srcpix1 = src[1];
2453         UINT8 cb = srcpix0 & 0xff;
2454         UINT8 cr = srcpix1 & 0xff;
2455         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2456         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2457      }
2458      for (x = 0; x < width / 2; x++)
2459      {
2460         UINT16 srcpix0 = *src++;
2461         UINT16 srcpix1 = *src++;
2462         UINT8 cb = srcpix0 & 0xff;
2463         UINT8 cr = srcpix1 & 0xff;
2464         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
2465         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2466      }
2467      if (xborderpix)
2468      {
2469         UINT16 srcpix1 = *--src;
2470         UINT16 srcpix0 = *--src;
2471         UINT8 cb = srcpix0 & 0xff;
2472         UINT8 cr = srcpix1 & 0xff;
2473         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2474         *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
2475      }
2476   }
2477
2478   // direct case
2479   else
2480   {
2481      if (xborderpix)
2482      {
2483         UINT16 srcpix0 = src[0];
2484         UINT16 srcpix1 = src[1];
2485         UINT8 cb = srcpix0 & 0xff;
2486         UINT8 cr = srcpix1 & 0xff;
2487         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2488         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2489      }
2490      for (x = 0; x < width; x += 2)
2491      {
2492         UINT16 srcpix0 = *src++;
2493         UINT16 srcpix1 = *src++;
2494         UINT8 cb = srcpix0 & 0xff;
2495         UINT8 cr = srcpix1 & 0xff;
2496         *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
2497         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2498      }
2499      if (xborderpix)
2500      {
2501         UINT16 srcpix1 = *--src;
2502         UINT16 srcpix0 = *--src;
2503         UINT8 cb = srcpix0 & 0xff;
2504         UINT8 cr = srcpix1 & 0xff;
2505         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2506         *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
2507      }
2508   }
2509}
2510
2511
2512
2513//============================================================
2514//  texture_set_data
2515//============================================================
2516
2517void texture_info::set_data(const render_texinfo *texsource, UINT32 flags)
2518{
2519   D3DLOCKED_RECT rect;
2520   HRESULT result;
2521
2522   // lock the texture
2523   switch (m_type)
2524   {
2525      default:
2526      case TEXTURE_TYPE_PLAIN:    result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, NULL, 0);                 break;
2527      case TEXTURE_TYPE_DYNAMIC:  result = (*d3dintf->texture.lock_rect)(m_d3dtex, 0, &rect, NULL, D3DLOCK_DISCARD);   break;
2528      case TEXTURE_TYPE_SURFACE:  result = (*d3dintf->surface.lock_rect)(m_d3dsurface, &rect, NULL, D3DLOCK_DISCARD);  break;
2529   }
2530   if (result != D3D_OK)
2531   {
2532      return;
2533   }
2534
2535   // loop over Y
2536   int miny = 0 - m_yborderpix;
2537   int maxy = texsource->height + m_yborderpix;
2538   for (int dsty = miny; dsty < maxy; dsty++)
2539   {
2540      int srcy = (dsty < 0) ? 0 : (dsty >= texsource->height) ? texsource->height - 1 : dsty;
2541      void *dst = (BYTE *)rect.pBits + (dsty + m_yborderpix) * rect.Pitch;
2542
2543      // switch off of the format and
2544      switch (PRIMFLAG_GET_TEXFORMAT(flags))
2545      {
2546         case TEXFORMAT_PALETTE16:
2547            copyline_palette16((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2548            break;
2549
2550         case TEXFORMAT_PALETTEA16:
2551            copyline_palettea16((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2552            break;
2553
2554         case TEXFORMAT_RGB32:
2555            copyline_rgb32((UINT32 *)dst, (UINT32 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2556            break;
2557
2558         case TEXFORMAT_ARGB32:
2559            copyline_argb32((UINT32 *)dst, (UINT32 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2560            break;
2561
2562         case TEXFORMAT_YUY16:
2563            if (m_texture_manager->get_yuv_format() == D3DFMT_YUY2)
2564               copyline_yuy16_to_yuy2((UINT16 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2565            else if (m_texture_manager->get_yuv_format() == D3DFMT_UYVY)
2566               copyline_yuy16_to_uyvy((UINT16 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2567            else
2568               copyline_yuy16_to_argb((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, m_xborderpix);
2569            break;
2570
2571         default:
2572            osd_printf_error("Unknown texture blendmode=%d format=%d\n", PRIMFLAG_GET_BLENDMODE(flags), PRIMFLAG_GET_TEXFORMAT(flags));
2573            break;
2574      }
2575   }
2576
2577   // unlock
2578   switch (m_type)
2579   {
2580      default:
2581      case TEXTURE_TYPE_PLAIN:    result = (*d3dintf->texture.unlock_rect)(m_d3dtex, 0);   break;
2582      case TEXTURE_TYPE_DYNAMIC:  result = (*d3dintf->texture.unlock_rect)(m_d3dtex, 0);   break;
2583      case TEXTURE_TYPE_SURFACE:  result = (*d3dintf->surface.unlock_rect)(m_d3dsurface);  break;
2584   }
2585   if (result != D3D_OK)
2586   {
2587      osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
2588   }
2589
2590   // prescale
2591   prescale();
2592}
2593
2594
2595
2596//============================================================
2597//  texture_info::prescale
2598//============================================================
2599
2600void texture_info::prescale()
2601{
2602   surface *scale_surface;
2603   HRESULT result;
2604   int i;
2605
2606   // if we don't need to, just skip it
2607   if (m_d3dtex == m_d3dfinaltex)
2608      return;
2609
2610   // for all cases, we need to get the surface of the render target
2611   result = (*d3dintf->texture.get_surface_level)(m_d3dfinaltex, 0, &scale_surface);
2612   if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture get_surface_level call\n", (int)result);
2613
2614   // if we have an offscreen plain surface, we can just StretchRect to it
2615   if (m_type == TEXTURE_TYPE_SURFACE)
2616   {
2617      assert(m_d3dsurface != NULL);
2618
2619      // set the source bounds
2620      RECT source;
2621      source.left = source.top = 0;
2622      source.right = m_texinfo.width + 2 * m_xborderpix;
2623      source.bottom = m_texinfo.height + 2 * m_yborderpix;
2624
2625      // set the target bounds
2626      RECT dest;
2627      dest = source;
2628      dest.right *= m_xprescale;
2629      dest.bottom *= m_yprescale;
2630
2631      // do the stretchrect
2632      result = (*d3dintf->device.stretch_rect)(m_renderer->get_device(), m_d3dsurface, &source, scale_surface, &dest, D3DTEXF_POINT);
2633      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device stretct_rect call\n", (int)result);
2634   }
2635
2636   // if we are using a texture render target, we need to do more preparations
2637   else
2638   {
2639      surface *backbuffer;
2640
2641      assert(m_d3dtex != NULL);
2642
2643      // first remember the original render target and set the new one
2644      result = (*d3dintf->device.get_render_target)(m_renderer->get_device(), 0, &backbuffer);
2645      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
2646      result = (*d3dintf->device.set_render_target)(m_renderer->get_device(), 0, scale_surface);
2647      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 1\n", (int)result);
2648      m_renderer->reset_render_states();
2649
2650      // start the scene
2651      result = (*d3dintf->device.begin_scene)(m_renderer->get_device());
2652      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
2653
2654      // configure the rendering pipeline
2655      m_renderer->set_filter(FALSE);
2656      m_renderer->set_blendmode(BLENDMODE_NONE);
2657      result = (*d3dintf->device.set_texture)(m_renderer->get_device(), 0, m_d3dtex);
2658      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result);
2659
2660      // lock the vertex buffer
2661      result = (*d3dintf->vertexbuf.lock)(m_renderer->get_vertex_buffer(), 0, 0, m_renderer->get_locked_buffer_ptr(), D3DLOCK_DISCARD);
2662      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer lock call\n", (int)result);
2663
2664      // configure the X/Y coordinates on the target surface
2665      vertex *lockedbuf = m_renderer->get_locked_buffer();
2666      lockedbuf[0].x = -0.5f;
2667      lockedbuf[0].y = -0.5f;
2668      lockedbuf[1].x = (float)((m_texinfo.width + 2 * m_xborderpix) * m_xprescale) - 0.5f;
2669      lockedbuf[1].y = -0.5f;
2670      lockedbuf[2].x = -0.5f;
2671      lockedbuf[2].y = (float)((m_texinfo.height + 2 * m_yborderpix) * m_yprescale) - 0.5f;
2672      lockedbuf[3].x = (float)((m_texinfo.width + 2 * m_xborderpix) * m_xprescale) - 0.5f;
2673      lockedbuf[3].y = (float)((m_texinfo.height + 2 * m_yborderpix) * m_yprescale) - 0.5f;
2674
2675      // configure the U/V coordintes on the source texture
2676      lockedbuf[0].u0 = 0.0f;
2677      lockedbuf[0].v0 = 0.0f;
2678      lockedbuf[1].u0 = (float)(m_texinfo.width + 2 * m_xborderpix) / (float)m_rawdims.c.x;
2679      lockedbuf[1].v0 = 0.0f;
2680      lockedbuf[2].u0 = 0.0f;
2681      lockedbuf[2].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
2682      lockedbuf[3].u0 = (float)(m_texinfo.width + 2 * m_xborderpix) / (float)m_rawdims.c.x;
2683      lockedbuf[3].v0 = (float)(m_texinfo.height + 2 * m_yborderpix) / (float)m_rawdims.c.y;
2684
2685      // reset the remaining vertex parameters
2686      for (i = 0; i < 4; i++)
2687      {
2688         lockedbuf[i].z = 0.0f;
2689         lockedbuf[i].rhw = 1.0f;
2690         lockedbuf[i].color = D3DCOLOR_ARGB(0xff,0xff,0xff,0xff);
2691      }
2692
2693      // unlock the vertex buffer
2694      result = (*d3dintf->vertexbuf.unlock)(m_renderer->get_vertex_buffer());
2695      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result);
2696      m_renderer->set_locked_buffer(NULL);
2697
2698      // set the stream and draw the triangle strip
2699      result = (*d3dintf->device.set_stream_source)(m_renderer->get_device(), 0, m_renderer->get_vertex_buffer(), sizeof(vertex));
2700      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_stream_source call\n", (int)result);
2701      result = (*d3dintf->device.draw_primitive)(m_renderer->get_device(), D3DPT_TRIANGLESTRIP, 0, 2);
2702      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
2703
2704      // end the scene
2705      result = (*d3dintf->device.end_scene)(m_renderer->get_device());
2706      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result);
2707
2708      // reset the render target and release our reference to the backbuffer
2709      result = (*d3dintf->device.set_render_target)(m_renderer->get_device(), 0, backbuffer);
2710      if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 2\n", (int)result);
2711      (*d3dintf->surface.release)(backbuffer);
2712      m_renderer->reset_render_states();
2713   }
2714
2715   // release our reference to the target surface
2716   (*d3dintf->surface.release)(scale_surface);
2717}
2718
2719
2720//============================================================
2721//  cache_target::~cache_target
2722//============================================================
2723
2724cache_target::~cache_target()
2725{
2726   for (int index = 0; index < 11; index++)
2727   {
2728      if (bloom_texture[index] != NULL)
2729      {
2730         (*d3dintf->texture.release)(bloom_texture[index]);
2731         bloom_texture[index] = NULL;
2732      }
2733      if (bloom_target[index] != NULL)
2734      {
2735         (*d3dintf->surface.release)(bloom_target[index]);
2736         bloom_target[index] = NULL;
2737      }
2738   }
2739
2740   if (last_texture != NULL)
2741   {
2742      (*d3dintf->texture.release)(last_texture);
2743      last_texture = NULL;
2744   }
2745   if (last_target != NULL)
2746   {
2747      (*d3dintf->surface.release)(last_target);
2748      last_target = NULL;
2749   }
2750}
2751
2752
2753//============================================================
2754//  cache_target::init - initializes a target cache
2755//============================================================
2756
2757bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y)
2758{
2759   int bloom_size = (width < height) ? width : height;
2760   int bloom_index = 0;
2761   int bloom_width = width;
2762   int bloom_height = height;
2763   for (; bloom_size >= 2 && bloom_index < 11; bloom_size >>= 1)
2764   {
2765      bloom_width >>= 1;
2766      bloom_height >>= 1;
2767      HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), bloom_width, bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
2768      if (result != D3D_OK)
2769      {
2770         return false;
2771      }
2772      (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]);
2773      bloom_index++;
2774   }
2775
2776   HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
2777   if (result != D3D_OK)
2778      return false;
2779   (*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target);
2780
2781   target_width = width * prescale_x;
2782   target_height = height * prescale_y;
2783
2784   return true;
2785}
2786
2787//============================================================
2788//  render_target::~render_target
2789//============================================================
2790
2791render_target::~render_target()
2792{
2793   for (int index = 0; index < 11; index++)
2794   {
2795      if (bloom_texture[index] != NULL)
2796      {
2797         (*d3dintf->texture.release)(bloom_texture[index]);
2798         bloom_texture[index] = NULL;
2799      }
2800      if (bloom_target[index] != NULL)
2801      {
2802         (*d3dintf->surface.release)(bloom_target[index]);
2803         bloom_target[index] = NULL;
2804      }
2805   }
2806
2807   for (int index = 0; index < 5; index++)
2808   {
2809      if (render_texture[index] != NULL)
2810      {
2811         (*d3dintf->texture.release)(render_texture[index]);
2812         render_texture[index] = NULL;
2813      }
2814      if (target[index] != NULL)
2815      {
2816         (*d3dintf->surface.release)(target[index]);
2817         target[index] = NULL;
2818      }
2819   }
2820
2821   if (prescaletexture != NULL)
2822   {
2823      (*d3dintf->texture.release)(prescaletexture);
2824      prescaletexture = NULL;
2825   }
2826   if (prescaletarget != NULL)
2827   {
2828      (*d3dintf->surface.release)(prescaletarget);
2829      prescaletarget = NULL;
2830   }
2831
2832   if (smalltexture != NULL)
2833   {
2834      (*d3dintf->texture.release)(smalltexture);
2835      smalltexture = NULL;
2836   }
2837   if (smalltarget != NULL)
2838   {
2839      (*d3dintf->surface.release)(smalltarget);
2840      smalltarget = NULL;
2841   }
2842}
2843
2844
2845//============================================================
2846//  render_target::init - initializes a render target
2847//============================================================
2848
2849bool render_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y)
2850{
2851   D3DFORMAT format = D3DFMT_A8R8G8B8;
2852
2853   HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[0]);
2854   if (result != D3D_OK)
2855      return false;
2856   (*d3dintf->texture.get_surface_level)(render_texture[0], 0, &target[0]);
2857
2858   result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[1]);
2859   if (result != D3D_OK)
2860      return false;
2861   (*d3dintf->texture.get_surface_level)(render_texture[1], 0, &target[1]);
2862
2863   result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[2]);
2864   if (result != D3D_OK)
2865      return false;
2866   (*d3dintf->texture.get_surface_level)(render_texture[2], 0, &target[2]);
2867
2868   result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &render_texture[3]);
2869   if (result != D3D_OK)
2870      return false;
2871   (*d3dintf->texture.get_surface_level)(render_texture[3], 0, &target[3]);
2872
2873   result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &render_texture[4]);
2874   if (result != D3D_OK)
2875      return false;
2876   (*d3dintf->texture.get_surface_level)(render_texture[4], 0, &target[4]);
2877
2878   result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &smalltexture);
2879   if (result != D3D_OK)
2880      return false;
2881   (*d3dintf->texture.get_surface_level)(smalltexture, 0, &smalltarget);
2882
2883   result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescaletexture);
2884   if (result != D3D_OK)
2885      return false;
2886   (*d3dintf->texture.get_surface_level)(prescaletexture, 0, &prescaletarget);
2887
2888   float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
2889   int bloom_index = 0;
2890   float bloom_width = d3d->get_width();
2891   float bloom_height = d3d->get_height();
2892   for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
2893   {
2894      bloom_width *= 0.5f;
2895      bloom_height *= 0.5f;
2896      result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
2897      if (result != D3D_OK)
2898         return false;
2899      (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]);
2900      bloom_index++;
2901   }
2902
2903   this->width = width;
2904   this->height = height;
2905
2906   target_width = width * prescale_x;
2907   target_height = height * prescale_y;
2908
2909   return true;
2910}
2911
2912};
trunk/src/osd/windows/drawd3d.h
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawd3d.h - Win32 Direct3D header
6//
7//============================================================
8
9#ifndef __WIN_DRAWD3D__
10#define __WIN_DRAWD3D__
11
12
13#include "d3dhlsl.h"
14
15
16//============================================================
17//  CONSTANTS
18//============================================================
19
20#define VERTEX_BASE_FORMAT  (D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEX2)
21#define VERTEX_BUFFER_SIZE  (40960*4+4)
22
23//============================================================
24//  TYPE DEFINITIONS
25//============================================================
26
27namespace d3d
28{
29class cache_target;
30class render_target;
31class renderer;
32
33/* cache_target is a simple linked list containing only a rednerable target and texture, used for phosphor effects */
34class cache_target
35{
36public:
37   // construction/destruction
38   cache_target() { }
39   ~cache_target();
40
41   bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y);
42
43   surface *last_target;
44   texture *last_texture;
45
46   int target_width;
47   int target_height;
48
49   int width;
50   int height;
51
52   int screen_index;
53
54   cache_target *next;
55   cache_target *prev;
56
57   surface *bloom_target[11];
58   texture *bloom_texture[11];
59};
60
61/* render_target is the information about a Direct3D render target chain */
62class render_target
63{
64public:
65   // construction/destruction
66   render_target() { }
67   ~render_target();
68
69   bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y);
70
71   int target_width;
72   int target_height;
73
74   int prescale_x;
75   int prescale_y;
76
77   int width;
78   int height;
79
80   int screen_index;
81   int page_index;
82
83   surface *prescaletarget;
84   texture *prescaletexture;
85   surface *smalltarget;
86   texture *smalltexture;
87   surface *target[5];
88   texture *render_texture[5];
89
90   render_target *next;
91   render_target *prev;
92
93   surface *bloom_target[11];
94   texture *bloom_texture[11];
95};
96
97/* renderer is the information about Direct3D for the current screen */
98class renderer : public osd_renderer
99{
100public:
101   //renderer() { }
102   renderer(osd_window *window);
103   virtual ~renderer();
104
105   virtual int create();
106   virtual render_primitive_list *get_primitives();
107   virtual int draw(const int update);
108   virtual void save();
109   virtual void record();
110   virtual void toggle_fsfx();
111   virtual void destroy();
112
113   int                     initialize();
114
115   int                     device_create(HWND device_HWND);
116   int                     device_create_resources();
117   void                    device_delete();
118   void                    device_delete_resources();
119
120   int                     device_verify_caps();
121   int                     device_test_cooperative();
122
123   int                     config_adapter_mode();
124   void                    pick_best_mode();
125   int                     get_adapter_for_monitor();
126
127   int                     update_window_size();
128
129   int                     pre_window_draw_check();
130   void                    begin_frame();
131   void                    end_frame();
132
133   void                    draw_line(const render_primitive *prim);
134   void                    draw_quad(const render_primitive *prim);
135   void                    batch_vector(const render_primitive *prim, float line_time);
136   void                    batch_vectors();
137
138   vertex *                mesh_alloc(int numverts);
139
140   void                    update_textures();
141
142   void                    process_primitives();
143   void                    primitive_flush_pending();
144
145   void                    set_texture(texture_info *texture);
146   void                    set_filter(int filter);
147   void                    set_wrap(D3DTEXTUREADDRESS wrap);
148   void                    set_modmode(DWORD modmode);
149   void                    set_blendmode(int blendmode);
150   void                    reset_render_states();
151
152   // Setters / getters
153   int                     get_adapter() { return m_adapter; }
154   int                     get_width() { return m_width; }
155   vec2f                   get_dims() { return vec2f(m_width, m_height); }
156   int                     get_height() { return m_height; }
157   int                     get_refresh() { return m_refresh; }
158
159   device *                get_device() { return m_device; }
160   present_parameters *    get_presentation() { return &m_presentation; }
161
162   vertex_buffer *         get_vertex_buffer() { return m_vertexbuf; }
163   vertex *                get_locked_buffer() { return m_lockedbuf; }
164   VOID **                 get_locked_buffer_ptr() { return (VOID **)&m_lockedbuf; }
165   void                    set_locked_buffer(vertex *lockedbuf) { m_lockedbuf = lockedbuf; }
166
167   void                    set_restarting(bool restarting) { m_restarting = restarting; }
168   bool                    is_mod2x_supported() { return (bool)m_mod2x_supported; }
169   bool                    is_mod4x_supported() { return (bool)m_mod4x_supported; }
170
171   D3DFORMAT               get_screen_format() { return m_screen_format; }
172   D3DFORMAT               get_pixel_format() { return m_pixformat; }
173   D3DDISPLAYMODE          get_origmode() { return m_origmode; }
174
175   UINT32                  get_last_texture_flags() { return m_last_texture_flags; }
176
177   texture_manager *       get_texture_manager() { return m_texture_manager; }
178   texture_info *          get_default_texture() { return m_texture_manager->get_default_texture(); }
179   texture_info *          get_vector_texture() { return m_texture_manager->get_vector_texture(); }
180
181   shaders *               get_shaders() { return m_shaders; }
182
183private:
184   int                     m_adapter;                  // ordinal adapter number
185   int                     m_width;                    // current width
186   int                     m_height;                   // current height
187   int                     m_refresh;                  // current refresh rate
188   int                     m_create_error_count;       // number of consecutive create errors
189
190   device *                m_device;                   // pointer to the Direct3DDevice object
191   int                     m_gamma_supported;          // is full screen gamma supported?
192   present_parameters      m_presentation;             // set of presentation parameters
193   D3DDISPLAYMODE          m_origmode;                 // original display mode for the adapter
194   D3DFORMAT               m_pixformat;                // pixel format we are using
195
196   vertex_buffer *         m_vertexbuf;                // pointer to the vertex buffer object
197   vertex *                m_lockedbuf;                // pointer to the locked vertex buffer
198   int                     m_numverts;                 // number of accumulated vertices
199
200   vertex *                m_vectorbatch;              // pointer to the vector batch buffer
201   int                     m_batchindex;               // current index into the vector batch
202
203   poly_info               m_poly[VERTEX_BUFFER_SIZE/3];// array to hold polygons as they are created
204   int                     m_numpolys;                 // number of accumulated polygons
205
206   bool                    m_restarting;               // if we're restarting
207
208   int                     m_mod2x_supported;          // is D3DTOP_MODULATE2X supported?
209   int                     m_mod4x_supported;          // is D3DTOP_MODULATE4X supported?
210   D3DFORMAT               m_screen_format;            // format to use for screen textures
211
212   texture_info *          m_last_texture;             // previous texture
213   UINT32                  m_last_texture_flags;       // previous texture flags
214   int                     m_last_blendenable;         // previous blendmode
215   int                     m_last_blendop;             // previous blendmode
216   int                     m_last_blendsrc;            // previous blendmode
217   int                     m_last_blenddst;            // previous blendmode
218   int                     m_last_filter;              // previous texture filter
219   D3DTEXTUREADDRESS       m_last_wrap;                // previous wrap state
220   DWORD                   m_last_modmode;             // previous texture modulation
221
222   void *                  m_hlsl_buf;                 // HLSL vertex data
223   shaders *               m_shaders;                  // HLSL interface
224
225   texture_manager *       m_texture_manager;          // texture manager
226
227   int                     m_line_count;
228};
229
230};
231
232#endif
trunk/src/osd/windows/drawdd.c
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawdd.c - Win32 DirectDraw implementation
6//
7//============================================================
8
9// standard windows headers
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12#include <mmsystem.h>
13#include <ddraw.h>
14#undef interface
15
16// MAME headers
17#include "emu.h"
18#include "render.h"
19#include "rendutil.h"
20#include "options.h"
21#include "rendersw.inc"
22
23// MAMEOS headers
24#include "winmain.h"
25#include "window.h"
26#include "config.h"
27
28
29
30//============================================================
31//  TYPE DEFINITIONS
32//============================================================
33
34typedef HRESULT (WINAPI *directdrawcreateex_ptr)(GUID FAR *lpGuid, LPVOID *lplpDD, REFIID iid, IUnknown FAR *pUnkOuter);
35typedef HRESULT (WINAPI *directdrawenumerateex_ptr)(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags);
36
37
38/* dd_info is the information about DirectDraw for the current screen */
39class renderer_dd : public osd_renderer
40{
41public:
42   renderer_dd(osd_window *window)
43   : osd_renderer(window, FLAG_NONE),
44      //adapter(0),
45      adapter_ptr(NULL),
46      clearouter(0),
47      blitwidth(0), blitheight(0),
48      //lastdest
49      ddraw(NULL),
50      primary(NULL),
51      back(NULL),
52      blit(NULL),
53      clipper(NULL),
54      gamma(NULL),
55      //DDSURFACEDESC2          primarydesc;
56      //DDSURFACEDESC2          blitdesc;
57      //DDSURFACEDESC2          origmode;
58      //ddcaps(0),
59      //helcaps(0),
60      membuffer(NULL),
61      membuffersize(0)
62   { }
63
64   virtual ~renderer_dd() { }
65
66   virtual int create();
67   virtual render_primitive_list *get_primitives();
68   virtual int draw(const int update);
69   virtual void save() {};
70   virtual void record() {};
71   virtual void toggle_fsfx() {};
72   virtual void destroy();
73
74   int                     width, height;              // current width, height
75   int                     refresh;                    // current refresh rate
76
77private:
78
79   inline void update_outer_rects();
80
81   // surface management
82   int ddraw_create();
83   int ddraw_create_surfaces();
84   void ddraw_delete();
85   void ddraw_delete_surfaces();
86   int ddraw_verify_caps();
87   int ddraw_test_cooperative();
88   HRESULT create_surface(DDSURFACEDESC2 *desc, IDirectDrawSurface7 **surface, const char *type);
89   int create_clipper();
90
91   // drawing helpers
92   void compute_blit_surface_size();
93   void blit_to_primary(int srcwidth, int srcheight);
94
95   // video modes
96   int config_adapter_mode();
97   void get_adapter_for_monitor(win_monitor_info *monitor);
98   void pick_best_mode();
99
100   // various
101   void calc_fullscreen_margins(DWORD desc_width, DWORD desc_height, RECT *margins);
102
103
104   GUID                    adapter;                    // current display adapter
105   GUID *                  adapter_ptr;                // pointer to current display adapter
106   int                     clearouter;                 // clear the outer areas?
107
108   INT32                   blitwidth, blitheight;      // current blit width/height values
109   RECT                    lastdest;                   // last destination rectangle
110
111   IDirectDraw7 *          ddraw;                      // pointer to the DirectDraw object
112   IDirectDrawSurface7 *   primary;                    // pointer to the primary surface object
113   IDirectDrawSurface7 *   back;                       // pointer to the back buffer surface object
114   IDirectDrawSurface7 *   blit;                       // pointer to the blit surface object
115   IDirectDrawClipper *    clipper;                    // pointer to the clipper object
116   IDirectDrawGammaControl *gamma;                     // pointer to the gamma control object
117
118   DDSURFACEDESC2          primarydesc;                // description of the primary surface
119   DDSURFACEDESC2          blitdesc;                   // description of the blitting surface
120   DDSURFACEDESC2          origmode;                   // original video mode
121
122   DDCAPS                  ddcaps;                     // capabilities of the device
123   DDCAPS                  helcaps;                    // capabilities of the hardware
124
125   UINT8 *                 membuffer;                  // memory buffer for complex rendering
126   UINT32                  membuffersize;              // current size of the memory buffer
127};
128
129
130/* monitor_enum_info holds information during a monitor enumeration */
131struct monitor_enum_info
132{
133   win_monitor_info *      monitor;                    // pointer to monitor we want
134   GUID                    guid;                       // GUID of the one we found
135   GUID *                  guid_ptr;                   // pointer to our GUID
136   int                     foundit;                    // TRUE if we found what we wanted
137};
138
139
140/* mode_enum_info holds information during a display mode enumeration */
141struct mode_enum_info
142{
143   renderer_dd *           renderer;
144   osd_window  *           window;
145   INT32                   minimum_width, minimum_height;
146   INT32                   target_width, target_height;
147   double                  target_refresh;
148   float                   best_score;
149};
150
151
152
153//============================================================
154//  GLOBALS
155//============================================================
156
157static HINSTANCE dllhandle;
158static directdrawcreateex_ptr directdrawcreateex;
159static directdrawenumerateex_ptr directdrawenumerateex;
160
161
162
163//============================================================
164//  INLINES
165//============================================================
166
167inline void renderer_dd::update_outer_rects()
168{
169   clearouter = (back != NULL) ? 3 : 1;
170}
171
172
173INLINE int better_mode(int width0, int height0, int width1, int height1, float desired_aspect)
174{
175   float aspect0 = (float)width0 / (float)height0;
176   float aspect1 = (float)width1 / (float)height1;
177   return (fabs(desired_aspect - aspect0) < fabs(desired_aspect - aspect1)) ? 0 : 1;
178}
179
180
181
182//============================================================
183//  PROTOTYPES
184//============================================================
185
186// core functions
187static void drawdd_exit(void);
188
189
190
191//============================================================
192//  drawnone_create
193//============================================================
194
195static osd_renderer *drawdd_create(osd_window *window)
196{
197   return global_alloc(renderer_dd(window));
198}
199
200
201//============================================================
202//  drawdd_init
203//============================================================
204
205int drawdd_init(running_machine &machine, osd_draw_callbacks *callbacks)
206{
207   // dynamically grab the create function from ddraw.dll
208   dllhandle = LoadLibrary(TEXT("ddraw.dll"));
209   if (dllhandle == NULL)
210   {
211      osd_printf_verbose("DirectDraw: Unable to access ddraw.dll\n");
212      return 1;
213   }
214
215   // import the create function
216   directdrawcreateex = (directdrawcreateex_ptr)GetProcAddress(dllhandle, "DirectDrawCreateEx");
217   if (directdrawcreateex == NULL)
218   {
219      osd_printf_verbose("DirectDraw: Unable to find DirectDrawCreateEx\n");
220      FreeLibrary(dllhandle);
221      dllhandle = NULL;
222      return 1;
223   }
224
225   // import the enumerate function
226   directdrawenumerateex = (directdrawenumerateex_ptr)GetProcAddress(dllhandle, "DirectDrawEnumerateExA");
227   if (directdrawenumerateex == NULL)
228   {
229      osd_printf_verbose("DirectDraw: Unable to find DirectDrawEnumerateExA\n");
230      FreeLibrary(dllhandle);
231      dllhandle = NULL;
232      return 1;
233   }
234
235   // fill in the callbacks
236   memset(callbacks, 0, sizeof(*callbacks));
237   callbacks->exit = drawdd_exit;
238   callbacks->create = drawdd_create;
239
240   osd_printf_verbose("DirectDraw: Using DirectDraw 7\n");
241   return 0;
242}
243
244
245
246//============================================================
247//  drawdd_exit
248//============================================================
249
250static void drawdd_exit(void)
251{
252   if (dllhandle != NULL)
253      FreeLibrary(dllhandle);
254}
255
256
257
258//============================================================
259//  drawdd_window_init
260//============================================================
261
262int renderer_dd::create()
263{
264   // configure the adapter for the mode we want
265   if (config_adapter_mode())
266      goto error;
267
268   // create the ddraw object
269   if (ddraw_create())
270      goto error;
271
272   return 0;
273
274error:
275   destroy();
276   osd_printf_error("Unable to initialize DirectDraw.\n");
277   return 1;
278}
279
280
281
282//============================================================
283//  drawdd_window_destroy
284//============================================================
285
286void renderer_dd::destroy()
287{
288   // delete the ddraw object
289   ddraw_delete();
290}
291
292
293
294//============================================================
295//  drawdd_window_get_primitives
296//============================================================
297
298render_primitive_list *renderer_dd::get_primitives()
299{
300   compute_blit_surface_size();
301   window().target()->set_bounds(blitwidth, blitheight, 0);
302   window().target()->set_max_update_rate((refresh == 0) ? origmode.dwRefreshRate : refresh);
303
304   return &window().target()->get_primitives();
305}
306
307
308
309//============================================================
310//  drawdd_window_draw
311//============================================================
312
313int renderer_dd::draw(const int update)
314{
315   render_primitive *prim;
316   int usemembuffer = FALSE;
317   HRESULT result;
318
319   // if we're updating, remember to erase the outer stuff
320   if (update)
321      update_outer_rects();
322
323   // if we have a ddraw object, check the cooperative level
324   if (ddraw_test_cooperative())
325      return 1;
326
327   // get the size; if we're too small, delete the existing surfaces
328   if (blitwidth > blitdesc.dwWidth || blitheight > blitdesc.dwHeight)
329      ddraw_delete_surfaces();
330
331   // if we need to create surfaces, do it now
332   if (blit == NULL && ddraw_create_surfaces() != 0)
333      return 1;
334
335   // select our surface and lock it
336   result = IDirectDrawSurface7_Lock(blit, NULL, &blitdesc, DDLOCK_WAIT, NULL);
337   if (result == DDERR_SURFACELOST)
338   {
339      osd_printf_verbose("DirectDraw: Lost surfaces; deleting and retrying next frame\n");
340      ddraw_delete_surfaces();
341      return 1;
342   }
343   if (result != DD_OK)
344   {
345      osd_printf_verbose("DirectDraw: Error %08X locking blit surface\n", (int)result);
346      return 1;
347   }
348
349   // render to it
350   window().m_primlist->acquire_lock();
351
352   // scan the list of primitives for tricky stuff
353   for (prim = window().m_primlist->first(); prim != NULL; prim = prim->next())
354      if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE ||
355         (prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32))
356      {
357         usemembuffer = TRUE;
358         break;
359      }
360
361   // if we're using the memory buffer, draw offscreen first and then copy
362   if (usemembuffer)
363   {
364      int x, y;
365
366      // based on the target format, use one of our standard renderers
367      switch (blitdesc.ddpfPixelFormat.dwRBitMask)
368      {
369         case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
370         case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
371         case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
372         case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, membuffer, blitwidth, blitheight, blitwidth);  break;
373         default:
374            osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
375            break;
376      }
377
378      // handle copying to both 16bpp and 32bpp destinations
379      for (y = 0; y < blitheight; y++)
380      {
381         if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 32)
382         {
383            UINT32 *src = (UINT32 *)membuffer + y * blitwidth;
384            UINT32 *dst = (UINT32 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
385            for (x = 0; x < blitwidth; x++)
386               *dst++ = *src++;
387         }
388         else if (blitdesc.ddpfPixelFormat.dwRGBBitCount == 16)
389         {
390            UINT16 *src = (UINT16 *)membuffer + y * blitwidth;
391            UINT16 *dst = (UINT16 *)((UINT8 *)blitdesc.lpSurface + y * blitdesc.lPitch);
392            for (x = 0; x < blitwidth; x++)
393               *dst++ = *src++;
394         }
395      }
396
397   }
398
399   // otherwise, draw directly
400   else
401   {
402      // based on the target format, use one of our standard renderers
403      switch (blitdesc.ddpfPixelFormat.dwRBitMask)
404      {
405         case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
406         case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 4); break;
407         case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
408         case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0, true>::draw_primitives(*window().m_primlist, blitdesc.lpSurface, blitwidth, blitheight, blitdesc.lPitch / 2); break;
409         default:
410            osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)blitdesc.ddpfPixelFormat.dwRBitMask, (int)blitdesc.ddpfPixelFormat.dwGBitMask, (int)blitdesc.ddpfPixelFormat.dwBBitMask);
411            break;
412      }
413   }
414   window().m_primlist->release_lock();
415
416   // unlock and blit
417   result = IDirectDrawSurface7_Unlock(blit, NULL);
418   if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X unlocking blit surface\n", (int)result);
419
420   // sync to VBLANK
421   if ((video_config.waitvsync || video_config.syncrefresh) && window().machine().video().throttled() && (!window().fullscreen() || back == NULL))
422   {
423      result = IDirectDraw7_WaitForVerticalBlank(ddraw, DDWAITVB_BLOCKBEGIN, NULL);
424      if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
425   }
426
427   // complete the blitting
428   blit_to_primary(blitwidth, blitheight);
429   return 0;
430}
431
432
433
434//============================================================
435//  ddraw_create
436//============================================================
437
438int renderer_dd::ddraw_create()
439{
440   HRESULT result;
441   int verify;
442
443   // if a device exists, free it
444   if (ddraw != NULL)
445      ddraw_delete();
446
447   // create the DirectDraw object
448   result = (*directdrawcreateex)(adapter_ptr, (LPVOID *)&ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
449   if (result != DD_OK)
450   {
451      osd_printf_verbose("DirectDraw: Error %08X during DirectDrawCreateEx call\n", (int)result);
452      goto error;
453   }
454
455   // verify the caps
456   verify = ddraw_verify_caps();
457   if (verify == 2)
458   {
459      osd_printf_error("DirectDraw: Error - Device does not meet minimum requirements for DirectDraw rendering\n");
460      goto error;
461   }
462   if (verify == 1)
463      osd_printf_verbose("DirectDraw: Warning - Device may not perform well for DirectDraw rendering\n");
464
465   // set the cooperative level
466   // for non-window modes, we will use full screen here
467   result = IDirectDraw7_SetCooperativeLevel(ddraw, win_window_list->m_hwnd, DDSCL_SETFOCUSWINDOW);
468   if (result != DD_OK)
469   {
470      osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_SetCooperativeLevel(FOCUSWINDOW) call\n", (int)result);
471      goto error;
472   }
473   result = IDirectDraw7_SetCooperativeLevel(ddraw, window().m_hwnd, DDSCL_SETDEVICEWINDOW | (window().fullscreen() ? DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE : DDSCL_NORMAL));
474   if (result != DD_OK)
475   {
476      osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_SetCooperativeLevel(DEVICEWINDOW) call\n", (int)result);
477      goto error;
478   }
479
480   // full screen mode: set the resolution
481   if (window().fullscreen() && video_config.switchres)
482   {
483      result = IDirectDraw7_SetDisplayMode(ddraw, width, height, 32, refresh, 0);
484      if (result != DD_OK)
485      {
486         osd_printf_verbose("DirectDraw: Error %08X attempting to set video mode %dx%d@%d call\n", (int)result, width, height, refresh);
487         goto error;
488      }
489   }
490
491   return ddraw_create_surfaces();
492
493error:
494   ddraw_delete();
495   return 1;
496}
497
498
499
500//============================================================
501//  ddraw_create_surfaces
502//============================================================
503
504int renderer_dd::ddraw_create_surfaces()
505{
506   HRESULT result;
507
508   // make a description of the primary surface
509   memset(&primarydesc, 0, sizeof(primarydesc));
510   primarydesc.dwSize = sizeof(primarydesc);
511   primarydesc.dwFlags = DDSD_CAPS;
512   primarydesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
513
514   // for triple-buffered full screen mode, allocate flipping surfaces
515   if (window().fullscreen() && video_config.triplebuf)
516   {
517      primarydesc.dwFlags |= DDSD_BACKBUFFERCOUNT;
518      primarydesc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX;
519      primarydesc.dwBackBufferCount = 2;
520   }
521
522   // create the primary surface and report errors
523   result = create_surface(&primarydesc, &primary, "primary");
524   if (result != DD_OK) goto error;
525
526   // full screen mode: get the back surface
527   back = NULL;
528   if (window().fullscreen() && video_config.triplebuf)
529   {
530      DDSCAPS2 caps = { DDSCAPS_BACKBUFFER };
531      result = IDirectDrawSurface7_GetAttachedSurface(primary, &caps, &back);
532      if (result != DD_OK)
533      {
534         osd_printf_verbose("DirectDraw: Error %08X getting attached back surface\n", (int)result);
535         goto error;
536      }
537   }
538
539   // now make a description of our blit surface, based on the primary surface
540   if (blitwidth == 0 || blitheight == 0)
541      compute_blit_surface_size();
542   blitdesc = primarydesc;
543   blitdesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
544   blitdesc.dwWidth = blitwidth;
545   blitdesc.dwHeight = blitheight;
546   blitdesc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
547
548   // then create the blit surface, fall back to system memory if video mem doesn't work
549   result = create_surface(&blitdesc, &blit, "blit");
550   if (result != DD_OK)
551   {
552      blitdesc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
553      result = create_surface(&blitdesc, &blit, "blit");
554   }
555   if (result != DD_OK) goto error;
556
557   // create a memory buffer for offscreen drawing
558   if (membuffersize < blitwidth * blitheight * 4)
559   {
560      membuffersize = blitwidth * blitheight * 4;
561      global_free_array(membuffer);
562      membuffer = global_alloc_array(UINT8, membuffersize);
563   }
564   if (membuffer == NULL)
565      goto error;
566
567   // create a clipper for windowed mode
568   if (!window().fullscreen() && create_clipper())
569      goto error;
570
571   // full screen mode: set the gamma
572   if (window().fullscreen())
573   {
574      // only set the gamma if it's not 1.0f
575      windows_options &options = downcast<windows_options &>(window().machine().options());
576      float brightness = options.full_screen_brightness();
577      float contrast = options.full_screen_contrast();
578      float fgamma = options.full_screen_gamma();
579      if (brightness != 1.0f || contrast != 1.0f || fgamma != 1.0f)
580      {
581         // see if we can get a GammaControl object
582         result = IDirectDrawSurface_QueryInterface(primary, WRAP_REFIID(IID_IDirectDrawGammaControl), (void **)&gamma);
583         if (result != DD_OK)
584         {
585            osd_printf_warning("DirectDraw: Warning - device does not support full screen gamma correction.\n");
586            this->gamma = NULL;
587         }
588
589         // proceed if we can
590         if (this->gamma != NULL)
591         {
592            DDGAMMARAMP ramp;
593            int i;
594
595            // create a standard ramp and set it
596            for (i = 0; i < 256; i++)
597               ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, fgamma) << 8;
598
599            // attempt to set it
600            result = IDirectDrawGammaControl_SetGammaRamp(this->gamma, 0, &ramp);
601            if (result != DD_OK)
602               osd_printf_verbose("DirectDraw: Error %08X attempting to set gamma correction.\n", (int)result);
603         }
604      }
605   }
606
607   // force some updates
608   update_outer_rects();
609   return 0;
610
611error:
612   ddraw_delete_surfaces();
613   return 1;
614}
615
616
617
618//============================================================
619//  ddraw_delete
620//============================================================
621
622void renderer_dd::ddraw_delete()
623{
624   // free surfaces
625   ddraw_delete_surfaces();
626
627   // restore resolutions
628   if (ddraw != NULL)
629      IDirectDraw7_RestoreDisplayMode(ddraw);
630
631   // reset cooperative level
632   if (ddraw != NULL && window().m_hwnd != NULL)
633      IDirectDraw7_SetCooperativeLevel(ddraw, window().m_hwnd, DDSCL_NORMAL);
634
635   // release the DirectDraw object itself
636   if (ddraw != NULL)
637      IDirectDraw7_Release(ddraw);
638   ddraw = NULL;
639}
640
641
642
643//============================================================
644//  ddraw_delete_surfaces
645//============================================================
646
647void renderer_dd::ddraw_delete_surfaces()
648{
649   // release the gamma control
650   if (gamma != NULL)
651      IDirectDrawGammaControl_Release(gamma);
652   gamma = NULL;
653
654   // release the clipper
655   if (clipper != NULL)
656      IDirectDrawClipper_Release(clipper);
657   clipper = NULL;
658
659   // free the memory buffer
660   global_free_array(membuffer);
661   membuffer = NULL;
662   membuffersize = 0;
663
664   // release the blit surface
665   if (blit != NULL)
666      IDirectDrawSurface7_Release(blit);
667   blit = NULL;
668
669   // release the back surface
670   if (back != NULL)
671      IDirectDrawSurface7_Release(back);
672   back = NULL;
673
674   // release the primary surface
675   if (primary != NULL)
676      IDirectDrawSurface7_Release(primary);
677   primary = NULL;
678}
679
680
681
682//============================================================
683//  ddraw_verify_caps
684//============================================================
685
686int renderer_dd::ddraw_verify_caps()
687{
688   int retval = 0;
689   HRESULT result;
690
691   // get the capabilities
692   ddcaps.dwSize = sizeof(ddcaps);
693   helcaps.dwSize = sizeof(helcaps);
694   result = IDirectDraw7_GetCaps(ddraw, &ddcaps, &helcaps);
695   if (result != DD_OK)
696   {
697      osd_printf_verbose("DirectDraw: Error %08X during IDirectDraw7_GetCaps call\n", (int)result);
698      return 1;
699   }
700
701   // determine if hardware stretching is available
702   if ((ddcaps.dwCaps & DDCAPS_BLTSTRETCH) == 0)
703   {
704      osd_printf_verbose("DirectDraw: Warning - Device does not support hardware stretching\n");
705      retval = 1;
706   }
707
708   return retval;
709}
710
711
712
713//============================================================
714//  ddraw_test_cooperative
715//============================================================
716
717int renderer_dd::ddraw_test_cooperative()
718{
719   HRESULT result;
720
721   // check our current status; if we lost the device, punt to GDI
722   result = IDirectDraw7_TestCooperativeLevel(ddraw);
723   switch (result)
724   {
725      // punt to GDI if someone else has exclusive mode
726      case DDERR_NOEXCLUSIVEMODE:
727      case DDERR_EXCLUSIVEMODEALREADYSET:
728         ddraw_delete_surfaces();
729         return 1;
730
731      // if we're ok, but we don't have a primary surface, create one
732      default:
733      case DD_OK:
734         if (primary == NULL)
735            return ddraw_create_surfaces();
736         return 0;
737   }
738}
739
740
741
742//============================================================
743//  create_surface
744//============================================================
745
746HRESULT renderer_dd::create_surface(DDSURFACEDESC2 *desc, IDirectDrawSurface7 **surface, const char *type)
747{
748   HRESULT result;
749
750   // create the surface as requested
751   result = IDirectDraw7_CreateSurface(ddraw, desc, surface, NULL);
752   if (result != DD_OK)
753   {
754      osd_printf_verbose("DirectDraw: Error %08X creating %s surface\n", (int)result, type);
755      return result;
756   }
757
758   // get a description of the primary surface
759   result = IDirectDrawSurface7_GetSurfaceDesc(*surface, desc);
760   if (result != DD_OK)
761   {
762      osd_printf_verbose("DirectDraw: Error %08X getting %s surface desciption\n", (int)result, type);
763      IDirectDrawSurface7_Release(*surface);
764      *surface = NULL;
765      return result;
766   }
767
768   // print out the good stuff
769   osd_printf_verbose("DirectDraw: %s surface created: %dx%dx%d (R=%08X G=%08X B=%08X)\n",
770            type,
771            (int)desc->dwWidth,
772            (int)desc->dwHeight,
773            (int)desc->ddpfPixelFormat.dwRGBBitCount,
774            (UINT32)desc->ddpfPixelFormat.dwRBitMask,
775            (UINT32)desc->ddpfPixelFormat.dwGBitMask,
776            (UINT32)desc->ddpfPixelFormat.dwBBitMask);
777   return result;
778}
779
780
781
782//============================================================
783//  create_clipper
784//============================================================
785
786int renderer_dd::create_clipper()
787{
788   HRESULT result;
789
790   // create a clipper for the primary surface
791   result = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL);
792   if (result != DD_OK)
793   {
794      osd_printf_verbose("DirectDraw: Error %08X creating clipper\n", (int)result);
795      return 1;
796   }
797
798   // set the clipper's hwnd
799   result = IDirectDrawClipper_SetHWnd(clipper, 0, window().m_hwnd);
800   if (result != DD_OK)
801   {
802      osd_printf_verbose("DirectDraw: Error %08X setting clipper hwnd\n", (int)result);
803      return 1;
804   }
805
806   // set the clipper on the primary surface
807   result = IDirectDrawSurface7_SetClipper(primary, clipper);
808   if (result != DD_OK)
809   {
810      osd_printf_verbose("DirectDraw: Error %08X setting clipper on primary surface\n", (int)result);
811      return 1;
812   }
813   return 0;
814}
815
816
817
818//============================================================
819//  compute_blit_surface_size
820//============================================================
821
822void renderer_dd::compute_blit_surface_size()
823{
824   INT32 newwidth, newheight;
825   int xscale, yscale;
826   RECT client;
827
828   // start with the minimum size
829   window().target()->compute_minimum_size(newwidth, newheight);
830
831   // get the window's client rectangle
832   GetClientRect(window().m_hwnd, &client);
833
834   // hardware stretch case: apply prescale
835   if (video_config.hwstretch)
836   {
837      int prescale = (window().prescale() < 1) ? 1 : window().prescale();
838
839      // clamp the prescale to something smaller than the target bounds
840      xscale = prescale;
841      while (xscale > 1 && newwidth * xscale > rect_width(&client))
842         xscale--;
843      yscale = prescale;
844      while (yscale > 1 && newheight * yscale > rect_height(&client))
845         yscale--;
846   }
847
848   // non stretch case
849   else
850   {
851      INT32 target_width = rect_width(&client);
852      INT32 target_height = rect_height(&client);
853      float desired_aspect = 1.0f;
854
855      // compute the appropriate visible area if we're trying to keepaspect
856      if (video_config.keepaspect)
857      {
858         win_monitor_info *monitor = window().winwindow_video_window_monitor(NULL);
859         window().target()->compute_visible_area(target_width, target_height, monitor->aspect(), window().target()->orientation(), target_width, target_height);
860         desired_aspect = (float)target_width / (float)target_height;
861      }
862
863      // compute maximum integral scaling to fit the window
864      xscale = (target_width + 2) / newwidth;
865      yscale = (target_height + 2) / newheight;
866
867      // try a little harder to keep the aspect ratio if desired
868      if (video_config.keepaspect)
869      {
870         // if we could stretch more in the X direction, and that makes a better fit, bump the xscale
871         while (newwidth * (xscale + 1) <= rect_width(&client) &&
872            better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale + 1), newheight * yscale, desired_aspect))
873            xscale++;
874
875         // if we could stretch more in the Y direction, and that makes a better fit, bump the yscale
876         while (newheight * (yscale + 1) <= rect_height(&client) &&
877            better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale + 1), desired_aspect))
878            yscale++;
879
880         // now that we've maxed out, see if backing off the maximally stretched one makes a better fit
881         if (rect_width(&client) - newwidth * xscale < rect_height(&client) - newheight * yscale)
882         {
883            while (xscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect))
884               xscale--;
885         }
886         else
887         {
888            while (yscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale - 1), desired_aspect))
889               yscale--;
890         }
891      }
892   }
893
894   // ensure at least a scale factor of 1
895   if (xscale == 0) xscale = 1;
896   if (yscale == 0) yscale = 1;
897
898   // apply the final scale
899   newwidth *= xscale;
900   newheight *= yscale;
901   if (newwidth != blitwidth || newheight != blitheight)
902   {
903      // force some updates
904      update_outer_rects();
905      osd_printf_verbose("DirectDraw: New blit size = %dx%d\n", newwidth, newheight);
906   }
907   blitwidth = newwidth;
908   blitheight = newheight;
909}
910
911
912
913//============================================================
914//  calc_fullscreen_margins
915//============================================================
916
917void renderer_dd::calc_fullscreen_margins(DWORD desc_width, DWORD desc_height, RECT *margins)
918{
919   margins->left = 0;
920   margins->top = 0;
921   margins->right = desc_width;
922   margins->bottom = desc_height;
923
924   if (window().win_has_menu())
925   {
926      static int height_with_menubar = 0;
927      if (height_with_menubar == 0)
928      {
929         RECT with_menu = { 100, 100, 200, 200 };
930         RECT without_menu = { 100, 100, 200, 200 };
931         AdjustWindowRect(&with_menu, WS_OVERLAPPED, TRUE);
932         AdjustWindowRect(&without_menu, WS_OVERLAPPED, FALSE);
933         height_with_menubar = (with_menu.bottom - with_menu.top) - (without_menu.bottom - without_menu.top);
934      }
935      margins->top = height_with_menubar;
936   }
937}
938
939
940
941//============================================================
942//  blit_to_primary
943//============================================================
944
945void renderer_dd::blit_to_primary(int srcwidth, int srcheight)
946{
947   IDirectDrawSurface7 *target = (back != NULL) ? back : primary;
948   win_monitor_info *monitor = window().winwindow_video_window_monitor(NULL);
949   DDBLTFX blitfx = { sizeof(DDBLTFX) };
950   RECT clear, outer, dest, source;
951   INT32 dstwidth, dstheight;
952   HRESULT result;
953
954   // compute source rect
955   source.left = source.top = 0;
956   source.right = srcwidth;
957   source.bottom = srcheight;
958
959   // compute outer rect -- windowed version
960   if (!window().fullscreen())
961   {
962      GetClientRect(window().m_hwnd, &outer);
963      ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[0]);
964      ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[1]);
965
966      // adjust to be relative to the monitor
967      osd_rect pos = monitor->position_size();
968      outer.left -= pos.left();
969      outer.right -= pos.left();
970      outer.top -= pos.top();
971      outer.bottom -= pos.top();
972   }
973
974   // compute outer rect -- full screen version
975   else
976   {
977      calc_fullscreen_margins(primarydesc.dwWidth, primarydesc.dwHeight, &outer);
978   }
979
980   // if we're respecting the aspect ratio, we need to adjust to fit
981   dstwidth = rect_width(&outer);
982   dstheight = rect_height(&outer);
983   if (!video_config.hwstretch)
984   {
985      // trim the source if necessary
986      if (rect_width(&outer) < srcwidth)
987      {
988         source.left += (srcwidth - rect_width(&outer)) / 2;
989         source.right = source.left + rect_width(&outer);
990      }
991      if (rect_height(&outer) < srcheight)
992      {
993         source.top += (srcheight - rect_height(&outer)) / 2;
994         source.bottom = source.top + rect_height(&outer);
995      }
996
997      // match the destination and source sizes
998      dstwidth = srcwidth = source.right - source.left;
999      dstheight = srcheight = source.bottom - source.top;
1000   }
1001   else if (video_config.keepaspect)
1002   {
1003      // compute the appropriate visible area
1004      window().target()->compute_visible_area(rect_width(&outer), rect_height(&outer), monitor->aspect(), window().target()->orientation(), dstwidth, dstheight);
1005   }
1006
1007   // center within
1008   dest.left = outer.left + (rect_width(&outer) - dstwidth) / 2;
1009   dest.right = dest.left + dstwidth;
1010   dest.top = outer.top + (rect_height(&outer) - dstheight) / 2;
1011   dest.bottom = dest.top + dstheight;
1012
1013   // compare against last destination; if different, force a redraw
1014   if (dest.left != lastdest.left || dest.right != lastdest.right || dest.top != lastdest.top || dest.bottom != lastdest.bottom)
1015   {
1016      lastdest = dest;
1017      update_outer_rects();
1018   }
1019
1020   // clear outer rects if we need to
1021   if (clearouter != 0)
1022   {
1023      clearouter--;
1024
1025      // clear the left edge
1026      if (dest.left > outer.left)
1027      {
1028         clear = outer;
1029         clear.right = dest.left;
1030         result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
1031         if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
1032      }
1033
1034      // clear the right edge
1035      if (dest.right < outer.right)
1036      {
1037         clear = outer;
1038         clear.left = dest.right;
1039         result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
1040         if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
1041      }
1042
1043      // clear the top edge
1044      if (dest.top > outer.top)
1045      {
1046         clear = outer;
1047         clear.bottom = dest.top;
1048         result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
1049         if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
1050      }
1051
1052      // clear the bottom edge
1053      if (dest.bottom < outer.bottom)
1054      {
1055         clear = outer;
1056         clear.top = dest.bottom;
1057         result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
1058         if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X clearing the screen\n", (int)result);
1059      }
1060   }
1061
1062   // do the blit
1063   result = IDirectDrawSurface7_Blt(target, &dest, blit, &source, DDBLT_WAIT, NULL);
1064   if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X blitting to the screen\n", (int)result);
1065
1066   // page flip if triple buffered
1067   if (window().fullscreen() && back != NULL)
1068   {
1069      result = IDirectDrawSurface7_Flip(primary, NULL, DDFLIP_WAIT);
1070      if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X waiting for VBLANK\n", (int)result);
1071   }
1072}
1073
1074
1075
1076//============================================================
1077//  config_adapter_mode
1078//============================================================
1079
1080int renderer_dd::config_adapter_mode()
1081{
1082   DDDEVICEIDENTIFIER2 identifier;
1083   HRESULT result;
1084
1085   // choose the monitor number
1086   get_adapter_for_monitor(window().monitor());
1087
1088   // create a temporary DirectDraw object
1089   result = (*directdrawcreateex)(adapter_ptr, (LPVOID *)&ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
1090   if (result != DD_OK)
1091   {
1092      osd_printf_verbose("DirectDraw: Error %08X during DirectDrawCreateEx call\n", (int)result);
1093      return 1;
1094   }
1095
1096   // get the identifier
1097   result = IDirectDraw7_GetDeviceIdentifier(ddraw, &identifier, 0);
1098   if (result != DD_OK)
1099   {
1100      osd_printf_error("Error getting identifier for device\n");
1101      return 1;
1102   }
1103   osd_printf_verbose("DirectDraw: Configuring device %s\n", identifier.szDescription);
1104
1105   // get the current display mode
1106   memset(&origmode, 0, sizeof(origmode));
1107   origmode.dwSize = sizeof(origmode);
1108   result = IDirectDraw7_GetDisplayMode(ddraw, &origmode);
1109   if (result != DD_OK)
1110   {
1111      osd_printf_verbose("DirectDraw: Error %08X getting current display mode\n", (int)result);
1112      IDirectDraw7_Release(ddraw);
1113      return 1;
1114   }
1115
1116   // choose a resolution: full screen mode case
1117   if (window().fullscreen())
1118   {
1119      // default to the current mode exactly
1120      width = origmode.dwWidth;
1121      height = origmode.dwHeight;
1122      refresh = origmode.dwRefreshRate;
1123
1124      // if we're allowed to switch resolutions, override with something better
1125      if (video_config.switchres)
1126         pick_best_mode();
1127   }
1128
1129   // release the DirectDraw object
1130   IDirectDraw7_Release(ddraw);
1131   ddraw = NULL;
1132
1133   // if we're not changing resolutions, make sure we have a resolution we can handle
1134   if (!window().fullscreen() || !video_config.switchres)
1135   {
1136      switch (origmode.ddpfPixelFormat.dwRBitMask)
1137      {
1138         case 0x00ff0000:
1139         case 0x000000ff:
1140         case 0xf800:
1141         case 0x7c00:
1142            break;
1143
1144         default:
1145            osd_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)origmode.ddpfPixelFormat.dwRBitMask, (int)origmode.ddpfPixelFormat.dwGBitMask, (int)origmode.ddpfPixelFormat.dwBBitMask);
1146            return 1;
1147      }
1148   }
1149
1150   return 0;
1151}
1152
1153
1154
1155//============================================================
1156//  monitor_enum_callback
1157//============================================================
1158
1159static BOOL WINAPI monitor_enum_callback(GUID FAR *guid, LPSTR description, LPSTR name, LPVOID context, HMONITOR hmonitor)
1160{
1161   monitor_enum_info *einfo = (monitor_enum_info *)context;
1162
1163   // do we match the desired monitor?
1164   if (hmonitor == einfo->monitor->handle() || (hmonitor == NULL && einfo->monitor->is_primary()))
1165   {
1166      einfo->guid_ptr = (guid != NULL) ? &einfo->guid : NULL;
1167      if (guid != NULL)
1168         einfo->guid = *guid;
1169      einfo->foundit = TRUE;
1170   }
1171   return 1;
1172}
1173
1174
1175
1176//============================================================
1177//  get_adapter_for_monitor
1178//============================================================
1179
1180void renderer_dd::get_adapter_for_monitor(win_monitor_info *monitor)
1181{
1182   monitor_enum_info einfo;
1183   HRESULT result;
1184
1185   // try to find our monitor
1186   memset(&einfo, 0, sizeof(einfo));
1187   einfo.monitor = monitor;
1188   result = (*directdrawenumerateex)(monitor_enum_callback, &einfo, DDENUM_ATTACHEDSECONDARYDEVICES);
1189   if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X during DirectDrawEnumerateEx call\n", (int)result);
1190
1191   // set up the adapter
1192   if (einfo.foundit && einfo.guid_ptr != NULL)
1193   {
1194      adapter = einfo.guid;
1195      adapter_ptr = &adapter;
1196   }
1197   else
1198      adapter_ptr = NULL;
1199}
1200
1201
1202
1203//============================================================
1204//  enum_modes_callback
1205//============================================================
1206
1207static HRESULT WINAPI enum_modes_callback(LPDDSURFACEDESC2 desc, LPVOID context)
1208{
1209   float size_score, refresh_score, final_score;
1210   mode_enum_info *einfo = (mode_enum_info *)context;
1211   renderer_dd *dd = einfo->renderer;
1212
1213   // skip non-32 bit modes
1214   if (desc->ddpfPixelFormat.dwRGBBitCount != 32)
1215      return DDENUMRET_OK;
1216
1217   // compute initial score based on difference between target and current
1218   size_score = 1.0f / (1.0f + fabs((float)((INT32)desc->dwWidth - einfo->target_width)) + fabs((float)((INT32)desc->dwHeight - einfo->target_height)));
1219
1220   // if the mode is too small, give a big penalty
1221   if (desc->dwWidth < einfo->minimum_width || desc->dwHeight < einfo->minimum_height)
1222      size_score *= 0.01f;
1223
1224   // if mode is smaller than we'd like, it only scores up to 0.1
1225   if (desc->dwWidth < einfo->target_width || desc->dwHeight < einfo->target_height)
1226      size_score *= 0.1f;
1227
1228   // if we're looking for a particular mode, that's a winner
1229   if (desc->dwWidth == einfo->window->m_win_config.width && desc->dwHeight == einfo->window->m_win_config.height)
1230      size_score = 2.0f;
1231
1232   // compute refresh score
1233   refresh_score = 1.0f / (1.0f + fabs((double)desc->dwRefreshRate - einfo->target_refresh));
1234
1235   // if refresh is smaller than we'd like, it only scores up to 0.1
1236   if ((double)desc->dwRefreshRate < einfo->target_refresh)
1237      refresh_score *= 0.1f;
1238
1239   // if we're looking for a particular refresh, make sure it matches
1240   if (desc->dwRefreshRate == einfo->window->m_win_config.refresh)
1241      refresh_score = 2.0f;
1242
1243   // weight size and refresh equally
1244   final_score = size_score + refresh_score;
1245
1246   // best so far?
1247   osd_printf_verbose("  %4dx%4d@%3dHz -> %f\n", (int)desc->dwWidth, (int)desc->dwHeight, (int)desc->dwRefreshRate, final_score * 1000.0f);
1248   if (final_score > einfo->best_score)
1249   {
1250      einfo->best_score = final_score;
1251      dd->width = desc->dwWidth;
1252      dd->height = desc->dwHeight;
1253      dd->refresh = desc->dwRefreshRate;
1254   }
1255   return DDENUMRET_OK;
1256}
1257
1258
1259
1260//============================================================
1261//  pick_best_mode
1262//============================================================
1263
1264void renderer_dd::pick_best_mode()
1265{
1266   mode_enum_info einfo;
1267   HRESULT result;
1268
1269   // determine the minimum width/height for the selected target
1270   // note: technically we should not be calling this from an alternate window
1271   // thread; however, it is only done during init time, and the init code on
1272   // the main thread is waiting for us to finish, so it is safe to do so here
1273   window().target()->compute_minimum_size(einfo.minimum_width, einfo.minimum_height);
1274
1275   // use those as the target for now
1276   einfo.target_width = einfo.minimum_width * MAX(1, window().prescale());
1277   einfo.target_height = einfo.minimum_height * MAX(1, window().prescale());
1278
1279   // determine the refresh rate of the primary screen
1280   einfo.target_refresh = 60.0;
1281   const screen_device *primary_screen = window().machine().config().first_screen();
1282   if (primary_screen != NULL)
1283      einfo.target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
1284   printf("Target refresh = %f\n", einfo.target_refresh);
1285
1286   // if we're not stretching, allow some slop on the minimum since we can handle it
1287   if (!video_config.hwstretch)
1288   {
1289      einfo.minimum_width -= 4;
1290      einfo.minimum_height -= 4;
1291   }
1292
1293   // if we are stretching, aim for a mode approximately 2x the game's resolution
1294   else if (window().prescale() <= 1)
1295   {
1296      einfo.target_width *= 2;
1297      einfo.target_height *= 2;
1298   }
1299
1300   // fill in the rest of the data
1301   einfo.window = &window();
1302   einfo.renderer = this;
1303   einfo.best_score = 0.0f;
1304
1305   // enumerate the modes
1306   osd_printf_verbose("DirectDraw: Selecting video mode...\n");
1307   result = IDirectDraw7_EnumDisplayModes(ddraw, DDEDM_REFRESHRATES, NULL, &einfo, enum_modes_callback);
1308   if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X during EnumDisplayModes call\n", (int)result);
1309   osd_printf_verbose("DirectDraw: Mode selected = %4dx%4d@%3dHz\n", width, height, refresh);
1310}
trunk/src/osd/windows/drawgdi.c
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawgdi.c - Win32 GDI drawing
6//
7//============================================================
8
9// standard windows headers
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12
13// MAME headers
14#include "emu.h"
15#include "rendersw.inc"
16
17// MAMEOS headers
18#include "window.h"
19
20
21//============================================================
22//  TYPE DEFINITIONS
23//============================================================
24
25class renderer_gdi : public osd_renderer
26{
27public:
28   renderer_gdi(osd_window *window)
29   : osd_renderer(window, FLAG_NONE), bmdata(NULL), bmsize(0) { }
30
31   virtual ~renderer_gdi() { }
32
33   virtual int create();
34   virtual render_primitive_list *get_primitives();
35   virtual int draw(const int update);
36   virtual void save() {};
37   virtual void record() {};
38   virtual void toggle_fsfx() {};
39   virtual void destroy();
40
41private:
42   /* gdi_info is the information for the current screen */
43   BITMAPINFO              bminfo;
44   UINT8 *                 bmdata;
45   size_t                  bmsize;
46};
47
48
49//============================================================
50//  PROTOTYPES
51//============================================================
52
53// core functions
54static void drawgdi_exit(void);
55
56//============================================================
57//  drawnone_create
58//============================================================
59
60static osd_renderer *drawgdi_create(osd_window *window)
61{
62   return global_alloc(renderer_gdi(window));
63}
64
65
66//============================================================
67//  drawgdi_init
68//============================================================
69
70int drawgdi_init(running_machine &machine, osd_draw_callbacks *callbacks)
71{
72   // fill in the callbacks
73   memset(callbacks, 0, sizeof(*callbacks));
74   callbacks->exit = drawgdi_exit;
75   callbacks->create = drawgdi_create;
76   return 0;
77}
78
79
80
81//============================================================
82//  drawgdi_exit
83//============================================================
84
85static void drawgdi_exit(void)
86{
87}
88
89
90
91//============================================================
92//  drawgdi_window_init
93//============================================================
94
95int renderer_gdi::create()
96{
97   // fill in the bitmap info header
98   bminfo.bmiHeader.biSize            = sizeof(bminfo.bmiHeader);
99   bminfo.bmiHeader.biPlanes          = 1;
100   bminfo.bmiHeader.biBitCount        = 32;
101   bminfo.bmiHeader.biCompression     = BI_RGB;
102   bminfo.bmiHeader.biSizeImage       = 0;
103   bminfo.bmiHeader.biXPelsPerMeter   = 0;
104   bminfo.bmiHeader.biYPelsPerMeter   = 0;
105   bminfo.bmiHeader.biClrUsed         = 0;
106   bminfo.bmiHeader.biClrImportant    = 0;
107
108   return 0;
109}
110
111
112
113//============================================================
114//  drawgdi_window_destroy
115//============================================================
116
117void renderer_gdi::destroy()
118{
119   // free the bitmap memory
120   if (bmdata != NULL)
121      global_free_array(bmdata);
122}
123
124
125
126//============================================================
127//  drawgdi_window_get_primitives
128//============================================================
129
130render_primitive_list *renderer_gdi::get_primitives()
131{
132   RECT client;
133   GetClientRect(window().m_hwnd, &client);
134   window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
135   return &window().target()->get_primitives();
136}
137
138
139
140//============================================================
141//  drawgdi_window_draw
142//============================================================
143
144int renderer_gdi::draw(const int update)
145{
146   int width, height, pitch;
147   RECT bounds;
148
149   // we don't have any special resize behaviors
150   if (window().m_resize_state == RESIZE_STATE_PENDING)
151      window().m_resize_state = RESIZE_STATE_NORMAL;
152
153   // get the target bounds
154   GetClientRect(window().m_hwnd, &bounds);
155
156   // compute width/height/pitch of target
157   width = rect_width(&bounds);
158   height = rect_height(&bounds);
159   pitch = (width + 3) & ~3;
160
161   // make sure our temporary bitmap is big enough
162   if (pitch * height * 4 > bmsize)
163   {
164      bmsize = pitch * height * 4 * 2;
165      global_free_array(bmdata);
166      bmdata = global_alloc_array(UINT8, bmsize);
167   }
168
169   // draw the primitives to the bitmap
170   window().m_primlist->acquire_lock();
171   software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, bmdata, width, height, pitch);
172   window().m_primlist->release_lock();
173
174   // fill in bitmap-specific info
175   bminfo.bmiHeader.biWidth = pitch;
176   bminfo.bmiHeader.biHeight = -height;
177
178   // blit to the screen
179   StretchDIBits(window().m_dc, 0, 0, width, height,
180            0, 0, width, height,
181            bmdata, &bminfo, DIB_RGB_COLORS, SRCCOPY);
182   return 0;
183}
trunk/src/osd/windows/drawnone.c
r244651r244652
1// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
3//============================================================
4//
5//  drawnone.c - stub "nothing" drawer
6//
7//============================================================
8
9// standard windows headers
10#define WIN32_LEAN_AND_MEAN
11#include <windows.h>
12
13// MAME headers
14#include "emu.h"
15
16// MAMEOS headers
17#include "window.h"
18
19
20class renderer_none : public osd_renderer
21{
22public:
23   renderer_none(osd_window *window)
24   : osd_renderer(window, FLAG_NONE) { }
25
26   virtual ~renderer_none() { }
27
28   virtual int create();
29   virtual render_primitive_list *get_primitives();
30   virtual int draw(const int update);
31   virtual void save() { };
32   virtual void record() { };
33   virtual void toggle_fsfx() { };
34   virtual void destroy();
35
36private:
37};
38
39//============================================================
40//  PROTOTYPES
41//============================================================
42
43// core functions
44static void drawnone_exit(void);
45
46//============================================================
47//  drawnone_create
48//============================================================
49
50osd_renderer *drawnone_create(osd_window *window)
51{
52   return global_alloc(renderer_none(window));
53}
54
55//============================================================
56//  drawnone_init
57//============================================================
58
59int drawnone_init(running_machine &machine, osd_draw_callbacks *callbacks)
60{
61   // fill in the callbacks
62   memset(callbacks, 0, sizeof(*callbacks));
63   callbacks->exit = drawnone_exit;
64   callbacks->create = drawnone_create;
65   return 0;
66}
67
68
69
70//============================================================
71//  drawnone_exit
72//============================================================
73
74static void drawnone_exit(void)
75{
76}
77
78
79
80//============================================================
81//  drawnone_window_init
82//============================================================
83
84int renderer_none::create()
85{
86   return 0;
87}
88
89
90
91//============================================================
92//  drawnone_window_destroy
93//============================================================
94
95void renderer_none::destroy()
96{
97}
98
99
100
101//============================================================
102//  drawnone_window_get_primitives
103//============================================================
104
105render_primitive_list *renderer_none::get_primitives()
106{
107   RECT client;
108   GetClientRect(window().m_hwnd, &client);
109   window().target()->set_bounds(rect_width(&client), rect_height(&client), window().aspect());
110   return &window().target()->get_primitives();
111}
112
113
114
115//============================================================
116//  drawnone_window_draw
117//============================================================
118
119int renderer_none::draw(const int update)
120{
121   return 0;
122}
trunk/src/osd/windows/windows.mak
r244651r244652
9999   $(OSDOBJ)/modules/midi \
100100   $(OSDOBJ)/modules/font \
101101   $(OSDOBJ)/modules/netdev \
102   $(OSDOBJ)/modules/render \
103   $(OSDOBJ)/modules/render/d3d \
102104   $(OSDOBJ)/modules/debugger/win
103105
104106ifdef USE_QTDEBUG
r244651r244652
373375#-------------------------------------------------
374376
375377OSDOBJS = \
376   $(WINOBJ)/d3d9intf.o \
377   $(WINOBJ)/drawd3d.o \
378   $(WINOBJ)/d3dhlsl.o \
379   $(WINOBJ)/drawdd.o \
380   $(WINOBJ)/drawgdi.o \
381   $(WINOBJ)/drawbgfx.o \
382   $(WINOBJ)/drawnone.o \
378   $(OSDOBJ)/modules/render/drawd3d.o \
379   $(OSDOBJ)/modules/render/d3d/d3d9intf.o \
380   $(OSDOBJ)/modules/render/d3d/d3dhlsl.o \
381   $(OSDOBJ)/modules/render/drawdd.o \
382   $(OSDOBJ)/modules/render/drawgdi.o \
383   $(OSDOBJ)/modules/render/drawbgfx.o \
384   $(OSDOBJ)/modules/render/drawnone.o \
383385   $(WINOBJ)/input.o \
384386   $(WINOBJ)/output.o \
385387   $(OSDOBJ)/modules/sound/js_sound.o  \
r244651r244652
403405
404406ifdef USE_OPENGL
405407OSDOBJS += \
406   $(WINOBJ)/../sdl/drawogl.o \
408   $(OSDOBJ)/modules/render/drawogl.o \
407409   $(OSDOBJ)/modules/opengl/gl_shader_tool.o \
408410   $(OSDOBJ)/modules/opengl/gl_shader_mgr.o
409411   
410412OBJDIRS += \
411   $(OSDOBJ)/modules/opengl \
412   $(WINOBJ)/../sdl
413   $(OSDOBJ)/modules/opengl
413414
414415DEFS += -DUSE_OPENGL=1
415416


Previous 199869 Revisions Next


© 1997-2024 The MAME Team